X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player.h;h=442d03e0ab7a783fd1b71bba44762e9675cb6e20;hb=b93c61c54e7ac56f6808b9a563d3e4221ca8482e;hp=f03747a5098cf5afc8effde12f13fc0dce416a8b;hpb=d13f2700b1773551307685cc7c34c804ccd6d664;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player.h b/player.h index f03747a..442d03e 100644 --- a/player.h +++ b/player.h @@ -1,15 +1,12 @@ /* - * Copyright 2021-2022 (C) Mount0 Software, Harry Godden - All Rights Reserved - * ----------------------------------------------------------------------------- - * - * Player head module - * - * ----------------------------------------------------------------------------- + * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved */ #ifndef PLAYER_H #define PLAYER_H +#define PLAYER_REWIND_FRAMES 60*4 + #include "audio.h" #include "common.h" #include "world.h" @@ -17,12 +14,13 @@ #include "bvh.h" static float - k_walkspeed = 7.0f, /* no longer used */ - k_runspeed = 14.0f, + k_walkspeed = 20.0f, /* no longer used */ + k_runspeed = 20.0f, k_board_radius = 0.3f, k_board_length = 0.45f, k_board_allowance = 0.04f, - k_friction_lat = 8.8f, + //k_friction_lat = 8.8f, + k_friction_lat = 12.0f, k_friction_resistance = 0.01f, k_max_push_speed = 16.0f, k_push_accel = 10.0f, @@ -32,11 +30,12 @@ static float k_steer_air_lerp = 0.3f, k_pump_force = 0.0f, k_downforce = 5.0f, + k_walk_downforce = 8.0f, k_jump_charge_speed = (1.0f/1.0f), k_jump_force = 5.0f, k_pitch_limit = 1.5f, k_look_speed = 2.0f, - k_walk_accel = 5.0f, + k_walk_accel = 150.0f, k_walk_friction = 8.0f; static int freecam = 0; @@ -65,7 +64,8 @@ static struct gplayer float vswitch, slip, slip_last, reverse; - float grab, jump; + float grab, jump, pushing, push_time; + double start_push; int in_air, on_board, jump_charge, jump_dir; m3x3f vr,vr_pstep; @@ -73,8 +73,10 @@ static struct gplayer phys, phys_gate_frame; - float pushing, push_time; - int is_dead; + m4x3f visual_transform, + inv_visual_transform; + + int is_dead, death_tick_allowance, rewinding; v3f land_target; v3f land_target_log[22]; @@ -89,7 +91,17 @@ static struct gplayer v3f camera_pos, smooth_localcam; v2f angles; - m4x3f camera, camera_inverse; + + struct rewind_frame + { + v3f pos; + v2f ang; + } + *rewind_buffer; + u32 rewind_incrementer, + rewind_length; + + float rewind_time; /* animation */ double jump_time; @@ -102,8 +114,10 @@ static struct gplayer fsetup, walk_timer, fjump, - fonboard; + fonboard, + frun; + float walk; int step_phase; /* player model */ @@ -118,7 +132,8 @@ static struct gplayer *anim_push, *anim_push_reverse, *anim_ollie, *anim_ollie_reverse, *anim_grabs, *anim_stop, - *anim_walk, *anim_run, *anim_idle; + *anim_walk, *anim_run, *anim_idle, + *anim_jump; u32 id_hip, id_ik_hand_l, @@ -161,6 +176,7 @@ static void player_kill(void); static float *player_cam_pos(void); static void player_save_frame(void); static void player_restore_frame(void); +static void player_save_rewind_frame(void); /* * Submodules @@ -228,21 +244,46 @@ static void player_init(void) /* 1 */ .function = reset_player }); + player.rewind_length = 0; + player.rewind_buffer = vg_alloc( sizeof(struct rewind_frame) + * PLAYER_REWIND_FRAMES ); + /* other systems */ vg_loader_highwater( player_model_init, player_model_free, NULL ); } -static void player_update(void) /* 2 */ +static void player_save_rewind_frame(void) +{ + if( player.rewind_length < PLAYER_REWIND_FRAMES ) + { + struct rewind_frame *fr = + &player.rewind_buffer[ player.rewind_length ++ ]; + + v2_copy( player.angles, fr->ang ); + v3_copy( player.camera_pos, fr->pos ); + + player.rewind_incrementer = 0; + } +} + +/* Deal with input etc */ +static void player_update_pre(void) { struct player_phys *phys = &player.phys; - for( int i=0; i0.0f) + if( vg_get_button_down( "reset" ) ) { + player.rewinding = 1; + player.rewind_time = (float)player.rewind_length - 0.0001f; + player_save_rewind_frame(); + player.is_dead = 0; + player.death_tick_allowance = 30; player_restore_frame(); if( !phys->on_board ) @@ -255,24 +296,57 @@ static void player_update(void) /* 2 */ player.mdl.shoes[1] = 1; world_routes_notify_reset(); + + /* apply 1 frame of movement */ + player_do_motion(); } if( vg_get_button_down( "switchmode" ) ) { phys->on_board ^= 0x1; + + if( phys->on_board ) + { + v3_muladds( phys->rb.v, phys->rb.forward, 0.2f, phys->rb.v ); + } } +} + +static void player_update_fixed(void) /* 2 */ +{ + if( player.rewinding ) + return; + + if( player.death_tick_allowance ) + player.death_tick_allowance --; + + struct player_phys *phys = &player.phys; -#if 0 - if( (glfwGetKey( vg_window, GLFW_KEY_O ) )) + if( player.is_dead ) { - player_ragdoll_copy_model( phys->rb.v ); - player.is_dead = 1; + player_ragdoll_iter(); + } + else + { + player.rewind_incrementer ++; + + if( player.rewind_incrementer > (u32)(0.25/VG_TIMESTEP_FIXED) ) + { + player_save_rewind_frame(); + } + + player_do_motion(); } -#endif +} + +static void player_update_post(void) +{ + for( int i=0; i 0 ); + + v2f override_angles; + v3f override_pos; + + float budget = vg.time_delta, + overall_length = player.rewind_length; + + world_routes_rollback_time( player.rewind_time / overall_length ); + + for( int i=0; (i<10)&&(player.rewind_time>0.0f)&&(budget>0.0f); i ++ ) + { + /* Interpolate frames */ + int i0 = floorf( player.rewind_time ), + i1 = VG_MIN( i0+1, player.rewind_length-1 ); + + struct rewind_frame *fr = &player.rewind_buffer[i0], + *fr1 = &player.rewind_buffer[i1]; + + float dist = vg_maxf( v3_dist( fr->pos, fr1->pos ), 0.001f ), + subl = vg_fractf( player.rewind_time ) + 0.001f, + + sramp= 3.0f-(1.0f/(0.4f+0.4f*player.rewind_time)), + speed = sramp*28.0f + 0.5f*player.rewind_time, + mod = speed * (budget / dist), + + advl = vg_minf( mod, subl ), + advt = (advl / mod) * budget; + + player.rewind_time -= advl; + budget -= advt; + } + + player.rewind_time = vg_maxf( 0.0f, player.rewind_time ); + + int i0 = floorf( player.rewind_time ), + i1 = VG_MIN( i0+1, player.rewind_length-1 ); + + struct rewind_frame *fr = &player.rewind_buffer[i0], + *fr1 = &player.rewind_buffer[i1]; + + float sub = vg_fractf(player.rewind_time); + + v3_lerp( fr->pos, fr1->pos, sub, override_pos ); + override_angles[0] = vg_alerpf( fr->ang[0], fr1->ang[0], sub ); + override_angles[1] = vg_lerpf ( fr->ang[1], fr1->ang[1], sub ); + + /* CAMERA POSITIONING: LAYER 1 */ + float blend = (4.0f-player.rewind_time) * 0.25f, + c = vg_clampf( blend, 0.0f, 1.0f ); + + camera_angles[0] = vg_alerpf(override_angles[0], player.angles[0], c); + camera_angles[1] = vg_lerpf (override_angles[1], player.angles[1], c); + v3_lerp( override_pos, player.camera_pos, c, camera_pos ); + } + } + + camera_update(); player_audio(); } -static void draw_player(void) /* 3 */ +static void draw_player( m4x3f cam ) { if( player.is_dead ) player_model_copy_ragdoll(); @@ -302,8 +448,8 @@ static void draw_player(void) /* 3 */ shader_viewchar_use(); vg_tex2d_bind( &tex_characters, 0 ); shader_viewchar_uTexMain( 0 ); - shader_viewchar_uCamera( player.camera[3] ); - shader_viewchar_uPv( vg_pv ); + shader_viewchar_uCamera( cam[3] ); + shader_viewchar_uPv( vg.pv ); shader_link_standard_ub( _shader_viewchar.id, 2 ); glUniformMatrix4x3fv( _uniform_viewchar_uTransforms, player.mdl.sk.bone_count, @@ -327,8 +473,11 @@ static float *player_get_pos(void) static void player_kill(void) { - player.is_dead = 1; - player_ragdoll_copy_model( player.phys.rb.v ); + if( player.death_tick_allowance == 0 ) + { + player.is_dead = 1; + player_ragdoll_copy_model( player.phys.rb.v ); + } } static float *player_cam_pos(void)