+ mdl_keyframe apose[32], bpose[32];
+ mdl_keyframe ground_pose[32];
+ {
+ /* when the player is moving fast he will crouch down a little bit */
+ float stand = 1.0f - vg_clampf( speed * 0.03f, 0.0f, 1.0f );
+ player.fstand = vg_lerpf( player.fstand, stand, 0.1f );
+
+ /* stand/crouch */
+ float dir_frame = player.fdirz * (15.0f/30.0f),
+ stand_blend = offset[1]*-2.0f;
+
+ skeleton_sample_anim( sk, player.mdl.anim_stand, dir_frame, apose );
+ skeleton_sample_anim( sk, player.mdl.anim_highg, dir_frame, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, stand_blend, apose );
+
+ /* sliding */
+ float slide_frame = player.fdirx * (15.0f/30.0f);
+ skeleton_sample_anim( sk, player.mdl.anim_slide, slide_frame, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, player.fslide, apose );
+
+ /* pushing */
+ player.fpush = vg_lerpf( player.fpush, player.pushing, 0.1f );
+
+ float pt = player.push_time;
+ if( player.reverse > 0.0f )
+ skeleton_sample_anim( sk, player.mdl.anim_push, pt, bpose );
+ else
+ skeleton_sample_anim( sk, player.mdl.anim_push_reverse, pt, bpose );
+
+ skeleton_lerp_pose( sk, apose, bpose, player.fpush, apose );
+
+ /* trick setup */
+ float setup_frame = player.jump * (12.0f/30.0f),
+ setup_blend = vg_minf( player.jump*5.0f, 1.0f );
+
+ float jump_frame = (vg_time - player.jump_time) + (12.0f/30.0f);
+ if( jump_frame >= (12.0f/30.0f) && jump_frame <= (40.0f/30.0f) )
+ setup_frame = jump_frame;
+
+ skeleton_sample_anim_clamped( sk, player.mdl.anim_ollie,
+ setup_frame, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, setup_blend, ground_pose );
+ }
+
+ mdl_keyframe air_pose[32];
+ {
+ float target = -vg_get_axis("horizontal");
+ player.fairdir = vg_lerpf( player.fairdir, target, 0.04f );
+
+ float air_frame = (player.fairdir*0.5f+0.5f) * (15.0f/30.0f);
+
+ skeleton_sample_anim( sk, player.mdl.anim_air, air_frame, air_pose );
+ }
+
+ skeleton_lerp_pose( sk, ground_pose, air_pose, player.ffly, apose );
+
+ /* additive effects */
+ apose[player.mdl.id_hip-1].co[0] += offset[0];
+ apose[player.mdl.id_hip-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_hand_l-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_hand_l-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_hand_r-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_hand_r-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_elbow_l-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_elbow_l-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_elbow_r-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_elbow_r-1].co[2] += offset[2];
+
+ skeleton_apply_pose( &player.mdl.sk, apose, k_anim_apply_defer_ik );
+ skeleton_apply_ik_pass( &player.mdl.sk );
+ skeleton_apply_pose( &player.mdl.sk, apose, k_anim_apply_deffered_only );
+
+ v3_copy( player.mdl.sk.final_mtx[player.mdl.id_head-1][3],
+ player.mdl.cam_pos );
+ skeleton_apply_inverses( &player.mdl.sk );
+ skeleton_apply_transform( &player.mdl.sk, player.rb.to_world );
+
+ skeleton_debug( &player.mdl.sk );
+}
+
+static void player_camera_update(void)
+{
+ /* Update camera matrices */
+ m4x3_identity( player.camera );
+ m4x3_rotate_y( player.camera, -player.angles[0] );
+ m4x3_rotate_x( player.camera, -player.angles[1] );
+ v3_copy( player.camera_pos, player.camera[3] );
+ m4x3_invert_affine( player.camera, player.camera_inverse );
+}
+
+static void player_animate_death_cam(void)
+{
+#if 0
+ v3f delta;
+ v3f head_pos;
+ v3_copy( player.mdl.ragdoll[k_chpart_head].co, head_pos );
+
+ v3_sub( head_pos, player.camera_pos, delta );
+ v3_normalize( delta );
+
+ v3f follow_pos;
+ v3_muladds( head_pos, delta, -2.5f, follow_pos );
+ v3_lerp( player.camera_pos, follow_pos, 0.1f, player.camera_pos );