X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_render.c;h=0d7e9221f547e2b7042e1d3ee22e0cacc47cb139;hb=1d06671f87a9d24596fc6808d8e0db889a818750;hp=ba50fc1402b0e55ce11a491865c321a824d5c398;hpb=f1fe55f957a3dbdb6ca20a696f0c1171e2d5e7ca;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_render.c b/player_render.c index ba50fc1..0d7e922 100644 --- a/player_render.c +++ b/player_render.c @@ -138,36 +138,48 @@ VG_STATIC void player_model_unload( struct player_model *board ){ dynamic_model_unload( &board->mdl ); } -VG_STATIC void player__animate( player_instance *player ){ - if( _player_animate[ player->subsystem ] ){ - player_animation res; - res.type = k_player_animation_type_fk; +VG_STATIC void player_apply_pose_to_skeleton( player_instance *player ){ + struct skeleton *sk = &player->playeravatar->sk; + player_pose *pose = &player->pose; - _player_animate[ player->subsystem ]( player, &res ); + 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_animate[ player->subsystem ]( player ); + _player_pose[ player->subsystem ]( player, &player->pose ); - m4x3f transform; - q_m3x3( res.root_q, transform ); - v3_copy( res.root_co, transform[3] ); struct skeleton *sk = &player->playeravatar->sk; if( player->holdout_time > 0.0f ){ - skeleton_lerp_pose( sk, res.pose, player->holdout_pose, - player->holdout_time, res.pose ); + 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( res.type == k_player_animation_type_fk ){ - skeleton_apply_pose( sk, res.pose, k_anim_apply_defer_ik ); - skeleton_apply_ik_pass( sk ); - skeleton_apply_pose( sk, res.pose, k_anim_apply_deffered_only ); - skeleton_apply_inverses( sk ); - skeleton_apply_transform( sk, transform ); - } - else { - skeleton_apply_pose( sk, res.pose, k_anim_apply_absolute ); - } - + player_apply_pose_to_skeleton( player ); skeleton_debug( sk ); } @@ -177,38 +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) */ - - player_animation res; replay_frame *frame = replay->cursor_frame, *next = NULL; - 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->anim.pose, next->anim.pose, t, res.pose); - v3_lerp( frame->anim.root_co, next->anim.root_co, t, res.root_co ); - q_nlerp( frame->anim.root_q, next->anim.root_q, t, res.root_q ); - res.type = k_player_animation_type_absolute; - player->board_pose.lean = vg_lerpf( frame->board_pose.lean, - next->board_pose.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 { - memcpy( &res, &frame->anim, sizeof(frame->anim) ); - memcpy( &frame->board_pose, &player->board_pose, - sizeof(player->board_pose) ); + else{ + player_copy_frame_animator( player, frame ); + _player_pose[ frame->system ]( player, &player->pose ); } } else return; - struct skeleton *sk = &player->playeravatar->sk; - skeleton_apply_pose( sk, res.pose, k_anim_apply_absolute ); + player_apply_pose_to_skeleton( player ); } VG_STATIC void player__pre_render( player_instance *player ){ @@ -234,7 +275,7 @@ VG_STATIC void player__pre_render( player_instance *player ){ VG_STATIC void render_board( camera *cam, world_instance *world, struct player_board *board, m4x3f root, - struct board_pose *pose, + struct player_board_pose *pose, enum board_shader shader ) { if( !board ) return; @@ -425,7 +466,7 @@ PLAYER_API void player__render( camera *cam, player_instance *player ){ render_board( cam, world, board, player->playeravatar->sk.final_mtx[ player->playeravatar->id_board], - &player->board_pose, + &player->pose.board, k_board_shader_player ); SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );