static void player_glide_pose( void *_animator, player_pose *pose ){
struct skeleton *sk = &localplayer.skeleton;
struct player_glide_animator *animator = _animator;
+ pose->type = k_player_pose_type_ik;
+ pose->board.lean = 0.0f;
skeleton_sample_anim( sk, player_glide.anim_glide, 0.0f, pose->keyframes );
- /* TODO: again the offset is wrong */
v3f temp;
- q_mulv( pose->root_q, (v3f){0,-0.5f,0}, temp );
-
+ q_mulv( animator->root_q, (v3f){0,-0.5f,0}, temp );
v3_add( animator->root_co, temp, pose->root_co );
+
v4_copy( animator->root_q, pose->root_q );
}
struct skeleton *sk = &localplayer.skeleton;
player_glide.anim_glide = skeleton_get_anim( sk, "glide_pose" );
-
void *alloc = vg_mem.rtmemory;
mdl_context *mdl = &player_glide.glider;
player__begin_holdout( (v3f){0,0,0} );
}
+/*
+ * TODO: more flexible way to call
+ * - this depends on the current state, but we need to pass a struct in
+ * that can hold that information instead so we can save it into
+ * the replay
+ */
static void player_glide_render( camera *cam, world_instance *world,
player_pose *pose ){
if( !((localplayer.subsystem == k_player_subsystem_glide) ||
+ (localplayer.observing_system == k_player_subsystem_glide) ||
localplayer.have_glider ||
localplayer.glider_orphan) )
return;
f32 target;
if( localplayer.subsystem == k_player_subsystem_glide ) target = 1.0f;
else target = 0.0f;
- vg_slewf( &player_glide.t, target, vg.time_frame_delta * 4.0f );
+
+ /* TODO: TEMP */
+ if( skaterift.activity != k_skaterift_replay )
+ vg_slewf( &player_glide.t, target, vg.time_frame_delta * 4.0f );
mdl_keyframe kf_backpack;
*sys0 = player_subsystems[frame->system];
void *a0 = replay_frame_data( frame, k_replay_framedata_animator );
+ struct replay_glider_data
+ *g0 = replay_frame_data( frame, k_replay_framedata_glider ),
+ *g1;
+
+ f32 t = 0.0f;
+
if( next ){
- f32 t = replay_subframe_time( replay );
+ t = replay_subframe_time( replay );
player_pose pose0, pose1;
sys1->pose( a1, &pose1 );
lerp_player_pose( &pose0, &pose1, t, &localplayer.pose );
+ g1 = replay_frame_data( next, k_replay_framedata_glider );
}
else{
sys0->pose( a0, &localplayer.pose );
+ g1 = NULL;
}
player__observe_system( frame->system );
if( sys0->sfx_comp )
sys0->sfx_comp( a0 );
+
+ if( g0 ){
+ if( g0->glider_orphan ){
+ if( g1 ){
+ v3_lerp( g0->co, g1->co, t, player_glide.rb.co );
+ q_nlerp( g0->q, g1->q, t, player_glide.rb.q );
+ }
+ else {
+ v3_copy( g0->co, player_glide.rb.co );
+ v4_copy( g0->q, player_glide.rb.q );
+ }
+
+ rb_update_matrices( &player_glide.rb );
+ }
+
+ if( g1 )
+ player_glide.t = vg_lerpf( g0->t, g1->t, t );
+ else
+ player_glide.t = g0->t;
+
+ localplayer.have_glider = g0->have_glider;
+ localplayer.glider_orphan = g0->glider_orphan;
+ }
+ else /* no glider data in g1, or edge case we dont care about */ {
+ localplayer.have_glider = 0;
+ localplayer.glider_orphan = 0;
+ player_glide.t = 0.0f;
+ }
}
else return;
static
void * replay_frame_data( replay_frame *frame, enum replay_framedata type ){
+ if( frame->data_table[type][1] == 0 )
+ return NULL;
+
void *baseptr = frame;
return baseptr + frame->data_table[type][0];
}
-static u16
-replay_frame_calculate_data_offsets( u16 data_table[4][2] ){
+static u16 replay_frame_calculate_data_offsets(
+ u16 data_table[k_replay_framedata_rows][2] ){
+
u32 total = vg_align8( sizeof(replay_frame) );
- for( u32 i=0; i<4; i++ ){
+ for( u32 i=0; i<k_replay_framedata_rows; i++ ){
data_table[i][0] = total;
total += vg_align8(data_table[i][1]);
static replay_frame *replay_newframe( replay_buffer *replay,
u16 animator_size,
u16 gamestate_size,
- u16 sfx_count ){
- u16 data_table[4][2];
+ u16 sfx_count,
+ bool save_glider ){
+ u16 data_table[ k_replay_framedata_rows ][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] = sfx_count*sizeof(struct net_sfx);
sizeof( replay_gamestate );
}
+ data_table[ k_replay_framedata_glider ][1] = 0;
+ if( save_glider ){
+ data_table[ k_replay_framedata_glider ][1] =
+ sizeof(struct replay_glider_data);
+ }
+
u32 nextsize = replay_frame_calculate_data_offsets( data_table );
replay_frame *frame = NULL;
else
frame = replay->data;
- for( u32 i=0; i<4; i++ ){
+ for( u32 i=0; i<k_replay_framedata_rows; i++ ){
frame->data_table[i][0] = data_table[i][0];
frame->data_table[i][1] = data_table[i][1];
}
k_gamestate_rate = 0.5;
int save_frame = 0,
- save_state = 0;
+ save_state = 0,
+ save_glider = 0;
if( force_gamestate ) save_state = 1;
if( statedelta > k_gamestate_rate ) save_state = 1;
if( delta > k_replay_rate ) save_frame = 1;
if( save_state ) save_frame = 1;
+ if( localplayer.have_glider || localplayer.glider_orphan ||
+ localplayer.subsystem == k_player_subsystem_glide ){
+ save_glider = 1;
+ }
+
if( !save_frame ) return;
u16 gamestate_size = 0;
[k_player_subsystem_skate] = sizeof(struct player_skate_state),
[k_player_subsystem_dead ] = localplayer.ragdoll.part_count *
sizeof(struct replay_rb),
- [k_player_subsystem_glide] = 0,
+ [k_player_subsystem_glide] = sizeof(struct replay_rb),
}[ localplayer.subsystem ];
}
replay_frame *frame = replay_newframe( replay,
animator_size, gamestate_size,
- localplayer.local_sfx_buffer_count );
+ localplayer.local_sfx_buffer_count,
+ save_glider );
frame->system = localplayer.subsystem;
if( save_state ){
/* permanent block */
memcpy( &gs->rb, &localplayer.rb, sizeof(rigidbody) );
+ memcpy( &gs->glider_rb, &player_glide.rb, sizeof(rigidbody) );
memcpy( &gs->cam_control, &localplayer.cam_control,
sizeof(struct player_cam_controller) );
v3_copy( localplayer.angles, gs->angles );
- gs->have_glider = localplayer.have_glider;
void *dst = replay_frame_data( frame, k_replay_framedata_gamestate );
v4_copy( rb->q, arr[i].q );
}
}
+ else if( localplayer.subsystem == k_player_subsystem_glide ){
+ struct replay_rb *arr = dst;
+ rigidbody *rb = &player_glide.rb;
+ v3_copy( rb->co, arr[0].co );
+ v3_copy( rb->w, arr[0].w );
+ v3_copy( rb->v, arr[0].v );
+ v4_copy( rb->q, arr[0].q );
+ }
+ }
+
+ if( save_glider ){
+ struct replay_glider_data *inf =
+ replay_frame_data( frame, k_replay_framedata_glider );
+
+ inf->have_glider = localplayer.have_glider;
+ inf->glider_orphan = localplayer.glider_orphan;
+ inf->t = player_glide.t;
+ v3_copy( player_glide.rb.co, inf->co );
+ v4_copy( player_glide.rb.q, inf->q );
}
replay->cursor = vg.time;
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, &player_walk.animator, animator_size );
- else if( localplayer.subsystem == k_player_subsystem_skate )
- memcpy( dst, &player_skate.animator, animator_size );
- else if( localplayer.subsystem == k_player_subsystem_dead ){
- memcpy( dst, &player_dead.animator, animator_size );
- }
- else if( localplayer.subsystem == k_player_subsystem_glide ){
- memcpy( dst, &player_glide.animator, animator_size );
- }
+ void *dst = replay_frame_data( frame, k_replay_framedata_animator ),
+ *src = player_subsystems[localplayer.subsystem]->animator_data;
+ memcpy( dst, src, animator_size );
/* sound effects */
memcpy( replay_frame_data( frame, k_replay_framedata_sfx ),
v3_copy( arr[i].co, part->prev_co );
v4_copy( arr[i].q, part->prev_q );
+ rb_update_matrices( rb );
}
}
+ else if( frame->system == k_player_subsystem_glide ){
+ struct replay_rb *arr = src;
+ rigidbody *rb = &player_glide.rb;
+ v3_copy( arr[0].co, rb->co );
+ v3_copy( arr[0].w, rb->w );
+ v3_copy( arr[0].v, rb->v );
+ v4_copy( arr[0].q, rb->q );
+ rb_update_matrices( rb );
+ }
+
+ /* restore the seperated glider data if we have it */
+ if( frame->data_table[ k_replay_framedata_glider ][1] ){
+ localplayer.subsystem = frame->system;
+
+ struct replay_glider_data *inf =
+ replay_frame_data( frame, k_replay_framedata_glider );
- localplayer.subsystem = frame->system;
- localplayer.have_glider = gs->have_glider;
+ localplayer.have_glider = inf->have_glider;
+ localplayer.glider_orphan = inf->glider_orphan;
+ player_glide.t = inf->t;
+ }
+ else {
+ localplayer.have_glider = 0;
+ localplayer.glider_orphan = 0;
+ player_glide.t = 0.0f;
+ }
memcpy( &localplayer.rb, &gs->rb, sizeof(rigidbody) );
+ memcpy( &player_glide.rb, &gs->glider_rb, sizeof(rigidbody) );
v3_copy( gs->angles, localplayer.angles );
v3_copy( frame->cam_pos, localplayer.cam.pos );
}
static void skaterift_replay_post_render(void){
+#ifndef SR_ALLOW_REWIND_HUB
if( world_static.active_instance != k_world_purpose_client )
return;
+#endif
/* capture the current resume frame at the very last point */
if( button_down( k_srbind_reset ) ){
}
}
-#if 0
-static void skaterift_get_replay_camera( camera *cam ){
- if( skaterift.freecam ){
- cam->nearz = 0.1f;
- cam->farz = 100.0f;
- v3_copy( skaterift.replay_freecam.pos, cam->pos );
- v3_copy( skaterift.replay_freecam.angles, cam->angles );
- cam->fov = skaterift.replay_freecam.fov;
- }
- else{
- replay_get_camera( &skaterift.replay, &skaterift.cam );
- }
-}
-#endif
-
static void skaterift_replay_debug_info(void){
player__debugtext( 2, "replay info" );
player__debugtext( 1, "head @%u | tail @%u\n", head, tail );
if( replay->statehead ){
- for( u32 i=0; i<4; i++ ){
+ for( u32 i=0; i<k_replay_framedata_rows; i++ ){
player__debugtext( 1, "[%u]: [%hu, %hu]\n", i,
replay->statehead->data_table[i][0],
replay->statehead->data_table[i][1] );