even more collision filtering
authorhgn <hgodden00@gmail.com>
Fri, 18 Nov 2022 07:08:22 +0000 (07:08 +0000)
committerhgn <hgodden00@gmail.com>
Fri, 18 Nov 2022 07:08:22 +0000 (07:08 +0000)
common.h
maps_src/mp_gridmap.mdl
player_physics.h
rigidbody.h
shaders/viewchar.fs
shaders/viewchar.h
skaterift.c

index c3f3e69d6fff15c262feeeaa6de270c1e30f3b97..2e254f9d22adb6849840618bf706aa1ffbc86696 100644 (file)
--- a/common.h
+++ b/common.h
@@ -7,6 +7,8 @@
 
 #define VG_TIMESTEP_FIXED (1.0/60.0)
 #define VG_3D
+#define VG_GAME
+#define VG_STATIC static
 #define VG_FRAMEBUFFER_RESIZE 1
 #include "vg/vg.h"
 #include "submodules/anyascii/impl/c/anyascii.c"
index 2284ed0d1b8ff9e1b7f59deaf459e0a7d205be1d..8b9ce51208db69023f5c3329de300ce2d61c6b87 100644 (file)
Binary files a/maps_src/mp_gridmap.mdl and b/maps_src/mp_gridmap.mdl differ
index e396e0031d3771cb937a5955b73c5f13bbed2de3..85f3744be2a274f7f585a0ad3343466c90888c39 100644 (file)
@@ -551,11 +551,27 @@ VG_STATIC void player_physics(void)
    rb_debug( rbb, 0xffffff00 );
 
    rb_ct manifold[64];
-   int len = 0;
+   int len_f = 0,
+       len_b = 0; 
+
+   len_f = rb_sphere_scene( rbf, &world.rb_geo, manifold );
+   rb_manifold_filter_coplanar( manifold, len_f, 0.05f );
+   rb_manifold_filter_pairs( manifold, len_f, 0.05f );
+   if( len_f > 1 )
+      rb_manifold_filter_backface( manifold, len_f );
+   len_f = rb_manifold_apply_filtered( manifold, len_f );
+   
+   rb_ct *man_b = &manifold[len_f];
+   len_b = rb_sphere_scene( rbb, &world.rb_geo, man_b );
+   rb_manifold_filter_coplanar( man_b, len_b, 0.05f );
+   rb_manifold_filter_pairs( man_b, len_b, 0.05f );
+   if( len_b > 1 )
+      rb_manifold_filter_backface( man_b, len_b );
+   len_b = rb_manifold_apply_filtered( man_b, len_b );
 
-   len += rb_sphere_scene( rbf, &world.rb_geo, manifold+len );
-   len += rb_sphere_scene( rbb, &world.rb_geo, manifold+len );
+   int len = len_f+len_b;
 
