+ mdl_unpack_glmesh( &msky, &world_global.skydome );
+ }
+ vg_release_thread_sync();
+
+ /* Other systems */
+ vg_info( "Loading other world systems\n" );
+
+ vg_loader_step( world_render_init, NULL );
+ vg_loader_step( world_sfd_init, NULL );
+ vg_loader_step( world_water_init, NULL );
+ vg_loader_step( world_gates_init, NULL );
+ vg_loader_step( world_routes_init, NULL );
+
+ /* Allocate dynamic world memory arena */
+ u32 max_size = 76*1024*1024;
+ world_global.generic_heap = vg_create_linear_allocator( vg_mem.rtmemory,
+ max_size,
+ VG_MEMORY_SYSTEM );
+}
+
+VG_STATIC void world_update( world_instance *world, v3f pos )
+{
+ /* TEMP!!!!!! */
+ static double g_time = 0.0;
+ g_time += vg.time_delta * (1.0/(k_day_length*60.0));
+
+
+ struct ub_world_lighting *state = &world->ub_lighting;
+
+ state->g_time = g_time;
+ state->g_realtime = vg.time;
+ state->g_debug_indices = k_debug_light_indices;
+ state->g_light_preview = k_light_preview;
+ state->g_debug_complexity = k_debug_light_complexity;
+
+ state->g_time_of_day = vg_fractf( g_time );
+ state->g_day_phase = cosf( state->g_time_of_day * VG_PIf * 2.0f );
+ state->g_sunset_phase= cosf( state->g_time_of_day * VG_PIf * 4.0f + VG_PIf );
+
+ state->g_day_phase = state->g_day_phase * 0.5f + 0.5f;
+ state->g_sunset_phase = powf( state->g_sunset_phase * 0.5f + 0.5f, 6.0f );
+
+ float a = state->g_time_of_day * VG_PIf * 2.0f;
+ state->g_sun_dir[0] = sinf( a );
+ state->g_sun_dir[1] = cosf( a );
+ state->g_sun_dir[2] = 0.2f;
+ v3_normalize( state->g_sun_dir );
+
+
+
+ glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
+ glBufferSubData( GL_UNIFORM_BUFFER, 0,
+ sizeof(struct ub_world_lighting), &world->ub_lighting );
+ /* TEMP!!!!!! */
+
+ world_global.sky_time += world_global.sky_rate * vg.time_delta;
+ world_global.sky_rate = vg_lerp( world_global.sky_rate,
+ world_global.sky_target_rate,
+ vg.time_delta * 5.0 );
+
+ world_routes_update( world );
+ world_routes_debug( world );
+
+ /* ---- SFD ------------ */
+
+ if( mdl_arrcount( &world->ent_route ) ){
+ u32 closest = 0;
+ float min_dist = INFINITY;
+
+ for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
+ ent_route *route = mdl_arritm( &world->ent_route, i );
+ float dist = v3_dist2( route->board_transform[3], pos );
+
+ if( dist < min_dist ){
+ min_dist = dist;
+ closest = i;
+ }
+ }
+
+ if( (world_global.sfd.active_route_board != closest)
+ || network_scores_updated )
+ {
+ network_scores_updated = 0;
+ world_global.sfd.active_route_board = closest;
+
+ ent_route *route = mdl_arritm( &world->ent_route, closest );
+ u32 id = route->official_track_id;
+
+ if( id != 0xffffffff ){
+ struct netmsg_board *local_board =
+ &scoreboard_client_data.boards[id];
+
+ for( int i=0; i<13; i++ ){
+ sfd_encode( i, &local_board->data[27*i] );
+ }
+ }else{
+ sfd_encode( 0, mdl_pstr( &world->meta, route->pstr_name ) );
+ sfd_encode( 1, "No data" );
+ }
+ }
+ }
+ sfd_update();
+
+#if 0
+ /* TODO: Bvh */
+
+ static float random_accum = 0.0f;
+ random_accum += vg.time_delta;
+
+ u32 random_ticks = 0;