phys adjustments
authorhgn <hgodden00@gmail.com>
Sat, 24 Dec 2022 01:36:15 +0000 (01:36 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 24 Dec 2022 01:36:15 +0000 (01:36 +0000)
player_physics.h
rigidbody.h
skaterift.c

index 50ea62e41951db888036ef5f427bb1db69d1b71c..a2aabff741f946f4ddd37d1471bde817f60e78a3 100644 (file)
@@ -598,6 +598,40 @@ VG_STATIC void player_walk_update_collision(void)
 }
 
 VG_STATIC void player_integrate(void);
+
+VG_STATIC int player_walk_surface_standable( v3f n )
+{
+   return v3_dot( n, (v3f){0.0f,1.0f,0.0f} ) > 0.5f;
+}
+
+VG_STATIC void player_walk_stepdown(void)
+{
+   struct player_phys *phys = &player.phys;
+   float max_dist = 0.4f;
+
+   v3f pa, pb;
+   v3_copy( phys->rb.co, pa );
+   pa[1] += 0.3f;
+
+   v3_muladds( pa, (v3f){0.01f,1.0f,0.01f}, -max_dist, pb );
+   vg_line( pa, pb, 0xff000000 );
+
+   /* TODO: Make #define */
+   float r = 0.3f,
+         t;
+
+   v3f n;
+   if( spherecast_world( pa, pb, r, &t, n ) != -1 )
+   {
+      if( player_walk_surface_standable( n ) )
+      {
+         phys->in_air = 0;
+         v3_lerp( pa, pb, t+0.001f, phys->rb.co );
+         phys->rb.co[1] -= 0.3f;
+      }
+   }
+}
+
 /*
  * Entire Walking physics model
  * TODO: sleep when under certain velotiy
@@ -753,12 +787,31 @@ VG_STATIC void player_walk_physics(void)
          phys->in_air = 1;
          return;
       }
+
+      /* Check if grounded by current manifold */
+      phys->in_air = 1;
+      for( int i=0; i<len; i++ )
+      {
+         struct contact *ct = &manifold[i];
+         if( player_walk_surface_standable( ct->n ) )
+            phys->in_air = 0;
+      }
+      
+      /* otherwise... */
+      if( phys->in_air )
+         player_walk_stepdown();
       
+#if 0
       /* if we've put us in the air, step down slowly */
       phys->in_air = 1;
       float max_dist = 0.3f,
             start_y = phys->rb.co[1];
 
+      v3f pa, pb;
+      v3_copy( phys->rb.co, pa );
+      v3_muladds( pa, (v3f){0.0f,1.0f,0.0f}, -max_dist, pb );
+
+
       for( int j=0; j<8; j++ )
       {
          for( int i=0; i<len; i++ )
@@ -798,6 +851,7 @@ VG_STATIC void player_walk_physics(void)
       
       /* Transitioning into air mode */
       phys->rb.co[1] = start_y;
+#endif
    }
 }
 
@@ -833,8 +887,8 @@ VG_STATIC int player_update_grind_collision( rb_ct *contact )
    v3f p0, p1, c0, c1;
    v3_muladds( phys->rb.co, phys->rb.forward,  0.5f, p0 );
    v3_muladds( phys->rb.co, phys->rb.forward, -0.5f, p1 );
-   v3_muladds( p0, phys->rb.up, 0.125f, p0 );
-   v3_muladds( p1, phys->rb.up, 0.125f, p1 );
+   v3_muladds( p0, phys->rb.up, 0.125f-0.15f, p0 );
+   v3_muladds( p1, phys->rb.up, 0.125f-0.15f, p1 );
 
    float const k_r = 0.25f;
    struct grind_edge *closest_edge = player_grind_collect_edge( p0, p1, 
index 51c274c855603ca1428dc81fa21cc3b21ced4085..aa8d4f8bc7a2b526766a6c57b5f1884f1d6623f1 100644 (file)
@@ -586,6 +586,44 @@ VG_STATIC int rb_manifold_apply_filtered( rb_ct *man, int len )
    return k;
 }
 
