X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_render.c;h=0d7e9221f547e2b7042e1d3ee22e0cacc47cb139;hb=5bfb36032928ba9f8d12e72961af68bfab9ea648;hp=283b2510e4f0db097d20cfc3ed343775e71b6c9a;hpb=09fc72b08113fa157a3abb2ded6086babedd10cf;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_render.c b/player_render.c index 283b251..0d7e922 100644 --- a/player_render.c +++ b/player_render.c @@ -138,38 +138,48 @@ VG_STATIC void player_model_unload( struct player_model *board ){ dynamic_model_unload( &board->mdl ); } +VG_STATIC void player_apply_pose_to_skeleton( player_instance *player ){ + struct skeleton *sk = &player->playeravatar->sk; + player_pose *pose = &player->pose; + + 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 ); + skeleton_apply_ik_pass( sk ); + skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_deffered_only ); + skeleton_apply_inverses( sk ); + skeleton_apply_transform( sk, transform ); + } + else if( pose->type == k_player_pose_type_fk_2 ){ + skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_always ); + skeleton_apply_inverses( sk ); + skeleton_apply_transform( sk, transform ); + } +} + VG_STATIC void player__animate( player_instance *player ){ if( _player_animate[ player->subsystem ] && - _player_pose[ player->subsystem ] ){ + _player_pose[ player->subsystem ] ){ _player_animate[ player->subsystem ]( player ); - _player_pose[ player->subsystem ]( player ); + _player_pose[ player->subsystem ]( player, &player->pose ); - player_pose *pose = &player->pose; - - m4x3f transform; - q_m3x3( pose->root_q, transform ); - v3_copy( pose->root_co, transform[3] ); struct skeleton *sk = &player->playeravatar->sk; if( player->holdout_time > 0.0f ){ + player_pose *pose = &player->pose; skeleton_lerp_pose( sk, pose->keyframes, player->holdout_pose.keyframes, player->holdout_time, pose->keyframes ); + q_nlerp( pose->root_q, player->holdout_pose.root_q, + player->holdout_time, pose->root_q ); player->holdout_time -= vg.time_frame_delta * 2.0f; } - if( pose->type == k_player_pose_type_fk ){ - skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_defer_ik ); - skeleton_apply_ik_pass( sk ); - skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_deffered_only ); - skeleton_apply_inverses( sk ); - skeleton_apply_transform( sk, transform ); - } - else { - skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_absolute ); - } - + player_apply_pose_to_skeleton( player ); skeleton_debug( sk ); } @@ -179,36 +189,67 @@ VG_STATIC void player__animate( player_instance *player ){ player__cam_iterate( player ); } +VG_STATIC void player_copy_frame_animator( player_instance *player, + replay_frame *frame ){ + void *animator_src = replay_frame_data( frame, k_replay_framedata_animator ); + u16 animator_size = frame->data_table[ k_replay_framedata_animator ][1]; + + if( frame->system == k_player_subsystem_walk ){ + memcpy( &player->_walk.animator, animator_src, animator_size ); + } + else if( frame->system == k_player_subsystem_dead ){ + memcpy( &player->_dead.animator, animator_src, animator_size ); + } + else if( frame->system == k_player_subsystem_skate ){ + memcpy( &player->_skate.animator, animator_src, animator_size ); + } + else if( frame->system == k_player_subsystem_drive ){ + + } +} + VG_STATIC void player__animate_from_replay( player_instance *player, replay_buffer *replay ){ - /* TODO: holdout blending (from when the game has to slow down) */ replay_frame *frame = replay->cursor_frame, *next = NULL; - - player_pose *pose = &player->pose; - if( frame ){ next = frame->r; if( next ){ f32 t = replay_subframe_time( replay ); + player_pose pose0, pose1; + + player_copy_frame_animator( player, frame ); + _player_pose[ frame->system ]( player, &pose0 ); + + player_copy_frame_animator( player, next ); + _player_pose[ next->system ]( player, &pose1 ); + + v3_lerp( pose0.root_co, pose1.root_co, t, player->pose.root_co ); + q_nlerp( pose0.root_q, pose1.root_q, t, player->pose.root_q ); + player->pose.type = pose0.type; + player->pose.board.lean = vg_lerpf( pose0.board.lean, + pose1.board.lean, t ); + struct skeleton *sk = &player->playeravatar->sk; - skeleton_lerp_pose( sk, frame->pose.keyframes, next->pose.keyframes, - t, pose->keyframes ); - v3_lerp( frame->pose.root_co, next->pose.root_co, t, pose->root_co ); - q_nlerp( frame->pose.root_q, next->pose.root_q, t, pose->root_q ); - pose->type = k_player_pose_type_absolute; - pose->board.lean = vg_lerpf( frame->pose.board.lean, - next->pose.board.lean, t ); + if( pose0.type != pose1.type ){ + /* it would be nice to apply IK pass in-keyframes. TOO BAD! */ + skeleton_copy_pose( sk, pose0.keyframes, player->pose.keyframes ); + } + else { + skeleton_lerp_pose( sk, pose0.keyframes, pose1.keyframes, + t, player->pose.keyframes ); + } + } + else{ + player_copy_frame_animator( player, frame ); + _player_pose[ frame->system ]( player, &player->pose ); } - else - memcpy( pose, &frame->pose, sizeof(frame->pose) ); } else return; - struct skeleton *sk = &player->playeravatar->sk; - skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_absolute ); + player_apply_pose_to_skeleton( player ); } VG_STATIC void player__pre_render( player_instance *player ){