};
struct bh_system{
+ u32 system_type;
void (*expand_bound)( void *user, boxf bound, u32 item_index );
float (*item_centroid)( void *user, u32 item_index, int axis );
void (*item_closest)( void *user, u32 item_index, v3f point, v3f closest );
int (*cast_ray)( void *user, u32 index, v3f co, v3f dir, ray_hit *hit );
};
+static float scene_bh_centroid( void *user, u32 item_index, int axis );
+static void scene_bh_swap( void *user, u32 ia, u32 ib );
+static void scene_bh_expand_bound( void *user, boxf bound, u32 item_index );
+
static void bh_update_bounds( bh_tree *bh, u32 inode ){
bh_node *node = &bh->nodes[ inode ];
box_init_inf( node->bbx );
for( u32 i=0; i<node->count; i++ ){
u32 idx = node->start+i;
- bh->system->expand_bound( bh->user, node->bbx, idx );
+ if( bh->system->system_type == 0x1 )
+ scene_bh_expand_bound( bh->user, node->bbx, idx );
+ else
+ bh->system->expand_bound( bh->user, node->bbx, idx );
}
}
float split = node->bbx[0][axis] + extent[axis]*0.5f;
float avg = 0.0;
- for( u32 t=0; t<node->count; t++ )
- {
+ for( u32 t=0; t<node->count; t++ ){
u32 idx = node->start+t;
- avg += bh->system->item_centroid( bh->user, idx, axis );
+
+ if( bh->system->system_type == 0x1 )
+ avg += scene_bh_centroid( bh->user, idx, axis );
+ else
+ avg += bh->system->item_centroid( bh->user, idx, axis );
}
avg /= (float)node->count;
split = avg;
j = i + node->count-1;
while( i <= j ){
- if( bh->system->item_centroid( bh->user, i, axis ) < split )
+ f32 centroid;
+
+ if( bh->system->system_type == 0x1 )
+ centroid = scene_bh_centroid( bh->user, i, axis );
+ else
+ centroid = bh->system->item_centroid( bh->user, i, axis );
+
+ if( centroid < split )
i ++;
else{
- bh->system->item_swap( bh->user, i, j );
+ if( bh->system->system_type == 0x1 )
+ scene_bh_swap( bh->user, i, j );
+ else
+ bh->system->item_swap( bh->user, i, j );
j --;
}
}
.item_closest = scene_bh_closest,
.item_swap = scene_bh_swap,
.item_debug = scene_bh_debug,
+ .system_type = 0x1
};
/*
/* TODO: Quasirandom? */
vg_info( "Map area: %f. Max particles: %u\n", area, particles );
+
+ u64 t0 = SDL_GetPerformanceCounter();
+#if 0
for( u32 i=0; i<particles; i++ ){
v3f pos;
v3_mul( volume, (v3f){ vg_randf64(), 1000.0f, vg_randf64() }, pos );
}
}
}
+#else
+
+ const f32 tile_scale = 16.0f;
+ v2i tiles = { volume[0]/tile_scale, volume[2]/tile_scale };
+
+ u32 per_tile = particles/(tiles[0]*tiles[1]);
+
+ for( i32 x=0; x<tiles[0]; x ++ ){
+ for( i32 z=0; z<tiles[1]; z ++ ){
+ for( u32 i=0; i<per_tile; i ++ ){
+ v3f co = { (f32)x+vg_randf64(), 0.0f, (f32)z+vg_randf64() };
+ v3_muls( co, tile_scale, co );
+ co[1] = 1000.0f;
+ v3_add( co, world->scene_geo.bbx[0], co );
+
+ ray_hit hit;
+ hit.dist = INFINITY;
+
+ if( ray_world( world, co, (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 );
+ count ++;
+ }
+ }
+
+ }
+ }
+ }
+
+#endif
+
+
+
+ u64 t1 = SDL_GetPerformanceCounter(),
+ utime_blobs = t1-t0,
+ ufreq = SDL_GetPerformanceFrequency();
+ f64 ftime_blobs = ((f64)utime_blobs / (f64)ufreq)*1000.0;
- vg_info( "%d foliage models added\n", count );
+ vg_info( "%d foliage models added. %f%% (%fms)\n", count,
+ 100.0*((f64)count/(f64)particles), ftime_blobs);
}
static
world->time += (world->info.timezone/24.0);
/* process resources from pack */
+ u64 t4 = SDL_GetPerformanceCounter();
world_gen_load_surfaces( world );
+ u64 t5 = SDL_GetPerformanceCounter();
world_gen_routes_ent_init( world );
world_gen_entities_init( world );
+ u64 t6 = SDL_GetPerformanceCounter();
/* main bulk */
+ u64 t0 = SDL_GetPerformanceCounter();
world_gen_generate_meshes( world );
+ u64 t1 = SDL_GetPerformanceCounter();
world_gen_routes_generate( instance_id );
+ u64 t2 = SDL_GetPerformanceCounter();
world_gen_compute_light_indices( world );
+ u64 t3 = SDL_GetPerformanceCounter();
mdl_close( meta );
+ u64 utime_mesh = t1-t0,
+ utime_route = t2-t1,
+ utime_indices = t3-t2,
+ utime_tex = t5-t4,
+ utime_ent = t6-t5,
+ ufreq = SDL_GetPerformanceFrequency();
+
+ f64 ftime_mesh = ((f64)utime_mesh / (f64)ufreq)*1000.0,
+ ftime_route = ((f64)utime_route / (f64)ufreq)*1000.0,
+ ftime_ind = ((f64)utime_route / (f64)ufreq)*1000.0,
+ ftime_tex = ((f64)utime_tex / (f64)ufreq)*1000.0,
+ ftime_ent = ((f64)utime_ent / (f64)ufreq)*1000.0;
+
+ vg_info( "wtime:mesh %.2fms route %.2fms ind %.2fms tex %.2fms ent %.2fms\n",
+ ftime_mesh, ftime_route, ftime_ind, ftime_tex, ftime_ent );
+
/* init player position.
* - this is overriden by the save state when(if) it loads */
ent_spawn *rp = world_find_spawn_by_name( world, "start" );