+ debug_capsule( mboard, k_board_length*2.0f, k_board_radius, 0xff0000ff );
+
+ boxf region = {{ -k_board_radius, -k_board_length, -k_board_radius },
+ { k_board_radius, k_board_length, k_board_radius }};
+ m4x3_transform_aabb( mboard, region );
+
+ u32 geo[256];
+ v3f tri[3];
+ int len = bh_select( &world.geo.bhtris, region, geo, 256 );
+
+ v3f poles[2];
+ m4x3_mulv(mboard, (v3f){0.0f,-k_board_length+k_board_radius,0.0f}, poles[0]);
+ m4x3_mulv(mboard, (v3f){0.0f, k_board_length-k_board_radius,0.0f}, poles[1]);
+
+ struct contact manifold[12];
+ int manifold_count = 0;
+
+ v3f surface_avg = {0.0f, 0.0f, 0.0f};
+
+ for( int i=0; i<len; i++ )
+ {
+ u32 *ptri = &world.geo.indices[ geo[i]*3 ];
+
+ for( int j=0; j<3; j++ )
+ v3_copy( world.geo.verts[ptri[j]].co, tri[j] );
+
+ vg_line(tri[0],tri[1],0xff00ff00 );
+ vg_line(tri[1],tri[2],0xff00ff00 );
+ vg_line(tri[2],tri[0],0xff00ff00 );
+
+ v3f temp;
+ v3_copy( player.rb.co, temp );
+
+ for( int j=0; j<2; j++ )
+ {
+ if(manifold_count >= vg_list_size(manifold))
+ {
+ vg_error("Manifold overflow!\n");
+ break;
+ }
+
+ rb_ct *ct = &manifold[manifold_count];
+ v3_copy( poles[j], player.rb.co );
+
+ manifold_count += rb_sphere_vs_triangle( &player.rb, tri, ct );
+ }
+
+ v3_copy( temp, player.rb.co );
+ }
+ rb_presolve_contacts( manifold, manifold_count );
+
+ if( !manifold_count )
+ {
+ player_start_air();
+ }
+ else
+ {
+ v3_normalize( surface_avg );
+
+ if( v3_dot( player.rb.v, surface_avg ) > 0.5f )
+ {
+ player_start_air();
+ }
+ else
+ player.in_air = 0;
+ }
+
+ for( int j=0; j<5; j++ )
+ {
+ for( int i=0; i<manifold_count; i++ )
+ {
+ struct contact *ct = &manifold[i];
+
+ v3f dv, delta;
+ v3_sub( ct->co, player.rb.co, delta );
+ v3_cross( player.rb.w, delta, dv );
+ v3_add( player.rb.v, dv, dv );
+
+ float vn = -v3_dot( dv, ct->n );
+ vn += ct->bias;
+
+ float temp = ct->norm_impulse;
+ ct->norm_impulse = vg_maxf( temp + vn, 0.0f );
+ vn = ct->norm_impulse - temp;
+
+ v3f impulse;
+ v3_muls( ct->n, vn, impulse );
+
+ if( fabsf(v3_dot( impulse, player.rb.forward )) > 10.0f ||
+ fabsf(v3_dot( impulse, player.rb.up )) > 50.0f )
+ {
+ player.is_dead = 1;
+ character_ragdoll_copypose( &player.mdl, player.rb.v );
+ return;
+ }
+
+ v3_add( impulse, player.rb.v, player.rb.v );
+ v3_cross( delta, impulse, impulse );
+
+ /*
+ * W Impulses are limited to the Y and X axises, we don't really want
+ * roll angular velocities being included.
+ *
+ * Can also tweak the resistance of each axis here by scaling the wx,wy
+ * components.
+ */
+
+ float wy = v3_dot( player.rb.up, impulse ),
+ wx = v3_dot( player.rb.right, impulse )*1.5f;
+
+ v3_muladds( player.rb.w, player.rb.up, wy, player.rb.w );
+ v3_muladds( player.rb.w, player.rb.right, wx, player.rb.w );
+ }
+ }