+VG_STATIC void player_grind(void)
+{
+ struct player_phys *phys = &player.phys;
+
+ v3f closest;
+ int idx = bh_closest_point( world.grind_bh, phys->rb.co, closest, INFINITY );
+ if( idx == -1 )
+ return;
+
+ 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 );
+
+ return;
+
+ idx = bh_closest_point( world.geo_bh, phys->rb.co, closest, INFINITY );
+ vg_line( phys->rb.co, closest, 0xff000000 );
+ vg_line_cross( closest, 0xff000000, 0.3f );
+
+ idx = world.scene_geo->arrindices[ idx * 3 ];
+ struct world_material *mat = world_tri_index_material( idx );
+
+ if( mat->info.flags & k_material_flag_grind_surface )
+ {
+ v3f grind_delta;
+ v3_sub( closest, phys->rb.co, grind_delta );
+
+ float p = v3_dot( phys->rb.forward, grind_delta );
+ v3_muladds( grind_delta, phys->rb.forward, -p, grind_delta );
+
+ float a = vg_maxf( 0.0f, 4.0f-v3_dist2( closest, phys->rb.co ) );
+ v3_muladds( phys->rb.v, grind_delta, a*0.2f, phys->rb.v );
+ }
+}
+