}
}
+#if 0
VG_STATIC int bh_ray( bh_tree *bh, v3f co, v3f dir, ray_hit *hit ){
if( bh->node_count < 2 )
return 0;
return count;
}
+#endif
typedef struct bh_iter bh_iter;
struct bh_iter{
};
enum material_flag{
- k_material_flag_skate_target = 0x00000001,
- k_material_flag_collision = 0x00000002,
- k_material_flag_grow_grass = 0x00000004,
- k_material_flag_grindable = 0x00000008,
- k_material_flag_invisible = 0x00000010,
- k_material_flag_boundary = 0x00000020,
- k_material_flag_preview_visibile = 0x00000040,
- k_material_flag_walking = 0x00000080
+ k_material_flag_skate_target = 0x0001,
+ k_material_flag_collision = 0x0002,
+ k_material_flag_grow_grass = 0x0004,
+ k_material_flag_grindable = 0x0008,
+ k_material_flag_invisible = 0x0010,
+ k_material_flag_boundary = 0x0020,
+ k_material_flag_preview_visibile = 0x0040,
+ k_material_flag_walking = 0x0080,
+
+ k_material_flag_ghosts =
+ k_material_flag_boundary|
+ k_material_flag_invisible|
+ k_material_flag_walking
};
#pragma pack(push,1)
if( rd->parts[i].obj.type == k_rb_shape_capsule ){
l = rb_capsule__scene( rd->parts[i].obj.rb.to_world,
&rd->parts[i].obj.inf.capsule,
- NULL, &world->rb_geo.inf.scene, buf );
+ NULL, &world->rb_geo.inf.scene, buf,
+ k_material_flag_ghosts );
}
else if( rd->parts[i].obj.type == k_rb_shape_box ){
l = rb_box__scene( rd->parts[i].obj.rb.to_world,
rd->parts[i].obj.rb.bbx,
- NULL, &world->rb_geo.inf.scene, buf );
+ NULL, &world->rb_geo.inf.scene, buf,
+ k_material_flag_ghosts );
}
else continue;
world_instance *world = world_current_instance();
int len = 0;
- len = rb_sphere__scene( mtx, sphere, NULL, &world->rb_geo.inf.scene, man );
+ len = rb_sphere__scene( mtx, sphere, NULL, &world->rb_geo.inf.scene, man,
+ k_material_flag_walking );
- for( int i=0; i<len; i++ )
- {
+ for( int i=0; i<len; i++ ){
man[i].rba = &player->rb;
man[i].rbb = NULL;
}
rb_manifold_filter_coplanar( man, len, 0.03f );
- if( len > 1 )
- {
+ if( len > 1 ){
rb_manifold_filter_backface( man, len );
rb_manifold_filter_joint_edges( man, len, 0.03f );
rb_manifold_filter_pairs( man, len, 0.03f );
float scan_radius = k_board_radius;
scan_radius *= vg_clampf( t, 0.02f, 1.0f );
- int idx = spherecast_world(trace_world, co0, co1, scan_radius, &t1, n);
+ int idx = spherecast_world( trace_world, co0, co1, scan_radius, &t1, n,
+ k_material_flag_walking );
if( idx != -1 ){
v3f co;
v3_lerp( co0, co1, t1, co );
v3f n;
int idx = spherecast_world( world0, co0,co1,
- k_board_radius*0.1f, &t1, n);
+ k_board_radius*0.1f, &t1, n,
+ k_material_flag_walking );
if( idx != -1 ){
goto invalidated_grind;
}
v3_muladds( left, player->rb.to_world[1], k_board_radius, left );
ray_l.dist = 2.1f * k_board_radius;
- res_l = ray_world( world, left, dir, &ray_l );
+ res_l = ray_world( world, left, dir, &ray_l, k_material_flag_walking );
if( res_l )
break;
v3_muladds( right, player->rb.to_world[1], k_board_radius, right );
ray_r.dist = 2.1f * k_board_radius;
- res_r = ray_world( world, right, dir, &ray_r );
+ res_r = ray_world( world, right, dir, &ray_r, k_material_flag_walking );
if( res_r )
break;
v3_muls( dir, 1.0f/ray.dist, dir );
ray.dist -= 0.025f;
- if( ray_world( world_current_instance(), origin, dir, &ray ) )
+ if( ray_world( world_current_instance(), origin, dir, &ray,
+ k_material_flag_walking ) )
return 0;
return 1;
v3f n;
float cast_radius = wheels[i].radius - k_penetration_slop * 2.0f;
- if( spherecast_world( world, current, future, cast_radius, &t, n ) != -1)
+ if( spherecast_world( world, current, future, cast_radius, &t, n,
+ k_material_flag_walking ) != -1)
max_time = vg_minf( max_time, t * s->substep );
}
float t;
v3f n;
if( (v3_dist2( head_wp0, head_wp1 ) > 0.001f) &&
- (spherecast_world( world, head_wp0, head_wp1, 0.2f, &t, n ) != -1) )
+ (spherecast_world( world, head_wp0, head_wp1, 0.2f, &t, n,
+ k_material_flag_walking ) != -1) )
{
v3_lerp( start_co, player->rb.co, t, player->rb.co );
rb_update_transform( &player->rb );
rb_ct *cman = &manifold[manifold_len];
int l = rb_capsule__scene( mtx, &capsule, NULL, &world->rb_geo.inf.scene,
- cman );
+ cman, k_material_flag_walking );
/* weld joints */
for( int i=0; i<l; i ++ )
ray_hit *ray = &samples[ sample_count ];
ray->dist = 2.0f;
- if( ray_world( world, pos, ray_dir, ray ) )
- {
+ if( ray_world( world, pos, ray_dir, ray, 0 ) ){
vg_line( pos, ray->pos, VG__RED );
vg_line_point( ray->pos, 0.025f, VG__BLACK );
ray_hit ray;
ray.dist = k_board_length*2.0f + 0.6f;
- if( ray_world( world, va, v0, &ray ) )
- {
+ if( ray_world( world, va, v0, &ray, 0 ) ){
vg_line( va, vb, VG__RED );
vg_line_point( ray.pos, 0.1f, VG__RED );
vg_error( "invalidated\n" );
}
v3_muls( v0, -1.0f, v0 );
- if( ray_world( world, vb, v0, &ray ) )
- {
+ if( ray_world( world, vb, v0, &ray, 0 ) ){
vg_line( va, vb, VG__RED );
vg_line_point( ray.pos, 0.1f, VG__RED );
vg_error( "invalidated\n" );
*/
len = rb_capsule__scene( mtx, &w->collider, NULL,
- &world->rb_geo.inf.scene, manifold );
+ &world->rb_geo.inf.scene, manifold, 0 );
player_walk_custom_filter( world, manifold, len, 0.01f );
len = rb_manifold_apply_filtered( manifold, len );
v3f n;
float t;
- if( spherecast_world( world, pa, pb, w->collider.radius, &t, n ) != -1 ){
+ if( spherecast_world( world, pa, pb,
+ w->collider.radius, &t, n, 0 ) != -1 ){
if( player_walk_normal_standable( player, n ) ){
v3_lerp( pa, pb, t, player->rb.co );
v3_muladds( player->rb.co, player->basis[1],
float t, sr = w->collider.radius-0.04f;
v3f n;
- if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n ) != -1 ){
+ if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n, 0 ) != -1 ){
v3_lerp( lwr_prev, lwr_now, vg_maxf(0.01f,t), player->rb.co );
player->rb.co[1] -= w->collider.radius;
rb_update_transform( &player->rb );
v3_add( player->rb.co, player->basis[1], mtx[3] );
- vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__RED );
+ vg_line_capsule( mtx, w->collider.radius, w->collider.height, VG__RED);
}
}
}
VG_STATIC int rb_sphere__scene( m4x3f mtxA, rb_sphere *b,
- m4x3f mtxB, rb_scene *s, rb_ct *buf ){
+ m4x3f mtxB, rb_scene *s, rb_ct *buf,
+ u16 ignore ){
scene_context *sc = s->bh_scene->user;
int count = 0;
u32 *ptri = &sc->arrindices[ idx*3 ];
v3f tri[3];
+ if( sc->arrvertices[ptri[0]].flags & ignore ) continue;
+
for( int j=0; j<3; j++ )
v3_copy( sc->arrvertices[ptri[j]].co, tri[j] );
}
VG_STATIC int rb_box__scene( m4x3f mtxA, boxf bbx,
- m4x3f mtxB, rb_scene *s, rb_ct *buf ){
+ m4x3f mtxB, rb_scene *s, rb_ct *buf, u16 ignore ){
scene_context *sc = s->bh_scene->user;
v3f tri[3];
while( bh_next( s->bh_scene, &it, &idx ) ){
u32 *ptri = &sc->arrindices[ idx*3 ];
+ if( sc->arrvertices[ptri[0]].flags & ignore ) continue;
for( int j=0; j<3; j++ )
v3_copy( sc->arrvertices[ptri[j]].co, tri[j] );
/* mtxB is defined only for tradition; it is not used currently */
VG_STATIC int rb_capsule__scene( m4x3f mtxA, rb_capsule *c,
m4x3f mtxB, rb_scene *s,
- rb_ct *buf ){
+ rb_ct *buf, u16 ignore ){
int count = 0;
boxf bbx;
i32 idx;
while( bh_next( s->bh_scene, &it, &idx ) ){
u32 *ptri = &sc->arrindices[ idx*3 ];
- v3f tri[3];
+ if( sc->arrvertices[ptri[0]].flags & ignore ) continue;
+ v3f tri[3];
for( int j=0; j<3; j++ )
v3_copy( sc->arrvertices[ptri[j]].co, tri[j] );
v3f co; /* 3*32 */
v2f uv; /* 2*32 */
i8 norm[4]; /* 4*8 */
- u16 unused[4];
+ u16 flags; /* only for the cpu. its junk on the gpu */
+ u16 unused[3];
};
#pragma pack(pop)
ctx->submesh.vertex_start = ctx->vertex_count;
}
+VG_STATIC void scene_set_vertex_flags( scene_context *ctx,
+ u32 start, u32 count, u16 flags ){
+ for( u32 i=0; i<count; i++ )
+ ctx->arrvertices[ start + i ].flags = flags;
+}
+
struct scene_upload_info{
scene_context *ctx;
glmesh *mesh;
vg_line( pc->co, pa->co, 0xff0000ff );
}
+#if 0
VG_STATIC int scene_bh_ray( void *user, u32 index, v3f co,
v3f dir, ray_hit *hit )
{
return 0;
}
+#endif
VG_STATIC void scene_bh_closest( void *user, u32 index, v3f point, v3f closest )
{
.item_closest = scene_bh_closest,
.item_swap = scene_bh_swap,
.item_debug = scene_bh_debug,
- .cast_ray = scene_bh_ray
};
/*
* An extra step is added onto the end to calculate the hit normal
*/
VG_STATIC int scene_raycast( scene_context *s, bh_tree *bh,
- v3f co, v3f dir, ray_hit *hit )
+ v3f co, v3f dir, ray_hit *hit, u16 ignore )
{
- int count = bh_ray( bh, co, dir, hit );
+ hit->tri = NULL;
+
+ bh_iter it;
+ bh_iter_init_ray( 0, &it, co, dir, hit->dist );
+ i32 idx;
+
+ while( bh_next( bh, &it, &idx ) ){
+ u32 *tri = &s->arrindices[ idx*3 ];
+
+ if( s->arrvertices[tri[0]].flags & ignore ) continue;
+
+ v3f vs[3];
+ for( u32 i=0; i<3; i++ )
+ v3_copy( s->arrvertices[tri[i]].co, vs[i] );
+
+ f32 t;
+ if( ray_tri( vs, co, dir, &t ) ){
+ if( t < hit->dist ){
+ hit->dist = t;
+ hit->tri = tri;
+ }
+ }
+ }
- if( count ){
+ if( hit->tri ){
v3f v0, v1;
float *pa = s->arrvertices[hit->tri[0]].co,
v3_muladds( co, dir, hit->dist, hit->pos );
}
- return count;
+ return hit->tri?1:0;
}
VG_STATIC bh_tree *scene_bh_create( void *lin_alloc, scene_context *s )
float t;
if( spherecast_world( world_current_instance(), ra, rb,
- gzoomer.obj.inf.sphere.radius, &t, rx ) != -1 )
+ gzoomer.obj.inf.sphere.radius, &t, rx, 0 ) != -1 )
{
v3_lerp( ra, rb, t, gzoomer.obj.rb.co );
gzoomer.obj.rb.co[1] += 4.0f;
#if 1
float t;
if( spherecast_world( world_current_instance(), pa, pb,
- k_car_wheel_radius, &t, n ) == -1 )
+ k_car_wheel_radius, &t, n, 0 ) == -1 )
{ t = 1.0f;
}
rb_ct manifold[64];
int len = rb_sphere__scene( rb->to_world, &gzoomer.obj.inf.sphere, NULL,
&world_current_instance()->rb_geo.inf.scene,
- manifold );
+ manifold, 0 );
for( int j=0; j<len; j++ ){
manifold[j].rba = rb;
manifold[j].rbb = &world_current_instance()->rb_geo.rb;
world_instance *world = world_current_instance();
- if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &contact ) ){
+ if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &contact,
+ k_material_flag_ghosts ) ){
struct world_surface *mat = ray_hit_surface( world, &contact );
if( mat->info.surface_prop == k_surface_prop_grass){
float dist = 200.0f;
for( int i=0; i<10; i++ ){
- if( ray_world( world_current_instance(), rc, rd, &ray ) ){
+ if( ray_world( world_current_instance(), rc, rd, &ray,
+ k_material_flag_ghosts ) ){
dist = (float)i*5.0f + ray.dist;
break;
}
ray_hit hit;
hit.dist = INFINITY;
- if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &hit )){
+ if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &hit,
+ k_material_flag_ghosts )){
struct world_surface *m1 = ray_hit_surface( world, &hit );
if((hit.normal[1] > 0.8f) && (m1 == mat) && (hit.pos[1] > 0.0f+10.0f)){
world_gen_add_blob( world, scene, &hit );
&world->meta, i );
scene_copy_slice( &world->scene_geo, &surf->sm_geo );
+ scene_set_vertex_flags( &world->scene_geo,
+ surf->sm_geo.vertex_start,
+ surf->sm_geo.vertex_count,
+ (u16)(surf->info.flags & 0xffff) );
}
/* compress that bad boy */
}
VG_STATIC int ray_world( world_instance *world,
- v3f pos, v3f dir, ray_hit *hit )
+ v3f pos, v3f dir, ray_hit *hit, u16 ignore )
{
- return scene_raycast( &world->scene_geo, world->geo_bh, pos, dir, hit );
+ return scene_raycast( &world->scene_geo, world->geo_bh, pos, dir, hit,
+ ignore );
}
/*
* Cast a sphere from a to b and see what time it hits
*/
VG_STATIC int spherecast_world( world_instance *world,
- v3f pa, v3f pb, float r, float *t, v3f n )
+ v3f pa, v3f pb, float r, float *t, v3f n,
+ u16 ignore )
{
boxf region;
box_init_inf( region );
i32 idx;
while( bh_next( world->geo_bh, &it, &idx ) ){
u32 *ptri = &world->scene_geo.arrindices[ idx*3 ];
- v3f tri[3];
+ if( world->scene_geo.arrvertices[ptri[0]].flags & ignore ) continue;
+ v3f tri[3];
boxf box;
box_init_inf( box );
-
for( int j=0; j<3; j++ ){
v3_copy( world->scene_geo.arrvertices[ptri[j]].co, tri[j] );
box_addpt( box, tri[j] );
ray_hit *hit, v3f tri[3] );
VG_STATIC int ray_world( world_instance *world,
- v3f pos, v3f dir, ray_hit *hit );
+ v3f pos, v3f dir, ray_hit *hit, u16 ignore );
VG_STATIC int spherecast_world( world_instance *world,
- v3f pa, v3f pb, float r, float *t, v3f n );
+ v3f pa, v3f pb, float r, float *t, v3f n,
+ u16 ignore );
VG_STATIC struct world_surface *world_tri_index_surface( world_instance *world,
u32 index );
ha.dist = 8.0f;
hb.dist = 8.0f;
- int resa = ray_world( world, sa, down, &ha ),
- resb = ray_world( world, sb, down, &hb );
+ int resa = ray_world( world, sa, down, &ha, k_material_flag_ghosts ),
+ resb = ray_world( world, sb, down, &hb, k_material_flag_ghosts );
if( pcbuf && resa ){
world_routes_pointcloud_spot( world, pcbuf, ha.pos,
u32 *tri = &world->scene_geo.arrindices[ idx*3 ];
v3f vs[3];
+ u16 mask = k_material_flag_preview_visibile;
+ if( !(world->scene_geo.arrvertices[tri[0]].flags & mask) )
+ continue;
+
for( u32 i=0; i<3; i++ ){
v3_copy( world->scene_geo.arrvertices[tri[i]].co, vs[i] );
}
f32 t;
if( ray_tri( vs, ro, dir, &t ) ){
v3_muladds( ro, dir, t, hit );
- struct world_surface *m1 =
- world_tri_index_surface( world, tri[0] );
-
- if( !(m1->info.flags & k_material_flag_preview_visibile) )
- continue;
if( world->water.enabled )
if( hit[1] < world->water.height )
int l = rb_sphere__scene( particle->obj.rb.to_world,
&particle->obj.inf.sphere,
- NULL, &world->rb_geo.inf.scene, buf );
+ NULL, &world->rb_geo.inf.scene, buf,
+ k_material_flag_ghosts );
for( int j=0; j<l; j++ ){
buf[j].rba = &particle->obj.rb;