From 3e59ac7081ea3005060b56449bc77c8f73cdc6b6 Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 18 Jul 2023 08:20:36 +0100 Subject: [PATCH] move everything to animator based --- player.h | 4 +- player_api.h | 4 +- player_dead.c | 122 ++++++++++++++++++++++++++++------- player_dead.h | 12 +++- player_drive.c | 3 +- player_drive.h | 2 +- player_render.c | 101 ++++++++++++++++++++--------- player_replay.c | 168 ++++++++++++++++++++++++------------------------ player_replay.h | 32 +++++---- player_skate.c | 36 ++++++----- player_skate.h | 3 +- player_walk.c | 6 +- player_walk.h | 4 +- workshop.c | 2 +- 14 files changed, 312 insertions(+), 187 deletions(-) diff --git a/player.h b/player.h index cb60d04..2d31e46 100644 --- a/player.h +++ b/player.h @@ -153,7 +153,7 @@ VG_STATIC void( *_player_post_update[])( player_instance *player ) = { player__walk_post_update, player__skate_post_update, - NULL, + player__dead_post_update, player__drive_post_update }; @@ -174,7 +174,7 @@ void( *_player_animate[])( player_instance *player ) = { }; VG_STATIC -void( *_player_pose[] )( player_instance *player ) = { +void( *_player_pose[] )( player_instance *player, player_pose *pose ) = { player__walk_pose, player__skate_pose, player__dead_pose, diff --git a/player_api.h b/player_api.h index 0165841..2c2d18e 100644 --- a/player_api.h +++ b/player_api.h @@ -11,8 +11,8 @@ typedef struct player_pose player_pose; struct player_pose{ enum player_pose_type { - k_player_pose_type_fk, /* regular FK animation */ - k_player_pose_type_absolute /* decomposition of the final matrices */ + k_player_pose_type_ik, /* regular IK animation */ + k_player_pose_type_fk_2, } type; diff --git a/player_dead.c b/player_dead.c index b6312cb..78cce2f 100644 --- a/player_dead.c +++ b/player_dead.c @@ -8,30 +8,9 @@ VG_STATIC void player__dead_update ( player_instance *player ) player_ragdoll_iter( &player->ragdoll ); } -VG_STATIC void player__dead_animate ( player_instance *player ){ - /* nothing here */ -} - -VG_STATIC void player__dead_pose ( player_instance *player ){ - player_pose *pose = &player->pose; - v3_zero( pose->root_co ); - q_identity( pose->root_q ); - - for( int i=0; ikeyframes); i ++ ){ - /* FUUUUTUUREEEE: squangle the rigidbodies back into OK keyframes */ - v3_zero( pose->keyframes[i].co ); - v3_fill( pose->keyframes[i].s, 1.0f ); - q_identity( pose->keyframes[i].q ); - } -} - -VG_STATIC void player__dead_post_animate( player_instance *player ){ +VG_STATIC void player__dead_post_update( player_instance *player ){ + struct player_dead *d = &player->_dead; struct player_avatar *av = player->playeravatar; - struct player_dead *d = &player->_dead; - - copy_ragdoll_pose_to_avatar( &player->ragdoll, player->playeravatar ); - player->cam_velocity_influence = 1.0f; - struct ragdoll_part *part = &player->ragdoll.parts[ av->id_hip-1 ]; v3f ext_co; @@ -47,6 +26,103 @@ VG_STATIC void player__dead_post_animate( player_instance *player ){ v3_zero( player->rb.w ); } +VG_STATIC void player__dead_animate( player_instance *player ){ + struct player_dead *d = &player->_dead; + struct player_dead_animator *animator = &d->animator; + struct player_ragdoll *rd = &player->ragdoll; + struct player_avatar *av = player->playeravatar; + struct skeleton *sk = &av->sk; + + m4x3f transforms[ 32 ]; + + /* root transform */ + q_m3x3( player->rb.q, transforms[0] ); + v3_copy( player->rb.co, transforms[0][3] ); + + v4_copy( player->rb.q, animator->transforms[0].q ); + v3_copy( player->rb.co, animator->transforms[0].co ); + + /* colliders with bones transforms */ + for( int i=0; ipart_count; i++ ){ + struct ragdoll_part *part = &rd->parts[i]; + + m4x3f mtx; + + v4f q_int; + v3f co_int; + + float substep = vg.time_fixed_extrapolate; + v3_lerp( part->prev_co, part->obj.rb.co, substep, co_int ); + q_nlerp( part->prev_q, part->obj.rb.q, substep, q_int ); + v4_copy( part->obj.rb.q, q_int ); + + q_m3x3( q_int, mtx ); + v3_copy( co_int, mtx[3] ); + + m4x3_mul( mtx, part->inv_collider_mtx, transforms[part->bone_id] ); + } + + /* bones without colliders transforms */ + for( u32 i=1; ibone_count; i++ ){ + struct skeleton_bone *sb = &sk->bones[i]; + + if( sb->parent && !sb->collider ){ + v3f delta; + v3_sub( sk->bones[i].co, sk->bones[sb->parent].co, delta ); + + m4x3f posemtx; + m3x3_identity( posemtx ); + v3_copy( delta, posemtx[3] ); + + /* final matrix */ + m4x3_mul( transforms[sb->parent], posemtx, transforms[i] ); + } + } + + /* measurements */ + for( u32 i=1; ibone_count; i++ ){ + struct skeleton_bone *sb = &sk->bones[i]; + + v3_zero( animator->transforms[i].co ); + q_identity( animator->transforms[i].q ); + + m4x3f parent, inverse, local; + m3x3_identity( parent ); + v3_sub( sk->bones[i].co, sk->bones[sb->parent].co, parent[3] ); + m4x3_mul( transforms[ sb->parent ], parent, parent ); + m4x3_invert_affine( parent, inverse ); + + v3f _s; + m4x3_mul( inverse, transforms[i], local ); + m4x3_decompose( local, animator->transforms[i].co, + animator->transforms[i].q, _s ); + } +} + +VG_STATIC void player__dead_pose( player_instance *player, player_pose *pose ){ + struct player_dead *d = &player->_dead; + struct player_dead_animator *animator = &d->animator; + struct player_ragdoll *rd = &player->ragdoll; + struct player_avatar *av = player->playeravatar; + struct skeleton *sk = &av->sk; + + pose->type = k_player_pose_type_fk_2; + pose->board.lean = 0.0f; + + v3_copy( animator->transforms[0].co, pose->root_co ); + v4_copy( animator->transforms[0].q, pose->root_q ); + + for( u32 i=1; ibone_count; i++ ){ + v3_copy( animator->transforms[i].co, pose->keyframes[i-1].co ); + v4_copy( animator->transforms[i].q, pose->keyframes[i-1].q ); + v3_fill( pose->keyframes[i-1].s, 1.0f ); + } +} + +VG_STATIC void player__dead_post_animate( player_instance *player ){ + player->cam_velocity_influence = 1.0f; +} + VG_STATIC void player__dead_im_gui ( player_instance *player ){ } diff --git a/player_dead.h b/player_dead.h index 43f7574..6a10bea 100644 --- a/player_dead.h +++ b/player_dead.h @@ -5,11 +5,21 @@ struct player_dead{ v3f co_lpf, v_lpf, w_lpf; + + struct player_dead_animator{ + struct { + v3f co; + v4f q; + } + transforms[ 32 ]; + } + animator; }; VG_STATIC void player__dead_update ( player_instance *player ); +VG_STATIC void player__dead_post_update ( player_instance *player ); VG_STATIC void player__dead_animate ( player_instance *player ); -VG_STATIC void player__dead_pose ( player_instance *player ); +VG_STATIC void player__dead_pose( player_instance *player, player_pose *pose ); VG_STATIC void player__dead_post_animate( player_instance *player ); VG_STATIC void player__dead_im_gui ( player_instance *player ); diff --git a/player_drive.c b/player_drive.c index 157ef40..1c83205 100644 --- a/player_drive.c +++ b/player_drive.c @@ -31,10 +31,9 @@ VG_STATIC void player__drive_post_update( player_instance *player ) VG_STATIC void player__drive_animate( player_instance *player ){} -VG_STATIC void player__drive_pose( player_instance *player ){ +VG_STATIC void player__drive_pose( player_instance *player, player_pose *pose ){ struct player_drive *drive = &player->_drive; struct skeleton *sk = &player->playeravatar->sk; - player_pose *pose = &player->pose; skeleton_sample_anim( sk, drive->anim_drive, 0.0f, pose->keyframes ); v3_copy( player->rb.co, pose->root_co ); diff --git a/player_drive.h b/player_drive.h index dcf689e..7e1bb98 100644 --- a/player_drive.h +++ b/player_drive.h @@ -13,7 +13,7 @@ VG_STATIC void player__drive_pre_update( player_instance *player ); VG_STATIC void player__drive_update( player_instance *player ); VG_STATIC void player__drive_post_update( player_instance *player ); VG_STATIC void player__drive_animate( player_instance *player ); -VG_STATIC void player__drive_pose( player_instance *player ); +VG_STATIC void player__drive_pose( player_instance *player, player_pose *pose ); VG_STATIC void player__drive_post_animate( player_instance *player ); VG_STATIC void player__drive_im_gui( player_instance *player ); diff --git a/player_render.c b/player_render.c index 283b251..d0d14a4 100644 --- a/player_render.c +++ b/player_render.c @@ -138,18 +138,36 @@ 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_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 ){ @@ -159,17 +177,7 @@ VG_STATIC void player__animate( player_instance *player ){ 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 +187,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 ){ diff --git a/player_replay.c b/player_replay.c index 319cf03..fc57680 100644 --- a/player_replay.c +++ b/player_replay.c @@ -13,43 +13,23 @@ VG_STATIC void replay_clear( replay_buffer *replay ){ replay->cursor = -99999.9; } -replay_gamestate *replay_frame_gamestate( replay_frame *frame ){ +VG_STATIC void * +replay_frame_data( replay_frame *frame, enum replay_framedata type ){ void *baseptr = frame; - return baseptr + vg_align8(sizeof(replay_frame)); + return baseptr + frame->data_table[type][0]; } -void *replay_gamestate_subsystem_data( replay_gamestate *gs ){ - void *baseptr = gs; - return baseptr + vg_align8(sizeof(replay_gamestate)); -} +VG_STATIC u16 +replay_frame_calculate_data_offsets( u16 data_table[4][2] ){ + u32 total = vg_align8( sizeof(replay_frame) ); + for( u32 i=0; i<4; i++ ){ + data_table[i][0] = total; + total += vg_align8(data_table[i][1]); -u32 replay_frame_gamestate_total_size( u32 subsystem_gamestate_size ){ - if( subsystem_gamestate_size ){ - return vg_align8( sizeof(replay_gamestate) ) + - vg_align8( subsystem_gamestate_size ); + if( total > 0xffff ) + vg_fatal_error( "Exceeded frame storage capacity\n" ); } - else - return 0; -} - -replay_sfx *replay_frame_sfx( replay_frame *frame, u32 index ){ - void *gs = replay_frame_gamestate( frame ); - u32 total_size = - replay_frame_gamestate_total_size( frame->subsystem_gamestate_size ); - - replay_sfx *array = (gs + total_size); - return &array[index]; -} - -u32 _replay_frame_size( u32 subsystem_gamestate_size, u32 sfx_count ){ - return vg_align8( sizeof( replay_frame ) ) + - replay_frame_gamestate_total_size( subsystem_gamestate_size ) + - vg_align8( sfx_count * sizeof(replay_sfx) ); -} - -u32 replay_frame_size( replay_frame *frame ){ - return _replay_frame_size( frame->subsystem_gamestate_size, - frame->sfx_count ); + return total; } VG_STATIC void replay_tailpop( replay_buffer *replay ){ @@ -67,15 +47,27 @@ VG_STATIC void replay_tailpop( replay_buffer *replay ){ } VG_STATIC replay_frame *replay_newframe( replay_buffer *replay, - u32 subsystem_gamestate_size, - u32 sfx_count ){ + u16 animator_size, + u16 gamestate_size, + u16 sfx_count ){ + u16 data_table[4][2]; + data_table[ k_replay_framedata_animator ][1] = animator_size; + data_table[ k_replay_framedata_gamestate ][1] = gamestate_size; + data_table[ k_replay_framedata_sfx ][1] = 0; + data_table[ k_replay_framedata_internal_gamestate ][1] = 0; + if( gamestate_size ){ + data_table[ k_replay_framedata_internal_gamestate ][1] = + sizeof( replay_gamestate ); + } + + u32 nextsize = replay_frame_calculate_data_offsets( data_table ); + replay_frame *frame = NULL; if( replay->head ){ assert( replay->head ); - u32 headsize = replay_frame_size( replay->head ), - nextpos = ((void *)replay->head - replay->data) + headsize, - nextsize = _replay_frame_size( subsystem_gamestate_size, sfx_count ); + u32 headsize = replay->head->total_size, + nextpos = ((void *)replay->head - replay->data) + headsize; if( nextsize > replay->size ){ vg_error( "Keyframe too big\n" ); @@ -94,7 +86,6 @@ VG_STATIC replay_frame *replay_newframe( replay_buffer *replay, } check_again:; - u32 tailpos = (void *)replay->tail - replay->data; if( tailpos >= nextpos ){ @@ -114,13 +105,17 @@ check_again:; else frame = replay->data; - frame->subsystem_gamestate_size = subsystem_gamestate_size; - frame->sfx_count = sfx_count; + for( u32 i=0; i<4; i++ ){ + frame->data_table[i][0] = data_table[i][0]; + frame->data_table[i][1] = data_table[i][1]; + } + + frame->total_size = nextsize; frame->l = replay->head; frame->r = NULL; replay->head = frame; if( !replay->tail ) replay->tail = frame; - if( subsystem_gamestate_size ) replay->statehead = frame; + if( gamestate_size ) replay->statehead = frame; return frame; } @@ -174,7 +169,7 @@ VG_STATIC replay_frame *replay_find_recent_stateframe( replay_buffer *replay ){ u32 i=4096; while( i --> 0 ){ if( !frame ) return frame; - if( frame->subsystem_gamestate_size ) return frame; + if( frame->data_table[ k_replay_framedata_gamestate ][1] ) return frame; frame = frame->l; } @@ -253,8 +248,7 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){ if( !save_frame ) return; - u32 gamestate_size = 0; - + u16 gamestate_size = 0; if( save_state ){ gamestate_size = (u32 []){ [k_player_subsystem_walk ] = sizeof(struct player_walk_state), @@ -264,12 +258,21 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){ sizeof(struct replay_rb) }[ localplayer.subsystem ]; } + + u16 animator_size = (u16 []){ + [k_player_subsystem_walk ] = sizeof(struct player_walk_animator), + [k_player_subsystem_drive] = 0, + [k_player_subsystem_skate] = sizeof(struct player_skate_animator), + [k_player_subsystem_dead ] = sizeof(struct player_dead_animator) + }[ localplayer.subsystem ]; - replay_frame *frame = replay_newframe( replay, gamestate_size, 0 ); + replay_frame *frame = replay_newframe( replay, + animator_size, gamestate_size, 0 ); + frame->system = localplayer.subsystem; if( save_state ){ - replay_gamestate *gs = replay_frame_gamestate( frame ); - gs->system = localplayer.subsystem; + replay_gamestate *gs = + replay_frame_data( frame, k_replay_framedata_internal_gamestate ); /* permanent block */ memcpy( &gs->rb, &localplayer.rb, sizeof(rigidbody) ); @@ -277,7 +280,7 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){ sizeof(struct player_cam_controller) ); v3_copy( localplayer.angles, gs->angles ); - void *dst = replay_gamestate_subsystem_data( gs ); + void *dst = replay_frame_data( frame, k_replay_framedata_gamestate ); /* subsytem/dynamic block */ if( localplayer.subsystem == k_player_subsystem_walk ) @@ -298,53 +301,44 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){ replay->cursor = vg.time; replay->cursor_frame = frame; - - player_pose *res = &frame->pose; - v3_zero( res->root_co ); - q_identity( res->root_q ); - res->type = k_player_pose_type_absolute; - - struct skeleton *sk = &localplayer.playeravatar->sk; - - memcpy( &frame->pose.board, &localplayer.pose.board, - sizeof(localplayer.pose.board) ); frame->time = vg.time; - v3_copy( localplayer.cam.pos, frame->cam_pos ); + /* camera */ + v3_copy( localplayer.cam.pos, frame->cam_pos ); if( localplayer.gate_waiting ){ m4x3_mulv( localplayer.gate_waiting->transport, frame->cam_pos, frame->cam_pos ); - - for( u32 i=1; ibone_count; i++ ){ - struct skeleton_bone *sb = &sk->bones[i]; - mdl_keyframe *kf = &res->keyframes[i-1]; - m4x3f mtx; - m4x3_mul( localplayer.gate_waiting->transport, sk->final_mtx[i], mtx ); - m4x3_decompose( mtx, kf->co, kf->q, kf->s ); - } } - else - skeleton_decompose_mtx_absolute( sk, res->keyframes ); - v3_copy( localplayer.cam.angles, frame->cam_angles ); frame->cam_fov = localplayer.cam.fov; + + /* animator */ + void *dst = replay_frame_data( frame, k_replay_framedata_animator ); + + if( localplayer.subsystem == k_player_subsystem_walk ) + memcpy( dst, &localplayer._walk.animator, animator_size ); + else if( localplayer.subsystem == k_player_subsystem_skate ) + memcpy( dst, &localplayer._skate.animator, animator_size ); + else if( localplayer.subsystem == k_player_subsystem_dead ){ + memcpy( dst, &localplayer._dead.animator, animator_size ); + } } VG_STATIC void skaterift_restore_frame( replay_frame *frame ){ - replay_gamestate *gs = replay_frame_gamestate( frame ); - void *src = replay_gamestate_subsystem_data( gs ); - - /* TODO: Move this to subsystem bindings now that its variable */ - if( gs->system == k_player_subsystem_walk ){ - memcpy( &localplayer._walk.state, src, - frame->subsystem_gamestate_size ); + replay_gamestate *gs = + replay_frame_data( frame, k_replay_framedata_internal_gamestate ); + void *src = replay_frame_data( frame, k_replay_framedata_gamestate ); + u16 src_size = frame->data_table[ k_replay_framedata_gamestate ][1]; + assert( src_size ); + + if(frame->system == k_player_subsystem_walk ){ + memcpy( &localplayer._walk.state, src, src_size ); } - else if( gs->system == k_player_subsystem_skate ){ - memcpy( &localplayer._skate.state, src, - frame->subsystem_gamestate_size ); + else if( frame->system == k_player_subsystem_skate ){ + memcpy( &localplayer._skate.state, src, src_size ); } - else if( gs->system == k_player_subsystem_dead ){ + else if( frame->system == k_player_subsystem_dead ){ player__dead_transition( &localplayer ); struct replay_rb *arr = src; @@ -362,7 +356,7 @@ void skaterift_restore_frame( replay_frame *frame ){ } } - localplayer.subsystem = gs->system; + localplayer.subsystem = frame->system; memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) ); v3_copy( gs->angles, localplayer.angles ); @@ -539,11 +533,17 @@ VG_STATIC void skaterift_replay_debug_info(void){ player__debugtext( 1, "head @%u | tail @%u\n", head, tail ); + for( u32 i=0; i<4; i++ ){ + player__debugtext( 1, "[%u]: [%hu, %hu]\n", i, + replay->statehead->data_table[i][0], + replay->statehead->data_table[i][1] ); + } + if( replay->statehead ){ u32 state = (void *)replay->statehead - replay->data; player__debugtext( 1, "gs @%u\n", state ); - player__debugtext( 1, "gamestate_size: %u\n", - replay->statehead->subsystem_gamestate_size ); + player__debugtext( 1, "gamestate_size: %hu\n", + replay->statehead->data_table[k_replay_framedata_gamestate][1] ); } else player__debugtext( 1, "gs @NULL\n" ); diff --git a/player_replay.h b/player_replay.h index 73bbb22..9890be0 100644 --- a/player_replay.h +++ b/player_replay.h @@ -19,33 +19,30 @@ struct replay_buffer { f64 cursor; }; -struct replay_frame { - player_pose pose; +enum replay_framedata{ + k_replay_framedata_animator, + k_replay_framedata_gamestate, + k_replay_framedata_internal_gamestate, + k_replay_framedata_sfx +}; +struct replay_frame { v3f cam_pos, cam_angles; f32 cam_fov; f64 time; replay_frame *l, *r; - u32 subsystem_gamestate_size, - sfx_count; + enum player_subsystem system; + u16 total_size; + u16 data_table[4][2]; }; struct replay_gamestate { - enum player_subsystem system; rigidbody rb; v3f angles; struct player_cam_controller cam_control; - -#if 0 - union { - struct player_skate_state skate; - struct player_walk_state walk; - struct player_ragdoll ragdoll; - }; -#endif }; struct replay_sfx { @@ -53,17 +50,18 @@ struct replay_sfx { }; VG_STATIC replay_frame *replay_newframe( replay_buffer *replay, - u32 gamestate_count, u32 sfx_count ); + u16 animator_size, + u16 gamestate_size, + u16 sfx_count ); VG_STATIC void replay_seek( replay_buffer *replay, f64 t ); -replay_gamestate *replay_frame_gamestate( replay_frame *frame ); -void *replay_gamestate_subsystem_data( replay_gamestate *gs ); -replay_sfx *replay_frame_sfx( replay_frame *frame, u32 index ); VG_STATIC replay_frame *replay_find_recent_stateframe( replay_buffer *replay ); VG_STATIC void replay_get_camera( replay_buffer *replay, camera *cam ); VG_STATIC void replay_get_frame_camera( replay_frame *frame, camera *cam ); VG_STATIC f32 replay_subframe_time( replay_buffer *replay ); VG_STATIC void replay_clear( replay_buffer *replay ); +VG_STATIC void * +replay_frame_data( replay_frame *frame, enum replay_framedata type ); VG_STATIC void skaterift_replay_pre_update(void); VG_STATIC void skaterift_replay_imgui(void); diff --git a/player_skate.c b/player_skate.c index fe34de2..d56fc98 100644 --- a/player_skate.c +++ b/player_skate.c @@ -1110,12 +1110,12 @@ VG_STATIC void player__skate_pre_update( player_instance *player ){ player->subsystem = k_player_subsystem_walk; v3f angles; - v3_copy( player->cam.angles, angles ); - angles[2] = 0.0f; + v3_copy( player->cam.angles, player->angles ); + player->angles[2] = 0.0f; player__begin_holdout( player ); player__skate_kill_audio( player ); - player__walk_transition( player, angles ); + player__walk_transition( player ); return; } @@ -2773,6 +2773,19 @@ VG_STATIC void player__skate_animate( player_instance *player ){ animator->board_euler[1] += extra; animator->trick_type = s->state.trick_type; + /* board lean */ + f32 lean1, lean2 = animator->steer[0] * animator->reverse * -0.36f, + lean; + + lean1 = animator->slide * animator->delayed_slip_dir; + if( fabsf(lean1)>fabsf(lean2) ) lean = lean1; + else lean = lean2; + + if( ((int)roundf(animator->board_euler[0])) % 2 ) lean = -lean; + lean = vg_clampf( lean, -1.0f, 1.0f ); + animator->board_lean = + vg_lerpf(animator->board_lean, lean, vg.time_delta*18.0f); + /* feet placement */ struct player_board *board = addon_cache_item_if_loaded( k_addon_type_board, @@ -2886,13 +2899,12 @@ VG_STATIC void player__skate_animate( player_instance *player ){ rb_extrapolate( &player->rb, animator->root_co, animator->root_q ); } -VG_STATIC void player__skate_pose( player_instance *player ){ +VG_STATIC void player__skate_pose( player_instance *player, player_pose *pose ){ struct player_avatar *av = player->playeravatar; struct skeleton *sk = &av->sk; struct player_skate *s = &player->_skate; struct player_skate_animator *animator = &s->animator; - player_pose *pose = &player->pose; - pose->type = k_player_pose_type_fk; + pose->type = k_player_pose_type_ik; v3_copy( animator->root_co, pose->root_co ); v4_copy( animator->root_q, pose->root_q ); @@ -2923,17 +2935,7 @@ VG_STATIC void player__skate_pose( player_instance *player ){ f32 dir_frame = animator->z * (15.0f/30.0f), stand_blend = animator->offset[1]*-2.0f; - f32 lean1, - lean2 = animator->steer[0] * animator->reverse * -0.36f, - lean; - - lean1 = animator->slide * animator->delayed_slip_dir; - if( fabsf(lean1)>fabsf(lean2) ) lean = lean1; - else lean = lean2; - - if( ((int)roundf(animator->board_euler[0])) % 2 ) lean = -lean; - lean = vg_clampf( lean, -1.0f, 1.0f ); - pose->board.lean = vg_lerpf(pose->board.lean, lean, vg.time_delta*18.0f); + pose->board.lean = animator->board_lean; stand_blend = vg_clampf( 1.0f-animator->local_cog[1], 0, 1 ); diff --git a/player_skate.h b/player_skate.h index e5dde12..3d1a980 100644 --- a/player_skate.h +++ b/player_skate.h @@ -112,6 +112,7 @@ struct player_skate{ v4f qflip; v3f board_euler; + f32 board_lean; v2f steer, grab; f32 jump_charge; @@ -325,7 +326,7 @@ VG_STATIC void player__skate_update ( player_instance *player ); VG_STATIC void player__skate_post_update ( player_instance *player ); VG_STATIC void player__skate_im_gui ( player_instance *player ); VG_STATIC void player__skate_animate ( player_instance *player ); -VG_STATIC void player__skate_pose ( player_instance *player ); +VG_STATIC void player__skate_pose( player_instance *player, player_pose *pose ); VG_STATIC void player__skate_post_animate ( player_instance *player ); VG_STATIC void player__skate_reset ( player_instance *player, ent_spawn *rp ); diff --git a/player_walk.c b/player_walk.c index 2c03843..077dfd9 100644 --- a/player_walk.c +++ b/player_walk.c @@ -787,15 +787,15 @@ VG_STATIC void player__walk_animate( player_instance *player ){ q_normalize( animator->root_q ); } -VG_STATIC void player__walk_pose( player_instance *player ){ +VG_STATIC void player__walk_pose( player_instance *player, player_pose *pose ){ struct player_walk *w = &player->_walk; struct player_walk_animator *animator = &w->animator; struct skeleton *sk = &player->playeravatar->sk; struct player_avatar *av = player->playeravatar; - player_pose *pose = &player->pose; v3_copy( animator->root_co, pose->root_co ); v4_copy( animator->root_q, pose->root_q ); + pose->board.lean = 0.0f; float walk_norm = (float)w->anim_walk->length/30.0f, run_norm = (float)w->anim_run->length/30.0f, @@ -914,7 +914,7 @@ VG_STATIC void player__walk_bind( player_instance *player ){ w->anim_intro = skeleton_get_anim( sk, "into_skate" ); } -VG_STATIC void player__walk_transition( player_instance *player, v3f angles ){ +VG_STATIC void player__walk_transition( player_instance *player ){ struct player_walk *w = &player->_walk; w->state.activity = k_walk_activity_air; diff --git a/player_walk.h b/player_walk.h index e1e0755..3dcdbd8 100644 --- a/player_walk.h +++ b/player_walk.h @@ -88,11 +88,11 @@ VG_STATIC void player__walk_pre_update ( player_instance *player ); VG_STATIC void player__walk_update ( player_instance *player ); VG_STATIC void player__walk_post_update ( player_instance *player ); VG_STATIC void player__walk_animate ( player_instance *player ); -VG_STATIC void player__walk_pose ( player_instance *player ); +VG_STATIC void player__walk_pose( player_instance *player, player_pose *pose ); VG_STATIC void player__walk_post_animate( player_instance *player ); VG_STATIC void player__walk_im_gui ( player_instance *player ); VG_STATIC void player__walk_bind ( player_instance *player ); -VG_STATIC void player__walk_transition ( player_instance *player, v3f angles ); +VG_STATIC void player__walk_transition ( player_instance *player ); VG_STATIC void player__walk_reset ( player_instance *player, ent_spawn *rp ); VG_STATIC void player__walk_restore( player_instance *player ); diff --git a/workshop.c b/workshop.c index b048af9..b0c8da6 100644 --- a/workshop.c +++ b/workshop.c @@ -900,7 +900,7 @@ VG_STATIC void workshop_render_player_preview(void){ struct skeleton *sk = &localplayer.playeravatar->sk; player_pose res; - res.type = k_player_pose_type_fk; + res.type = k_player_pose_type_ik; struct skeleton_anim *anim = skeleton_get_anim( sk, "idle_cycle+y" ); skeleton_sample_anim( sk, anim, vg.time*0.1f, res.keyframes ); -- 2.25.1