2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
10 VG_STATIC
void world_load( world_instance
*world
, const char *path
);
12 VG_STATIC
void world_add_all_if_material( m4x3f transform
, scene
*pscene
,
13 mdl_context
*mdl
, u32 id
)
15 for( int i
=0; i
<mdl
->info
.node_count
; i
++ )
17 mdl_node
*pnode
= mdl_node_from_id( mdl
, i
);
19 for( int j
=0; j
<pnode
->submesh_count
; j
++ )
21 mdl_submesh
*sm
= mdl_node_submesh( mdl
, pnode
, j
);
22 if( sm
->material_id
== id
)
25 mdl_node_transform( pnode
, transform2
);
26 m4x3_mul( transform
, transform2
, transform2
);
28 scene_add_mdl_submesh( pscene
, mdl
, sm
, transform2
);
34 VG_STATIC
void world_add_blob( world_instance
*world
,
35 scene
*pscene
, ray_hit
*hit
)
38 v4f qsurface
, qrandom
;
41 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, hit
->normal
, axis
);
43 float angle
= v3_dot(hit
->normal
,(v3f
){0.0f
,1.0f
,0.0f
});
44 q_axis_angle( qsurface
, axis
, angle
);
45 q_axis_angle( qrandom
, (v3f
){0.0f
,1.0f
,0.0f
}, vg_randf()*VG_TAUf
);
46 q_mul( qsurface
, qrandom
, qsurface
);
47 q_m3x3( qsurface
, transform
);
48 v3_copy( hit
->pos
, transform
[3] );
52 { .co
= { -1.00f
, 0.0f
, 0.0f
} },
53 { .co
= { 1.00f
, 0.0f
, 0.0f
} },
54 { .co
= { -1.00f
, 1.2f
, 0.0f
} },
55 { .co
= { 1.00f
, 1.2f
, 0.0f
} },
56 { .co
= { -0.25f
, 2.0f
, 0.0f
} },
57 { .co
= { 0.25f
, 2.0f
, 0.0f
} }
60 const u32 indices
[] = { 0,1,3, 0,3,2, 2,3,5, 2,5,4 };
62 if( pscene
->vertex_count
+ vg_list_size(verts
) > pscene
->max_vertices
)
63 vg_fatal_exit_loop( "Scene vertex buffer overflow" );
65 if( pscene
->indice_count
+ vg_list_size(indices
) > pscene
->max_indices
)
66 vg_fatal_exit_loop( "Scene index buffer overflow" );
68 scene_vert
*dst_verts
= &pscene
->arrvertices
[ pscene
->vertex_count
];
69 u32
*dst_indices
= &pscene
->arrindices
[ pscene
->indice_count
];
71 scene_vert
*ref
= &world
->scene_geo
->arrvertices
[ hit
->tri
[0] ];
73 for( u32 i
=0; i
<vg_list_size(verts
); i
++ )
75 scene_vert
*pvert
= &dst_verts
[ i
],
78 m4x3_mulv( transform
, src
->co
, pvert
->co
);
79 scene_vert_pack_norm( pvert
, transform
[1] );
81 v2_copy( ref
->uv
, pvert
->uv
);
84 for( u32 i
=0; i
<vg_list_size(indices
); i
++ )
85 dst_indices
[i
] = indices
[i
] + pscene
->vertex_count
;
87 pscene
->vertex_count
+= vg_list_size(verts
);
88 pscene
->indice_count
+= vg_list_size(indices
);
91 /* Sprinkle foliage models over the map on terrain material */
92 VG_STATIC
void world_apply_procedural_foliage( world_instance
*world
,
93 struct world_material
*mat
)
95 if( vg
.quality_profile
== k_quality_profile_low
)
98 vg_info( "Applying foliage (%u)\n", mat
->info
.pstr_name
);
100 vg_linear_clear( vg_mem
.scratch
);
102 mdl_context
*mfoliage
=
103 mdl_load_full( vg_mem
.scratch
, "models/rs_foliage.mdl");
106 v3_sub( world
->scene_geo
->bbx
[1], world
->scene_geo
->bbx
[0], volume
);
109 mdl_node
*mblob
= mdl_node_from_name( mfoliage
, "blob" );
110 mdl_submesh
*sm_blob
= mdl_node_submesh( mfoliage
, mblob
, 0 );
114 float area
= volume
[0]*volume
[2];
115 u32 particles
= 0.08f
* area
;
117 vg_info( "Map area: %f. Max particles: %u\n", area
, particles
);
119 for( int i
=0;i
<particles
;i
++ )
122 v3_mul( volume
, (v3f
){ vg_randf(), 1000.0f
, vg_randf() }, pos
);
124 v3_add( pos
, world
->scene_geo
->bbx
[0], pos
);
129 if( ray_world( world
, pos
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
131 struct world_material
*m1
= ray_hit_material( world
, &hit
);
132 if((hit
.normal
[1] > 0.8f
) && (m1
== mat
) && (hit
.pos
[1] > 0.0f
+10.0f
))
134 world_add_blob( world
, world
->scene_no_collide
, &hit
);
140 vg_info( "%d foliage models added\n", count
);
143 VG_STATIC
void world_ents_allocate( world_instance
*world
)
145 vg_info( "Allocating entities\n" );
147 /* count entites to allocate buffers for them.
148 * maybe in the future we just store these numbers in the model file...
150 * TODO: use this in world_routes too */
163 (void*)&world
->spawns
,
164 sizeof(struct respawn_point
)
168 (void*)&world
->audio_things
,
169 sizeof(struct world_audio_thing
)
173 (void*)&world
->triggers
,
174 sizeof(struct trigger_zone
)
177 k_classtype_logic_relay
,
178 (void*)&world
->logic_relays
,
179 sizeof(struct logic_relay
)
182 k_classtype_logic_achievement
,
183 (void*)&world
->logic_achievements
,
184 sizeof(struct logic_achievement
)
187 k_classtype_point_light
,
188 (void*)&world
->lights
,
189 sizeof(struct world_light
)
193 for( int i
=0; i
<vg_list_size(entity_counts
); i
++ )
194 entity_counts
[i
].count
= 0;
196 for( int i
=0; i
<world
->meta
->info
.node_count
; i
++ )
198 mdl_node
*pnode
= mdl_node_from_id( world
->meta
, i
);
200 for( int j
=0; j
<vg_list_size(entity_counts
); j
++ )
202 if( pnode
->classtype
== entity_counts
[j
].ct
)
204 pnode
->sub_uid
= entity_counts
[j
].count
;
205 entity_counts
[j
].count
++;
211 for( int i
=0; i
<vg_list_size(entity_counts
); i
++ )
213 struct countable
*counter
= &entity_counts
[i
];
215 u32 bufsize
= counter
->item_size
*counter
->count
;
216 *counter
->to_allocate
= vg_linear_alloc( world_global
.generic_heap
,
221 VG_STATIC
void world_pct_spawn( world_instance
*world
, mdl_node
*pnode
)
223 struct respawn_point
*rp
= &world
->spawns
[ world
->spawn_count
++ ];
225 v3_copy( pnode
->co
, rp
->co
);
226 v4_copy( pnode
->q
, rp
->q
);
227 rp
->name
= mdl_pstr( world
->meta
, pnode
->pstr_name
);
230 VG_STATIC
void world_pct_water( world_instance
*world
, mdl_node
*pnode
)
232 if( world
->water
.enabled
)
234 vg_warn( "Multiple water surfaces in level! ('%s')\n",
235 mdl_pstr( world
->meta
, pnode
->pstr_name
));
239 world
->water
.enabled
= 1;
240 water_set_surface( world
, pnode
->co
[1] );
243 VG_STATIC
void world_pct_audio( world_instance
*world
, mdl_node
*pnode
)
245 struct world_audio_thing
*thing
= &world
->audio_things
[
246 world
->audio_things_count
];
248 memset( thing
, 0, sizeof(struct world_audio_thing
) );
249 struct classtype_audio
*aud
= mdl_get_entdata( world
->meta
, pnode
);
251 v3_copy( pnode
->co
, thing
->pos
);
253 if( aud
->flags
& AUDIO_FLAG_SPACIAL_3D
)
254 thing
->volume
= aud
->volume
* pnode
->s
[0];
256 thing
->volume
= aud
->volume
;
258 thing
->flags
= aud
->flags
;
259 thing
->temp_embedded_clip
.path
= mdl_pstr( world
->meta
, aud
->pstr_file
);
260 thing
->temp_embedded_clip
.source_mode
= k_audio_source_mono
;
262 audio_clip_load( &thing
->temp_embedded_clip
, world_global
.audio_heap
);
263 thing
->player
.name
= mdl_pstr( world
->meta
, pnode
->pstr_name
);
264 thing
->player
.enqued
= 0;
266 pnode
->sub_uid
= world
->audio_things_count
;
267 world
->audio_things_count
++;
270 VG_STATIC
void world_pct_trigger( world_instance
*world
, mdl_node
*pnode
)
272 struct trigger_zone
*trigger
= &world
->triggers
[ world
->trigger_count
];
273 struct classtype_trigger
*inf
= mdl_get_entdata( world
->meta
, pnode
);
277 mdl_node
*target_node
= mdl_node_from_id( world
->meta
, inf
->target
);
279 trigger
->target
.sub_id
= target_node
->sub_uid
;
280 trigger
->target
.classtype
= target_node
->classtype
;
284 vg_warn( "Trigger with no target...\n" );
288 mdl_node_transform( pnode
, trigger
->transform
);
289 m4x3_invert_full( trigger
->transform
, trigger
->inv_transform
);
291 world
->trigger_count
++;
295 VG_STATIC
void world_pct_relay( world_instance
*world
, mdl_node
*pnode
)
297 struct logic_relay
*relay
= &world
->logic_relays
[ world
->relay_count
];
298 struct classtype_logic_relay
*inf
= mdl_get_entdata( world
->meta
, pnode
);
300 relay
->target_count
= 0;
302 for( int i
=0; i
<vg_list_size(relay
->targets
); i
++ )
304 if( inf
->targets
[i
] )
306 struct relay_target
*target
= &relay
->targets
[relay
->target_count
++];
307 mdl_node
*other
= mdl_node_from_id( world
->meta
, inf
->targets
[i
] );
309 target
->classtype
= other
->classtype
;
310 target
->sub_id
= other
->sub_uid
;
314 v3_copy( pnode
->co
, relay
->pos
);
315 world
->relay_count
++;
319 VG_STATIC
void world_pct_achievement( world_instance
*world
, mdl_node
*pnode
)
321 struct logic_achievement
*ach
=
322 &world
->logic_achievements
[ world
->achievement_count
];
323 struct classtype_logic_achievement
*inf
=
324 mdl_get_entdata( world
->meta
, pnode
);
326 v3_copy( pnode
->co
, ach
->pos
);
327 ach
->achievement_id
= mdl_pstr( world
->meta
, inf
->pstr_name
);
330 world
->achievement_count
++;
333 VG_STATIC
void world_pct_point_light( world_instance
*world
, mdl_node
*pnode
)
335 struct world_light
*light
= &world
->lights
[ world
->light_count
];
336 v3_copy( pnode
->co
, light
->co
);
338 struct classtype_point_light
*inf
= mdl_get_entdata( world
->meta
, pnode
);
339 v4_copy( inf
->colour
, light
->colour
);
341 world
->light_count
++;
344 VG_STATIC
void world_entities_process( world_instance
*world
)
346 struct entity_instruction
349 void (*process
)( world_instance
*world
, mdl_node
*pnode
);
351 entity_instructions
[] =
353 { k_classtype_spawn
, world_pct_spawn
},
354 { k_classtype_water
, world_pct_water
},
355 { k_classtype_audio
, world_pct_audio
},
356 { k_classtype_trigger
, world_pct_trigger
},
357 { k_classtype_logic_relay
, world_pct_relay
},
358 { k_classtype_logic_achievement
, world_pct_achievement
},
359 { k_classtype_point_light
, world_pct_point_light
}
362 for( int i
=0; i
<world
->meta
->info
.node_count
; i
++ )
364 mdl_node
*pnode
= mdl_node_from_id( world
->meta
, i
);
366 for( int j
=0; j
<vg_list_size(entity_instructions
); j
++ )
368 struct entity_instruction
*instr
= &entity_instructions
[j
];
370 if( pnode
->classtype
== instr
->ct
)
372 instr
->process( world
, pnode
);
379 VG_STATIC
void world_scene_compute_light_clusters( world_instance
*world
,
382 for( int i
=0; i
<sc
->vertex_count
; i
++ )
384 scene_vert
*vert
= &sc
->arrvertices
[i
];
385 vert
->lights
[0] = 255;
386 vert
->lights
[1] = 255;
387 vert
->lights
[2] = 255;
388 vert
->lights
[3] = 255;
390 float distances
[4] = { INFINITY
, INFINITY
, INFINITY
, INFINITY
};
392 for( int j
=0; j
<world
->light_count
; j
++ )
394 float dist
= v3_dist2( world
->lights
[j
].co
, vert
->co
);
397 for( int k
=best_pos
-1; k
>=0; k
-- )
398 if( dist
< distances
[k
] )
403 for( int k
=3; k
>best_pos
; k
-- )
405 distances
[k
] = distances
[k
-1];
406 vert
->lights
[k
] = vert
->lights
[k
-1];
409 distances
[best_pos
] = dist
;
410 vert
->lights
[best_pos
] = j
;
416 VG_STATIC
void world_generate( world_instance
*world
)
419 * Compile meshes into the world scenes
421 world
->scene_geo
= scene_init( world_global
.generic_heap
, 320000, 1200000 );
424 m4x3_identity( midentity
);
427 * Generate scene: collidable geometry
428 * ----------------------------------------------------------------
431 vg_info( "Generating collidable geometry\n" );
434 for( int i
=0; i
<world
->material_count
; i
++ )
436 struct world_material
*mat
= &world
->materials
[ i
];
438 if( mat
->info
.flags
& k_material_flag_collision
)
439 world_add_all_if_material( midentity
, world
->scene_geo
, world
->meta
, i
);
441 scene_copy_slice( world
->scene_geo
, &mat
->sm_geo
);
443 world_scene_compute_light_clusters( world
, world
->scene_geo
);
445 /* compress that bad boy */
446 world
->scene_geo
= scene_fix( world_global
.generic_heap
, world
->scene_geo
);
448 vg_acquire_thread_sync();
450 scene_upload( world
->scene_geo
, &world
->mesh_geo
);
452 vg_release_thread_sync();
454 /* setup spacial mapping and rigidbody */
455 world
->geo_bh
= scene_bh_create( world_global
.generic_heap
,
458 v3_zero( world
->rb_geo
.co
);
459 q_identity( world
->rb_geo
.q
);
461 world
->rb_geo
.type
= k_rb_shape_scene
;
462 world
->rb_geo
.inf
.scene
.bh_scene
= world
->geo_bh
;
463 world
->rb_geo
.is_world
= 1;
464 rb_init( &world
->rb_geo
);
467 * Generate scene: non-collidable geometry
468 * ----------------------------------------------------------------
470 vg_info( "Generating non-collidable geometry\n" );
472 world
->scene_no_collide
= scene_init( world_global
.generic_heap
,
475 for( int i
=0; i
<world
->material_count
; i
++ )
477 struct world_material
*mat
= &world
->materials
[ i
];
479 if( !(mat
->info
.flags
& k_material_flag_collision
) )
481 world_add_all_if_material( midentity
, world
->scene_no_collide
,
485 if( mat
->info
.flags
& k_material_flag_grow_grass
)
486 world_apply_procedural_foliage( world
, mat
);
488 scene_copy_slice( world
->scene_no_collide
, &mat
->sm_no_collide
);
490 world_scene_compute_light_clusters( world
, world
->scene_no_collide
);
492 /* upload and free that */
493 vg_acquire_thread_sync();
495 scene_upload( world
->scene_no_collide
, &world
->mesh_no_collide
);
497 vg_release_thread_sync();
499 vg_linear_del( world_global
.generic_heap
, world
->scene_no_collide
);
500 world
->scene_no_collide
= NULL
;
503 VG_STATIC
int reset_player( int argc
, char const *argv
[] );
504 VG_STATIC
void world_post_process( world_instance
*world
)
506 /* initialize audio if need be */
508 for( int i
=0; i
<world
->audio_things_count
; i
++ )
510 struct world_audio_thing
*thingy
= &world
->audio_things
[ i
];
512 audio_player_init( &thingy
->player
);
513 audio_player_set_flags( &thingy
->player
, thingy
->flags
);
514 audio_player_set_vol( &thingy
->player
, thingy
->volume
);
515 audio_player_set_pan( &thingy
->player
, 0.0f
);
517 if( thingy
->flags
& AUDIO_FLAG_SPACIAL_3D
)
518 audio_player_set_position( &thingy
->player
, thingy
->pos
);
520 if( thingy
->flags
& AUDIO_FLAG_AUTO_START
)
521 audio_player_playclip( &thingy
->player
, &thingy
->temp_embedded_clip
);
525 vg_acquire_thread_sync();
528 * Rendering the depth map
533 v3_sub( world
->scene_geo
->bbx
[1], world
->scene_geo
->bbx
[0], extent
);
535 float fl
= world
->scene_geo
->bbx
[0][0],
536 fr
= world
->scene_geo
->bbx
[1][0],
537 fb
= world
->scene_geo
->bbx
[0][2],
538 ft
= world
->scene_geo
->bbx
[1][2],
542 m4x4_zero( ortho
.mtx
.p
);
543 ortho
.mtx
.p
[0][0] = 2.0f
* rl
;
544 ortho
.mtx
.p
[2][1] = 2.0f
* tb
;
545 ortho
.mtx
.p
[3][0] = (fr
+ fl
) * -rl
;
546 ortho
.mtx
.p
[3][1] = (ft
+ fb
) * -tb
;
547 ortho
.mtx
.p
[3][3] = 1.0f
;
548 m4x3_identity( ortho
.transform
);
549 camera_update_view( &ortho
);
550 camera_finalize( &ortho
);
552 glDisable(GL_DEPTH_TEST
);
554 glDisable(GL_CULL_FACE
);
555 render_fb_bind( &world
->heightmap
);
556 shader_blitcolour_use();
557 shader_blitcolour_uColour( (v4f
){-9999.0f
,-9999.0f
,-9999.0f
,-9999.0f
} );
562 glBlendFunc(GL_ONE
, GL_ONE
);
563 glBlendEquation(GL_MAX
);
565 render_world_depth( world
, &ortho
);
567 glEnable(GL_DEPTH_TEST
);
568 glBindFramebuffer( GL_FRAMEBUFFER
, 0 );
570 /* Upload lighting uniform buffer */
571 if( world
->water
.enabled
)
572 v4_copy( world
->water
.plane
, world
->ub_lighting
.g_water_plane
);
575 v3f
*bounds
= world
->scene_geo
->bbx
;
577 info_vec
[0] = bounds
[0][0];
578 info_vec
[1] = bounds
[0][2];
579 info_vec
[2] = 1.0f
/ (bounds
[1][0]-bounds
[0][0]);
580 info_vec
[3] = 1.0f
/ (bounds
[1][2]-bounds
[0][2]);
581 v4_copy( info_vec
, world
->ub_lighting
.g_depth_bounds
);
583 /* add scene lights */
584 for( int i
=0; i
<world
->light_count
; i
++ )
586 struct world_light
*light
= &world
->lights
[i
];
588 v3_muls( light
->colour
, light
->colour
[3] * 2.0f
,
589 world
->ub_lighting
.g_point_light_colours
[i
] );
591 world
->ub_lighting
.g_point_light_positions
[i
] );
594 /* upload full buffer */
595 glBindBuffer( GL_UNIFORM_BUFFER
, world
->ubo_lighting
);
596 glBufferSubData( GL_UNIFORM_BUFFER
, 0,
597 sizeof(struct ub_world_lighting
), &world
->ub_lighting
);
600 vg_release_thread_sync();
604 * Setup scene collider
606 reset_player( 1, (const char *[]){"start"} );
610 VG_STATIC
void world_process_resources( world_instance
*world
)
612 vg_info( "Loading textures\n" );
613 world
->texture_count
= world
->meta
->info
.texture_count
;
614 world
->textures
= vg_linear_alloc( world_global
.generic_heap
,
615 sizeof(GLuint
)*world
->texture_count
);
617 vg_acquire_thread_sync();
620 world
->textures
[0] = vg_tex2d_new();
621 vg_tex2d_set_error();
625 for( int i
=1; i
<world
->texture_count
; i
++ )
627 mdl_texture
*tex
= &world
->meta
->texture_buffer
[i
];
629 if( !tex
->pack_offset
)
631 vg_release_thread_sync();
632 vg_fatal_exit_loop( "World models must have packed textures!" );
635 vg_linear_clear( vg_mem
.scratch
);
636 world
->textures
[i
] = vg_tex2d_new();
637 vg_tex2d_set_error();
638 vg_tex2d_qoi( world
->meta
->pack
+ tex
->pack_offset
, tex
->pack_length
,
639 mdl_pstr( world
->meta
, tex
->pstr_name
));
644 vg_release_thread_sync();
646 vg_info( "Loading materials\n" );
648 u32 size
= sizeof(struct world_material
) * world
->meta
->info
.material_count
;
649 world
->materials
= vg_linear_alloc( world_global
.generic_heap
, size
);
651 world
->material_count
= world
->meta
->info
.material_count
;
652 memset( world
->materials
, 0, size
);
654 for( int i
=1; i
<world
->material_count
; i
++ )
655 world
->materials
[i
].info
= world
->meta
->material_buffer
[i
];
658 struct world_material
*errmat
= &world
->materials
[0];
659 v4_copy( (v4f
){ 1.0f
,0.0f
,0.0f
,1.0f
}, errmat
->info
.colour
);
660 v4_copy( (v4f
){ 1.0f
,0.0f
,0.0f
,1.0f
}, errmat
->info
.colour1
);
661 errmat
->info
.flags
= 0x00;
662 errmat
->info
.pstr_name
= 0; /* useless? */
663 errmat
->info
.shader
= -1;
664 errmat
->info
.tex_decal
= 0;
665 errmat
->info
.tex_diffuse
= 0;
666 errmat
->info
.tex_normal
= 0;
669 VG_STATIC
void world_unload( world_instance
*world
)
671 vg_acquire_thread_sync();
674 mesh_free( &world
->mesh_route_lines
);
675 mesh_free( &world
->mesh_geo
);
676 mesh_free( &world
->mesh_no_collide
);
678 /* FIXME: CANT DO THIS HERE */
679 world_global
.time
= 0.0;
680 world_global
.rewind_from
= 0.0;
681 world_global
.rewind_to
= 0.0;
682 world_global
.last_use
= 0.0;
683 world_global
.active_gate
= 0;
684 world_global
.current_run_version
= 2;
685 world_global
.active_route_board
= 0;
687 for( int i
=0; i
<vg_list_size(world_global
.ui_bars
); i
++ )
689 struct route_ui_bar
*uib
= &world_global
.ui_bars
[i
];
690 uib
->segment_start
= 0;
691 uib
->segment_count
= 0;
694 uib
->fade_timer_start
= 0.0;
698 /* delete textures and meshes */
699 glDeleteTextures( world
->texture_count
, world
->textures
);
701 /* delete the entire block of memory */
702 /* FIXME: WE CANT DO THIS SHIT ANYMORE, NEED TO DEALLOC FROM ABOVE */
704 vg_linear_clear( world
->dynamic_vgl
);
705 vg_linear_clear( world
->audio_vgl
);
709 vg_release_thread_sync();
712 VG_STATIC
void world_add_global_light( world_instance
*world
,
713 v2f dir
, v3f colour
)
715 int id
= world
->ub_lighting
.g_light_count
;
717 v3_copy( colour
, world
->ub_lighting
.g_light_colours
[id
] );
718 v3_copy( (v3f
){ cosf(dir
[1]) * cosf(dir
[0]),
720 sinf(dir
[1]) * cosf(dir
[0]) },
721 world
->ub_lighting
.g_light_directions
[id
] );
723 world
->ub_lighting
.g_light_count
++;
726 VG_STATIC
void world_clean( world_instance
*world
)
728 /* clean dangling pointers */
731 world
->textures
= NULL
;
732 world
->texture_count
= 0;
733 world
->materials
= NULL
;
734 world
->material_count
= 0;
736 world
->scene_geo
= NULL
;
737 world
->scene_no_collide
= NULL
;
738 world
->scene_lines
= NULL
;
740 world
->geo_bh
= NULL
;
741 world
->trigger_bh
= NULL
;
742 world
->audio_bh
= NULL
;
744 world
->spawns
= NULL
;
745 world
->spawn_count
= 0;
747 world
->audio_things
= NULL
;
748 world
->audio_things_count
= 0;
750 world
->triggers
= NULL
;
751 world
->trigger_count
= 0;
753 world
->lights
= NULL
;
754 world
->light_count
= 0;
756 world
->logic_relays
= NULL
;
757 world
->relay_count
= 0;
759 world
->logic_achievements
= NULL
;
760 world
->achievement_count
= 0;
763 world
->node_count
= 0;
765 world
->routes
= NULL
;
766 world
->route_count
= 0;
769 world
->gate_count
= 0;
771 world
->collectors
= NULL
;
772 world
->collector_count
= 0;
774 world
->water
.enabled
= 0;
777 /* default lighting conditions
778 * -------------------------------------------------------------*/
779 world
->ub_lighting
.g_light_count
= 0;
780 world
->ub_lighting
.g_light_preview
= 0;
781 world
->ub_lighting
.g_shadow_samples
= 8;
782 world
->ub_lighting
.g_water_fog
= 0.04f
;
784 v4_zero( world
->ub_lighting
.g_water_plane
);
785 v4_zero( world
->ub_lighting
.g_depth_bounds
);
786 v4_zero( world
->ub_lighting
.g_ambient_colour
);
788 v3_copy( (v3f
){ 0.09f
, 0.03f
, 0.07f
}, world
->ub_lighting
.g_ambient_colour
);
790 world_add_global_light( world
, (v2f
){ 0.63f
, -0.08f
},
791 (v3f
){ 1.36f
, 1.35f
, 1.01f
} );
793 world_add_global_light( world
, (v2f
){ -2.60f
, -0.13f
},
794 (v3f
){ 0.33f
, 0.56f
, 0.64f
} );
796 world_add_global_light( world
, (v2f
){ 2.60f
, -0.84f
},
797 (v3f
){ 0.05f
, 0.05f
, 0.23f
} );
799 world
->ub_lighting
.g_light_directions
[0][3] = 9.50f
;
800 world
->ub_lighting
.g_light_colours
[0][3] = 0.65f
;
803 VG_STATIC
void world_load( world_instance
*world
, const char *path
)
805 world_unload( world
);
806 world_clean( world
);
808 world
->meta
= mdl_load_full( world_global
.generic_heap
, path
);
809 vg_info( "Loading world: %s\n", path
);
811 /* process resources from pack */
812 world_process_resources( world
);
814 /* dynamic allocations */
815 world_ents_allocate( world
);
816 world_routes_allocate( world
);
818 /* meta processing */
819 world_routes_process( world
);
820 world_entities_process( world
);
823 world_generate( world
);
824 world_routes_generate( world
);
825 world_post_process( world
);
828 #endif /* WORLD_GEN_H */