From: hgn Date: Sat, 24 Dec 2022 01:36:15 +0000 (+0000) Subject: phys adjustments X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=02e138a27fd43ed09bc1869691a8a3a4224d0132;hp=5b06975b35952497d771db4171c7454123edfea1;p=carveJwlIkooP6JGAAIwe30JlM.git phys adjustments --- diff --git a/player_physics.h b/player_physics.h index 50ea62e..a2aabff 100644 --- a/player_physics.h +++ b/player_physics.h @@ -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; in ) ) + 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; irb.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, diff --git a/rigidbody.h b/rigidbody.h index 51c274c..aa8d4f8 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -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; itype != 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); diff --git a/skaterift.c b/skaterift.c index 5f2f706..6d402bf 100644 --- a/skaterift.c +++ b/skaterift.c @@ -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(); }