+#if 0
    /* 
     * Preprocess collision points, and create a surface picture.
     * we want contacts that are within our 'capsule's internal line to be 
@@ -576,6 +592,7 @@ VG_STATIC void player_physics(void)
          v3_normalize( manifold[i].n );
       }
    }
+#endif
 
    rb_presolve_contacts( manifold, len );
    v3f surface_avg = {0.0f, 0.0f, 0.0f};
index 480e43fb5d086752fb42d9ec559681d6f1d97442..2e66fe68e5fea5800f3fcfc0201abfded3c4adf4 100644 (file)
@@ -103,7 +103,7 @@ VG_STATIC struct contact
          normal_mass, tangent_mass[2];
 
    u32 element_id;
-   int cluster;
+   int disabled;
 }
 rb_contact_buffer[256];
 VG_STATIC int rb_contact_count = 0;
@@ -148,10 +148,13 @@ VG_STATIC void rb_tangent_basis( v3f n, v3f tx, v3f ty )
 
 VG_STATIC void rb_debug_contact( rb_ct *ct )
 {
-   v3f p1;
-   v3_muladds( ct->co, ct->n, 0.1f, p1 );
-   vg_line_pt3( ct->co, 0.025f, 0xff0000ff );
-   vg_line( ct->co, p1, 0xffffffff );
+   if( !ct->disabled )
+   {
+      v3f p1;
+      v3_muladds( ct->co, ct->n, 0.1f, p1 );
+      vg_line_pt3( ct->co, 0.025f, 0xff0000ff );
+      vg_line( ct->co, p1, 0xffffffff );
+   }
 }
 
 VG_STATIC void debug_sphere( m4x3f m, float radius, u32 colour )
@@ -833,6 +836,114 @@ VG_STATIC int rb_box_triangle_sat( rigidbody *rba, v3f tri_src[3] )
    return 1;
 }
 
+/*
+ * -----------------------------------------------------------------------------
+ *                                Manifold
+ * -----------------------------------------------------------------------------
+ */
+
+VG_STATIC int rb_manifold_apply_filtered( rb_ct *man, int len )
+{
+   int k = 0;
+
+   for( int i=0; i<len; i++ )
+   {
+      rb_ct *ct = &man[i];
+
+      if( ct->disabled )
+         continue;
+
+      man[k ++] = man[i];
+   }
+
+   return k;
+}
+
+/*
+ * Resolve overlapping pairs
+ */
+VG_STATIC void rb_manifold_filter_pairs( rb_ct *man, int len, float r )
+{
+   for( int i=0; i<len-1; i++ )
+   {
+      rb_ct *ci = &man[i];
+      int similar = 0;
+
+      if( ci->disabled ) continue;
+
+      for( int j=i+1; j<len; j++ )
+      {
+         rb_ct *cj = &man[j];
+
+         if( cj->disabled ) continue;
+
+         if( v3_dist2( ci->co, cj->co ) < r*r )
+         {
+            cj->disabled = 1;
+            v3_add( cj->n, ci->n, ci->n );
+            ci->p += cj->p;
+            similar ++;
+         }
+      }
+
+      if( similar )
+      {
+         float n = 1.0f/((float)similar+1.0f);
+         v3_muls( ci->n, n, ci->n );
+         ci->p *= n;
+
+         if( v3_length2(ci->n) < 0.1f*0.1f )
+            ci->disabled = 1;
+         else
+            v3_normalize( ci->n );
+      }
+   }
+}
+
+/* 
+ * Remove contacts that are facing away from A
+ */
+VG_STATIC void rb_manifold_filter_backface( rb_ct *man, int len )
+{
+   for( int i=0; i<len; i++ )
+   {
+      rb_ct *ct = &man[i];
+      if( ct->disabled ) continue;
+
+      v3f delta;
+      v3_sub( ct->co, ct->rba->co, delta );
+      
+      if( v3_dot( delta, ct->n ) > -0.001f )
+         ct->disabled = 1;
+   }
+}
+
+/*
+ * Filter out duplicate coplanar results. Good for spheres.
+ */
+VG_STATIC void rb_manifold_filter_coplanar( rb_ct *man, int len, float w )
+{
+   for( int i=0; i<len-1; i++ )
+   {
+      rb_ct *ci = &man[i];
+      if( ci->disabled ) continue;
+
+      float d1 = v3_dot( ci->co, ci->n );
+
+      for( int j=i+1; j<len; j++ )
+      {
+         rb_ct *cj = &man[j];
+         if( cj->disabled ) continue;
+         
+         float d2 = v3_dot( cj->co, ci->n ),
+               d  = d2-d1;
+
+         if( fabsf( d ) <= w )
+            cj->disabled = 1;
+      }
+   }
+}
+
 /*
  * -----------------------------------------------------------------------------
  *                            Collision matrix
@@ -927,6 +1038,7 @@ VG_STATIC int rb_capsule_manifold_done( rigidbody *rba, rigidbody *rbb,
       ct->p = manifold->r0 - d;
       ct->rba = rba;
       ct->rbb = rbb;
+      ct->disabled = 0;
 
       count ++;
    }
@@ -946,6 +1058,7 @@ VG_STATIC int rb_capsule_manifold_done( rigidbody *rba, rigidbody *rbb,
       ct->p = manifold->r1 - d;
       ct->rba = rba;
       ct->rbb = rbb;
+      ct->disabled = 0;
 
       count ++;
    }
@@ -993,6 +1106,7 @@ VG_STATIC int rb_capsule_sphere( rigidbody *rba, rigidbody *rbb, rb_ct *buf )
 
       ct->rba = rba;
       ct->rbb = rbb;
+      ct->disabled = 0;
 
       return 1;
    }
@@ -1213,6 +1327,7 @@ VG_STATIC int rb_sphere_box( rigidbody *rba, rigidbody *rbb, rb_ct *buf )
 
       ct->rba = rba;
       ct->rbb = rbb;
+      ct->disabled = 0;
       return 1;
    }
 
@@ -1239,6 +1354,7 @@ VG_STATIC int rb_sphere_sphere( rigidbody *rba, rigidbody *rbb, rb_ct *buf )
       v3_muladds( rbb->co, ct->n, rbb->inf.sphere.radius, p1 );
       v3_add( p0, p1, ct->co );
       v3_muls( ct->co, 0.5f, ct->co );
+      ct->disabled = 0;
       ct->p = r-d;
       ct->rba = rba;
       ct->rbb = rbb;
@@ -1283,6 +1399,7 @@ VG_STATIC int rb_sphere_triangle( rigidbody *rba, rigidbody *rbb,
       float d = sqrtf(d2);
 
       v3_copy( co, ct->co );
+      ct->disabled = 0;
       ct->p = r-d;
       ct->rba = rba;
       ct->rbb = rbb;
@@ -1482,6 +1599,7 @@ next_vert:;
          v3_normalize( ct->n );
 
          v3_copy( co, ct->co );
+         ct->disabled = 0;
          ct->p = r-d;
          ct->rba = rba;
          ct->rbb = rbb;
@@ -1630,6 +1748,7 @@ VG_STATIC int rb_box_scene( rigidbody *rba, rigidbody *rbb, rb_ct *buf )
          if( ct->p < 0.0f )
             continue;
 
+         ct->disabled = 0;
          ct->rba = rba;
          ct->rbb = rbb;
          count ++;
@@ -1731,9 +1850,11 @@ VG_STATIC void rb_presolve_contacts( rb_ct *buffer, int len )
    for( int i=0; i<len; i++ )
    {
       rb_ct *ct = &buffer[i];
+
       ct->bias = -0.2f * k_rb_rate * vg_minf( 0.0f, -ct->p+k_penetration_slop );
       rb_tangent_basis( ct->n, ct->t[0], ct->t[1] );
 
+      ct->disabled = 0;
       ct->norm_impulse = 0.0f;
       ct->tangent_impulse[0] = 0.0f;
       ct->tangent_impulse[1] = 0.0f;
@@ -1816,6 +1937,7 @@ VG_STATIC void rb_solve_contacts( rb_ct *buf, int len )
    for( int i=0; i<len; i++ )
    {
       struct contact *ct = &buf[i];
+
       rigidbody *rb = ct->rba;
 
       v3f rv, da, db;
index 9c46328bb2c0b268b20e053732d14d02bbf7feeb..57edff5eda7dff0f81b491bf2dd948ce8b4aa05e 100644 (file)
@@ -27,6 +27,6 @@ void main()
    vfrag = do_light_shadowing( vfrag );
    vfrag = apply_fog( vfrag, fdist );
 
-   float opacity = clamp( fdist, 0.1, 1.0 );
+   float opacity = clamp( fdist*fdist, 0.1, 1.0 );
    FragColor = vec4(vfrag,opacity);
 }
index d7181ff4e85e213cb79ae5cce1ce1908f4c2e123..21d98c06bf06cc93843795bfa9c418691e6d2a4a 100644 (file)
@@ -183,7 +183,7 @@ static struct vg_shader _shader_viewchar = {
 "   vfrag = do_light_shadowing( vfrag );\n"
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
-"   float opacity = clamp( fdist, 0.1, 1.0 );\n"
+"   float opacity = clamp( fdist*fdist, 0.1, 1.0 );\n"
 "   FragColor = vec4(vfrag,opacity);\n"
 "}\n"
 ""},
index d4bf10ca42d014aec0c14148abf60750ec634e3f..5f782d70877f5eca72cdd935554a331042e717b9 100644 (file)
@@ -11,8 +11,6 @@
  * =============================================================================
  */
 
-#define VG_STATIC static
-#define VG_GAME
 #define SR_NETWORKED
 
 #include "common.h"
@@ -97,6 +95,7 @@ VG_STATIC void vg_load(void)
 
    /* 'systems' are completely loaded now */
    strcpy( world.world_name, "maps/mp_mtzero.mdl" );
+   strcpy( world.world_name, "maps/mp_gridmap.mdl" );
    world_load();
    vg_console_load_autos();
 }