X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_gen.h;h=3f574987d3335f24af95443ca459ec414ed1d331;hb=6b9993651343af73bd48e2213910bbaadb41edaf;hp=63cb1ef98f1e91c38799f1f9d2e78a7a65e81b69;hpb=0a33f65eecb5e75cddaefa08d3a5eb1a301d0479;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_gen.h b/world_gen.h index 63cb1ef..3f57498 100644 --- a/world_gen.h +++ b/world_gen.h @@ -7,7 +7,7 @@ #include "world.h" -VG_STATIC void world_load( world_instance *world, const char *path ); +VG_STATIC void world_load( u32 index, const char *path ); VG_STATIC void world_add_all_if_material( m4x3f transform, scene *pscene, mdl_context *mdl, u32 id ) @@ -126,105 +126,12 @@ VG_STATIC void world_apply_procedural_foliage( world_instance *world, vg_info( "%d foliage models added\n", count ); } - -#if 0 - -VG_STATIC void world_pct_audio( world_instance *world, mdl_node *pnode ) -{ - struct world_audio_thing *thing = &world->audio_things[ - world->audio_things_count ]; - - memset( thing, 0, sizeof(struct world_audio_thing) ); - struct classtype_audio *aud = mdl_get_entdata( world->meta, pnode ); - - v3_copy( pnode->co, thing->pos ); - - thing->volume = aud->volume; - thing->range = pnode->s[0]; - - thing->flags = aud->flags; - thing->temp_embedded_clip.path = mdl_pstr( world->meta, aud->pstr_file ); - thing->temp_embedded_clip.flags = aud->flags; - - audio_clip_load( &thing->temp_embedded_clip, world_global.generic_heap ); - - pnode->sub_uid = world->audio_things_count; - world->audio_things_count ++; -} - -VG_STATIC void world_pct_nonlocal_gate( world_instance *world, mdl_node *pnode ) -{ - struct nonlocal_gate *gate = &world->nonlocal_gates[ - world->nonlocalgate_count ++ ]; - struct classtype_gate *inf = mdl_get_entdata( world->meta, pnode ); - - gate->working = 0; - gate->node = pnode; - gate->target_map_index = 0; - v2_copy( inf->dims, gate->gate.dims ); -} - -VG_STATIC void world_link_nonlocal_gates( int index_a, int index_b ) -{ - vg_info( "Linking non-local gates\n" ); - world_instance *a = &world_global.worlds[ index_a ], - *b = &world_global.worlds[ index_b ]; - - for( int i=0; inonlocalgate_count; i++ ) - { - struct nonlocal_gate *ga = &a->nonlocal_gates[i]; - struct classtype_gate *ga_inf = mdl_get_entdata( a->meta, ga->node ); - const char *ga_name = mdl_pstr( a->meta, ga_inf->target ); - - for( int j=0; jnonlocalgate_count; j++ ) - { - struct nonlocal_gate *gb = &b->nonlocal_gates[j]; - struct classtype_gate *gb_inf = mdl_get_entdata( b->meta, gb->node ); - const char *gb_name = mdl_pstr( b->meta, gb_inf->target ); - - if( !strcmp( ga_name, gb_name ) ) - { - vg_success( "Created longjump for ID '%s'\n", ga_name ); - - v4f qYflip; - q_axis_angle( qYflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); - - /* TODO: Gates are created very wonkily. refactor. */ - ga->target_map_index = index_b; - gb->target_map_index = index_a; - ga->working = 1; - gb->working = 1; - - v4_copy( ga->node->q, ga->gate.q[0] ); - v4_copy( gb->node->q, ga->gate.q[1] ); - v3_copy( ga->node->co, ga->gate.co[0] ); - v3_copy( gb->node->co, ga->gate.co[1] ); - - v4_copy( gb->node->q, gb->gate.q[0] ); - v4_copy( ga->node->q, gb->gate.q[1] ); - v3_copy( gb->node->co, gb->gate.co[0] ); - v3_copy( ga->node->co, gb->gate.co[1] ); - - /* reverse B's direction */ - q_mul( gb->gate.q[0], qYflip, gb->gate.q[0] ); - q_mul( gb->gate.q[1], qYflip, gb->gate.q[1] ); - q_normalize( gb->gate.q[0] ); - q_normalize( gb->gate.q[1] ); - - gate_transform_update( &ga->gate ); - gate_transform_update( &gb->gate ); - } - } - } -} -#endif - VG_STATIC void world_generate( world_instance *world ) { /* * Compile meshes into the world scenes */ - world->scene_geo = scene_init( world_global.generic_heap, 320000, 1200000 ); + world->scene_geo = scene_init( world->heap, 320000, 1200000 ); m4x3f midentity; m4x3_identity( midentity ); @@ -247,7 +154,7 @@ VG_STATIC void world_generate( world_instance *world ) } /* compress that bad boy */ - world->scene_geo = scene_fix( world_global.generic_heap, world->scene_geo ); + world->scene_geo = scene_fix( world->heap, world->scene_geo ); vg_acquire_thread_sync(); { @@ -256,16 +163,16 @@ VG_STATIC void world_generate( world_instance *world ) vg_release_thread_sync(); /* setup spacial mapping and rigidbody */ - world->geo_bh = scene_bh_create( world_global.generic_heap, - world->scene_geo ); + world->geo_bh = scene_bh_create( world->heap, world->scene_geo ); - v3_zero( world->rb_geo.co ); - q_identity( world->rb_geo.q ); + v3_zero( world->rb_geo.rb.co ); + v3_zero( world->rb_geo.rb.v ); + q_identity( world->rb_geo.rb.q ); + v3_zero( world->rb_geo.rb.w ); world->rb_geo.type = k_rb_shape_scene; world->rb_geo.inf.scene.bh_scene = world->geo_bh; - world->rb_geo.is_world = 1; - rb_init( &world->rb_geo ); + rb_init_object( &world->rb_geo ); /* * Generate scene: non-collidable geometry @@ -273,8 +180,7 @@ VG_STATIC void world_generate( world_instance *world ) */ vg_info( "Generating non-collidable geometry\n" ); - world->scene_no_collide = scene_init( world_global.generic_heap, - 200000, 500000 ); + world->scene_no_collide = scene_init( world->heap, 200000, 500000 ); for( u32 i=0; isurface_count; i++ ){ struct world_surface *mat = &world->surfaces[ i ]; @@ -297,7 +203,7 @@ VG_STATIC void world_generate( world_instance *world ) } vg_release_thread_sync(); - vg_linear_del( world_global.generic_heap, world->scene_no_collide ); + vg_linear_del( world->heap, world->scene_no_collide ); world->scene_no_collide = NULL; } @@ -334,16 +240,23 @@ VG_STATIC void world_compute_light_indices( world_instance *world ) icubes_max[i] = cubes_max[i]; } + v3f cube_size; + v3i icubes_count; v3i_sub( icubes_max, icubes_min, icubes_count ); for( int i=0; i<3; i++ ){ - icubes_count[i] = VG_MIN( 128, icubes_count[i]+1 ); - cubes_max[i] = icubes_min[i] + icubes_count[i]; + int clamped_count = VG_MIN( 128, icubes_count[i]+1 ); + float clamped_max = icubes_min[i] + clamped_count, + max = icubes_min[i] + icubes_count[i]+1; + + icubes_count[i] = clamped_count; + cube_size[i] = (max / clamped_max) * k_light_cube_size; + cubes_max[i] = clamped_max; } - v3_muls( cubes_min, k_light_cube_size, cubes_min ); - v3_muls( cubes_max, k_light_cube_size, cubes_max ); + v3_mul( cubes_min, cube_size, cubes_min ); + v3_mul( cubes_max, cube_size, cubes_max ); for( int i=0; i<3; i++ ){ float range = cubes_max[i]-cubes_min[i]; @@ -355,18 +268,14 @@ VG_STATIC void world_compute_light_indices( world_instance *world ) int total_cubes = icubes_count[0]*icubes_count[1]*icubes_count[2]; - u32 *cubes_index = vg_linear_alloc( world_global.generic_heap, - total_cubes * sizeof(u32) * 2.0f ); + u32 *cubes_index = vg_linear_alloc( world->heap, + vg_align8(total_cubes*sizeof(u32)*2) ); vg_info( "Computing light cubes (%d) [%f %f %f] -> [%f %f %f]\n", total_cubes, cubes_min[0], -cubes_min[2], cubes_min[1], cubes_max[0], -cubes_max[2], cubes_max[1] ); - v3_copy( cubes_min, world->ub_lighting.g_cube_min ); - v3f cube_size; - v3_div( (v3f){1.0f,1.0f,1.0f}, world->ub_lighting.g_cube_inv_range, - cube_size ); float bound_radius = v3_length( cube_size ); for( int iz = 0; izheap, cubes_index ); vg_release_thread_sync(); } @@ -522,10 +431,10 @@ VG_STATIC void world_post_process( world_instance *world ) /* colour + night */ v3_muls( light->colour, light->colour[3] * 2.0f, light_dst[i*3+0] ); - light_dst[i*3+0][3] = -1.0f; + light_dst[i*3+0][3] = 2.0f; if( !light->daytime ){ - u32 hash = (i * 29986577) & 0xff; + u32 hash = (i * 29986577u) & 0xffu; float switch_on = hash; switch_on *= (1.0f/255.0f); @@ -588,7 +497,7 @@ VG_STATIC void world_post_process( world_instance *world ) glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); - render_fb_bind( &world->heightmap ); + render_fb_bind( &world->heightmap, 0 ); shader_blitcolour_use(); shader_blitcolour_uColour( (v4f){-9999.0f,-9999.0f,-9999.0f,-9999.0f} ); render_fsquad(); @@ -609,13 +518,6 @@ VG_STATIC void world_post_process( world_instance *world ) } vg_release_thread_sync(); - -#if 0 - /* - * Setup scene collider - */ - reset_player( 1, (const char *[]){"start"} ); -#endif } VG_STATIC void world_process_resources( world_instance *world ) @@ -625,8 +527,8 @@ VG_STATIC void world_process_resources( world_instance *world ) world->texture_count = 0; world->texture_count = world->meta.textures.count+1; - world->textures = vg_linear_alloc( world_global.generic_heap, - sizeof(GLuint)*world->texture_count ); + world->textures = vg_linear_alloc( world->heap, + vg_align8(sizeof(GLuint)*world->texture_count) ); vg_acquire_thread_sync(); { @@ -645,10 +547,13 @@ VG_STATIC void world_process_resources( world_instance *world ) } vg_linear_clear( vg_mem.scratch ); + void *src_data = vg_linear_alloc( vg_mem.scratch, + tex->file.pack_size ); + mdl_fread_pack_file( &world->meta, &tex->file, src_data ); + world->textures[i+1] = vg_tex2d_new(); vg_tex2d_set_error(); - vg_tex2d_qoi( mdl_arritm( &world->meta.pack, tex->file.pack_offset ), - tex->file.pack_size, + vg_tex2d_qoi( src_data, tex->file.pack_size, mdl_pstr( &world->meta, tex->file.pstr_path )); vg_tex2d_nearest(); vg_tex2d_repeat(); @@ -659,8 +564,8 @@ VG_STATIC void world_process_resources( world_instance *world ) vg_info( "Loading materials\n" ); world->surface_count = world->meta.materials.count+1; - world->surfaces = vg_linear_alloc( world_global.generic_heap, - sizeof(struct world_surface)*world->surface_count ); + world->surfaces = vg_linear_alloc( world->heap, + vg_align8(sizeof(struct world_surface)*world->surface_count) ); /* error material */ struct world_surface *errmat = &world->surfaces[0]; @@ -672,7 +577,7 @@ VG_STATIC void world_process_resources( world_instance *world ) } } -VG_STATIC void world_unload( world_instance *world ) +VG_STATIC void world_free( world_instance *world ) { vg_acquire_thread_sync(); @@ -688,39 +593,18 @@ VG_STATIC void world_unload( world_instance *world ) glDeleteTextures( 1, &world->tex_light_entities ); glDeleteTextures( 1, &world->tex_light_cubes ); - /* FIXME: CANT DO THIS HERE */ - /* whynot? */ - /* oh this should be moved to a global function */ - world_global.time = 0.0; - world_global.rewind_from = 0.0; - world_global.rewind_to = 0.0; - world_global.last_use = 0.0; - world_global.sfd.active_route_board = 0; - /* delete textures and meshes */ glDeleteTextures( world->texture_count, world->textures ); - /* delete the entire block of memory */ - /* FIXME: WE CANT DO THIS SHIT ANYMORE, NEED TO DEALLOC FROM ABOVE */ -#if 0 - vg_linear_clear( world->dynamic_vgl ); - vg_linear_clear( world->audio_vgl ); -#endif - vg_release_thread_sync(); + + world->status = k_world_status_unloaded; } -VG_STATIC void world_clean( world_instance *world ) +VG_STATIC void world_init_blank( world_instance *world ) { memset( &world->meta, 0, sizeof(mdl_context) ); - /* - * TODO: Theres probably a better way to do this? */ - /* yep, find all members that can be memsetted to 0. this is probably - * every member anyway, given the below is just setting to 0 - * - * also: rename clean to init? */ - world->textures = NULL; world->texture_count = 0; world->surfaces = NULL; @@ -759,8 +643,10 @@ VG_STATIC void world_clean( world_instance *world ) v3_copy( (v3f){1.10f, 0.89f, 0.35f}, state->g_sun_colour ); } -VG_STATIC void world_entities_init( world_instance *world ) +VG_STATIC void world_entities_init( u32 world_id ) { + world_instance *world = &world_global.worlds[world_id]; + /* lights */ for( u32 j=0; jent_light); j ++ ){ ent_light *light = mdl_arritm( &world->ent_light, j ); @@ -777,7 +663,55 @@ VG_STATIC void world_entities_init( world_instance *world ) /* gates */ for( u32 j=0; jent_gate); j ++ ){ ent_gate *gate = mdl_arritm( &world->ent_gate, j ); - gate_transform_update( gate ); + + if( gate->type == k_gate_type_teleport ){ + gate_transform_update( gate ); + } + else if( gate->type == k_gate_type_nonlocal_unlinked ){ + const char *key = mdl_pstr( &world->meta, gate->target ); + vg_info( "key: %s\n", key ); + + for( u32 i=0; istatus != k_world_status_loaded ) continue; + vg_info( "Checking world %u for key matches\n", i ); + + for( u32 j=0; jent_gate ); j++ ){ + ent_gate *gate2 = mdl_arritm( &other->ent_gate, j ); + if( gate2->type != k_gate_type_nonlocal_unlinked ) continue; + + const char *key2 = mdl_pstr( &other->meta, gate2->target ); + vg_info( " key2: %s\n", key2 ); + + if( strcmp( key, key2 ) ) continue; + + vg_success( "Non-local matching pair '%s' found. (%u:%u)\n", + key, world_id, i ); + + gate->type = k_gate_type_nonlocel; + gate2->type = k_gate_type_nonlocel; + gate->target = i; + gate2->target = world_id; + + v3_copy( gate->co[0], gate2->co[1] ); + v3_copy( gate2->co[0], gate->co[1] ); + v4_copy( gate->q[0], gate2->q[1] ); + v4_copy( gate2->q[0], gate->q[1] ); + + v4f qflip; + q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); + q_mul( gate->q[0], qflip, gate->q[0] ); + q_mul( gate->q[1], qflip, gate->q[1] ); + + gate_transform_update( gate ); + gate_transform_update( gate2 ); + + goto matched; + } + } +matched:; + } } /* water */ @@ -791,58 +725,111 @@ VG_STATIC void world_entities_init( world_instance *world ) world->water.enabled = 1; water_set_surface( world, water->transform.co[1] ); } + + /* volumes */ + for( u32 j=0; jent_volume); j++ ){ + ent_volume *volume = mdl_arritm( &world->ent_volume, j ); + mdl_transform_m4x3( &volume->transform, volume->to_world ); + m4x3_invert_full( volume->to_world, volume->to_local ); + } + + /* audio packs */ + for( u32 j=0; jent_audio); j++ ){ + ent_audio *audio = mdl_arritm( &world->ent_audio, j ); + + for( u32 k=0; kclip_count; k++ ){ + ent_audio_clip *clip = mdl_arritm( &world->ent_audio_clip, + audio->clip_start+k ); + + if( clip->file.pack_size ){ + u32 size = clip->file.pack_size, + offset = clip->file.pack_offset; + + /* embedded files are fine to clear the scratch buffer, only + * external audio uses it */ + + vg_linear_clear( vg_mem.scratch ); + void *data = vg_linear_alloc( vg_mem.scratch, + clip->file.pack_size ); + + mdl_fread_pack_file( &world->meta, &clip->file, data ); + + clip->clip.path = NULL; + clip->clip.flags = audio->flags; + clip->clip.data = data; + clip->clip.size = size; + } + else{ + clip->clip.path = mdl_pstr( &world->meta, clip->file.pstr_path ); + clip->clip.flags = audio->flags; + clip->clip.data = NULL; + clip->clip.size = 0; + } + + audio_clip_load( &clip->clip, world->heap ); + } + } } -VG_STATIC void world_load( world_instance *world, const char *path ) +VG_STATIC void world_load( u32 index, const char *path ) { - world_unload( world ); - world_clean( world ); + world_instance *world = &world_global.worlds[index]; + world_init_blank( world ); + world->status = k_world_status_loading; vg_info( "Loading world: %s\n", path ); - mdl_open( &world->meta, path, world_global.generic_heap ); - mdl_load_metadata_block( &world->meta, world_global.generic_heap ); - mdl_load_animation_block( &world->meta, world_global.generic_heap ); - mdl_load_mesh_block( &world->meta, world_global.generic_heap ); - mdl_load_pack_block( &world->meta, world_global.generic_heap ); - - mdl_load_array( &world->meta, &world->ent_gate, - "ent_gate", world_global.generic_heap ); - mdl_load_array( &world->meta, &world->ent_spawn, - "ent_spawn", world_global.generic_heap ); - mdl_load_array( &world->meta, &world->ent_light, - "ent_light", world_global.generic_heap ); - - mdl_load_array( &world->meta, &world->ent_route_node, - "ent_route_node", world_global.generic_heap ); - mdl_load_array( &world->meta, &world->ent_path_index, - "ent_path_index", world_global.generic_heap ); - mdl_load_array( &world->meta, &world->ent_checkpoint, - "ent_checkpoint", world_global.generic_heap ); - mdl_load_array( &world->meta, &world->ent_route, - "ent_route", world_global.generic_heap ); - mdl_load_array( &world->meta, &world->ent_water, - "ent_water", world_global.generic_heap ); - - mdl_close( &world->meta ); + void *allocator = NULL; + if( index == 0 ) allocator = world_global.heap; + else allocator = world_global.worlds[index-1].heap; + + u32 heap_availible = vg_linear_remaining( allocator ); + u32 min_overhead = sizeof(vg_linear_allocator); + + if( heap_availible < (min_overhead+1024) ){ + vg_fatal_exit_loop( "out of memory" ); + } + + u32 size = heap_availible - min_overhead; + void *heap = vg_create_linear_allocator( allocator, size, + VG_MEMORY_SYSTEM ); + + world->heap = heap; + mdl_context *meta = &world->meta; + + mdl_open( meta, path, world->heap ); + mdl_load_metadata_block( meta, world->heap ); + mdl_load_animation_block( meta, world->heap ); + mdl_load_mesh_block( meta, world->heap ); + + mdl_load_array( meta, &world->ent_gate, "ent_gate", heap ); + mdl_load_array( meta, &world->ent_spawn, "ent_spawn", heap ); + mdl_load_array( meta, &world->ent_light, "ent_light", heap ); + mdl_load_array( meta, &world->ent_route_node,"ent_route_node", heap ); + mdl_load_array( meta, &world->ent_path_index,"ent_path_index", heap ); + mdl_load_array( meta, &world->ent_checkpoint,"ent_checkpoint", heap ); + mdl_load_array( meta, &world->ent_route, "ent_route", heap ); + mdl_load_array( meta, &world->ent_water, "ent_water", heap ); + mdl_load_array( meta, &world->ent_audio_clip,"ent_audio_clip", heap ); + mdl_load_array( meta, &world->ent_audio, "ent_audio", heap ); + mdl_load_array( meta, &world->ent_volume, "ent_volume", heap ); /* process resources from pack */ world_process_resources( world ); -#if 0 - /* dynamic allocations */ - world_ents_allocate( world ); - world_routes_allocate( world ); - - /* meta processing */ -#endif world_routes_ent_init( world ); - world_entities_init( world ); + world_entities_init( index ); + world->volume_bh = bh_create( heap, &bh_system_volumes, world, + mdl_arrcount( &world->ent_volume ), 1 ); /* main bulk */ world_generate( world ); world_routes_generate( world ); world_post_process( world ); + + mdl_close( meta ); + + world->status = k_world_status_loaded; } #endif /* WORLD_GEN_H */