void( *_player_post_update[])( player_instance *player ) = {
player__walk_post_update,
player__skate_post_update,
- NULL,
+ player__dead_post_update,
player__drive_post_update
};
};
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,
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;
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; i<vg_list_size(pose->keyframes); 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;
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; i<rd->part_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; i<sk->bone_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; i<sk->bone_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; i<sk->bone_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 ){
}
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 );
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 );
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 );
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 ){
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 );
}
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 ){
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 ){
}
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" );
}
check_again:;
-
u32 tailpos = (void *)replay->tail - replay->data;
if( tailpos >= nextpos ){
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;
}
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;
}
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),
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) );
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 )
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; i<sk->bone_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;
}
}
- localplayer.subsystem = gs->system;
+ localplayer.subsystem = frame->system;
memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) );
v3_copy( gs->angles, localplayer.angles );
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" );
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 {
};
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);
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;
}
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,
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 );
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 );
v4f qflip;
v3f board_euler;
+ f32 board_lean;
v2f steer, grab;
f32 jump_charge;
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 );
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,
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;
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 );
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 );