From: hgn Date: Wed, 15 Feb 2023 23:53:08 +0000 (+0000) Subject: but this is not a perfect work X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;ds=inline;h=4ebc4d14b5a0e8619445cb78b1ceee8ce353dfbc;p=carveJwlIkooP6JGAAIwe30JlM.git but this is not a perfect work --- diff --git a/player_skate.c b/player_skate.c index df3d424..2e6e07b 100644 --- a/player_skate.c +++ b/player_skate.c @@ -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;