+
+ q_axis_angle( animator->root_q, (v3f){0.0f,1.0f,0.0f}, walk_yaw + VG_PIf );
+}
+
+static void player__walk_pose( void *_animator, player_pose *pose ){
+ struct player_walk *w = &player_walk;
+ struct player_walk_animator *animator = _animator;
+ struct skeleton *sk = &localplayer.skeleton;
+
+ v3_copy( animator->root_co, pose->root_co );
+ v4_copy( animator->root_q, pose->root_q );
+ pose->board.lean = 0.0f;
+ pose->type = k_player_pose_type_ik;
+
+ float walk_norm = (float)w->anim_walk->length/30.0f,
+ run_norm = (float)w->anim_run->length/30.0f,
+ t = animator->walk_timer,
+ l = vg_clampf( animator->run*15.0f, 0.0f, 1.0f ),
+ idle_walk = vg_clampf( (animator->run-0.1f)/(1.0f-0.1f), 0.0f, 1.0f );
+
+ /* walk/run */
+ mdl_keyframe apose[32], bpose[32];
+ skeleton_sample_anim( sk, w->anim_walk, t*walk_norm, apose );
+ skeleton_sample_anim( sk, w->anim_run, t*run_norm, bpose );
+
+ skeleton_lerp_pose( sk, apose, bpose, l, apose );
+
+ /* idle */
+ skeleton_sample_anim( sk, w->anim_idle, vg.time*0.1f, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, 1.0f-idle_walk, apose );
+
+ /* air */
+ skeleton_sample_anim( sk, w->anim_jump, vg.time*0.6f, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, animator->fly, apose );
+
+ /* sit */
+ if( animator->sit_t > 0.0f ){
+ f32 sit_norm = (f32)(w->anim_sit->length-1)/30.0f,
+ st = vg_minf( 1.0f, animator->sit_t );
+ skeleton_sample_anim( sk, w->anim_sit, st*sit_norm, bpose );
+
+ v4f qy,qp;
+ f32 *qh = bpose[localplayer.id_head-1].q;
+ q_axis_angle( qy, (v3f){0.0f,1.0f,0.0f}, animator->yaw*0.5f*st );
+ q_axis_angle( qp, (v3f){0.0f,0.0f,1.0f}, animator->pitch*st );
+ q_mul( qy, qh, qh );
+ q_mul( qh, qp, qh );
+ q_normalize( qh );
+
+ qh = bpose[localplayer.id_chest-1].q;
+ q_axis_angle( qy, (v3f){0.0f,1.0f,0.0f}, animator->yaw*0.5f*st );
+ q_mul( qy, qh, qh );
+ q_normalize( qh );
+
+ skeleton_lerp_pose( sk, apose, bpose, vg_minf(1.0f,st*10.0f), apose );