i hope your hapy
[carveJwlIkooP6JGAAIwe30JlM.git] / world.h
1 /*
2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
3 */
4
5 #include "common.h"
6
7 #ifndef WORLD_H
8 #define WORLD_H
9
10 typedef struct world_instance world_instance;
11
12 #include "vg/vg_loader.h"
13
14 #include "network.h"
15 #include "network_msg.h"
16 #include "scene.h"
17 #include "render.h"
18 #include "rigidbody.h"
19 #include "bvh.h"
20 #include "model.h"
21
22 #include "shaders/scene_standard.h"
23 #include "shaders/scene_standard_alphatest.h"
24 #include "shaders/scene_vertex_blend.h"
25 #include "shaders/scene_terrain.h"
26 #include "shaders/scene_depth.h"
27 #include "shaders/scene_position.h"
28
29 #include "shaders/model_sky.h"
30
31 typedef struct teleport_gate teleport_gate;
32
33 enum { k_max_ui_segments = 8 };
34
35 enum { k_max_ui_elements = k_max_ui_segments };
36 enum { k_max_element_verts = 10 };
37 enum { k_max_element_indices = 20 };
38
39 enum { k_route_ui_max_verts = k_max_ui_elements*k_max_element_verts };
40 enum { k_route_ui_max_indices = k_max_ui_elements*k_max_element_indices };
41
42 enum logic_type
43 {
44 k_logic_type_relay = 1,
45 k_logic_type_chance = 2,
46 k_logic_type_achievement = 3
47 };
48
49 enum geo_type
50 {
51 k_geo_type_solid = 0,
52 k_geo_type_nonsolid = 1,
53 k_geo_type_water = 2
54 };
55
56 static const float k_light_cube_size = 8.0f;
57
58 struct world_instance
59 {
60 /* This is a small flag we use to changelevel.
61 * It will not be cleared until all sounds stop playing
62 */
63
64 /* Fixed items
65 * -------------------------------------------------------
66 */
67
68 char world_name[ 64 ];
69
70 struct
71 {
72 boxf depthbounds;
73 int depth_computed;
74
75 float height;
76 int enabled;
77 v4f plane;
78 }
79 water;
80
81 /* STD140 */
82 struct ub_world_lighting
83 {
84 v4f g_cube_min,
85 g_cube_inv_range;
86
87 v4f g_water_plane,
88 g_depth_bounds;
89
90 v4f g_daysky_colour;
91 v4f g_nightsky_colour;
92 v4f g_sunset_colour;
93 v4f g_ambient_colour;
94 v4f g_sunset_ambient;
95 v4f g_sun_colour;
96 v4f g_sun_dir;
97
98 float g_water_fog;
99 float g_time;
100 float g_realtime;
101 float g_shadow_length;
102 float g_shadow_spread;
103
104 float g_time_of_day;
105 float g_day_phase;
106 float g_sunset_phase;
107
108 int g_light_preview;
109 int g_shadow_samples;
110
111 int g_debug_indices;
112 int g_debug_complexity;
113 }
114 ub_lighting;
115 GLuint ubo_lighting;
116 int ubo_bind_point;
117
118 GLuint tbo_light_entities,
119 tex_light_entities,
120 tex_light_cubes;
121
122 v3i light_cubes;
123
124 struct framebuffer heightmap;
125
126 /*
127 * Dynamically allocated when world_load is called.
128 *
129 * the following arrays index somewhere into this linear
130 * allocator
131 *
132 * (world_gen.h)
133 * --------------------------------------------------------------------------
134 */
135 /*
136 * Main world .mdl
137 */
138 mdl_context meta;
139
140 GLuint *textures;
141 u32 texture_count;
142
143 struct world_surface
144 {
145 mdl_material info;
146 mdl_submesh sm_geo,
147 sm_no_collide;
148 }
149 * surfaces;
150 u32 surface_count;
151
152 mdl_array_ptr ent_spawn,
153 ent_gate,
154 ent_light,
155 ent_route_node,
156 ent_path_index,
157 ent_checkpoint,
158 ent_route;
159
160 #if 0
161 /*
162 * Named safe places to respawn
163 */
164 struct respawn_point
165 {
166 v3f co;
167 v4f q;
168 const char *name;
169 }
170 * spawns;
171 u32 spawn_count;
172
173 /*
174 * Audio player entities
175 */
176 struct world_audio_thing
177 {
178 v3f pos;
179 float volume, range;
180 u32 flags;
181 audio_clip temp_embedded_clip;
182 }
183 * audio_things;
184 u32 audio_things_count;
185
186 struct soundscape
187 {
188 /* locking */
189 audio_channel *channels[4];
190
191 /* accessable without locking */
192 v3f spawn_position;
193
194 u32 usage_count;
195 u32 max_instances;
196 u32 allow_transitions;
197 float transition_duration;
198 const char *label;
199 }
200 * soundscapes;
201 u32 soundscape_count;
202
203 /*
204 * Box volume entities
205 */
206 struct world_volume
207 {
208 m4x3f transform, inv_transform;
209 mdl_node *node;
210 }
211 * volumes;
212 u32 volume_count;
213
214 /*
215 * Lights
216 */
217 struct world_light
218 {
219 mdl_node *node;
220 struct classtype_world_light *inf;
221 m4x3f inverse_world;
222 v2f angle_sin_cos;
223 }
224 * lights;
225 u32 light_count;
226
227 /*
228 * Routes (world_routes.h)
229 * --------------------------------------------------------------------------
230 */
231
232 struct route_node
233 {
234 v3f co, right, up, h;
235 u32 next[2];
236
237 u32 special_type, special_id, current_refs, ref_count;
238 u32 route_ids[4]; /* Gates can be linked into up to four routes */
239 }
240 *nodes;
241 u32 node_count;
242
243 struct route
244 {
245 u32 track_id;
246 v4f colour;
247
248 u32 start;
249 mdl_submesh sm;
250
251 int active;
252 float factive;
253
254 double best_lap, latest_pass; /* Session */
255
256 m4x3f scoreboard_transform;
257 }
258 *routes;
259 u32 route_count;
260
261 struct route_gate
262 {
263 struct teleport_gate
264 {
265 v3f co[2];
266 v4f q[2];
267 v2f dims;
268
269 m4x3f to_world, transport;
270 }
271 gate;
272
273 u32 node_id;
274
275 struct route_timing
276 {
277 u32 version; /* Incremented on every teleport */
278 double time;
279 }
280 timing;
281 }
282 *gates;
283 u32 gate_count;
284
285 struct nonlocal_gate
286 {
287 struct teleport_gate gate;
288 mdl_node *node;
289
290 u32 target_map_index, working;
291 }
292 *nonlocal_gates;
293 u32 nonlocalgate_count;
294
295 struct route_collector
296 {
297 struct route_timing timing;
298 }
299 *collectors;
300 u32 collector_count;
301 #endif
302
303
304 /* logic
305 * ----------------------------------------------------
306 */
307
308 /* world geometry */
309 scene *scene_geo,
310 *scene_no_collide,
311 *scene_lines;
312
313 /* spacial mappings */
314 bh_tree *audio_bh,
315 *volume_bh,
316 *geo_bh;
317
318 /* graphics */
319 glmesh mesh_route_lines;
320 glmesh mesh_geo,
321 mesh_no_collide,
322 mesh_water;
323
324 rigidbody rb_geo; /* todo.. ... */
325 };
326
327 VG_STATIC struct world_global
328 {
329 /*
330 * Allocated as system memory
331 * --------------------------------------------------------------------------
332 */
333 void *generic_heap;
334
335 /* rendering */
336 glmesh skydome;
337 glmesh mesh_gate;
338 mdl_submesh sm_gate_surface,
339 sm_gate_marker[4];
340
341 double sky_time, sky_rate, sky_target_rate;
342
343 u32 current_run_version;
344 double time, rewind_from, rewind_to, last_use;
345
346 /* water rendering */
347 struct
348 {
349 struct framebuffer fbreflect, fbdepth;
350 }
351 water;
352
353 /* split flap display */
354 struct
355 {
356 mdl_submesh *sm_module, *sm_card;
357 glmesh mesh_base, mesh_display;
358
359 u32 w, h;
360 float *buffer;
361 }
362 sfd;
363
364 v3f render_gate_pos;
365 int active_route_board;
366 int in_volume;
367
368 int switching_to_new_world;
369
370 world_instance worlds[4];
371 u32 world_count;
372 u32 active_world;
373 }
374 world_global;
375
376 VG_STATIC world_instance *get_active_world( void )
377 {
378 return &world_global.worlds[ world_global.active_world ];
379 }
380
381 /*
382 * API
383 */
384
385 VG_STATIC
386 int ray_hit_is_ramp( world_instance *world, ray_hit *hit );
387
388 VG_STATIC
389 struct world_surface *ray_hit_surface( world_instance *world, ray_hit *hit );
390
391 VG_STATIC
392 void ray_world_get_tri( world_instance *world, ray_hit *hit, v3f tri[3] );
393
394 VG_STATIC
395 int ray_world( world_instance *world, v3f pos, v3f dir, ray_hit *hit );
396
397 /*
398 * Submodules
399 */
400
401 #include "world_routes.h"
402 #include "world_sfd.h"
403 #include "world_render.h"
404 #include "world_water.h"
405 #include "world_volumes.h"
406 #include "world_gen.h"
407 #include "world_gate.h"
408
409 /*
410 * -----------------------------------------------------------------------------
411 * Events
412 * -----------------------------------------------------------------------------
413 */
414
415 VG_STATIC int world_stop_sound( int argc, const char *argv[] )
416 {
417 world_instance *world = get_active_world();
418 return 0;
419 }
420
421 VG_STATIC void world_init(void)
422 {
423 world_global.sky_rate = 1.0;
424 world_global.sky_target_rate = 1.0;
425
426 shader_scene_standard_register();
427 shader_scene_standard_alphatest_register();
428 shader_scene_vertex_blend_register();
429 shader_scene_terrain_register();
430 shader_scene_depth_register();
431 shader_scene_position_register();
432
433 shader_model_sky_register();
434
435 vg_info( "Loading world resources\n" );
436
437 vg_linear_clear( vg_mem.scratch );
438
439 mdl_context msky;
440 mdl_open( &msky, "models/rs_skydome.mdl", vg_mem.scratch );
441 mdl_load_metadata_block( &msky, vg_mem.scratch );
442 mdl_load_mesh_block( &msky, vg_mem.scratch );
443 mdl_close( &msky );
444
445 vg_acquire_thread_sync();
446 {
447 mdl_unpack_glmesh( &msky, &world_global.skydome );
448 }
449 vg_release_thread_sync();
450
451 /* Other systems */
452 vg_info( "Loading other world systems\n" );
453
454 vg_loader_step( world_render_init, NULL );
455 #if 0
456 vg_loader_step( world_sfd_init, NULL );
457 #endif
458 vg_loader_step( world_water_init, NULL );
459 vg_loader_step( world_gates_init, NULL );
460 vg_loader_step( world_routes_init, NULL );
461
462 /* Allocate dynamic world memory arena */
463 u32 max_size = 76*1024*1024;
464 world_global.generic_heap = vg_create_linear_allocator( vg_mem.rtmemory,
465 max_size,
466 VG_MEMORY_SYSTEM );
467 }
468
469 VG_STATIC void world_update( world_instance *world, v3f pos )
470 {
471 /* TEMP!!!!!! */
472 static double g_time = 0.0;
473 g_time += vg.time_delta * (1.0/(k_day_length*60.0));
474
475
476 struct ub_world_lighting *state = &world->ub_lighting;
477
478 state->g_time = g_time;
479 state->g_realtime = vg.time;
480 state->g_debug_indices = k_debug_light_indices;
481 state->g_light_preview = k_light_preview;
482 state->g_debug_complexity = k_debug_light_complexity;
483
484 state->g_time_of_day = vg_fractf( g_time );
485 state->g_day_phase = cosf( state->g_time_of_day * VG_PIf * 2.0f );
486 state->g_sunset_phase= cosf( state->g_time_of_day * VG_PIf * 4.0f + VG_PIf );
487
488 state->g_day_phase = state->g_day_phase * 0.5f + 0.5f;
489 state->g_sunset_phase = powf( state->g_sunset_phase * 0.5f + 0.5f, 6.0f );
490
491 float a = state->g_time_of_day * VG_PIf * 2.0f;
492 state->g_sun_dir[0] = sinf( a );
493 state->g_sun_dir[1] = cosf( a );
494 state->g_sun_dir[2] = 0.2f;
495 v3_normalize( state->g_sun_dir );
496
497
498
499 glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
500 glBufferSubData( GL_UNIFORM_BUFFER, 0,
501 sizeof(struct ub_world_lighting), &world->ub_lighting );
502 /* TEMP!!!!!! */
503
504 world_global.sky_time += world_global.sky_rate * vg.time_delta;
505 world_global.sky_rate = vg_lerp( world_global.sky_rate,
506 world_global.sky_target_rate,
507 vg.time_delta * 5.0 );
508
509 world_routes_update( world );
510 world_routes_debug( world );
511
512 #if 0
513 if( world->route_count > 0 ){
514 int closest = 0;
515 float min_dist = INFINITY;
516
517 for( int i=0; i<world->route_count; i++ )
518 {
519 float d = v3_dist2( world->routes[i].scoreboard_transform[3], pos );
520
521 if( d < min_dist )
522 {
523 min_dist = d;
524 closest = i;
525 }
526 }
527
528 if( (world_global.active_route_board != closest)
529 || network_scores_updated )
530 {
531 network_scores_updated = 0;
532 world_global.active_route_board = closest;
533
534 struct route *route = &world->routes[closest];
535
536 u32 id = route->track_id;
537
538 if( id != 0xffffffff )
539 {
540 struct netmsg_board *local_board =
541 &scoreboard_client_data.boards[id];
542
543 for( int i=0; i<13; i++ )
544 {
545 sfd_encode( i, &local_board->data[27*i] );
546 }
547 }
548 }
549 }
550 #endif
551
552 #if 0
553 /* TODO: Bvh */
554
555 static float random_accum = 0.0f;
556 random_accum += vg.time_delta;
557
558 u32 random_ticks = 0;
559
560 while( random_accum > 0.1f ){
561 random_accum -= 0.1f;
562 random_ticks ++;
563 }
564
565 float radius = 25.0f;
566 boxf volume_proximity;
567 v3_add( pos, (v3f){ radius, radius, radius }, volume_proximity[1] );
568 v3_sub( pos, (v3f){ radius, radius, radius }, volume_proximity[0] );
569
570 bh_iter it;
571 bh_iter_init( 0, &it );
572 int idx;
573
574 int in_volume = 0;
575
576 while( bh_next( world->volume_bh, &it, volume_proximity, &idx ) )
577 {
578 struct world_volume *zone = &world->volumes[idx];
579
580 if( zone->node->classtype == k_classtype_volume_audio )
581 {
582 vg_line_boxf_transformed( zone->transform, (boxf){{-1.0f,-1.0f,-1.0f},
583 { 1.0f, 1.0f, 1.0f}},
584 0xff00c0ff );
585 #if 0
586 for( int j=0; j<random_ticks; j++ )
587 {
588 logic_packet packet;
589 packet.location = zone->target_logic_brick;
590 packet.function = 0;
591
592 packet.type = k_mdl_128bit_datatype_vec3;
593 packet.data._v4f[0] = vg_randf()*2.0f-1.0f;
594 packet.data._v4f[1] = vg_randf()*2.0f-1.0f;
595 packet.data._v4f[2] = vg_randf()*2.0f-1.0f;
596 m4x3_mulv( zone->transform, packet.data._v4f, packet.data._v4f );
597
598 logic_bricks_send_packet( world, &packet );
599 }
600 #endif
601 continue;
602 }
603
604 v3f local;
605 m4x3_mulv( zone->inv_transform, pos, local );
606
607 if( (fabsf(local[0]) <= 1.0f) &&
608 (fabsf(local[1]) <= 1.0f) &&
609 (fabsf(local[2]) <= 1.0f) )
610 {
611 in_volume = 1;
612
613 if( !world_global.in_volume )
614 {
615 #if 0
616 logic_packet packet;
617 packet.location = zone->target_logic_brick;
618 packet.function = 0;
619
620 packet.type = k_mdl_128bit_datatype_vec3;
621 v3_copy( pos, packet.data._v4f );
622
623 logic_bricks_send_packet( world, &packet );
624 #endif
625 }
626
627 vg_line_boxf_transformed( zone->transform, (boxf){{-1.0f,-1.0f,-1.0f},
628 { 1.0f, 1.0f, 1.0f}},
629 0xff00ff00 );
630 }
631 else
632 {
633 vg_line_boxf_transformed( zone->transform, (boxf){{-1.0f,-1.0f,-1.0f},
634 { 1.0f, 1.0f, 1.0f}},
635 0xff0000ff );
636 }
637 }
638 #endif
639
640 #if 0
641 if( k_debug_light_indices )
642 {
643 for( int i=0; i<world->light_count; i++ ){
644 struct world_light *light = &world->lights[i];
645 struct classtype_world_light *inf = light->inf;
646
647 u32 colour = 0xff000000;
648 u8 r = inf->colour[0] * 255.0f,
649 g = inf->colour[1] * 255.0f,
650 b = inf->colour[2] * 255.0f;
651
652 colour |= r;
653 colour |= g << 8;
654 colour |= b << 16;
655
656 vg_line_pt3( light->node->co, 0.25f, colour );
657 }
658 }
659
660 world_global.in_volume = in_volume;
661 #endif
662
663 #if 0
664 sfd_update();
665
666 /* process soundscape transactions */
667 audio_lock();
668 for( int i=0; i<world->soundscape_count; i++ )
669 {
670 struct soundscape *s = &world->soundscapes[i];
671 s->usage_count = 0;
672
673 for( int j=0; j<s->max_instances; j++ )
674 {
675 if( s->channels[j] )
676 {
677 if( audio_channel_finished(s->channels[j]) )
678 s->channels[j] = audio_relinquish_channel( s->channels[j] );
679 else
680 s->usage_count ++;
681 }
682 }
683 }
684 audio_unlock();
685 #endif
686 }
687
688 /*
689 * -----------------------------------------------------------------------------
690 * API implementation
691 * -----------------------------------------------------------------------------
692 */
693
694 VG_STATIC void ray_world_get_tri( world_instance *world,
695 ray_hit *hit, v3f tri[3] )
696 {
697 for( int i=0; i<3; i++ )
698 v3_copy( world->scene_geo->arrvertices[ hit->tri[i] ].co, tri[i] );
699 }
700
701 VG_STATIC int ray_world( world_instance *world,
702 v3f pos, v3f dir, ray_hit *hit )
703 {
704 return scene_raycast( world->scene_geo, world->geo_bh, pos, dir, hit );
705 }
706
707 /*
708 * Cast a sphere from a to b and see what time it hits
709 */
710 VG_STATIC int spherecast_world( world_instance *world,
711 v3f pa, v3f pb, float r, float *t, v3f n )
712 {
713 bh_iter it;
714 bh_iter_init( 0, &it );
715
716 boxf region;
717 box_init_inf( region );
718 box_addpt( region, pa );
719 box_addpt( region, pb );
720
721 v3_add( (v3f){ r, r, r}, region[1], region[1] );
722 v3_add( (v3f){-r,-r,-r}, region[0], region[0] );
723
724 v3f dir;
725 v3_sub( pb, pa, dir );
726
727 v3f dir_inv;
728 dir_inv[0] = 1.0f/dir[0];
729 dir_inv[1] = 1.0f/dir[1];
730 dir_inv[2] = 1.0f/dir[2];
731
732 int hit = -1;
733 float min_t = 1.0f;
734
735 int idx;
736 while( bh_next( world->geo_bh, &it, region, &idx ) )
737 {
738 u32 *ptri = &world->scene_geo->arrindices[ idx*3 ];
739 v3f tri[3];
740
741 boxf box;
742 box_init_inf( box );
743
744 for( int j=0; j<3; j++ )
745 {
746 v3_copy( world->scene_geo->arrvertices[ptri[j]].co, tri[j] );
747 box_addpt( box, tri[j] );
748 }
749
750 v3_add( (v3f){ r, r, r}, box[1], box[1] );
751 v3_add( (v3f){-r,-r,-r}, box[0], box[0] );
752
753 if( !ray_aabb1( box, pa, dir_inv, 1.0f ) )
754 continue;
755
756 float t;
757 v3f n1;
758 if( spherecast_triangle( tri, pa, dir, r, &t, n1 ) )
759 {
760 if( t < min_t )
761 {
762 min_t = t;
763 hit = idx;
764 v3_copy( n1, n );
765 }
766 }
767 }
768
769 *t = min_t;
770 return hit;
771 }
772
773 VG_STATIC
774 struct world_surface *world_tri_index_surface( world_instance *world,
775 u32 index )
776 {
777 for( int i=1; i<world->surface_count; i++ )
778 {
779 struct world_surface *mat = &world->surfaces[i];
780
781 if( (index >= mat->sm_geo.vertex_start) &&
782 (index < mat->sm_geo.vertex_start+mat->sm_geo.vertex_count ) )
783 {
784 return mat;
785 }
786 }
787
788 /* error surface */
789 return &world->surfaces[0];
790 }
791
792 VG_STATIC struct world_surface *world_contact_surface( world_instance *world,
793 rb_ct *ct )
794 {
795 return world_tri_index_surface( world, ct->element_id );
796 }
797
798 VG_STATIC struct world_surface *ray_hit_surface( world_instance *world,
799 ray_hit *hit )
800 {
801 return world_tri_index_surface( world, hit->tri[0] );
802 }
803
804 #endif /* WORLD_H */