Notices & clean
[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 static int ray_world( v3f pos, v3f dir, ray_hit *hit );
8
9 #ifndef WORLD_H
10 #define WORLD_H
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 "lighting.h"
21 #include "model.h"
22
23 #include "traffic.h" /*TODO: -> world_traffic.h */
24
25 #include "shaders/terrain.h"
26 #include "shaders/sky.h"
27 #include "shaders/planeinf.h"
28 #include "shaders/standard.h"
29 #include "shaders/vblend.h"
30 #include "shaders/gpos.h"
31 #include "shaders/fscolour.h"
32 #include "shaders/alphatest.h"
33
34 enum { k_max_ui_segments = 8 };
35 enum { k_max_ui_splits_per_segment = 16 };
36
37 enum { k_max_ui_elements = k_max_ui_segments*k_max_ui_splits_per_segment };
38 enum { k_max_element_verts = 10 };
39 enum { k_max_element_indices = 20 };
40
41 enum { k_route_ui_max_verts = k_max_ui_elements*k_max_element_verts };
42 enum { k_route_ui_max_indices = k_max_ui_elements*k_max_element_indices };
43
44 static struct gworld
45 {
46 struct subworld_gen
47 {
48
49 }
50 subworld_gen;
51
52 /* gameplay */
53 struct respawn_point
54 {
55 v3f co;
56 v4f q;
57 char name[32];
58 }
59 spawns[32];
60 u32 spawn_count;
61
62 struct subworld_routes
63 {
64 struct route_node
65 {
66 v3f co, right, up, h;
67 u32 next[2];
68
69 u32 special_type, special_id, current_refs, ref_count;
70 u32 route_ids[4]; /* Gates can be linked into up to four routes */
71 }
72 *nodes;
73
74 u32 node_count,
75 node_cap;
76
77 struct route
78 {
79 u32 track_id;
80 v4f colour;
81
82 u32 start;
83 mdl_submesh sm;
84
85 int active;
86 float factive;
87
88 double best_lap, latest_pass; /* Session */
89
90 struct
91 {
92 GLuint vao, vbo, ebo;
93
94 u32 indices_head;
95 u32 vertex_head;
96
97 float last_notch;
98
99 struct route_ui_segment
100 {
101 float length;
102 u32 vertex_start, vertex_count,
103 index_start, index_count, notches;
104 }
105 segments[k_max_ui_segments];
106
107 u32 segment_start, segment_count, fade_start, fade_count;
108 double fade_timer_start;
109 float xpos;
110 }
111 ui;
112
113 m4x3f scoreboard_transform;
114 }
115 *routes;
116
117 double last_interaction;
118
119 u32 route_count,
120 route_cap;
121
122 struct route_gate
123 {
124 struct teleport_gate
125 {
126 v3f co[2];
127 v4f q[2];
128 v2f dims;
129
130 m4x3f to_world, recv_to_world, transport;
131 }
132 gate;
133
134 u32 node_id;
135
136 struct route_timing
137 {
138 u32 version; /* Incremented on every teleport */
139 double time;
140 }
141 timing;
142 }
143 *gates;
144
145 struct route_collector
146 {
147 struct route_timing timing;
148 }
149 *collectors;
150
151 u32 gate_count,
152 gate_cap,
153 collector_count,
154 collector_cap;
155
156 u32 active_gate,
157 current_run_version;
158
159 scene scene_lines;
160 }
161 routes;
162
163 struct subworld_sfd
164 {
165 scene mesh;
166 mdl_submesh *sm_module, *sm_card;
167 glmesh temp;
168
169 struct sfd_instance
170 {
171 float *buffer;
172
173 u32 w,h;
174 }
175 tester;
176 }
177 sfd;
178
179 /* Paths */
180 traffic_node traffic[128];
181 u32 traffic_count;
182
183 #if 0
184 traffic_driver van_man[6];
185 #endif
186
187 /* Physics */
188
189 /* Rendering & geometry */
190 scene geo, foliage;
191 rigidbody rb_geo;
192
193 /* TODO Maybe make this less hardcoded */
194 mdl_submesh sm_geo_std_oob, sm_geo_std, sm_geo_vb,
195 sm_foliage_main, sm_foliage_alphatest,
196 sm_graffiti, sm_subworld, sm_terrain;
197
198 glmesh skybox, skydome;
199 mdl_submesh dome_upper, dome_lower;
200
201 glmesh cars;
202 mdl_submesh car_holden;
203
204 /* Load time */
205
206 struct instance_cache
207 {
208 mdl_header *mdl;
209 u32 pstr_file;
210 }
211 * instance_cache;
212 u32 instance_cache_count,
213 instance_cache_cap;
214
215 v3f render_gate_pos;
216 int active_route_board;
217 }
218 world;
219
220 /*
221 * API
222 */
223
224 static int ray_hit_is_ramp( ray_hit *hit );
225 static int ray_hit_is_terrain( ray_hit *hit );
226 static void ray_world_get_tri( ray_hit *hit, v3f tri[3] );
227 static int ray_world( v3f pos, v3f dir, ray_hit *hit );
228
229 /*
230 * Submodules
231 */
232 #include "world_routes.h"
233 #include "world_sfd.h"
234 #include "world_render.h"
235 #include "world_water.h"
236 #include "world_gen.h"
237 #include "world_gate.h"
238
239 /*
240 * -----------------------------------------------------------------------------
241 * Events
242 * -----------------------------------------------------------------------------
243 */
244
245 static void world_init(void)
246 {
247 shader_terrain_register();
248 shader_sky_register();
249 shader_planeinf_register();
250 shader_gpos_register();
251 shader_fscolour_register();
252 shader_alphatest_register();
253
254 vg_info( "Loading world resources\n" );
255
256 VG_REQUIRED_ASSET( mdl_header*, mcars, mdl_load, "models/rs_cars.mdl" );
257 VG_REQUIRED_ASSET( mdl_header*, msky, mdl_load, "models/rs_skydome.mdl" );
258
259 mdl_node *nholden = mdl_node_from_name( mcars, "holden" );
260 world.car_holden = *mdl_node_submesh( mcars, nholden, 0 );
261
262 mdl_node *nlower = mdl_node_from_name( msky, "dome_lower" ),
263 *nupper = mdl_node_from_name( msky, "dome_upper" );
264
265 world.dome_lower = *mdl_node_submesh( msky, nlower, 0 );
266 world.dome_upper = *mdl_node_submesh( msky, nupper, 0 );
267
268 vg_acquire_thread_sync();
269 {
270 mdl_unpack_glmesh( mcars, &world.cars );
271 mdl_unpack_glmesh( msky, &world.skydome );
272 }
273 vg_release_thread_sync();
274
275 vg_free(mcars);
276 vg_free(msky);
277
278 /* Other systems */
279 vg_info( "Loading other world systems\n" );
280
281 vg_loader_highwater( world_render_init, world_render_free, NULL );
282 vg_loader_highwater( world_sfd_init, world_sfd_free, NULL );
283 vg_loader_highwater( world_water_init, world_water_free, NULL );
284 vg_loader_highwater( world_gates_init, world_gates_free, NULL );
285 vg_loader_highwater( world_routes_init, world_routes_free, NULL );
286 }
287
288 static void world_free( void *_ )
289 {
290 mesh_free( &world.cars );
291 mesh_free( &world.skydome );
292 }
293
294 static void world_update( v3f pos )
295 {
296 world_routes_update();
297 world_routes_debug();
298
299 int closest = 0;
300 float min_dist = INFINITY;
301
302 for( int i=0; i<world.routes.route_count; i++ )
303 {
304 float d = v3_dist2( world.routes.routes[i].scoreboard_transform[3], pos );
305
306 if( d < min_dist )
307 {
308 min_dist = d;
309 closest = i;
310 }
311 }
312
313 if( (world.active_route_board != closest) || network_scores_updated )
314 {
315 network_scores_updated = 0;
316 world.active_route_board = closest;
317 struct subworld_sfd *sfd = &world.sfd;
318
319 struct route *route = &world.routes.routes[closest];
320
321 u32 id = route->track_id;
322
323 if( id != 0xffffffff )
324 {
325 struct netmsg_board *local_board = &scoreboard_client_data.boards[id];
326
327 for( int i=0; i<13; i++ )
328 {
329 sfd_encode( &sfd->tester, i, &local_board->data[27*i] );
330 }
331 }
332 }
333
334 sfd_update( &world.sfd.tester );
335 }
336
337 /*
338 * -----------------------------------------------------------------------------
339 * API implementation
340 * -----------------------------------------------------------------------------
341 */
342
343 static void ray_world_get_tri( ray_hit *hit, v3f tri[3] )
344 {
345 for( int i=0; i<3; i++ )
346 v3_copy( world.geo.verts[ hit->tri[i] ].co, tri[i] );
347 }
348
349 static int ray_world( v3f pos, v3f dir, ray_hit *hit )
350 {
351 return scene_raycast( &world.geo, pos, dir, hit );
352 }
353
354 static int ray_hit_is_terrain( ray_hit *hit )
355 {
356 u32 valid_start = 0,
357 valid_end = world.sm_terrain.vertex_count;
358
359 return (hit->tri[0] >= valid_start) &&
360 (hit->tri[0] < valid_end);
361 }
362
363 static int ray_hit_is_ramp( ray_hit *hit )
364 {
365 u32 valid_start = world.sm_geo_std.vertex_start,
366 valid_end = world.sm_geo_vb.vertex_start;
367
368 return (hit->tri[0] >= valid_start) &&
369 (hit->tri[0] < valid_end);
370 }
371
372 #endif /* WORLD_H */