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