X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player.h;h=b05714e4e893209fe2198628700419d72c600c50;hb=1030b1e134d422a3cbc1e06102053447da59ceba;hp=a378f72a7e76368c012ab3a156a9b7a28c95be3d;hpb=55faf7fcd56fad190f53e6da4417c5bb1c2234d7;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player.h b/player.h index a378f72..b05714e 100644 --- a/player.h +++ b/player.h @@ -3,6 +3,7 @@ #include "audio.h" #include "common.h" +#include "world.h" #include "character.h" #include "bvh.h" @@ -13,16 +14,17 @@ static float k_walkspeed = 2.0f, k_board_radius = 0.3f, - k_board_length = 0.55f, + k_board_length = 0.45f, k_board_allowance = 0.04f, - k_friction_lat = 8.68f, - k_friction_resistance = 0.02f, + k_friction_lat = 8.8f, + k_friction_resistance = 0.01f, k_max_push_speed = 16.0f, k_push_accel = 5.0f, k_push_cycle_rate = 8.0f, k_steer_ground = 2.5f, k_steer_air = 3.6f, k_steer_air_lerp = 0.3f, + k_pump_force = 000.0f, k_downforce = 5.0f; static int freecam = 0; @@ -31,7 +33,7 @@ static int walk_grid_iterations = 1; static struct gplayer { /* Physics */ - rigidbody rb; + rigidbody rb, collide_front, collide_back, rb_gate_frame; v3f a, v_last, m, bob, vl; @@ -68,7 +70,8 @@ player = { .on_board = 1, - .rb = { .type = k_rb_shape_capsule } + .collide_front = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f }, + .collide_back = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f } }; /* @@ -163,7 +166,7 @@ static void player_start_air(void) float best_velocity_mod = 0.0f, best_velocity_delta = -9999.9f; - float k_bias = 0.97f; + float k_bias = 0.96f; v3f axis; v3_cross( player.rb.up, player.rb.v, axis ); @@ -286,7 +289,8 @@ static void player_physics_control(void) for( int i=0; i<5; i++ ) { vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * fwd_resistance ); - vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -8.78f *substep ); + vel[0] = stable_force( vel[0], + vg_signf( vel[0] ) * -k_friction_lat*substep ); } static double start_push = 0.0; @@ -302,6 +306,19 @@ static void player_physics_control(void) new_vel -= vg_minf(current, k_max_push_speed); vel[2] -= new_vel * player.reverse; } + + /* Pumping */ + static float previous = 0.0f; + float delta = previous - player.grab, + pump = delta * k_pump_force*ktimestep; + previous = player.grab; + + v3f p1; + v3_muladds( player.rb.co, player.rb.up, pump, p1 ); + vg_line( player.rb.co, p1, 0xff0000ff ); + + vel[1] += pump; + m3x3_mulv( player.rb.to_world, vel, player.rb.v ); @@ -392,80 +409,70 @@ static void player_physics_control_air(void) v2_lerp( player.board_xy, target, ktimestep*3.0f, player.board_xy ); } +static void player_init(void) +{ + rb_init( &player.collide_front ); + rb_init( &player.collide_back ); +} + static void player_physics(void) { /* - * Player physics uses a customized routine seperate from the main - * rigidbody implementation. It requires some non-standard impulse - * responses being applied for example limiting the effect on certain axises - * ( especially for angular velocity ) - * - * The capsule collider is also at a different angle to the players roation. + * Update collision fronts */ - - m4x3f mboard; - v3_copy( player.rb.to_world[0], mboard[0] ); - v3_copy( player.rb.to_world[2], mboard[1] ); - v3_copy( player.rb.to_world[1], mboard[2] ); - m4x3_mulv( player.rb.to_world, (v3f){ 0.0f, 0.3f, 0.0f }, mboard[3] ); - - debug_capsule( mboard, k_board_length*2.0f, k_board_radius, 0xff0000ff ); - - boxf region = {{ -k_board_radius, -k_board_length, -k_board_radius }, - { k_board_radius, k_board_length, k_board_radius }}; - m4x3_transform_aabb( mboard, region ); - u32 geo[256]; - v3f tri[3]; - int len = bh_select( &world.geo.bhtris, region, geo, 256 ); + rigidbody *rbf = &player.collide_front, + *rbb = &player.collide_back; - v3f poles[2]; - m4x3_mulv(mboard, (v3f){0.0f,-k_board_length+k_board_radius,0.0f}, poles[0]); - m4x3_mulv(mboard, (v3f){0.0f, k_board_length-k_board_radius,0.0f}, poles[1]); + m3x3_copy( player.rb.to_world, player.collide_front.to_world ); + m3x3_copy( player.rb.to_world, player.collide_back.to_world ); - struct contact manifold[12]; - int manifold_count = 0; + player.air_blend = vg_lerpf( player.air_blend, player.in_air, 0.1f ); + float h = player.air_blend*0.2f; - v3f surface_avg = {0.0f, 0.0f, 0.0f}; + m4x3_mulv( player.rb.to_world, (v3f){0.0f,h,-k_board_length}, rbf->co ); + v3_copy( rbf->co, rbf->to_world[3] ); + m4x3_mulv( player.rb.to_world, (v3f){0.0f,h, k_board_length}, rbb->co ); + v3_copy( rbb->co, rbb->to_world[3] ); - for( int i=0; ito_world, rbf->to_local ); + m4x3_invert_affine( rbb->to_world, rbb->to_local ); - for( int j=0; j<3; j++ ) - v3_copy( world.geo.verts[ptri[j]].co, tri[j] ); + rb_update_bounds( rbf ); + rb_update_bounds( rbb ); - vg_line(tri[0],tri[1],0xff00ff00 ); - vg_line(tri[1],tri[2],0xff00ff00 ); - vg_line(tri[2],tri[0],0xff00ff00 ); + rb_debug( rbf, 0xff00ffff ); + rb_debug( rbb, 0xffffff00 ); - v3f temp; - v3_copy( player.rb.co, temp ); + rb_ct manifold[24]; + int len = 0; - for( int j=0; j<2; j++ ) - { - if(manifold_count >= vg_list_size(manifold)) - { - vg_error("Manifold overflow!\n"); - break; - } + len += rb_sphere_vs_scene( rbf, &world.rb_geo, manifold+len ); + len += rb_sphere_vs_scene( rbb, &world.rb_geo, manifold+len ); - rb_ct *ct = &manifold[manifold_count]; - v3_copy( poles[j], player.rb.co ); - - manifold_count += rb_sphere_vs_triangle( &player.rb, tri, ct ); - } - - v3_copy( temp, player.rb.co ); - } - rb_presolve_contacts( manifold, manifold_count ); + rb_presolve_contacts( manifold, len ); + v3f surface_avg = {0.0f, 0.0f, 0.0f}; - if( !manifold_count ) + if( !len ) { player_start_air(); } else { + for( int i=0; i 0.5f ) @@ -478,7 +485,7 @@ static void player_physics(void) for( int j=0; j<5; j++ ) { - for( int i=0; igate; if( gate_intersect( gate, player.rb.co, prevco ) ) { @@ -608,7 +619,9 @@ static void player_do_motion(void) v4f transport_rotation; m3x3_q( gate->transport, transport_rotation ); q_mul( transport_rotation, player.rb.q, player.rb.q ); - + + world_routes_activate_gate( i ); + player.rb_gate_frame = player.rb; break; } } @@ -1592,14 +1605,12 @@ static void player_animate(void) /* Head */ float lslip = fabsf(player.slip); - - float grabt = vg_get_axis( "grabr" )*0.5f+0.5f; - player.grab = vg_lerpf( player.grab, grabt, 0.04f ); float kheight = 2.0f, kleg = 0.6f; v3f offset; + v3_zero( offset ); m3x3_mulv( player.rb.to_local, player.bob, offset ); static float speed_wobble = 0.0f, speed_wobble_2 = 0.0f; @@ -1619,11 +1630,30 @@ static void player_animate(void) offset[0] = vg_clampf( offset[0], -0.8f, 0.8f ); offset[1] = vg_clampf( offset[1], -0.5f, 0.0f ); + /* + * Player rotation + */ +#if 0 + float angle = v3_dot( player.rb.up, (v3f){0.0f,1.0f,0.0f} ); + v3f axis; + v3_cross( player.rb.up, (v3f){0.0f,1.0f,0.0f}, axis ); + + v4f correction; + if( angle < 0.99f && 0 ) + { + m3x3_mulv( player.rb.to_local, axis, axis ); + q_axis_angle( correction, axis, acosf(angle) ); + } + else + { + q_identity( correction ); + } /* * Animation blending * =========================================== */ +#endif static float fslide = 0.0f; static float fdirz = 0.0f; @@ -1642,7 +1672,7 @@ static void player_animate(void) character_pose_reset( &player.mdl ); /* TODO */ - float fstand1 = 1.0f-(1.0f-fstand)*0.3f; + float fstand1 = 1.0f-(1.0f-fstand)*0.0f; float amt_air = ffly*ffly, amt_ground = 1.0f-amt_air, @@ -1663,9 +1693,8 @@ static void player_animate(void) character_final_pose( &player.mdl, offset, &pose_slide1, amt_slide*(1.0f-fdirx) ); - character_final_pose( &player.mdl, (v3f){0.0f,0.0f,0.0f}, + character_final_pose( &player.mdl, (v4f){0.0f,0.0f,0.0f,1.0f}, &pose_fly, amt_air ); - /* * Additive effects @@ -1956,6 +1985,8 @@ static int reset_player( int argc, char const *argv[] ) rb_update_transform( &player.rb ); m3x3_mulv( player.rb.to_world, (v3f){ 0.0f, 0.0f, -1.2f }, player.rb.v ); + + player.rb_gate_frame = player.rb; return 1; } @@ -1966,7 +1997,15 @@ static void player_update(void) player.land_target_colours[i], 0.25f); if( vg_get_axis("grabl")>0.0f) - reset_player(0,NULL); + { + player.rb = player.rb_gate_frame; + player.is_dead = 0; + player.in_air = 1; + m3x3_identity( player.vr ); + + player.mdl.shoes[0] = 1; + player.mdl.shoes[1] = 1; + } if( vg_get_button_down( "switchmode" ) ) {