+ }
+
+ dynamic_model_load( &ctx, &board->mdl, path, fixup_table );
+ mdl_close( &ctx );
+}
+
+static void player_model_unload( struct player_model *board ){
+ dynamic_model_unload( &board->mdl );
+}
+
+static void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
+ m4x3f *final_mtx ){
+ m4x3f transform;
+ q_m3x3( pose->root_q, transform );
+ v3_copy( pose->root_co, transform[3] );
+
+ if( pose->type == k_player_pose_type_ik ){
+ skeleton_apply_pose( sk, pose->keyframes,
+ k_anim_apply_defer_ik, final_mtx );
+ skeleton_apply_ik_pass( sk, final_mtx );
+ skeleton_apply_pose( sk, pose->keyframes,
+ k_anim_apply_deffered_only, final_mtx );
+ skeleton_apply_inverses( sk, final_mtx );
+ skeleton_apply_transform( sk, transform, final_mtx );
+ }
+ else if( pose->type == k_player_pose_type_fk_2 ){
+ skeleton_apply_pose( sk, pose->keyframes,
+ k_anim_apply_always, final_mtx );
+ skeleton_apply_inverses( sk, final_mtx );
+ skeleton_apply_transform( sk, transform, final_mtx );
+ }
+}
+
+static void player__animate(void){
+ struct player_subsystem_interface *sys =
+ player_subsystems[localplayer.subsystem];
+
+ struct player_board *board =
+ addon_cache_item_if_loaded( k_addon_type_board,
+ localplayer.board_view_slot );
+
+ assert( sys->animate );
+ assert( sys->pose );
+ assert( sys->animator_data );
+
+ sys->animate();
+
+ player_pose *pose = &localplayer.pose;
+ sys->pose( sys->animator_data, pose );
+
+ struct skeleton *sk = &localplayer.skeleton;
+
+ if( localplayer.holdout_time > 0.0f ){
+ skeleton_lerp_pose( sk,
+ pose->keyframes,localplayer.holdout_pose.keyframes,
+ localplayer.holdout_time, pose->keyframes );
+
+ v3_muladds( pose->root_co, localplayer.holdout_pose.root_co,
+ localplayer.holdout_time, pose->root_co );
+ q_nlerp( pose->root_q, localplayer.holdout_pose.root_q,
+ localplayer.holdout_time, pose->root_q );
+
+ localplayer.holdout_time -= vg.time_frame_delta * 2.0f;
+ }
+
+ effect_blink_apply( &localplayer.effect_data.blink,
+ &localplayer.pose, vg.time_delta );
+ apply_full_skeleton_pose( sk, &localplayer.pose, localplayer.final_mtx );
+
+ if( sys->effects ){
+ sys->effects( sys->animator_data, localplayer.final_mtx, board,
+ &localplayer.effect_data );
+ }
+
+ skeleton_debug( sk, localplayer.final_mtx );
+
+ if( sys->post_animate )
+ sys->post_animate();