- struct instance_cache
- {
- mdl_context *mdl;
- u32 pstr_file;
- }
- instance_cache[32];
- u32 instance_cache_count;
-}
-world;
-
-
-/*
- * API
- */
-
-VG_STATIC int ray_hit_is_ramp( ray_hit *hit );
-VG_STATIC int ray_hit_is_terrain( ray_hit *hit );
-VG_STATIC void ray_world_get_tri( ray_hit *hit, v3f tri[3] );
-VG_STATIC int ray_world( v3f pos, v3f dir, ray_hit *hit );
-
-/*
- * Submodules
- */
-
-#include "world_routes.h"
-#include "world_sfd.h"
-#include "world_render.h"
-#include "world_water.h"
-#include "world_gen.h"
-#include "world_gate.h"
-
-/*
- * -----------------------------------------------------------------------------
- * Events
- * -----------------------------------------------------------------------------
- */
-
-VG_STATIC void world_init(void)
-{
- vg_convar_push( (struct vg_convar){
- .name = "water_enable",
- .data = &world.water.enabled,
- .data_type = k_convar_dtype_i32,
- .opt_i32 = { .min=0, .max=1, .clamp=1 },
- .persistent = 0
- });
-
- world.sky_rate = 1.0;
- world.sky_target_rate = 1.0;
-
- shader_terrain_register();
- shader_sky_register();
- shader_planeinf_register();
- shader_gpos_register();
- shader_fscolour_register();
- shader_alphatest_register();
-
- vg_info( "Loading world resources\n" );
-
- vg_linear_clear( vg_mem.scratch );
- mdl_context *msky = mdl_load_full( vg_mem.scratch, "models/rs_skydome.mdl" );
-
- mdl_node *nlower = mdl_node_from_name( msky, "dome_lower" ),
- *nupper = mdl_node_from_name( msky, "dome_upper" );
-
- world.dome_lower = *mdl_node_submesh( msky, nlower, 0 );
- world.dome_upper = *mdl_node_submesh( msky, nupper, 0 );
-
- vg_acquire_thread_sync();
- {
- mdl_unpack_glmesh( msky, &world.skydome );
- }
- vg_release_thread_sync();
-
- /* Other systems */
- vg_info( "Loading other world systems\n" );
-
- vg_loader_highwater( world_render_init, NULL, NULL );
- vg_loader_highwater( world_sfd_init, NULL, NULL );
- vg_loader_highwater( world_water_init, NULL, NULL );
- vg_loader_highwater( world_gates_init, NULL, NULL );
- vg_loader_highwater( world_routes_init, NULL, NULL );
-
- /* Allocate dynamic world memory arena */
- u32 max_size = 72*1024*1024;
- world.dynamic_vgl = vg_create_linear_allocator( vg_mem.rtmemory, max_size );
-}
-
-VG_STATIC void world_update( v3f pos )
-{
- world.sky_time += world.sky_rate * vg.time_delta;
- world.sky_rate = vg_lerp( world.sky_rate, world.sky_target_rate,
- vg.time_delta * 5.0 );
-
- world_routes_update();
-#if 0
- world_routes_debug();
-#endif
-
- int closest = 0;
- float min_dist = INFINITY;
-
- for( int i=0; i<world.route_count; i++ )
- {
- float d = v3_dist2( world.routes[i].scoreboard_transform[3], pos );
-
- if( d < min_dist )
- {
- min_dist = d;
- closest = i;
- }
- }
-
- if( (world.active_route_board != closest) || network_scores_updated )
- {
- network_scores_updated = 0;
- world.active_route_board = closest;