X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player.h;h=46c7dd4de0d416836bbe1b05d3b358fe80d71216;hb=d045af680c6b8ca267a7aded69e2e510e659d2ab;hp=a0ac8585ab863ea969c5815629a90f8afc16a5dc;hpb=84a7ae83a25966e0004a1a4b409dbb3d49fae286;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player.h b/player.h index a0ac858..46c7dd4 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,25 +14,27 @@ 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; static int walk_grid_iterations = 1; +static float fc_speed = 10.0f; static struct gplayer { /* Physics */ - rigidbody rb; + rigidbody rb, collide_front, collide_back, rb_gate_frame; v3f a, v_last, m, bob, vl; @@ -68,7 +71,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 } }; /* @@ -97,13 +101,13 @@ static void player_mouseview(void) v2_sub( vg_mouse, mouse_last, delta ); v2_copy( vg_mouse, mouse_last ); - v2_muladds( view_vel, delta, 0.005f, view_vel ); + v2_muladds( view_vel, delta, 0.001f, view_vel ); } v2_muladds( view_vel, (v2f){ vg_get_axis("h1"), vg_get_axis("v1") }, 0.05f, view_vel ); - v2_muls( view_vel, 0.7f, view_vel ); + v2_muls( view_vel, 0.93f, view_vel ); v2_add( view_vel, player.angles, player.angles ); player.angles[1] = vg_clampf( player.angles[1], -VG_PIf*0.5f, VG_PIf*0.5f ); } @@ -112,7 +116,7 @@ static void player_freecam(void) { player_mouseview(); - float movespeed = 25.0f; + float movespeed = fc_speed; v3f lookdir = { 0.0f, 0.0f, -1.0f }, sidedir = { 1.0f, 0.0f, 0.0f }; @@ -159,11 +163,8 @@ static void player_start_air(void) player.in_air = 1; float pstep = ktimestep*10.0f; - - float best_velocity_mod = 0.0f, - best_velocity_delta = -9999.9f; - - float k_bias = 0.97f; + float best_velocity_delta = -9999.9f; + float k_bias = 0.96f; v3f axis; v3_cross( player.rb.up, player.rb.v, axis ); @@ -225,7 +226,6 @@ static void player_start_air(void) if( (land_delta < 0.0f) && (land_delta > best_velocity_delta) ) { best_velocity_delta = land_delta; - best_velocity_mod = vmod; v3_copy( contact.pos, player.land_target ); @@ -286,7 +286,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 +303,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,88 +406,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 ); - vg_line(tri[0],tri[1],0xff00ff00 ); - vg_line(tri[1],tri[2],0xff00ff00 ); - vg_line(tri[2],tri[0],0xff00ff00 ); + rb_update_bounds( rbf ); + rb_update_bounds( rbb ); - v3f co, norm; - float p; + rb_debug( rbf, 0xff00ffff ); + rb_debug( rbb, 0xffffff00 ); - for( int j=0; j<2; j++ ) - { - if( sphere_vs_triangle( poles[j], k_board_radius, tri,co,norm,&p) ) - { - if(manifold_count >= vg_list_size(manifold)) - { - vg_error("Manifold overflow!\n"); - break; - } + rb_ct manifold[24]; + int len = 0; - v3f p1; - v3_muladds( poles[j], norm, p, p1 ); - vg_line( poles[j], p1, 0xffffffff ); + len += rb_sphere_vs_scene( rbf, &world.rb_geo, manifold+len ); + len += rb_sphere_vs_scene( rbb, &world.rb_geo, manifold+len ); - struct contact *ct = &manifold[manifold_count ++]; - v3_copy( co, ct->co ); - v3_copy( norm, ct->n ); - - ct->bias = -0.2f*k_rb_rate*vg_minf(0.0f,-p+k_board_allowance); - ct->norm_impulse = 0.0f; - - v3_add( norm, surface_avg, surface_avg ); - } - } - } + 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 ) @@ -486,7 +482,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 ) ) { @@ -616,7 +616,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; } } @@ -1011,6 +1013,7 @@ static void player_walkgrid_iter(struct walkgrid *wg, int iter) pa[0] = wg->region[0][0] + (float)wg->cell_id[0] *k_gridscale; pa[1] = (wg->region[0][1] + wg->region[1][1]) * 0.5f + k_gridscale; pa[2] = wg->region[0][2] + (float)wg->cell_id[1] *k_gridscale; +#if 0 pb[0] = pa[0]; pb[1] = pa[1]; pb[2] = pa[2] + k_gridscale; @@ -1020,7 +1023,6 @@ static void player_walkgrid_iter(struct walkgrid *wg, int iter) pd[0] = pa[0] + k_gridscale; pd[1] = pa[1]; pd[2] = pa[2]; -#if 0 /* if you want to draw the current cell */ vg_line( pa, pb, 0xff00ffff ); vg_line( pb, pc, 0xff00ffff ); @@ -1600,14 +1602,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; @@ -1627,11 +1627,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; @@ -1650,7 +1669,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, @@ -1671,9 +1690,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 @@ -1964,6 +1982,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; } @@ -1974,7 +1994,17 @@ 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; + + world_routes_notify_reset(); + } if( vg_get_button_down( "switchmode" ) ) {