X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world.h;h=66b3b28f2c0b14a961cf7ea04ef4b27321332cc7;hb=a8ba9cc44e1ae9aeca62fb579a3105c625e59133;hp=c7485d17b4bf9fe7622811fdef8be3a8afa9be1a;hpb=e70b6d550d63af95cafd9ffdee1918faf02a6892;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world.h b/world.h index c7485d1..66b3b28 100644 --- a/world.h +++ b/world.h @@ -56,12 +56,19 @@ enum geo_type 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_unloading = 3 /* dont spawn sounds and stuff */ + } + status; struct{ boxf depthbounds; @@ -73,6 +80,8 @@ struct world_instance { } water; + f64 time; + /* STD140 */ struct ub_world_lighting{ v4f g_cube_min, @@ -118,7 +127,6 @@ struct world_instance { float probabilities[3]; v3i light_cubes; - struct framebuffer heightmap; /* @@ -147,6 +155,7 @@ struct world_instance { * surfaces; u32 surface_count; + ent_worldinfo info; mdl_array_ptr ent_spawn, ent_gate, ent_light, @@ -158,7 +167,12 @@ struct world_instance { ent_audio_clip, ent_audio, - ent_volume; + ent_volume, + ent_traffic, + ent_skateshop, + ent_marker, + ent_camera, + ent_swspreview; ent_gate *rendering_gate; @@ -167,9 +181,9 @@ struct world_instance { */ /* 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, @@ -191,6 +205,7 @@ struct world_global{ * -------------------------------------------------------------------------- */ void *heap; + char *load_target; /* rendering */ glmesh skydome; @@ -214,6 +229,7 @@ struct world_global{ glmesh mesh_base, mesh_display; mdl_submesh sm_base; u32 active_route_board; + scene_context scene; u32 w, h; float *buffer; @@ -223,10 +239,7 @@ struct world_global{ v3f render_gate_pos; int in_volume; - int switching_to_new_world; - world_instance worlds[4]; - u32 world_count; u32 active_world; /* text particles */ @@ -253,6 +266,7 @@ struct world_global{ 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 ) { @@ -379,15 +393,9 @@ VG_STATIC void world_init(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" ); @@ -403,42 +411,42 @@ VG_STATIC void world_init(void) 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; @@ -449,9 +457,9 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call ) 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; iclip_count; i++ ){ @@ -464,7 +472,6 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call ) bar += p; if( chance < bar ){ - audio_lock(); if( audio->behaviour == k_channel_behaviour_unlimited ){ @@ -480,6 +487,7 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call ) 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 ); @@ -511,6 +519,7 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call ) 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 ); } @@ -522,13 +531,26 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call ) } } -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; iallocated && (ch->world_id == world_id) ){ + ch = audio_channel_fadeout( ch, 1.0f ); + } } + audio_unlock(); } VG_STATIC void world_update( world_instance *world, v3f pos ) @@ -541,6 +563,67 @@ VG_STATIC void world_update( world_instance *world, v3f pos ) world_routes_update_timer_texts( world ); world_routes_update( world ); //world_routes_debug( world ); + + /* ---- traffic -------- */ + + for( u32 i=0; ient_traffic ); i++ ){ + ent_traffic *traffic = mdl_arritm( &world->ent_traffic, i ); + + u32 i1 = traffic->index, + i0, + i2 = i1+1; + + if( i1 == 0 ) i0 = traffic->node_count-1; + else i0 = i1-1; + + if( i2 >= traffic->node_count ) i2 = 0; + + i0 += traffic->start_node; + i1 += traffic->start_node; + i2 += traffic->start_node; + + v3f h[3]; + + ent_route_node *rn0 = mdl_arritm( &world->ent_route_node, i0 ), + *rn1 = mdl_arritm( &world->ent_route_node, i1 ), + *rn2 = mdl_arritm( &world->ent_route_node, i2 ); + + v3_copy( rn1->co, h[1] ); + v3_lerp( rn0->co, rn1->co, 0.5f, h[0] ); + v3_lerp( rn1->co, rn2->co, 0.5f, h[2] ); + + float const k_sample_dist = 0.0025f; + v3f pc, pd; + eval_bezier3( h[0], h[1], h[2], traffic->t, pc ); + eval_bezier3( h[0], h[1], h[2], traffic->t+k_sample_dist, pd ); + + v3f v0; + v3_sub( pd, pc, v0 ); + float length = vg_maxf( 0.0001f, v3_length( v0 ) ); + v3_muls( v0, 1.0f/length, v0 ); + + float mod = k_sample_dist / length; + + traffic->t += traffic->speed * vg.time_delta * mod; + + if( traffic->t > 1.0f ){ + traffic->t -= 1.0f; + + if( traffic->t > 1.0f ) traffic->t = 0.0f; + + traffic->index ++; + + if( traffic->index >= traffic->node_count ) + traffic->index = 0; + } + + v3_copy( pc, traffic->transform.co ); + + float a = atan2f( -v0[0], v0[2] ); + q_axis_angle( traffic->transform.q, (v3f){0.0f,1.0f,0.0f}, -a ); + + vg_line_pt3( traffic->transform.co, 0.3f, VG__BLUE ); + } /* ---- SFD ------------ */ @@ -621,9 +704,8 @@ 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 ); @@ -637,9 +719,7 @@ VG_STATIC void world_update( world_instance *world, v3f pos ) for( int j=0; jscene_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 ); } /* @@ -720,14 +800,14 @@ VG_STATIC int spherecast_world( world_instance *world, 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] ); } @@ -788,7 +868,7 @@ VG_STATIC struct world_surface *ray_hit_surface( world_instance *world, */ 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" @@ -799,9 +879,9 @@ VG_STATIC void world_audio_sample_distances( v3f co, int *index, float *value ); 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 );