but this is not a perfect work
authorhgn <hgodden00@gmail.com>
Wed, 15 Feb 2023 23:53:08 +0000 (23:53 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 15 Feb 2023 23:53:08 +0000 (23:53 +0000)
player_skate.c

index df3d42439671373fe1c77bfd2d6c2ca0e6822200..2e6e07b78aac0359cc6e1022247ffcebb910c853 100644 (file)
@@ -616,6 +616,9 @@ void player__approximate_best_trajectory( player_instance *player )
    float angle_begin = -(1.0f-fabsf( player->rb.to_world[1][1] )),
          angle_end   =   1.0f;
 
+   struct grind_info grind;
+   int grind_located = 0;
+
    for( int m=0;m<=15; m++ )
    {
       struct land_prediction *p = &s->predictions[ s->prediction_count ++ ];
@@ -646,6 +649,33 @@ void player__approximate_best_trajectory( player_instance *player )
          co1[1] += -0.5f * k_gravity * t*t;
          v3_add( launch_co, co1, co1 );
 
+         if( !grind_located && (launch_v[1] - k_gravity*t < 0.0f) )
+         {
+            v3f closest;
+            if( bh_closest_point( world.geo_bh, co1, closest, 1.0f ) != -1 )
+            {
+               v3f ve;
+               v3_copy( launch_v, ve );
+               ve[1] -= k_gravity * t;
+
+               if( skate_grind_scansq( closest, ve, 0.5f, &grind ) )
+               {
+                  v2f v0 = { ve[0], ve[2] },
+                      v1 = { grind.dir[0], grind.dir[2] };
+
+                  v2_normalize( v0 );
+                  v2_normalize( v1 );
+
+                  float a = v2_dot( v0, v1 );
+
+                  if( a >= cosf( VG_PIf * 0.125f ) )
+                  {
+                     grind_located = 1;
+                  }
+               }
+            }
+         }
+
          float t1;
          v3f n;
 
@@ -672,6 +702,76 @@ void player__approximate_best_trajectory( player_instance *player )
          s->prediction_count --;
    }
 
+
+
+   if( grind_located )
+   {
+      v3f v0;
+      v3_sub( grind.co, player->rb.co, v0 );
+
+      v3f ax;
+      v3_copy( v0, ax );
+      ax[1] = 0.0f;
+      v3_normalize( ax );
+
+      v2f d = { v3_dot( v0, ax ), v0[1] },
+          v = { v3_dot( player->rb.v, ax ), player->rb.v[1] };
+
+      float a = atan2f( v[1], v[0] ),
+            m = v2_length( v ),
+
+            root = m*m*m*m - k_gravity*(k_gravity*d[0]*d[0] + 2.0f*d[1]*m*m);
+
+      if( root > 0.0f )
+      {
+         root = sqrtf( root );
+         float a0 = atanf( (m*m + root) / (k_gravity * d[0]) ),
+               a1 = atanf( (m*m - root) / (k_gravity * d[0]) );
+
+         if( fabsf(a0-a) < fabsf(a1-a) )
+            a = a0;
+         else
+            a = a1;
+         /* TODO: sweep the path before chosing the smallest dist */
+         /* TODO: Jump in normal direction not to_world[1] */
+         /* TODO: Grind require manual be pulled in correct direction */
+
+         struct land_prediction *p = &s->predictions[ s->prediction_count ++ ];
+
+         p->log_length = 0;
+         p->land_dist = 0.0f;
+         v3_zero( p->apex );
+         p->type = k_prediction_grind;
+
+         v3_muls( ax, cosf( a ) * m, p->v );
+         p->v[1] += sinf( a ) * m;
+         p->land_dist = d[0] / (cosf(a)*m);
+
+         v3_copy( grind.n, p->n );
+
+         /* add a trace */
+         for( int i=0; i<=20; i++ )
+         {
+            float t = (float)i * (1.0f/20.0f) * p->land_dist;
+
+            v3f p0;
+            v3_muls( p->v, t, p0 );
+            p0[1] += -0.5f * k_gravity * t*t;
+
+            v3_add( player->rb.co, p0, p->log[ p->log_length ++ ] );
+         }
+
+         /* determine score */
+         v3f ve;
+         v3_copy( p->v, ve );
+         ve[1] -= k_gravity * p->land_dist;
+         p->score = -v3_dot( ve, grind.n ) * 0.85f;
+      }
+   }
+
+
+
+
    float score_min =  INFINITY,
          score_max = -INFINITY;