target normal for rails
authorhgn <hgodden00@gmail.com>
Fri, 2 Dec 2022 21:21:53 +0000 (21:21 +0000)
committerhgn <hgodden00@gmail.com>
Fri, 2 Dec 2022 21:21:53 +0000 (21:21 +0000)
player.h
player_physics.h

index c98f10c83654c9744c2e51802cdc2b7223dfd8e1..95517725e435a2a895874d94321d74b15233b944 100644 (file)
--- a/player.h
+++ b/player.h
@@ -69,7 +69,6 @@ VG_STATIC struct gplayer
 
       /* Utility */
       float vswitch, slip, slip_last, reverse;
-
       float grab, jump, pushing, push_time;
       v2f grab_mouse_delta;
 
index b6283bf3c6353fa1c4f31000e201a6fc88371556..6bfb559204e87f2923dabbf5c29271537f2c276e 100644 (file)
@@ -367,6 +367,12 @@ VG_STATIC void player_physics_control_air(void)
    float time_to_impact = 0.0f;
    float limiter = 1.0f;
 
+   struct grind_edge *best_grind = NULL;
+   float closest_grind = INFINITY;
+
+   v3f target_normal = { 0.0f, 1.0f, 0.0f };
+   int has_target = 0;
+
    for( int i=0; i<50; i++ )
    {
       v3_copy( pco, pco1 );
@@ -380,34 +386,51 @@ VG_STATIC void player_physics_control_air(void)
       v3_sub( pco, pco1, vdir );
       contact.dist = v3_length( vdir );
       v3_divs( vdir, contact.dist, vdir);
+
+      v3f c0, c1;
+      struct grind_edge *ge = player_grind_collect_edge( pco, pco1,
+                                                         c0, c1, 0.4f );
+
+      if( ge && (v3_dot((v3f){0.0f,1.0f,0.0f},vdir) < -0.2f ) )
+      {
+         vg_line( ge->p0, ge->p1, 0xff0000ff );
+         vg_line_cross( pco, 0xff0000ff, 0.25f );
+         has_target = 1;
+         break;
+      }
       
       float orig_dist = contact.dist;
-      if( ray_world( pco1, vdir, &contact ))
+      if( ray_world( pco1, vdir, &contact ) )
       {
-         float angle = v3_dot( phys->rb.up, contact.normal );
-         v3f axis; 
-         v3_cross( phys->rb.up, contact.normal, axis );
-
+         v3_copy( contact.normal, target_normal );
+         has_target = 1;
          time_to_impact += (contact.dist/orig_dist)*pstep;
-         limiter = vg_minf( 5.0f, time_to_impact )/5.0f;
-         limiter = 1.0f-limiter;
-         limiter *= limiter;
-         limiter = 1.0f-limiter;
-
-         if( fabsf(angle) < 0.99f )
-         {
-            v4f correction;
-            q_axis_angle( correction, axis, 
-                  acosf(angle)*(1.0f-limiter)*3.0f*VG_TIMESTEP_FIXED );
-            q_mul( correction, phys->rb.q, phys->rb.q );
-         }
-
          vg_line_cross( contact.pos, 0xffff0000, 0.25f );
          break;
       }
       time_to_impact += pstep;
    }
 
+   if( has_target )
+   {
+      float angle = v3_dot( phys->rb.up, target_normal );
+      v3f axis; 
+      v3_cross( phys->rb.up, target_normal, axis );
+
+      limiter = vg_minf( 5.0f, time_to_impact )/5.0f;
+      limiter = 1.0f-limiter;
+      limiter *= limiter;
+      limiter = 1.0f-limiter;
+
+      if( fabsf(angle) < 0.99f )
+      {
+         v4f correction;
+         q_axis_angle( correction, axis, 
+                        acosf(angle)*(1.0f-limiter)*3.0f*VG_TIMESTEP_FIXED );
+         q_mul( correction, phys->rb.q, phys->rb.q );
+      }
+   }
+
    v2f steer = { player.input_js1h->axis.value,
                  player.input_js1v->axis.value };