+
+ /*
+ * Additive effects
+ * ==========================
+ */
+ struct ik_basic *arm_l = &player.mdl.ik_arm_l,
+ *arm_r = &player.mdl.ik_arm_r;
+
+ v3f localv;
+ m3x3_mulv( player.to_local, player.v, localv );
+ v3_muladds( arm_l->end, localv, -0.01f, arm_l->end );
+ v3_muladds( arm_r->end, localv, -0.01f, arm_r->end );
+
+ /* New board transformation */
+ v4f board_rotation; v3f board_location;
+
+ /* TODO: Move this out of animate into update */
+ v2_lerp( player.board_xy, (v2f){ vg_get_axis("h1"), vg_get_axis("v1") },
+ ktimestep*3.0f, player.board_xy );
+
+ v4f rz, rx;
+ q_axis_angle( rz, (v3f){ 0.0f, 0.0f, 1.0f }, player.board_xy[0] );
+ q_axis_angle( rx, (v3f){ 1.0f, 0.0f, 0.0f }, player.board_xy[1] );
+ q_mul( rx, rz, board_rotation );
+
+ v3f *mboard = player.mdl.matrices[k_chpart_board];// player.mboard;
+ q_m3x3( board_rotation, mboard );
+ m3x3_mulv( mboard, (v3f){ 0.0f, -0.5f, 0.0f }, board_location );
+ v3_add( (v3f){0.0f,0.5f,0.0f}, board_location, board_location );
+ v3_copy( board_location, mboard[3] );
+
+
+ float wheel_r = offset[0]*-0.4f;
+ v4f qwheel;
+ q_axis_angle( qwheel, (v3f){0.0f,1.0f,0.0f}, wheel_r );
+
+ q_m3x3( qwheel, player.mdl.matrices[k_chpart_wb] );
+
+ m3x3_transpose( player.mdl.matrices[k_chpart_wb],
+ player.mdl.matrices[k_chpart_wf] );
+ v3_copy( player.mdl.offsets[k_chpart_wb],
+ player.mdl.matrices[k_chpart_wb][3] );
+ v3_copy( player.mdl.offsets[k_chpart_wf],
+ player.mdl.matrices[k_chpart_wf][3] );
+
+ m4x3_mul( mboard, player.mdl.matrices[k_chpart_wb],
+ player.mdl.matrices[k_chpart_wb] );
+ m4x3_mul( mboard, player.mdl.matrices[k_chpart_wf],
+ player.mdl.matrices[k_chpart_wf] );
+
+ m4x3_mulv( mboard, player.mdl.ik_leg_l.end, player.mdl.ik_leg_l.end );
+ m4x3_mulv( mboard, player.mdl.ik_leg_r.end, player.mdl.ik_leg_r.end );
+
+
+ v3_copy( player.mdl.ik_arm_l.end, player.handl_target );
+ v3_copy( player.mdl.ik_arm_r.end, player.handr_target );
+
+ if( 1||player.in_air )
+ {
+ float tuck = player.board_xy[1],
+ tuck_amt = fabsf( tuck ) * (1.0f-fabsf(player.board_xy[0]));
+
+ float crouch = player.grab*0.3f;
+ v3_muladds( player.mdl.ik_body.base, (v3f){0.0f,-1.0f,0.0f},
+ crouch, player.mdl.ik_body.base );
+ v3_muladds( player.mdl.ik_body.end, (v3f){0.0f,-1.0f,0.0f},
+ crouch*1.2f, player.mdl.ik_body.end );
+
+ if( tuck < 0.0f )
+ {
+ //foot_l *= 1.0f-tuck_amt*1.5f;
+
+ if( player.grab > 0.1f )
+ {
+ m4x3_mulv( mboard, (v3f){0.1f,0.14f,0.6f},
+ player.handl_target );
+ }
+ }
+ else
+ {
+ //foot_r *= 1.0f-tuck_amt*1.4f;
+
+ if( player.grab > 0.1f )
+ {
+ m4x3_mulv( mboard, (v3f){0.1f,0.14f,-0.6f},
+ player.handr_target );
+ }
+ }
+ }
+
+ v3_lerp( player.handl, player.handl_target, 0.1f, player.handl );
+ v3_lerp( player.handr, player.handr_target, 0.1f, player.handr );
+
+ v3_copy( player.handl, player.mdl.ik_arm_l.end );
+ v3_copy( player.handr, player.mdl.ik_arm_r.end );
+
+ /* Head rotation */
+
+ static float rhead = 0.0f;
+ rhead = vg_lerpf( rhead,
+ vg_clampf(atan2f( localv[2], -localv[0] ),-1.0f,1.0f), 0.04f );
+ player.mdl.rhead = rhead;
+}
+
+static void draw_player(void)
+{
+ /* Draw */
+ vg_tex2d_bind( &tex_pallet, 0 );
+
+ m4x3_copy( player.to_world, player.mdl.mroot );
+ character_eval( &player.mdl );
+ character_draw( &player.mdl, 1.0f );
+}
+
+static void vg_framebuffer_resize( int w, int h )
+{
+ glBindTexture( GL_TEXTURE_2D, render.rgb_background );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, NULL );