dont remember
[carveJwlIkooP6JGAAIwe30JlM.git] / world_gen.h
1 #ifndef WORLD_GEN_H
2 #define WORLD_GEN_H
3
4 /*
5 * FUTURE:
6 * If we have multiple levels, write an unloader
7 */
8
9 #include "world.h"
10
11 static void world_add_all_if_material( m4x3f transform, scene *pscene,
12 mdl_header *mdl, u32 id )
13 {
14 for( int i=0; i<mdl->node_count; i++ )
15 {
16 mdl_node *pnode = mdl_node_from_id( mdl, i );
17
18 for( int j=0; j<pnode->submesh_count; j++ )
19 {
20 mdl_submesh *sm = mdl_node_submesh( mdl, pnode, j );
21
22 if( sm->material_id == id )
23 {
24 m4x3f transform2;
25 mdl_node_transform( pnode, transform2 );
26 m4x3_mul( transform, transform2, transform2 );
27
28 scene_add_submesh( pscene, mdl, sm, transform2 );
29 }
30 }
31
32 if( pnode->classtype == k_classtype_instance )
33 {
34 if( pnode->sub_uid )
35 {
36 u32 instance_id = pnode->sub_uid -1;
37 struct instance_cache *cache = &world.instance_cache[instance_id];
38 mdl_header *mdl2 = cache->mdl;
39
40 m4x3f transform2;
41 mdl_node_transform( pnode, transform2 );
42 m4x3_mul( transform, transform2, transform2 );
43
44 world_add_all_if_material( transform2, pscene, mdl2, id );
45 }
46 }
47 }
48 }
49
50 static void world_apply_procedural_foliage(void)
51 {
52 mdl_header *mfoliage = mdl_load("models/rs_foliage.mdl");
53
54 v3f volume;
55 v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
56 volume[1] = 1.0f;
57
58 m4x3f transform;
59 mdl_node *mblob = mdl_node_from_name( mfoliage, "blob" );
60 mdl_submesh *sm_blob = mdl_node_submesh( mfoliage, mblob, 0 );
61
62 for( int i=0;i<100000;i++ )
63 {
64 v3f pos;
65 v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
66 pos[1] = 1000.0f;
67 v3_add( pos, world.geo.bbx[0], pos );
68
69 ray_hit hit;
70 hit.dist = INFINITY;
71
72 if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
73 {
74 if( (hit.normal[1] > 0.8f) && ray_hit_is_terrain(&hit) &&
75 (hit.pos[1] > 0.0f+10.0f) )
76 {
77 v4f qsurface, qrandom;
78 v3f axis;
79
80 v3_cross( (v3f){0.0f,1.0f,0.0f}, hit.normal, axis );
81
82 float angle = v3_dot(hit.normal,(v3f){0.0f,1.0f,0.0f});
83 q_axis_angle( qsurface, axis, angle );
84 q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf()*VG_TAUf );
85 q_mul( qsurface, qrandom, qsurface );
86 q_m3x3( qsurface, transform );
87
88 v3_copy( hit.pos, transform[3] );
89 scene_add_submesh( &world.foliage, mfoliage, sm_blob, transform);
90 }
91 }
92 }
93
94 vg_free( mfoliage );
95 }
96
97 static void world_load(void)
98 {
99 mdl_header *mworld = mdl_load( "models/mp_dev.mdl" );
100 vg_info( "Loading world: models/mp_dev.mdl\n" );
101
102 world.spawn_count = 0;
103 world.traffic_count = 0;
104 world.instance_cache = NULL;
105
106 /*
107 * Process entities
108 */
109 for( int i=0; i<mworld->node_count; i++ )
110 {
111 mdl_node *pnode = mdl_node_from_id( mworld, i );
112
113 if( pnode->classtype == k_classtype_none )
114 {}
115 else if( pnode->classtype == k_classtype_spawn )
116 {
117 struct respawn_point *rp = &world.spawns[ world.spawn_count ++ ];
118
119 v3_copy( pnode->co, rp->co );
120 v4_copy( pnode->q, rp->q );
121 strcpy( rp->name, mdl_pstr( mworld, pnode->pstr_name ) );
122 }
123 else if( pnode->classtype == k_classtype_water )
124 {
125 if( wrender.enabled )
126 {
127 vg_warn( "Multiple water surfaces in level! ('%s')\n",
128 mdl_pstr( mworld, pnode->pstr_name ));
129 continue;
130 }
131
132 mdl_submesh *sm = mdl_node_submesh( mworld, pnode, 0 );
133
134 if( sm )
135 {
136 vg_acquire_thread_sync();
137 {
138 glmesh surf;
139 mdl_unpack_submesh( mworld, &surf, sm );
140 water_set_surface( &surf, pnode->co[1] );
141 }
142 vg_release_thread_sync();
143 }
144 }
145 else if( pnode->classtype == k_classtype_car_path )
146 {
147 struct classtype_car_path *p = mdl_get_entdata( mworld, pnode );
148 traffic_node *tn = &world.traffic[ world.traffic_count ];
149 tn->mn_next = NULL;
150 tn->mn_next1 = NULL;
151
152 if( p->target ) tn->mn_next = mdl_node_from_id( mworld, p->target );
153 if( p->target1 ) tn->mn_next1 = mdl_node_from_id( mworld, p->target1 );
154
155 m4x3f transform;
156 mdl_node_transform( pnode, transform );
157 m3x3_mulv( transform, (v3f){1.0f,0.0f,0.0f}, tn->h );
158 v3_copy( transform[3], tn->co );
159
160 pnode->sub_uid = world.traffic_count ++;
161 }
162 else if( pnode->classtype == k_classtype_instance )
163 {
164 struct classtype_instance *inst = mdl_get_entdata( mworld, pnode );
165 pnode->sub_uid = 0;
166
167 int cached = 0;
168 for( int i=0; i<world.instance_cache_count; i++ )
169 {
170 struct instance_cache *cache = &world.instance_cache[i];
171 if( inst->pstr_file == cache->pstr_file )
172 {
173 cached = 1;
174 pnode->sub_uid = i+1;
175 break;
176 }
177 }
178
179 if( !cached )
180 {
181 world.instance_cache = buffer_reserve(
182 world.instance_cache, world.instance_cache_count,
183 &world.instance_cache_cap, 1,
184 sizeof(struct instance_cache) );
185
186 struct instance_cache *cache =
187 &world.instance_cache[world.instance_cache_count];
188
189 const char *filename = mdl_pstr(mworld, inst->pstr_file);
190
191 cache->pstr_file = inst->pstr_file;
192 cache->mdl = mdl_load( filename );
193
194 if( cache->mdl )
195 {
196 world.instance_cache_count ++;
197 pnode->sub_uid = world.instance_cache_count;
198 mdl_link_materials( mworld, cache->mdl );
199 vg_success( "Cached %s\n", filename );
200 }
201 else
202 {
203 vg_warn( "Failed to cache %s\n", filename );
204 }
205 }
206 }
207 }
208
209 world.instance_cache = buffer_fix( world.instance_cache,
210 world.instance_cache_count,
211 &world.instance_cache_cap,
212 sizeof( struct instance_cache ) );
213
214 #if 0
215 traffic_finalize( world.traffic, world.traffic_count );
216 for( int i=0; i<vg_list_size(world.van_man); i++ )
217 world.van_man[i].current =&world.traffic[vg_randint(world.traffic_count)];
218 #endif
219
220 /*
221 * Compile meshes into the world scenes
222 */
223 scene_init( &world.geo );
224
225 u32 mat_surf = 0,
226 mat_surf_oob = 0,
227 mat_vertex_blend = 0,
228 mat_alphatest = 0,
229 mat_graffiti = 0,
230 mat_subworld = 0,
231 mat_terrain = 0;
232
233 for( int i=1; i<mworld->material_count; i++ )
234 {
235 mdl_material *mat = mdl_material_from_id( mworld, i );
236 const char *mat_name = mdl_pstr( mworld, mat->pstr_name );
237
238 if( !strcmp( "surf", mat_name ))
239 mat_surf = i;
240 else if( !strcmp( "surf_oob", mat_name ))
241 mat_surf_oob = i;
242 else if( !strcmp( "vertex_blend", mat_name ))
243 mat_vertex_blend = i;
244 else if( !strcmp( "alphatest", mat_name ))
245 mat_alphatest = i;
246 else if( !strcmp( "graffitibox", mat_name ))
247 mat_graffiti = i;
248 else if( !strcmp( "terrain", mat_name ) )
249 mat_terrain = i;
250 }
251
252 m4x3f midentity;
253 m4x3_identity( midentity );
254
255 if( mat_terrain )
256 world_add_all_if_material( midentity, &world.geo, mworld, mat_terrain );
257 scene_copy_slice( &world.geo, &world.sm_terrain );
258
259 if( mat_surf_oob )
260 world_add_all_if_material( midentity, &world.geo, mworld, mat_surf_oob );
261 else
262 vg_warn( "No OOB surface\n" );
263 scene_copy_slice( &world.geo, &world.sm_geo_std_oob );
264
265 if( mat_surf )
266 world_add_all_if_material( midentity, &world.geo, mworld, mat_surf );
267 scene_copy_slice( &world.geo, &world.sm_geo_std );
268
269 if( mat_vertex_blend )
270 world_add_all_if_material( midentity, &world.geo,mworld,mat_vertex_blend);
271 scene_copy_slice( &world.geo, &world.sm_geo_vb );
272
273 vg_acquire_thread_sync();
274 scene_upload( &world.geo );
275 vg_release_thread_sync();
276
277 scene_bh_create( &world.geo );
278
279
280 /* Foliage /nocollide layer.
281 * TODO: Probably should have material traits for this
282 */
283 scene_init( &world.foliage );
284
285 world_apply_procedural_foliage();
286 scene_copy_slice( &world.foliage, &world.sm_foliage_main );
287
288 world_add_all_if_material( midentity, &world.foliage, mworld, mat_alphatest);
289 scene_copy_slice( &world.foliage, &world.sm_foliage_alphatest );
290
291 world_add_all_if_material( midentity, &world.foliage, mworld, mat_graffiti );
292 scene_copy_slice( &world.foliage, &world.sm_graffiti );
293
294
295 vg_acquire_thread_sync();
296 {
297 scene_upload( &world.foliage );
298
299 /*
300 * Rendering the depth map
301 */
302 m4x4f ortho;
303 m4x3f camera;
304
305 v3f extent;
306 v3_sub( world.geo.bbx[1], world.geo.bbx[0], extent );
307
308 float fl = world.geo.bbx[0][0],
309 fr = world.geo.bbx[1][0],
310 fb = world.geo.bbx[0][2],
311 ft = world.geo.bbx[1][2],
312 rl = 1.0f / (fr-fl),
313 tb = 1.0f / (ft-fb);
314
315 m4x4_zero( ortho );
316 ortho[0][0] = 2.0f * rl;
317 ortho[2][1] = 2.0f * tb;
318 ortho[3][0] = (fr + fl) * -rl;
319 ortho[3][1] = (ft + fb) * -tb;
320 ortho[3][3] = 1.0f;
321 m4x3_identity( camera );
322
323 glViewport( 0, 0, 1024, 1024 );
324 glDisable(GL_DEPTH_TEST);
325 glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_depthmap );
326 shader_fscolour_use();
327 shader_fscolour_uColour( (v4f){-9999.0f,-9999.0f,-9999.0f,-9999.0f} );
328 render_fsquad();
329
330 glEnable(GL_BLEND);
331 glBlendFunc(GL_ONE, GL_ONE);
332 glBlendEquation(GL_MAX);
333 render_world_depth( ortho, camera );
334 glDisable(GL_BLEND);
335 glEnable(GL_DEPTH_TEST);
336 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
337
338
339 /*
340 * TODO: World settings entity
341 */
342 struct ub_world_lighting *winfo = &gpipeline.ub_world_lighting;
343 v4_copy( wrender.plane, winfo->g_water_plane );
344
345 v4f bounds;
346 bounds[0] = world.geo.bbx[0][0];
347 bounds[1] = world.geo.bbx[0][2];
348 bounds[2] = 1.0f/ (world.geo.bbx[1][0]-world.geo.bbx[0][0]);
349 bounds[3] = 1.0f/ (world.geo.bbx[1][2]-world.geo.bbx[0][2]);
350 v4_copy( bounds, winfo->g_depth_bounds );
351
352 winfo->g_water_fog = 0.04f;
353 render_update_lighting_ub();
354 }
355
356 vg_release_thread_sync();
357
358 world_routes_loadfrom( mworld );
359
360 for( int i=0; i<world.instance_cache_count; i++ )
361 vg_free( world.instance_cache[i].mdl );
362
363 vg_free( world.instance_cache );
364 vg_free( mworld );
365 scene_free_offline_buffers( &world.foliage );
366
367 /*
368 * Setup scene collider
369 */
370 v3_zero( world.rb_geo.co );
371 q_identity( world.rb_geo.q );
372
373 world.rb_geo.type = k_rb_shape_scene;
374 world.rb_geo.inf.scene.pscene = &world.geo;
375 world.rb_geo.is_world = 1;
376 rb_init( &world.rb_geo );
377 }
378
379 #endif /* WORLD_GEN_H */