From: hgn Date: Tue, 8 Nov 2022 00:05:38 +0000 (+0000) Subject: numerous input and physics X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=ec0918b2ef17a71418a57417689fd3042915aeeb;p=carveJwlIkooP6JGAAIwe30JlM.git numerous input and physics --- diff --git a/audio.h b/audio.h index 9622c50..43adf05 100644 --- a/audio.h +++ b/audio.h @@ -266,11 +266,14 @@ VG_STATIC void audio_sample_occlusion( v3f origin ) { d += contact.dist; +#if 0 vg_line( origin, contact.pos, 0xff0000ff ); vg_line_pt3( contact.pos, 0.1f, 0xff0000ff ); if( lv ) vg_line( contact.pos, last, 0xffffffff ); +#endif + v3_copy( contact.pos, last ); lv = 1; } @@ -278,7 +281,10 @@ VG_STATIC void audio_sample_occlusion( v3f origin ) { v3f p1; v3_muladds( origin, dir, sample_dist, p1 ); + +#if 0 vg_line( origin, p1, 0xffcccccc ); +#endif d += sample_dist; lv = 0; @@ -327,8 +333,10 @@ VG_STATIC enum audio_sprite_type audio_sample_sprite_random( v3f origin, } else { +#if 0 vg_line( pos, contact.pos, 0xff0000ff ); vg_line_pt3( contact.pos, 0.3f, 0xff0000ff ); +#endif return k_audio_sprite_type_none; } } diff --git a/models_src/mp_dev.mdl b/models_src/mp_dev.mdl index 5a431b1..47f0db7 100644 Binary files a/models_src/mp_dev.mdl and b/models_src/mp_dev.mdl differ diff --git a/player.h b/player.h index c8c9abc..61a1391 100644 --- a/player.h +++ b/player.h @@ -66,6 +66,8 @@ VG_STATIC struct gplayer reverse; float grab, jump, pushing, push_time; + v2f grab_mouse_delta; + double start_push; int in_air, on_board, jump_charge, jump_dir; @@ -93,8 +95,6 @@ VG_STATIC struct gplayer *input_js1v, *input_js2h, *input_js2v, - *input_emjs2h, - *input_emjs2v, *input_jump, *input_push, *input_walkh, @@ -225,8 +225,6 @@ VG_STATIC void player_init(void) /* 1 player.input_grab = vg_create_named_input( "grab", k_input_type_axis_norm ); player.input_js2h = vg_create_named_input( "grab-h", k_input_type_axis ); player.input_js2v = vg_create_named_input( "grab-v", k_input_type_axis ); - player.input_emjs2h = vg_create_named_input( "kbgrab-h", k_input_type_axis ); - player.input_emjs2v = vg_create_named_input( "kbgrab-v", k_input_type_axis ); player.input_jump = vg_create_named_input( "jump", k_input_type_button ); player.input_push = vg_create_named_input( "push", k_input_type_axis_norm ); @@ -250,23 +248,19 @@ VG_STATIC void player_init(void) /* 1 "bind -steer-v w", "bind +steer-v s", - "bind grab gp-rt", - "bind grab-h gp-rs-h", - "bind grab-v gp-rs-v", - - "bind -kbgrab-h left", - "bind +kbgrab-h right", - "bind -kbgrab-v down", - "bind +kbgrab-v up", + "bind grab gp-rt", + "bind +grab shift", + "bind grab-h gp-rs-h", + "bind grab-v gp-rs-v", "bind jump space", "bind jump gp-a", "bind push gp-lt", - "bind +push shift", + "bind +push w", - "bind walk-h gp-ls-h", - "bind walk-v gp-ls-v", + "bind walk-h gp-ls-h", + "bind walk-v -gp-ls-v", "bind +walk-h d", "bind -walk-h a", "bind +walk-v w", diff --git a/player_animation.h b/player_animation.h index 594f282..88fe669 100644 --- a/player_animation.h +++ b/player_animation.h @@ -232,8 +232,15 @@ VG_STATIC void player_animate(void) skeleton_sample_anim( sk, player.mdl.anim_air, air_frame, apose ); static v2f grab_choice; - v2_lerp( grab_choice, (v2f){vg_get_axis("grabh"), vg_get_axis("grabv")}, - 0.04f, grab_choice ); + + v2f grab_input = { player.input_js2h->axis.value, + player.input_js2v->axis.value }; + v2_add( player.phys.grab_mouse_delta, grab_input, grab_input ); + if( v2_length2( grab_input ) <= 0.001f ) + grab_input[0] = -1.0f; + else + v2_normalize_clamp( grab_input ); + v2_lerp( grab_choice, grab_input, 2.4f*vg.time_delta, grab_choice ); float ang = atan2f( grab_choice[0], grab_choice[1] ), ang_unit = (ang+VG_PIf) * (1.0f/VG_TAUf), diff --git a/player_physics.h b/player_physics.h index 4178e04..52e4c30 100644 --- a/player_physics.h +++ b/player_physics.h @@ -195,10 +195,11 @@ VG_STATIC void player_physics_control(void) vel[1] += pump; - m3x3_mulv( phys->rb.to_world, vel, phys->rb.v ); - float steer = player.input_js1h->axis.value, + float input = player.input_js1h->axis.value, + grab = player.input_grab->axis.value, + steer = input * (1.0f-(phys->jump+grab)*0.4f), steer_scaled = vg_signf(steer) * powf(steer,2.0f) * k_steer_ground; phys->iY -= steer_scaled * VG_TIMESTEP_FIXED; @@ -269,22 +270,24 @@ VG_STATIC void player_physics_control_air(void) time_to_impact += pstep; } - float steerh = player.input_js1h->axis.value, - steerv = player.input_js1v->axis.value; + v2f steer = { player.input_js1h->axis.value, + player.input_js1v->axis.value }; - phys->iY -= steerh * k_steer_air * VG_TIMESTEP_FIXED; + float l2 = v2_length2( steer ); + if( l2 > 1.0f ) + v2_muls( steer, 1.0f/sqrtf(l2), steer ); - { - float iX = steerv * - phys->reverse * k_steer_air * limiter * VG_TIMESTEP_FIXED; + phys->iY -= steer[0] * k_steer_air * VG_TIMESTEP_FIXED; - static float siX = 0.0f; - siX = vg_lerpf( siX, iX, k_steer_air_lerp ); - - v4f rotate; - q_axis_angle( rotate, phys->rb.right, siX ); - q_mul( rotate, phys->rb.q, phys->rb.q ); - } + float iX = steer[1] * + phys->reverse * k_steer_air * limiter * VG_TIMESTEP_FIXED; + + static float siX = 0.0f; + siX = vg_lerpf( siX, iX, k_steer_air_lerp ); + + v4f rotate; + q_axis_angle( rotate, phys->rb.right, siX ); + q_mul( rotate, phys->rb.q, phys->rb.q ); #if 0 v2f target = {0.0f,0.0f}; @@ -603,32 +606,22 @@ VG_STATIC void player_physics(void) } } - float grabt = vg_maxf( player.input_grab->axis.value, - vg_maxf( fabsf( player.input_emjs2h->axis.value ), - fabsf( player.input_emjs2v->axis.value ) ) - ); + float grabt = player.input_grab->axis.value; + + if( grabt > 0.5f ) + { + v2_muladds( phys->grab_mouse_delta, vg.mouse_delta, 0.02f, + phys->grab_mouse_delta ); + v2_normalize_clamp( phys->grab_mouse_delta ); + } + else + v2_zero( phys->grab_mouse_delta ); phys->grab = vg_lerpf( phys->grab, grabt, 0.14f ); player.phys.pushing = 0.0f; if( !phys->in_air ) { -#if 0 - v3f axis; - float angle = v3_dot( phys->rb.up, surface_avg ); - v3_cross( phys->rb.up, surface_avg, axis ); - - //float cz = v3_dot( player.rb.forward, axis ); - //v3_muls( player.rb.forward, cz, axis ); - - if( angle < 0.999f ) - { - v4f correction; - q_axis_angle( correction, axis, acosf(angle)*18.0f*VG_TIMESTEP_FIXED ); - q_mul( correction, phys->rb.q, phys->rb.q ); - } -#else - /* 20/10/22: make this only go axisways instead, may effect velocities. */ v3f projected, axis; @@ -653,9 +646,6 @@ VG_STATIC void player_physics(void) q_mul( correction, phys->rb.q, phys->rb.q ); } - -#endif - float const DOWNFORCE = -k_downforce*VG_TIMESTEP_FIXED; v3_muladds( phys->rb.v, phys->rb.up, DOWNFORCE, phys->rb.v ); diff --git a/rigidbody.h b/rigidbody.h index 10b4359..04d5a9c 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -103,6 +103,7 @@ VG_STATIC struct contact normal_mass, tangent_mass[2]; u32 element_id; + int cluster; } rb_contact_buffer[256]; VG_STATIC int rb_contact_count = 0; @@ -1247,12 +1248,19 @@ VG_STATIC int rb_sphere_sphere( rigidbody *rba, rigidbody *rbb, rb_ct *buf ) return 0; } +#define RIGIDBODY_DYNAMIC_MESH_EDGES + VG_STATIC int rb_sphere_triangle( rigidbody *rba, rigidbody *rbb, v3f tri[3], rb_ct *buf ) { v3f delta, co; +#ifdef RIGIDBODY_DYNAMIC_MESH_EDGES + closest_on_triangle( rba->co, tri, co ); +#else closest_on_triangle_1( rba->co, tri, co ); +#endif + v3_sub( rba->co, co, delta ); vg_line( rba->co, co, 0xffff0000 ); @@ -1289,24 +1297,142 @@ VG_STATIC int rb_sphere_scene( rigidbody *rba, rigidbody *rbb, rb_ct *buf ) scene *sc = rbb->inf.scene.bh_scene->user; u32 geo[128]; - v3f tri[3]; - int len = bh_select( rbb->inf.scene.bh_scene, rba->bbx_world, geo, 128 ); + int len = bh_select( rbb->inf.scene.bh_scene, rba->bbx_world, geo, 128 ); int count = 0; +#ifdef RIGIDBODY_DYNAMIC_MESH_EDGES + /* !experimental! build edge array on the fly. time could be improved! */ + + v3f co_picture[128*3]; + int unique_cos = 0; + + struct face_info + { + int unique_cos[3]; /* indexes co_picture array */ + int collided; + v3f normal; + u32 element_id; + } + faces[128]; + + /* create geometry picture */ + for( int i=0; iarrindices[ geo[i]*3 ]; + struct face_info *inf = &faces[i]; + inf->element_id = tri_indices[0]; + inf->collided = 0; + + for( int j=0; j<3; j++ ) + { + struct mdl_vert *pvert = &sc->arrvertices[tri_indices[j]]; + + for( int k=0; kco, co_picture[k] ) < 0.01f*0.01f ) + { + inf->unique_cos[j] = k; + goto next_vert; + } + } + + inf->unique_cos[j] = unique_cos; + v3_copy( pvert->co, co_picture[ unique_cos ++ ] ); +next_vert:; + } + + v3f ab, ac; + v3_sub( co_picture[inf->unique_cos[2]], + co_picture[inf->unique_cos[0]], ab ); + + v3_sub( co_picture[inf->unique_cos[1]], + co_picture[inf->unique_cos[0]], ac ); + v3_cross( ac, ab, inf->normal ); + v3_normalize( inf->normal ); + } + + + /* build edges brute force */ + int edge_picture[ 128*3 ][4]; + int unique_edges = 0; + + for( int i=0; iunique_cos[i0], inf->unique_cos[i1] ), + e1 = VG_MAX( inf->unique_cos[i0], inf->unique_cos[i1] ), + matched = 0; + + for( int k=0; kunique_cos[i0]; + edge_picture[ unique_edges ][1] = inf->unique_cos[i1]; + + edge_picture[ unique_edges ][2] = i; + edge_picture[ unique_edges ][3] = -1; + + unique_edges ++; + } + } + } +#endif + + v3f tri[3]; + for( int i=0; iunique_cos[0]], + *v1 = co_picture[inf->unique_cos[1]], + *v2 = co_picture[inf->unique_cos[2]]; + + v3_copy( v0, tri[0] ); + v3_copy( v1, tri[1] ); + v3_copy( v2, tri[2] ); + + buf[count].element_id = inf->element_id; +#else u32 *ptri = &sc->arrindices[ geo[i]*3 ]; for( int j=0; j<3; j++ ) v3_copy( sc->arrvertices[ptri[j]].co, tri[j] ); - - vg_line(tri[0],tri[1],0xff00ff00 ); - vg_line(tri[1],tri[2],0xff00ff00 ); - vg_line(tri[2],tri[0],0xff00ff00 ); buf[count].element_id = ptri[0]; - count += rb_sphere_triangle( rba, rbb, tri, buf+count ); +#endif + + vg_line( tri[0],tri[1],0x10ffffff ); + vg_line( tri[1],tri[2],0x10ffffff ); + vg_line( tri[2],tri[0],0x10ffffff ); + + int hits = rb_sphere_triangle( rba, rbb, tri, buf+count ); +#ifdef RIGIDBODY_DYNAMIC_MESH_EDGES + if( hits ) + inf->collided = 1; +#endif + count += hits; if( count == 12 ) { @@ -1315,6 +1441,62 @@ VG_STATIC int rb_sphere_scene( rigidbody *rba, rigidbody *rbb, rb_ct *buf ) } } +#ifdef RIGIDBODY_DYNAMIC_MESH_EDGES + for( int i=0; icollided || inf_j->collided ) + continue; + + v3f co, delta; + closest_point_segment( co_picture[edge[0]], co_picture[edge[1]], + rba->co, co ); + + v3_sub( rba->co, co, delta ); + float d2 = v3_length2( delta ), + r = rba->inf.sphere.radius; + + if( d2 < r*r ) + { + float d = sqrtf(d2); + + v3_muls( delta, 1.0f/d, delta ); + float c0 = v3_dot( inf_i->normal, delta ), + c1 = v3_dot( inf_j->normal, delta ); + + if( c0 < 0.0f || c1 < 0.0f ) + continue; + + rb_ct *ct = buf+count; + + v3_muls( inf_i->normal, c0, ct->n ); + v3_muladds( ct->n, inf_j->normal, c1, ct->n ); + v3_normalize( ct->n ); + + v3_copy( co, ct->co ); + ct->p = r-d; + ct->rba = rba; + ct->rbb = rbb; + ct->element_id = inf_i->element_id; + + count ++; + + if( count == 12 ) + { + vg_warn( "Geometry too dense!\n" ); + return count; + } + } + } +#endif + return count; }