+/*
+ * Merge two contacts if they are within radius(r) of eachother
+ */
+VG_STATIC void rb_manifold_contact_weld( rb_ct *ci, rb_ct *cj, float r )
+{
+   if( v3_dist2( ci->co, cj->co ) < r*r )
+   {
+      cj->type = k_contact_type_disabled;
+      ci->p = (ci->p + cj->p) * 0.5f;
+
+      v3_add( ci->co, cj->co, ci->co );
+      v3_muls( ci->co, 0.5f, ci->co );
+
+      v3f delta;
+      v3_sub( ci->rba->co, ci->co, delta );
+
+      float c0 = v3_dot( ci->n, delta ),
+            c1 = v3_dot( cj->n, delta );
+
+      if( c0 < 0.0f || c1 < 0.0f )
+      {
+         /* error */
+         ci->type = k_contact_type_disabled;
+      }
+      else
+      {
+         v3f n;
+         v3_muls( ci->n, c0, n );
+         v3_muladds( n, cj->n, c1, n );
+         v3_normalize( n );
+         v3_copy( n, ci->n );
+      }
+   }
+}
+
+/*
+ * 
+ */
 VG_STATIC void rb_manifold_filter_joint_edges( rb_ct *man, int len, float r )
 {
    for( int i=0; i<len-1; i++ )
@@ -599,41 +637,16 @@ VG_STATIC void rb_manifold_filter_joint_edges( rb_ct *man, int len, float r )
          rb_ct *cj = &man[j];
          if( cj->type != k_contact_type_edge ) 
             continue;
-
-         if( v3_dist2( ci->co, cj->co ) < r*r )
-         {
-            cj->type = k_contact_type_disabled;
-            ci->p = (ci->p + cj->p) * 0.5f;
-
-            v3_add( ci->co, cj->co, ci->co );
-            v3_muls( ci->co, 0.5f, ci->co );
-
-            v3f delta;
-            v3_sub( ci->rba->co, ci->co, delta );
-
-            float c0 = v3_dot( ci->n, delta ),
-                  c1 = v3_dot( cj->n, delta );
-
-            if( c0 < 0.0f || c1 < 0.0f )
-            {
-               /* error */
-               ci->type = k_contact_type_disabled;
-            }
-            else
-            {
-               v3f n;
-               v3_muls( ci->n, c0, n );
-               v3_muladds( n, cj->n, c1, n );
-               v3_normalize( n );
-               v3_copy( n, ci->n );
-            }
-         }
+         
+         rb_manifold_contact_weld( ci, cj, r );
       }
    }
 }
 
 /*
  * Resolve overlapping pairs
+ *
+ * TODO: Remove?
  */
 VG_STATIC void rb_manifold_filter_pairs( rb_ct *man, int len, float r )
 {
@@ -1173,6 +1186,13 @@ VG_STATIC int rb_sphere_triangle( rigidbody *rba, rigidbody *rbb,
       v3_sub( tri[1], tri[0], ac );
       v3_cross( ac, ab, tn );
       v3_copy( tn, ct->n );
+
+      if( v3_length2( ct->n ) <= 0.00001f )
+      {
+         vg_error( "Zero area triangle!\n" );
+         return 0;
+      }
+
       v3_normalize( ct->n );
 
       float d = sqrtf(d2);
index 5f2f7066a3d6ca9475031c1d87535fb40626b52b..6d402bfc260422a819dcff16154e075413bc6c62 100644 (file)
@@ -96,7 +96,9 @@ VG_STATIC void vg_load(void)
 
    /* 'systems' are completely loaded now */
    strcpy( world.world_name, "maps/mp_mtzero.mdl" );
+#if 0
    strcpy( world.world_name, "maps/mp_gridmap.mdl" );
+#endif
    world_load();
    vg_console_load_autos();
 }