numerous input and physics
authorhgn <hgodden00@gmail.com>
Tue, 8 Nov 2022 00:05:38 +0000 (00:05 +0000)
committerhgn <hgodden00@gmail.com>
Tue, 8 Nov 2022 00:05:38 +0000 (00:05 +0000)
audio.h
models_src/mp_dev.mdl
player.h
player_animation.h
player_physics.h
rigidbody.h

diff --git a/audio.h b/audio.h
index 9622c50a81eee572bb52a082339f45668d4e15b0..43adf052e289077ef860e1ef8ba82f1452b3d1b8 100644 (file)
--- 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;
       }
    }
index 5a431b1904064715da263275029b521925514dc1..47f0db7c57e290f24999b1570e024f671435bad2 100644 (file)
Binary files a/models_src/mp_dev.mdl and b/models_src/mp_dev.mdl differ
index c8c9abc54b8932ecd480838014a44001ca9c4dfb..61a1391261e758f913c77fe5b46bb8b0f45ebaab 100644 (file)
--- 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",
index 594f282c3be7e8917bcb111a98d84080dbc17c1d..88fe6690e8039ace9ae538e159c729a36de6487e 100644 (file)
@@ -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),
index 4178e04265eea1d1125640fb97f0b8ec3c41e34d..52e4c3080f82aa4dcae6a9e5e4d6a182942d2c86 100644 (file)
@@ -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 );
 
index 10b4359f56537641354c59e982e0d9d8a37b6098..04d5a9c9830c824d466b7c3fb7cff82364556726 100644 (file)
@@ -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; i<len; i++ )
+   {
+      u32 *tri_indices = &sc->arrindices[ 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; k<unique_cos; k++ )
+         {
+            if( v3_dist( pvert->co, 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; i<len; i++ )
+   {
+      struct face_info *inf = &faces[i];
+      
+      for( int j=0; j<3; j++ )
+      {
+         int i0 = j,
+             i1 = (j+1)%3,
+             e0 = VG_MIN( inf->unique_cos[i0], inf->unique_cos[i1] ),
+             e1 = VG_MAX( inf->unique_cos[i0], inf->unique_cos[i1] ),
+             matched = 0;
+
+         for( int k=0; k<unique_edges; k ++ )
+         {
+            int k0 = VG_MIN( edge_picture[k][0], edge_picture[k][1] ),
+                k1 = VG_MAX( edge_picture[k][0], edge_picture[k][1] );
+
+            /* matched ! */
+            if( (k0 == e0) && (k1 == e1) )
+            {
+               edge_picture[ k ][3] = i;
+               matched = 1;
+               break;
+            }
+         }
+      
+         if( !matched )
+         {
+            /* create new edge */
+            edge_picture[ unique_edges ][0] = inf->unique_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; i<len; i++ )
    {
+#ifdef RIGIDBODY_DYNAMIC_MESH_EDGES
+      struct face_info *inf = &faces[i];
+
+      float *v0 = co_picture[inf->unique_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; i<unique_edges; i++ )
+   {
+      int *edge = edge_picture[i];
+
+      if( edge[3] == -1 )
+         continue;
+
+      struct face_info *inf_i = &faces[edge[2]],
+                       *inf_j = &faces[edge[3]];
+      
+      if( inf_i->collided || 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;
 }