static const float k_light_cube_size = 8.0f;
struct world_instance {
+
/* Fixed items
* -------------------------------------------------------
*/
void *heap;
- char world_name[ 64 ];
enum world_status{
k_world_status_unloaded = 0,
k_world_status_loading = 1,
- k_world_status_loaded = 2
+ k_world_status_loaded = 2,
+ k_world_status_unloading = 3 /* dont spawn sounds and stuff */
}
status;
}
water;
+ f64 time;
+
/* STD140 */
struct ub_world_lighting{
v4f g_cube_min,
float probabilities[3];
v3i light_cubes;
-
struct framebuffer heightmap;
/*
* surfaces;
u32 surface_count;
+ ent_worldinfo info;
mdl_array_ptr ent_spawn,
ent_gate,
ent_light,
ent_audio_clip,
ent_audio,
ent_volume,
- ent_traffic;
+ ent_traffic,
+ ent_skateshop,
+ ent_marker,
+ ent_camera,
+ ent_swspreview;
ent_gate *rendering_gate;
*/
/* world geometry */
- scene *scene_geo,
- *scene_no_collide,
- *scene_lines;
+ scene_context scene_geo,
+ scene_no_collide,
+ scene_lines;
/* spacial mappings */
bh_tree *audio_bh,
* --------------------------------------------------------------------------
*/
void *heap;
+ char *load_target;
/* rendering */
glmesh skydome;
glmesh mesh_base, mesh_display;
mdl_submesh sm_base;
u32 active_route_board;
+ scene_context scene;
u32 w, h;
float *buffer;
v3f render_gate_pos;
int in_volume;
- int switching_to_new_world;
-
world_instance worlds[4];
- u32 world_count;
u32 active_world;
/* text particles */
u32 text_particle_count;
}
static world_global;
+VG_STATIC void entity_call( world_instance *world, ent_call *call );
VG_STATIC world_instance *get_active_world( void )
{
mdl_context msky;
mdl_open( &msky, "models/rs_skydome.mdl", vg_mem.scratch );
mdl_load_metadata_block( &msky, vg_mem.scratch );
- mdl_load_mesh_block( &msky, vg_mem.scratch );
+ mdl_async_load_glmesh( &msky, &world_global.skydome );
mdl_close( &msky );
- vg_acquire_thread_sync();
- {
- mdl_unpack_glmesh( &msky, &world_global.skydome );
- }
- vg_release_thread_sync();
-
/* Other systems */
vg_info( "Loading other world systems\n" );
VG_MEMORY_SYSTEM );
}
-typedef struct ent_call ent_call;
-struct ent_call{
- ent_index ent;
- u32 function;
- void *data;
-};
-
-VG_STATIC void entity_call( world_instance *world, ent_call *call );
-
VG_STATIC void ent_volume_call( world_instance *world, ent_call *call )
{
- ent_volume *volume = mdl_arritm( &world->ent_volume, call->ent.index );
- if( !volume->target.type ) return;
+ u32 index = mdl_entity_id_id( call->id );
+ ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+ if( !volume->target ) return;
if( call->function == k_ent_function_trigger ){
- call->ent = volume->target;
+ call->id = volume->target;
if( volume->type == k_volume_subtype_particle ){
float *co = alloca( sizeof(float)*3 );
- co[0] = vg_randf()*2.0f-1.0f;
- co[1] = vg_randf()*2.0f-1.0f;
- co[2] = vg_randf()*2.0f-1.0f;
+ co[0] = vg_randf64()*2.0f-1.0f;
+ co[1] = vg_randf64()*2.0f-1.0f;
+ co[2] = vg_randf64()*2.0f-1.0f;
m4x3_mulv( volume->to_world, co, co );
call->function = k_ent_function_particle_spawn;
call->data = co;
entity_call( world, call );
}
- else
+ else{
entity_call( world, call );
+ }
}
}
VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
{
- ent_audio *audio = mdl_arritm( &world->ent_audio, call->ent.index );
+ if( world->status == k_world_status_unloading ){
+ vg_warn( "cannot modify audio while unloading world\n" );
+ return;
+ }
+
+ u8 world_id = (world - world_global.worlds) + 1;
+ u32 index = mdl_entity_id_id( call->id );
+ ent_audio *audio = mdl_arritm( &world->ent_audio, index );
v3f sound_co;
v3_copy( audio->transform.co, sound_co );
}
else
- vg_fatal_exit_loop( "ent_audio_call (invalid function id)" );
+ vg_fatal_error( "ent_audio_call (invalid function id)" );
- float chance = vg_randf()*100.0f,
+ float chance = vg_randf64()*100.0f,
bar = 0.0f;
for( u32 i=0; i<audio->clip_count; i++ ){
bar += p;
if( chance < bar ){
-
audio_lock();
if( audio->behaviour == k_channel_behaviour_unlimited ){
if( ch ){
audio_channel_init( ch, &clip->clip, audio->flags );
audio_channel_group( ch, audio->group );
+ audio_channel_world( ch, world_id );
audio_channel_set_spacial( ch, sound_co, audio->transform.s[0] );
audio_channel_edit_volume( ch, audio->volume, 1 );
ch = audio_relinquish_channel( ch );
if( ch ){
audio_channel_init( ch, &clip->clip, audio->flags );
audio_channel_group( ch, audio->group );
+ audio_channel_world( ch, world_id );
audio_channel_fadein( ch, audio->crossfade );
ch = audio_relinquish_channel( ch );
}
}
}
-VG_STATIC void entity_call( world_instance *world, ent_call *call )
+/* finds any active playing in world and fades them out, we can only do this
+ * while unloading */
+VG_STATIC void world_fadeout_audio( world_instance *world )
{
- if( call->ent.type == k_ent_volume ){
- ent_volume_call( world, call );
- } else if( call->ent.type == k_ent_audio ){
- ent_audio_call( world, call );
+ if( world->status != k_world_status_unloading ){
+ vg_fatal_error( "World status must be set to 'unloading', to fadeout"
+ " audio.\n" );
+ }
+
+ u8 world_id = (world - world_global.worlds) + 1;
+
+ audio_lock();
+ for( u32 i=0; i<AUDIO_CHANNELS; i++ ){
+ audio_channel *ch = &vg_audio.channels[i];
+
+ if( ch->allocated && (ch->world_id == world_id) ){
+ ch = audio_channel_fadeout( ch, 1.0f );
+ }
}
+ audio_unlock();
}
VG_STATIC void world_update( world_instance *world, v3f pos )
if( !world_global.in_volume ){
ent_call basecall;
- basecall.ent.index = idx;
- basecall.ent.type = k_ent_volume;
basecall.function = k_ent_function_trigger;
+ basecall.id = mdl_entity_id( k_ent_volume, idx );
basecall.data = NULL;
entity_call( world, &basecall );
for( int j=0; j<random_ticks; j++ ){
ent_call basecall;
- basecall.ent.index = idx;
- basecall.ent.type = k_ent_volume;
- basecall.function = k_ent_function_trigger;
+ basecall.id = mdl_entity_id( k_ent_volume, idx );
basecall.data = NULL;
entity_call( world, &basecall );
ray_hit *hit, v3f tri[3] )
{
for( int i=0; i<3; i++ )
- v3_copy( world->scene_geo->arrvertices[ hit->tri[i] ].co, tri[i] );
+ v3_copy( world->scene_geo.arrvertices[ hit->tri[i] ].co, tri[i] );
}
VG_STATIC int ray_world( world_instance *world,
v3f pos, v3f dir, ray_hit *hit )
{
- return scene_raycast( world->scene_geo, world->geo_bh, pos, dir, hit );
+ return scene_raycast( &world->scene_geo, world->geo_bh, pos, dir, hit );
}
/*
int idx;
while( bh_next( world->geo_bh, &it, region, &idx ) ){
- u32 *ptri = &world->scene_geo->arrindices[ idx*3 ];
+ u32 *ptri = &world->scene_geo.arrindices[ idx*3 ];
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] );
+ v3_copy( world->scene_geo.arrvertices[ptri[j]].co, tri[j] );
box_addpt( box, tri[j] );
}
*/
VG_STATIC
-enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output);
+enum audio_sprite_type world_audio_sample_sprite_kandom(v3f origin, v3f output);
VG_STATIC void world_audio_sample_distances( v3f co, int *index, float *value );
#include "audio.h"
VG_STATIC
enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output)
{
- v3f chance = { (vg_randf()-0.5f) * 30.0f,
+ v3f chance = { (vg_randf64()-0.5f) * 30.0f,
8.0f,
- (vg_randf()-0.5f) * 30.0f };
+ (vg_randf64()-0.5f) * 30.0f };
v3f pos;
v3_add( chance, origin, pos );