v3_muladds( vel, gravity, timestep, vel );
}
+VG_STATIC struct
+grind_edge *player_grind_collect_edge( v3f p0, v3f p1,
+ v3f c0, v3f c1, float max_dist )
+{
+ struct player_phys *phys = &player.phys;
+
+ bh_iter it;
+ bh_iter_init( 0, &it );
+
+ boxf region;
+
+ box_init_inf( region );
+ box_addpt( region, p0 );
+ box_addpt( region, p1 );
+
+ float k_r = max_dist;
+ v3_add( (v3f){ k_r, k_r, k_r}, region[1], region[1] );
+ v3_add( (v3f){-k_r,-k_r,-k_r}, region[0], region[0] );
+
+ float closest = k_r*k_r;
+ struct grind_edge *closest_edge = NULL;
+
+ int idx;
+ while( bh_next( world.grind_bh, &it, region, &idx ) )
+ {
+ struct grind_edge *edge = &world.grind_edges[ idx ];
+
+ float s,t;
+ v3f pa, pb;
+
+ float d2 =
+ closest_segment_segment( p0, p1, edge->p0, edge->p1, &s,&t, pa, pb );
+
+ if( d2 < closest )
+ {
+ closest = d2;
+ closest_edge = edge;
+ v3_copy( pa, c0 );
+ v3_copy( pb, c1 );
+ }
+ }
+
+ return closest_edge;
+}
+
/*
* Called when launching into the air to predict and adjust trajectories
*/
for( int m=-3;m<=12; m++ )
{
+ struct land_log *log = &player.land_log[ player.land_log_count ++ ];
+ log->count = 0;
+ log->colour = 0xff000000;
+
float vmod = ((float)m / 15.0f)*0.09f;
v3f pco, pco1, pv;
m3x3_mulv( vr, pv, pv );
v3_muladds( pco, pv, pstep, pco );
+ struct grind_edge *best_grind = NULL;
+ float closest_grind = INFINITY;
+
for( int i=0; i<50; i++ )
{
v3_copy( pco, pco1 );
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 ) )
+ {
+ float d2 = v3_dist2( c0, c1 );
+ if( d2 < closest_grind )
+ {
+ closest_grind = d2;
+ best_grind = ge;
+ }
+ }
+
if( ray_world( pco1, vdir, &contact ))
{
float land_delta = v3_dot( pv, contact.normal );
q_m3x3( vr_q, phys->vr );
}
- v3_copy( contact.pos,
- player.land_target_log[player.land_log_count] );
- player.land_target_colours[player.land_log_count] =
- 0xff000000 | scolour;
+ v3_copy( contact.pos, log->positions[ log->count ++ ] );
+ log->colour = 0xff000000 | scolour;
+ break;
+ }
+
+ v3_copy( pco, log->positions[ log->count ++ ] );
+ }
- player.land_log_count ++;
+ if( best_grind )
+ {
+ log->colour = 0xff0000ff;
+
+ float score = -closest_grind * 0.05f;
- break;
+ if( score > best_velocity_delta )
+ {
+ best_velocity_delta = score;
+
+ m3x3_copy( vr, phys->vr_pstep );
+ q_axis_angle( vr_q, axis, vmod*0.1f );
+ q_m3x3( vr_q, phys->vr );
}
}
}
{
struct player_phys *phys = &player.phys;
- bh_iter it;
- bh_iter_init( 0, &it );
-
- boxf region;
-
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 );
- box_init_inf( region );
- box_addpt( region, p0 );
- box_addpt( region, p1 );
-
float const k_r = 0.25f;
- v3_add( (v3f){ k_r, k_r, k_r}, region[1], region[1] );
- v3_add( (v3f){-k_r,-k_r,-k_r}, region[0], region[0] );
+ struct grind_edge *closest_edge = player_grind_collect_edge( p0, p1,
+ c0, c1, k_r );
- vg_line( p0, p1, 0xff0000ff );
- vg_line_boxf( region, 0xff0000ff );
-
- float closest = k_r*k_r;
- struct grind_edge *closest_edge = NULL;
- int idx;
- while( bh_next( world.grind_bh, &it, region, &idx ) )
- {
- struct grind_edge *edge = &world.grind_edges[ idx ];
-
- float s,t;
- v3f pa, pb;
-
- float d2 =
- closest_segment_segment( p0, p1, edge->p0, edge->p1, &s,&t, pa, pb );
-
- if( d2 < closest )
- {
- closest = d2;
- closest_edge = edge;
- v3_copy( pa, c0 );
- v3_copy( pb, c1 );
- }
- }
+ vg_line( p0, p1, 0xff0000ff );
if( closest_edge )
{
}
return 0;
-
-#if 0
- v3f closest;
- int idx = bh_closest_point( world.grind_bh, phys->rb.co, closest, INFINITY );
- if( idx != -1 )
- {
- struct grind_edge *edge = &world.grind_edges[ idx ];
-
- vg_line( phys->rb.co, closest, 0xff000000 );
- vg_line_cross( closest, 0xff000000, 0.3f );
- vg_line( edge->p0, edge->p1, 0xff000000 );
-
- v3f delta;
- v3_sub( closest, phys->rb.co, delta );
-
- if( v3_length2(delta) < 0.5f*0.5f )
- {
- v3_copy( closest, phys->rb.co );
-
- v3f line_dir;
- v3_sub( edge->p1, edge->p0, line_dir );
- v3_normalize( line_dir );
-
- float p = v3_dot( phys->rb.v, line_dir );
- v3_muls( line_dir, p, phys->rb.v );
- phys->grind = 1;
- }
- else
- phys->grind = 0;
- }
-#endif
}
/* Manifold must be able to hold at least 64 elements */
float const DOWNFORCE = -k_downforce*2.0f*VG_TIMESTEP_FIXED;
v3_muladds( phys->rb.v, phys->rb.up, DOWNFORCE, phys->rb.v );
+ m3x3_identity( phys->vr );
+ m3x3_identity( phys->vr_pstep );
}
else
{
player_physics_control_passive();
if( grind_col )
+ {
+ phys->in_air = 0;
player_physics_control_grind();
+ }
else
{
if( phys->in_air )