a fairly major physics update
[carveJwlIkooP6JGAAIwe30JlM.git] / player_physics.h
index 50ea62e41951db888036ef5f427bb1db69d1b71c..6a744e877a4e8107fb6aa16645e04e5e03353de2 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, 
@@ -1312,6 +1366,12 @@ VG_STATIC void player_freecam(void)
    v3_add( move_vel, player.camera_pos, player.camera_pos );
 }
 
+VG_STATIC int kill_player( int argc, char const *argv[] )
+{
+   player_kill();
+   return 0;
+}
+
 VG_STATIC int reset_player( int argc, char const *argv[] )
 {
    struct player_phys *phys = &player.phys;
@@ -1374,10 +1434,12 @@ VG_STATIC int reset_player( int argc, char const *argv[] )
 
    v3f delta = {1.0f,0.0f,0.0f};
    m3x3_mulv( the_long_way, delta, delta );
-
-   player.angles[0] = atan2f( delta[0], -delta[2] ); 
-   player.angles[1] = -asinf( delta[1] );
-
+   
+   if( !freecam )
+   {
+      player.angles[0] = atan2f( delta[0], -delta[2] ); 
+      player.angles[1] = -asinf( delta[1] );
+   }
 
    v4_copy( rp->q, phys->rb.q );
    v3_copy( rp->co, phys->rb.co );