From: hgn Date: Fri, 18 Nov 2022 07:08:22 +0000 (+0000) Subject: even more collision filtering X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;ds=sidebyside;h=6d98c1e42c1617a8a426f9f0c0df99b75725b486;p=carveJwlIkooP6JGAAIwe30JlM.git even more collision filtering --- diff --git a/common.h b/common.h index c3f3e69..2e254f9 100644 --- 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" diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl index 2284ed0..8b9ce51 100644 Binary files a/maps_src/mp_gridmap.mdl and b/maps_src/mp_gridmap.mdl differ diff --git a/player_physics.h b/player_physics.h index e396e00..85f3744 100644 --- a/player_physics.h +++ b/player_physics.h @@ -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}; diff --git a/rigidbody.h b/rigidbody.h index 480e43f..2e66fe6 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -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; idisabled ) + 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; idisabled ) continue; + + for( int j=i+1; jdisabled ) 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; idisabled ) 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; idisabled ) continue; + + float d1 = v3_dot( ci->co, ci->n ); + + for( int j=i+1; jdisabled ) 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; ibias = -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; irba; v3f rv, da, db; diff --git a/shaders/viewchar.fs b/shaders/viewchar.fs index 9c46328..57edff5 100644 --- a/shaders/viewchar.fs +++ b/shaders/viewchar.fs @@ -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); } diff --git a/shaders/viewchar.h b/shaders/viewchar.h index d7181ff..21d98c0 100644 --- a/shaders/viewchar.h +++ b/shaders/viewchar.h @@ -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" ""}, diff --git a/skaterift.c b/skaterift.c index d4bf10c..5f782d7 100644 --- a/skaterift.c +++ b/skaterift.c @@ -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(); }