X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_physics.h;h=6bfb559204e87f2923dabbf5c29271537f2c276e;hb=e7f34d37fb7a68f4a30995656c8f1c9075997124;hp=80a07b2d450f54cd2d5e03c85e534d702ad8c0ad;hpb=297468e5a3cc8c7805c16fdd615f42f3876eb908;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_physics.h b/player_physics.h index 80a07b2..6bfb559 100644 --- a/player_physics.h +++ b/player_physics.h @@ -367,6 +367,12 @@ VG_STATIC void player_physics_control_air(void) float time_to_impact = 0.0f; float limiter = 1.0f; + struct grind_edge *best_grind = NULL; + float closest_grind = INFINITY; + + v3f target_normal = { 0.0f, 1.0f, 0.0f }; + int has_target = 0; + for( int i=0; i<50; i++ ) { v3_copy( pco, pco1 ); @@ -380,34 +386,51 @@ VG_STATIC void player_physics_control_air(void) v3_sub( pco, pco1, vdir ); contact.dist = v3_length( vdir ); v3_divs( vdir, contact.dist, vdir); + + v3f c0, c1; + struct grind_edge *ge = player_grind_collect_edge( pco, pco1, + c0, c1, 0.4f ); + + if( ge && (v3_dot((v3f){0.0f,1.0f,0.0f},vdir) < -0.2f ) ) + { + vg_line( ge->p0, ge->p1, 0xff0000ff ); + vg_line_cross( pco, 0xff0000ff, 0.25f ); + has_target = 1; + break; + } float orig_dist = contact.dist; - if( ray_world( pco1, vdir, &contact )) + if( ray_world( pco1, vdir, &contact ) ) { - float angle = v3_dot( phys->rb.up, contact.normal ); - v3f axis; - v3_cross( phys->rb.up, contact.normal, axis ); - + v3_copy( contact.normal, target_normal ); + has_target = 1; time_to_impact += (contact.dist/orig_dist)*pstep; - limiter = vg_minf( 5.0f, time_to_impact )/5.0f; - limiter = 1.0f-limiter; - limiter *= limiter; - limiter = 1.0f-limiter; - - if( fabsf(angle) < 0.99f ) - { - v4f correction; - q_axis_angle( correction, axis, - acosf(angle)*(1.0f-limiter)*3.0f*VG_TIMESTEP_FIXED ); - q_mul( correction, phys->rb.q, phys->rb.q ); - } - vg_line_cross( contact.pos, 0xffff0000, 0.25f ); break; } time_to_impact += pstep; } + if( has_target ) + { + float angle = v3_dot( phys->rb.up, target_normal ); + v3f axis; + v3_cross( phys->rb.up, target_normal, axis ); + + limiter = vg_minf( 5.0f, time_to_impact )/5.0f; + limiter = 1.0f-limiter; + limiter *= limiter; + limiter = 1.0f-limiter; + + if( fabsf(angle) < 0.99f ) + { + v4f correction; + q_axis_angle( correction, axis, + acosf(angle)*(1.0f-limiter)*3.0f*VG_TIMESTEP_FIXED ); + q_mul( correction, phys->rb.q, phys->rb.q ); + } + } + v2f steer = { player.input_js1h->axis.value, player.input_js1v->axis.value }; @@ -973,33 +996,60 @@ VG_STATIC void player_do_motion(void) int len = player_update_collision_manifold( manifold ); int grind_col = player_update_grind_collision( &manifold[len] ); + static int _grind_col_pre = 0; + if( grind_col ) { phys->grind = 1; v3f up = { 0.0f, 1.0f, 0.0f }; float angle = v3_dot( phys->rb.up, up ); - v3f axis; - v3_cross( phys->rb.up, up, axis ); if( fabsf(angle) < 0.99f ) { + v3f axis; + v3_cross( phys->rb.up, up, axis ); + v4f correction; q_axis_angle( correction, axis, VG_TIMESTEP_FIXED * 10.0f * acosf(angle) ); q_mul( correction, phys->rb.q, phys->rb.q ); } - float const DOWNFORCE = -k_downforce*2.0f*VG_TIMESTEP_FIXED; - v3_muladds( phys->rb.v, phys->rb.up, DOWNFORCE, phys->rb.v ); + float const DOWNFORCE = -k_downforce*1.2f*VG_TIMESTEP_FIXED; + v3_muladds( phys->rb.v, manifold[len].n, DOWNFORCE, phys->rb.v ); m3x3_identity( phys->vr ); m3x3_identity( phys->vr_pstep ); + + if( !_grind_col_pre ) + { + audio_lock(); + audio_player_set_flags( &audio_player_extra, + AUDIO_FLAG_SPACIAL_3D ); + audio_player_set_position( &audio_player_extra, phys->rb.co ); + audio_player_set_vol( &audio_player_extra, 20.0f ); + audio_player_playclip( &audio_player_extra, &audio_board[5] ); + audio_unlock(); + } } else { phys->grind = 0; player_adhere_ground( manifold, len ); + + if( _grind_col_pre ) + { + audio_lock(); + audio_player_set_flags( &audio_player_extra, + AUDIO_FLAG_SPACIAL_3D ); + audio_player_set_position( &audio_player_extra, phys->rb.co ); + audio_player_set_vol( &audio_player_extra, 20.0f ); + audio_player_playclip( &audio_player_extra, &audio_board[6] ); + audio_unlock(); + } } + _grind_col_pre = grind_col; + rb_presolve_contacts( manifold, len+ VG_MAX(0,grind_col) ); player_collision_response( manifold, len+ VG_MAX(0,grind_col) ); @@ -1065,6 +1115,15 @@ VG_STATIC void player_do_motion(void) m3x3_mulv( gate->transport, phys->m, phys->m ); m3x3_mulv( gate->transport, phys->bob, phys->bob ); + /* Pre-emptively edit the camera matrices so that the motion vectors + * are correct */ + m4x3f transport_i; + m4x4f transport_4; + m4x3_invert_affine( gate->transport, transport_i ); + m4x3_expand( transport_i, transport_4 ); + m4x4_mul( main_camera.mtx.pv, transport_4, main_camera.mtx.pv ); + m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); + v4f transport_rotation; m3x3_q( gate->transport, transport_rotation ); q_mul( transport_rotation, phys->rb.q, phys->rb.q ); @@ -1104,8 +1163,8 @@ VG_STATIC void player_freecam(void) v3f lookdir = { 0.0f, 0.0f, -1.0f }, sidedir = { 1.0f, 0.0f, 0.0f }; - m3x3_mulv( camera_mtx, lookdir, lookdir ); - m3x3_mulv( camera_mtx, sidedir, sidedir ); + m3x3_mulv( main_camera.transform, lookdir, lookdir ); + m3x3_mulv( main_camera.transform, sidedir, sidedir ); static v3f move_vel = { 0.0f, 0.0f, 0.0f }; @@ -1167,6 +1226,13 @@ VG_STATIC int reset_player( int argc, char const *argv[] ) if( !rp ) { vg_error( "No spawn found\n" ); + vg_info( "Player position: %f %f %f\n", player.phys.rb.co[0], + player.phys.rb.co[1], + player.phys.rb.co[2] ); + vg_info( "Player velocity: %f %f %f\n", player.phys.rb.v[0], + player.phys.rb.v[1], + player.phys.rb.v[2] ); + if( !world.spawn_count ) return 0;