UFO: Alien Invasion
Loading...
Searching...
No Matches
bsp.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 1997-2001 Id Software, Inc.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "common.h"
27#include "qfiles.h"
28#include "tracing.h"
29#include "routing.h"
30#include "../shared/parse.h"
31
34
35/*
36===============================================================================
37MAP LOADING
38===============================================================================
39*/
40
41static int CMod_ValidateLump (const lump_t* lump, const char* functionName, size_t elementSize, const char* elementName, int elementMaxCount)
42{
43 if (!lump)
44 Com_Error(ERR_DROP, "%s: No lump given", functionName);
45 if (lump->filelen % elementSize)
46 Com_Error(ERR_DROP, "%s: funny lump size (%i => " UFO_SIZE_T ")", functionName, lump->filelen, elementSize);
47 const int count = lump->filelen / elementSize;
48 Com_DPrintf(DEBUG_ENGINE, S_COLOR_GREEN "...%s: %i\n", elementName, count);
49
50 if (count < 1)
51 Com_Error(ERR_DROP, "Map with no %s", elementName);
52 if (count > elementMaxCount)
53 Com_Error(ERR_DROP, "Map has too many %s: %i", elementName, count);
54
55 return count;
56}
57
68static void CMod_LoadSubmodels (MapTile& tile, const byte* base, const lump_t* lump, const vec3_t shift)
69{
70 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(dBspModel_t), "models", MAX_MAP_MODELS);
71
72 const dBspModel_t* in = (const dBspModel_t*) (base + lump->fileofs);
73
75 tile.models = out;
76 tile.nummodels = count;
77
78 for (int i = 0; i < count; i++, in++, out++) {
79 /* Record the shift in case we need to undo it. */
80 VectorCopy(shift, out->shift);
81 /* spread the mins / maxs by a pixel */
83 out->cbmBox.expand(1);
84 out->cbmBox.shift(shift);
85 out->headnode = LittleLong(in->headnode);
86 out->tile = tile.idx; /* backlink to the loaded map tile */
87 }
88}
89
90
97static void CMod_LoadSurfaces (MapTile& tile, const byte* base, const lump_t* lump)
98{
99 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(dBspTexinfo_t), "surfaces", MAX_MAP_TEXINFO);
100
101 const dBspTexinfo_t* in = (const dBspTexinfo_t*) (base + lump->fileofs);
102
104
105 tile.surfaces = out;
106 tile.numtexinfo = count;
107
108 for (int i = 0; i < count; i++, in++, out++) {
109 Q_strncpyz(out->name, in->texture, sizeof(out->name));
111 }
112}
113
114
123static void CMod_LoadNodes (MapTile& tile, const byte* base, const lump_t* lump, const vec3_t shift)
124{
125 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(dBspNode_t), "nodes", MAX_MAP_NODES);
126
127 const dBspNode_t* in = (const dBspNode_t*) (base + lump->fileofs);
128
129 /* add some for the box */
131
132 tile.numnodes = count;
133 tile.nodes = out;
134
135 for (int i = 0; i < count; i++, out++, in++) {
137 out->plane = nullptr;
138 else
139 out->plane = tile.planes + LittleLong(in->planenum);
140
141 /* in case this is a map assemble */
142 for (int j = 0; j < 3; j++) {
143 out->mins[j] = LittleShort(in->mins[j]) + shift[j];
144 out->maxs[j] = LittleShort(in->maxs[j]) + shift[j];
145 }
146
147 for (int j = 0; j < 2; j++) {
148 int child = LittleLong(in->children[j]);
149 out->children[j] = child;
150 }
151 }
152}
153
160static void CMod_LoadBrushes (MapTile& tile, const byte* base, const lump_t* lump)
161{
162 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(dBspBrush_t), "brushes", MAX_MAP_BRUSHES);
163
164 const dBspBrush_t* in = (const dBspBrush_t*) (base + lump->fileofs);
165
166 /* add some for the box */
168
169 tile.numbrushes = count;
170 tile.brushes = out;
171
172 for (int i = 0; i < count; i++, out++, in++) {
174 out->numsides = LittleLong(in->numsides);
176 }
177}
178
185static void CMod_LoadLeafs (MapTile& tile, const byte* base, const lump_t* lump)
186{
187 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(dBspLeaf_t), "leafs", MAX_MAP_LEAFS);
188
189 const dBspLeaf_t* in = (const dBspLeaf_t*) (base + lump->fileofs);
190
191 /* add some for the box */
193
194 tile.numleafs = count;
195 tile.leafs = out;
196
197 for (int i = 0; i < count; i++, in++, out++) {
201 }
202
203 if (tile.leafs[0].contentFlags != CONTENTS_SOLID)
204 Com_Error(ERR_DROP, "Map leaf 0 is not CONTENTS_SOLID");
205 tile.emptyleaf = -1;
206 for (int i = 1; i < tile.numleafs; i++) {
207 if (!tile.leafs[i].contentFlags) {
208 tile.emptyleaf = i;
209 break;
210 }
211 }
212 if (tile.emptyleaf == -1)
213 Com_Error(ERR_DROP, "Map does not have an empty leaf");
214}
215
224static void CMod_LoadPlanes (MapTile& tile, const byte* base, const lump_t* lump, const vec3_t shift)
225{
226 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(dBspPlane_t), "planes", MAX_MAP_PLANES);
227
228 const dBspPlane_t* in = (const dBspPlane_t*) (base + lump->fileofs);
229
230 /* add some for the box */
232
233 tile.numplanes = count;
234 tile.planes = out;
235
236 for (int i = 0; i < count; i++, in++, out++) {
237 out->dist = LittleFloat(in->dist);
238 out->type = LittleLong(in->type);
239
240 /* load normals and shift (map assembly) */
241 for (int j = 0; j < 3; j++) {
242 out->normal[j] = LittleFloat(in->normal[j]);
243 out->dist += out->normal[j] * shift[j];
244 }
245 }
246}
247
254static void CMod_LoadLeafBrushes (MapTile& tile, const byte* base, const lump_t* lump)
255{
256 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(unsigned short), "leafbrushes", MAX_MAP_LEAFBRUSHES);
257
258 const unsigned short* in = (const unsigned short*) (base + lump->fileofs);
259
260 /* add some for the box */
261 unsigned short* out = Mem_PoolAllocTypeN(unsigned short, count + 1, com_cmodelSysPool);
262
263 tile.numleafbrushes = count;
264 tile.leafbrushes = out;
265
266 for (int i = 0; i < count; i++, in++, out++)
267 *out = LittleShort(*in);
268}
269
276static void CMod_LoadBrushSides (MapTile& tile, const byte* base, const lump_t* lump)
277{
278 const int count = CMod_ValidateLump(lump, __FUNCTION__, sizeof(dBspBrushSide_t), "brushsides", MAX_MAP_BRUSHSIDES);
279
280 const dBspBrushSide_t* in = (const dBspBrushSide_t*) (base + lump->fileofs);
281
282 /* add some for the box */
284
285 tile.numbrushsides = count;
286 tile.brushsides = out;
287
288 for (int i = 0; i < count; i++, in++, out++) {
289 const int num = LittleShort(in->planenum);
290 const int j = LittleShort(in->texinfo);
291 if (j >= tile.numtexinfo)
292 Com_Error(ERR_DROP, "Bad brushside texinfo");
293 out->plane = &tile.planes[num];
294 out->surface = &tile.surfaces[j];
295 }
296}
297
304static int CMod_DeCompressRouting (const byte** source, byte* dataStart)
305{
306 byte* data_p = dataStart;
307 const byte* src = *source;
308
309 while (*src) {
310 int c;
311
312 if (*src & 0x80) {
313 /* repetitions */
314 c = *src++ & ~0x80;
315 /* Remember that the total bytes that are the same is c + 2 */
316 for (int i = 0; i < c + 2; i++)
317 *data_p++ = *src;
318 src++;
319 } else {
320 /* identities */
321 c = *src++;
322 for (int i = 0; i < c; i++)
323 *data_p++ = *src++;
324 }
325 }
326
327 src++;
328 *source = src;
329
330 return data_p - dataStart;
331}
332
333/*
334===============================================================================
335TRACING NODES
336===============================================================================
337*/
338
345static void CM_MakeTracingNodes (MapTile& tile)
346{
348
349 tile.numtheads = 0;
350 tile.numcheads = 0;
351
352 for (int i = 0; i < tile.nummodels; i++) {
353 if (tile.models[i].headnode == LEAFNODE || tile.models[i].headnode >= tile.numnodes + 6)
354 continue;
355
356 tile.thead[tile.numtheads] = tnode - tile.tnodes;
357 tile.theadlevel[tile.numtheads] = i;
358 tile.numtheads++;
359 assert(tile.numtheads < LEVEL_MAX);
360
361 /* If this level (i) is the last visible level or earlier, then trace it.
362 * Otherwise don't; we have separate checks for entities. */
363 if (i < NUM_REGULAR_MODELS)
364 TR_BuildTracingNode_r(&tile, &tnode, tile.models[i].headnode, i);
365 }
366}
367
380static void CMod_LoadRouting (MapTile& tile, mapData_t* mapData, const byte* base, const char* name, const lump_t* lump, const int sX, const int sY, const int sZ)
381{
383 Routing* tempMap = static_cast<Routing*>(Mem_Alloc(sizeof(Routing)));
384 const int targetLength = sizeof(tile.wpMins) + sizeof(tile.wpMaxs) + sizeof(Routing);
385
386 double start = time(nullptr);
387
388 if (!lump)
389 Com_Error(ERR_DROP, "CMod_LoadRouting: No lump given");
390
391 if (!lump->filelen)
392 Com_Error(ERR_DROP, "CMod_LoadRouting: Map has NO routing lump");
393
394 assert((sX > -(PATHFINDING_WIDTH / 2)) && (sX < (PATHFINDING_WIDTH / 2)));
395 assert((sY > -(PATHFINDING_WIDTH / 2)) && (sY < (PATHFINDING_WIDTH / 2)));
396 assert((sZ >= 0) && (sZ < PATHFINDING_HEIGHT));
397
398 const byte* source = base + lump->fileofs;
399
400 int length = CMod_DeCompressRouting(&source, (byte*)tile.wpMins);
401 length += CMod_DeCompressRouting(&source, (byte*)tile.wpMaxs);
402 length += CMod_DeCompressRouting(&source, (byte*)tempMap);
403
404 if (length != targetLength)
405 Com_Error(ERR_DROP, "CMod_LoadRouting: Map has BAD routing lump; expected %i got %i", targetLength, length);
406
407 /* endian swap possibly necessary */
408 for (int i = 0; i < 3; i++) {
409 tile.wpMins[i] = LittleLong(tile.wpMins[i]);
410 tile.wpMaxs[i] = LittleLong(tile.wpMaxs[i]);
411 }
412
413 Com_DPrintf(DEBUG_ROUTING, "Map:%s Offset:(%i, %i, %i)\n", name, sX, sY, sZ);
414 Com_DPrintf(DEBUG_ROUTING, "wpMins:(%i, %i, %i) wpMaxs:(%i, %i, %i)\n", tile.wpMins[0], tile.wpMins[1],
415 tile.wpMins[2], tile.wpMaxs[0], tile.wpMaxs[1], tile.wpMaxs[2]);
416
417 /* wpMins and wpMaxs have the map size data from the initial build.
418 * Offset this by the given parameters so the stored values are in real coordinates. */
419 tile.wpMins[0] += sX;
420 tile.wpMins[1] += sY;
421 tile.wpMins[2] += sZ;
422 tile.wpMaxs[0] += sX;
423 tile.wpMaxs[1] += sY;
424 tile.wpMaxs[2] += sZ;
425
426 Com_DPrintf(DEBUG_ROUTING, "Shifted wpMins:(%i, %i, %i) wpMaxs:(%i, %i, %i)\n", tile.wpMins[0],
427 tile.wpMins[1], tile.wpMins[2], tile.wpMaxs[0], tile.wpMaxs[1], tile.wpMaxs[2]);
428
429 /* Things that need to be done:
430 * The floor, ceiling, and route data can be copied over from the map.
431 * All data must be regenerated for cells with overlapping content or where new
432 * model data is adjacent to a cell with existing model data. */
433
434 /* Copy the routing information into our master table */
435 const int minX = std::max(tile.wpMins[0], 0);
436 const int minY = std::max(tile.wpMins[1], 0);
437 const int minZ = std::max(tile.wpMins[2], 0);
438 const int maxX = std::min(tile.wpMaxs[0], PATHFINDING_WIDTH - 1);
439 const int maxY = std::min(tile.wpMaxs[1], PATHFINDING_WIDTH - 1);
440 const int maxZ = std::min(tile.wpMaxs[2], PATHFINDING_HEIGHT - 1);
441
442 assert(minX <= maxX);
443 assert(minY <= maxY);
444 assert(minZ <= maxZ);
445
446 Com_DPrintf(DEBUG_ROUTING, "Tile bounds: (%i, %i, %i) to (%i, %i, %i)\n", minX, minY, minZ, maxX, maxY, maxZ);
447 Com_DPrintf(DEBUG_ROUTING, "Source bounds: (%i, %i, %i) to (%i, %i, %i)\n", minX - sX, minY - sY, minZ - sZ,
448 maxX - sX, maxY - sY, maxZ - sZ);
449
451 /* Adjust starting x and y by size to catch large actor cell overlap. */
452 for (int y = minY - size; y <= maxY; y++)
453 for (int x = minX - size; x <= maxX; x++) {
454 /* Just incase x or y start negative. */
455 if (x < 0 || y < 0)
456 continue;
457 for (int z = minZ; z <= maxZ; z++) {
458 mapData->routing.copyPosData(*tempMap, size + 1, x, y, z, sX, sY, sZ);
459 }
460 /* Update the reroute table */
461 if (!mapData->reroute[size][y][x]) {
462 mapData->reroute[size][y][x] = tile.idx + 1;
463 } else {
464 mapData->reroute[size][y][x] = ROUTING_NOT_REACHABLE;
465 }
466 }
467
468 Com_DPrintf(DEBUG_ROUTING, "Done copying data.\n");
469
470 double end = time(nullptr);
471 Com_DPrintf(DEBUG_ROUTING, "Loaded routing for tile %s in %5.1fs\n", name, end - start);
472
473 Mem_Free(tempMap);
474}
475
476
488static void CMod_LoadEntityString (MapTile& tile, const char* entityString, mapData_t* mapData, const byte* base, const lump_t* l, const vec3_t shift)
489{
490 if (!l)
491 Com_Error(ERR_DROP, "CMod_LoadEntityString: No lump given (entitystring: '%s')", entityString ? entityString : "none");
492
493 if (!l->filelen)
494 Com_Error(ERR_DROP, "CMod_LoadEntityString: Map has NO entity lump (offset: %u, length: %u, entitystring: '%s')", l->fileofs, l->filelen, entityString ? entityString : "none");
495
496 if (l->filelen + 1 > MAX_MAP_ENTSTRING)
497 Com_Error(ERR_DROP, "CMod_LoadEntityString: Map has too large entity lump (offset: %u, length: %u, entitystring: '%s')", l->fileofs, l->filelen, entityString ? entityString : "none");
498
499 /* merge entitystring information */
500 const char* es = (const char*) (base + l->fileofs);
501 while (1) {
502 cBspModel_t* model = nullptr;
503 /* parse the opening brace */
504 const char* token = Com_Parse(&es);
505 if (!es)
506 break;
507 if (token[0] != '{')
508 Com_Error(ERR_DROP, "CMod_LoadEntityString: found %s when expecting { (offset: %u, length: %u, remaining: '%s')", token, l->fileofs, l->filelen, es);
509
510 /* new entity */
511 Q_strcat(mapData->mapEntityString, sizeof(mapData->mapEntityString), "{ ");
512
513 /* go through all the dictionary pairs */
514 while (1) {
515 /* parse key */
516 token = Com_Parse(&es);
517 if (token[0] == '}')
518 break;
519 if (!es)
520 Com_Error(ERR_DROP, "CMod_LoadEntityString: EOF without closing brace");
521
522 char keyname[256];
523 Q_strncpyz(keyname, token, sizeof(keyname));
524
525 /* parse value */
526 token = Com_Parse(&es);
527 if (!es)
528 Com_Error(ERR_DROP, "CMod_LoadEntityString: EOF without closing brace");
529
530 if (token[0] == '}')
531 Com_Error(ERR_DROP, "CMod_LoadEntityString: closing brace without data for keyname %s", keyname);
532
533 /* alter value, if needed */
534 if (Q_streq(keyname, "origin")) {
535 /* origins are shifted */
536 vec3_t v;
537 if (sscanf(token, "%f %f %f", &(v[0]), &(v[1]), &(v[2])) != 3)
538 Com_Error(ERR_DROP, "CMod_LoadEntityString: invalid origin token '%s' for keyname %s", token, keyname);
539 VectorAdd(v, shift, v);
540 Q_strcat(mapData->mapEntityString, sizeof(mapData->mapEntityString), "%s \"%f %f %f\" ", keyname, v[0], v[1], v[2]);
541 /* If we have a model, then unadjust it's mins and maxs. */
542 if (model) {
543 VectorSubtract(model->cbmBox.mins, shift, model->cbmBox.mins);
544 VectorSubtract(model->cbmBox.maxs, shift, model->cbmBox.maxs);
545 model = nullptr; /* reset it, or the next origin will shift it again */
546 }
547 } else if (Q_streq(keyname, "model") && token[0] == '*') {
548 /* adapt inline model number */
549 int num = atoi(token + 1);
550 /* Get the model */
551 model = &tile.models[NUM_REGULAR_MODELS + num - 1];
552 /* Now update the model number to reflect prior tiles loaded. */
553 num += mapData->numInline;
554 Q_strcat(mapData->mapEntityString, sizeof(mapData->mapEntityString), "%s *%i ", keyname, num);
555 } else if (Q_streq(keyname, "targetname") || Q_streq(keyname, "target")) {
556 Q_strcat(mapData->mapEntityString, sizeof(mapData->mapEntityString), "%s \"%s-%i\" ", keyname, token, tile.idx);
557 } else {
558 if (Q_streq(keyname, "classname") && Q_streq(token, "worldspawn")) {
559 if (Q_strvalid(entityString))
560 Q_strcat(mapData->mapEntityString, sizeof(mapData->mapEntityString), "%s", entityString);
561 }
562 /* just store key and value */
563 Q_strcat(mapData->mapEntityString, sizeof(mapData->mapEntityString), "%s \"%s\" ", keyname, token);
564 }
565 }
566
567 /* finish entity */
568 Q_strcat(mapData->mapEntityString, sizeof(mapData->mapEntityString), "} ");
569 }
570}
571
576static void CMod_LoadLighting (MapTile& tile, const byte* base, const lump_t* lump)
577{
578 if (lump->filelen == 0)
579 return;
580
582 memcpy(tile.lightdata, base + lump->fileofs, lump->filelen);
583}
584
589static void CM_InitBoxHull (MapTile& tile)
590{
591 tile.box_headnode = tile.numnodes;
592 tile.box_planes = &tile.planes[tile.numplanes];
593 /* sanity check if you only use one maptile => no map assembly */
594 if (tile.idx == 1 && (tile.numnodes + 6 > MAX_MAP_NODES
595 || tile.numbrushes + 1 > MAX_MAP_BRUSHES
598 || tile.numplanes + 12 > MAX_MAP_PLANES))
599 Com_Error(ERR_DROP, "Not enough room for box tree");
600
601 tile.box_brush = &tile.brushes[tile.numbrushes];
602 tile.box_brush->numsides = 6;
605
606 tile.box_leaf = &tile.leafs[tile.numleafs];
609 tile.box_leaf->numleafbrushes = 1;
610
611 tile.leafbrushes[tile.numleafbrushes] = tile.numbrushes;
612
613 /* each side */
614 for (int i = 0; i < 6; i++) {
615 const int side = i & 1;
616
617 /* brush sides */
618 cBspBrushSide_t* s = &tile.brushsides[tile.numbrushsides + i];
619 s->plane = tile.planes + (tile.numplanes + i * 2 + side);
620 s->surface = &nullSurface;
621
622 /* nodes */
623 cBspNode_t* c = &tile.nodes[tile.box_headnode + i];
624 c->plane = tile.planes + (tile.numplanes + i * 2);
625 c->children[side] = -1 - tile.emptyleaf;
626 if (i != 5)
627 c->children[side ^ 1] = tile.box_headnode + i + 1;
628 else
629 c->children[side ^ 1] = LEAFNODE - tile.numleafs;
630
631 /* planes */
632 cBspPlane_t* p = &tile.box_planes[i * 2];
633 p->type = i >> 1;
635 p->normal[i >> 1] = 1;
636
637 p = &tile.box_planes[i * 2 + 1];
638 p->type = PLANE_ANYX + (i >> 1);
640 p->normal[i >> 1] = -1;
641 }
642}
643
644void CM_LoadBsp (MapTile& tile, const dBspHeader_t& header, const vec3_t shift, const byte* base)
645{
646 /* load into heap */
647 CMod_LoadSurfaces(tile, base, &header.lumps[LUMP_TEXINFO]);
648 CMod_LoadLeafs(tile, base, &header.lumps[LUMP_LEAFS]);
649 CMod_LoadLeafBrushes(tile, base, &header.lumps[LUMP_LEAFBRUSHES]);
650 CMod_LoadPlanes(tile, base, &header.lumps[LUMP_PLANES], shift);
651 CMod_LoadBrushes(tile, base, &header.lumps[LUMP_BRUSHES]);
652 CMod_LoadBrushSides(tile, base, &header.lumps[LUMP_BRUSHSIDES]);
653 CMod_LoadSubmodels(tile, base, &header.lumps[LUMP_MODELS], shift);
654 CMod_LoadNodes(tile, base, &header.lumps[LUMP_NODES], shift);
655}
656
674static void CM_AddMapTile (const char* name, const char* entityString, const bool day, const int sX, const int sY, const byte sZ, mapData_t* mapData, mapTiles_t* mapTiles)
675{
676 Com_DPrintf(DEBUG_ENGINE, "CM_AddMapTile: %s at %i,%i,%i\n", name, sX, sY, sZ);
677 assert(name);
678 assert(name[0]);
679 assert((sX > -(PATHFINDING_WIDTH / 2)) && (sX < (PATHFINDING_WIDTH / 2)));
680 assert((sY > -(PATHFINDING_WIDTH / 2)) && (sY < (PATHFINDING_WIDTH / 2)));
681 assert(sZ < PATHFINDING_HEIGHT);
682
683 /* load the file */
684 char filename[MAX_QPATH];
685 Com_sprintf(filename, sizeof(filename), "maps/%s.bsp", name);
686 byte* buf;
687 const int length = FS_LoadFile(filename, &buf);
688 if (!buf)
689 Com_Error(ERR_DROP, "Couldn't load %s", filename);
690
691 const unsigned checksum = LittleLong(Com_BlockChecksum(buf, length));
692
693 dBspHeader_t header = *(dBspHeader_t*) buf;
694 BSP_SwapHeader(&header, filename);
695
696 if (header.version != BSPVERSION)
697 Com_Error(ERR_DROP, "CM_AddMapTile: %s has wrong version number (%i should be %i)", name, header.version, BSPVERSION);
698
699 const byte* base = (const byte*) buf;
700
701 /* init */
702 if (mapTiles->numTiles >= MAX_MAPTILES)
703 Com_Error(ERR_FATAL, "CM_AddMapTile: too many tiles loaded %i", mapTiles->numTiles);
704
705 MapTile& tile = mapTiles->mapTiles[mapTiles->numTiles];
706 OBJZERO(tile);
707 tile.idx = mapTiles->numTiles;
708 Q_strncpyz(tile.name, name, sizeof(tile.name));
709
710 /* use for random map assembly for shifting origins and so on */
712 /* pathfinding and the like must be shifted on the worldplane when we
713 * are assembling a map */
714 VectorSet(shift, sX * UNIT_SIZE, sY * UNIT_SIZE, sZ * UNIT_HEIGHT);
715
716 CM_LoadBsp(tile, header, shift, base);
717 CMod_LoadEntityString(tile, entityString, mapData, base, &header.lumps[LUMP_ENTITIES], shift);
718 if (day)
719 CMod_LoadLighting(tile, base, &header.lumps[LUMP_LIGHTING_DAY]);
720 else
721 CMod_LoadLighting(tile, base, &header.lumps[LUMP_LIGHTING_NIGHT]);
722
723 CM_InitBoxHull(tile);
725
726 mapData->numInline += tile.nummodels - NUM_REGULAR_MODELS;
727
728 CMod_LoadRouting(tile, mapData, base, name, &header.lumps[LUMP_ROUTING], sX, sY, sZ);
729
730 /* now increase the amount of loaded tiles */
731 mapTiles->numTiles++;
732
733 /* Now find the map bounds with the updated numTiles. */
734 /* calculate new border after merge */
736
738
739 mapData->mapChecksum += checksum;
740}
741
746{
747 int x, y, z;
748 int cols = 0;
749 /* stopwatch */
750 const double start = time(nullptr);
751
752 GridBox rBox(mapData->mapBox); /* the box we will actually reroute */
753 rBox.clipToMaxBoundaries();
754
755 /* First, close the borders of the map. This is needed once we produce tiles with open borders.
756 * It's done by setting the connection (height) to 0 */
757 for (actorSizeEnum_t actorSize = 1; actorSize <= ACTOR_MAX_SIZE; actorSize++) {
758 for (z = rBox.getMinZ(); z <= rBox.getMaxZ(); z++) {
759 for (y = rBox.getMinY(); y <= rBox.getMaxY(); y++) {
760 x = rBox.getMinX();
761 mapData->routing.setConn(actorSize, x, y, z, 6, 0); /* NX-PY */
762 mapData->routing.setConn(actorSize, x, y, z, 1, 0); /* NX */
763 mapData->routing.setConn(actorSize, x, y, z, 5, 0); /* NX-NY */
764 x = rBox.getMaxX();
765 mapData->routing.setConn(actorSize, x, y, z, 4, 0); /* PX-PY */
766 mapData->routing.setConn(actorSize, x, y, z, 0, 0); /* PX */
767 mapData->routing.setConn(actorSize, x, y, z, 7, 0); /* PX-NY */
768 }
769 for (x = rBox.getMinX(); x <= rBox.getMaxX(); x++) {
770 y = rBox.getMinY();
771 mapData->routing.setConn(actorSize, x, y, z, 5, 0); /* NY-NX */
772 mapData->routing.setConn(actorSize, x, y, z, 3, 0); /* NY */
773 mapData->routing.setConn(actorSize, x, y, z, 7, 0); /* NY-PX */
774 y = rBox.getMaxY();
775 mapData->routing.setConn(actorSize, x, y, z, 6, 0); /* PY-NX */
776 mapData->routing.setConn(actorSize, x, y, z, 2, 0); /* PY */
777 mapData->routing.setConn(actorSize, x, y, z, 4, 0); /* PY-PX */
778 }
779 }
780 }
781
782 /* Floor pass */
783 for (actorSizeEnum_t actorSize = ACTOR_SIZE_INVALID; actorSize < ACTOR_MAX_SIZE; actorSize++) {
784 for (y = rBox.getMinY(); y <= rBox.getMaxY(); y++) {
785 for (x = rBox.getMinX(); x <= rBox.getMaxX(); x++) {
786 if (mapData->reroute[actorSize][y][x] == ROUTING_NOT_REACHABLE) {
787 cols++;
788 for (z = rBox.getMaxZ(); z >= rBox.getMinZ(); z--) {
789 const int newZ = RT_CheckCell(mapTiles, mapData->routing, actorSize + 1, x, y, z, nullptr);
790 assert(newZ <= z);
791 z = newZ;
792 }
793 }
794 }
795 }
796 }
797
798 /* Wall pass */
799 for (actorSizeEnum_t actorSize = ACTOR_SIZE_INVALID; actorSize < ACTOR_MAX_SIZE; actorSize++) {
800 for (y = rBox.getMinY(); y <= rBox.getMaxY(); y++) {
801 for (x = rBox.getMinX(); x <= rBox.getMaxX(); x++) {
802 const byte tile = mapData->reroute[actorSize][y][x];
803 if (tile) {
804 byte fromTile1 = 0;
805 byte fromTile2 = 0;
806 byte fromTile3 = 0;
807 mapTiles->getTilesAt(x ,y, fromTile1, fromTile2, fromTile3);
808 for (int dir = 0; dir < CORE_DIRECTIONS; dir++) {
809 const int dx = x + dvecs[dir][0];
810 const int dy = y + dvecs[dir][1];
811 /* Skip if the destination is out of bounds. */
812 if (dx < 0 || dx >= PATHFINDING_WIDTH || dy < 0 || dy >= PATHFINDING_WIDTH)
813 continue;
814 const int tile2 = mapData->reroute[actorSize][dy][dx];
815 /* Both cells are present and if either cell is ROUTING_NOT_REACHABLE or if the cells are different. */
816 if (tile2 && (tile2 == ROUTING_NOT_REACHABLE || tile2 != tile)) {
817#if 0 // this causes problems eg. at baseattack entrance (see bug 5292). Disabled until the underlying problem is found
818 byte toTile1 = 0;
819 byte toTile2 = 0;
820 byte toTile3 = 0;
821 mapTiles->getTilesAt(dx ,dy, toTile1, toTile2, toTile3);
822
823 int minZ = 0;
824 int maxZ = PATHFINDING_HEIGHT;
825 if (fromTile1 == toTile1) { /* same tile */
826 if (fromTile2 && toTile2) { /* and there are stacked tiles */
827 if (fromTile2 == toTile2) { /* the stacked tiles are also the same */
828 mapTiles->getTileOverlap(toTile1, toTile2, minZ, maxZ); /* reduce the z-range to reroute */
829 }
830 }
831 }
832 RT_UpdateConnectionColumn(mapTiles, mapData->routing, actorSize + 1, x, y, dir, nullptr, minZ, maxZ);
833#else
834 RT_UpdateConnectionColumn(mapTiles, mapData->routing, actorSize + 1, x, y, dir);
835#endif // 1
836 }
837 }
838 }
839 }
840 }
841 }
842 const double end = time(nullptr);
843 Com_Printf("Rerouted %i cols for RMA in %5.1fs\n", cols, end - start);
844}
845
860void CM_LoadMap (const char* tiles, bool day, const char* pos, const char* entityString, mapData_t* mapData, mapTiles_t* mapTiles)
861{
862 char name[MAX_VAR];
863 char base[MAX_QPATH];
864
866
867 /* init */
868 base[0] = 0;
869
870 /* Reset the map related data */
873
874 /* load tiles */
875 while (tiles) {
876 /* get tile name */
877 const char* token = Com_Parse(&tiles);
878 if (!tiles) {
880 return;
881 }
882
883 /* get base path */
884 if (token[0] == '-') {
885 Q_strncpyz(base, token + 1, sizeof(base));
886 continue;
887 }
888
889 /* get tile name */
890 Com_DPrintf(DEBUG_ENGINE, "CM_LoadMap: token: %s\n", token);
891 if (token[0] == '+')
892 Com_sprintf(name, sizeof(name), "%s%s", base, token + 1);
893 else
894 Q_strncpyz(name, token, sizeof(name));
895
896 if (pos && pos[0]) {
897 ipos3_t sh;
898 /* get position and add a tile */
899 for (int i = 0; i < 3; i++) {
900 token = Com_Parse(&pos);
901 if (!pos)
902 Com_Error(ERR_DROP, "CM_LoadMap: invalid positions");
903 sh[i] = atoi(token);
904 }
905 if (sh[0] <= -(PATHFINDING_WIDTH / 2) || sh[0] >= PATHFINDING_WIDTH / 2)
906 Com_Error(ERR_DROP, "CM_LoadMap: invalid x position given: %i\n", sh[0]);
907 if (sh[1] <= -(PATHFINDING_WIDTH / 2) || sh[1] >= PATHFINDING_WIDTH / 2)
908 Com_Error(ERR_DROP, "CM_LoadMap: invalid y position given: %i\n", sh[1]);
909 if (sh[2] >= PATHFINDING_HEIGHT)
910 Com_Error(ERR_DROP, "CM_LoadMap: invalid z position given: %i\n", sh[2]);
911 CM_AddMapTile(name, entityString, day, sh[0], sh[1], sh[2], mapData, mapTiles);
912 } else {
913 /* load only a single tile, if no positions are specified */
914 CM_AddMapTile(name, entityString, day, 0, 0, 0, mapData, mapTiles);
915 return;
916 }
917 }
918
919 Com_Error(ERR_DROP, "CM_LoadMap: invalid tile names");
920}
921
930{
931 /* we only want inline models here */
932 if (!name || name[0] != '*')
933 Com_Error(ERR_DROP, "CM_InlineModel: bad name: '%s'", name ? name : "");
934 /* skip the '*' character and get the inline model number */
935 int num = atoi(name + 1) - 1;
936 if (num < 0 || num >= MAX_MODELS)
937 Com_Error(ERR_DROP, "CM_InlineModel: bad number %i - max inline models are %i", num, MAX_MODELS);
938
939 /* search all the loaded tiles for the given inline model */
940 for (int i = 0; i < mapTiles->numTiles; i++) {
941 const int models = mapTiles->mapTiles[i].nummodels - NUM_REGULAR_MODELS;
942 assert(models >= 0);
943
944 if (num >= models)
945 num -= models;
946 else
947 return &(mapTiles->mapTiles[i].models[NUM_REGULAR_MODELS + num]);
948 }
949
950 Com_Error(ERR_DROP, "CM_InlineModel: Error cannot find model '%s'\n", name);
951}
952
964{
966 assert(model);
967 VectorCopy(origin, model->origin);
968 VectorCopy(angles, model->angles);
969
970 return model;
971}
972
980{
981 const cBspModel_t* model = CM_InlineModel(mapTiles, name);
982 assert(model);
983 CalculateMinsMaxs(model->angles, model->cbmBox, model->origin, aabb);
984}
985
991float CM_GetVisibility (const mapTiles_t* mapTiles, const pos3_t position)
992{
993 for (int i = 0; i < mapTiles->numTiles; i++) {
994 const MapTile& tile = mapTiles->mapTiles[i];
995 if (VectorInside(position, tile.wpMins, tile.wpMaxs)) {
996 if (tile.lightdata == nullptr)
997 return 1.0f;
999 return 1.0f;
1000 }
1001 }
1002
1003 /* point is outside of any loaded tile */
1004 Com_Printf("given point %i:%i:%i is not inside of any loaded tile\n", position[0], position[1], position[2]);
1005 return 1.0f;
1006}
#define LittleLong(X)
Definition byte.h:37
#define LittleShort(X)
Definition byte.h:35
#define LittleFloat(X)
Definition byte.h:57
Definition aabb.h:42
vec3_t maxs
Definition aabb.h:258
vec3_t mins
Definition aabb.h:257
void setFromLittleFloat(const AABB &other)
Definition aabb.h:87
void shift(const vec3_t shiftVec)
shove the whole box by the given vector
Definition aabb.h:246
void expand(const float byVal)
expand the box in all directions, but clip them to the maximum boundaries
Definition aabb.h:240
pos_t getMinY() const
Definition mathlib.h:177
void clipToMaxBoundaries()
Definition mathlib.h:215
pos_t getMinZ() const
Definition mathlib.h:180
pos_t getMaxY() const
Definition mathlib.h:186
pos_t getMinX() const
Definition mathlib.h:174
pos_t getMaxX() const
Definition mathlib.h:183
pos_t getMaxZ() const
Definition mathlib.h:189
Stores the data of a map tile, mostly the BSP stuff.
Definition typedefs.h:85
int numbrushes
Definition typedefs.h:112
cBspPlane_t * planes
Definition typedefs.h:97
int numcheads
Definition typedefs.h:127
int box_headnode
Definition typedefs.h:117
cBspModel_t * models
Definition typedefs.h:110
int numtexinfo
Definition typedefs.h:93
int emptyleaf
Definition typedefs.h:104
char name[MAX_QPATH]
Definition typedefs.h:87
int numleafs
Definition typedefs.h:102
int numtheads
Definition typedefs.h:123
int idx
Definition typedefs.h:88
int numbrushsides
Definition typedefs.h:90
byte * lightdata
Definition typedefs.h:134
int numleafbrushes
Definition typedefs.h:106
cBspBrush_t * box_brush
Definition typedefs.h:118
cBspNode_t * nodes
Definition typedefs.h:100
cBspLeaf_t * leafs
Definition typedefs.h:103
int theadlevel[LEVEL_MAX]
Definition typedefs.h:125
cBspPlane_t * box_planes
Definition typedefs.h:116
ipos3_t wpMaxs
Definition typedefs.h:131
cBspSurface_t * surfaces
Definition typedefs.h:94
int nummodels
Definition typedefs.h:109
intptr_t thead[LEVEL_MAX]
Definition typedefs.h:124
tnode_t * tnodes
Definition typedefs.h:122
cBspLeaf_t * box_leaf
Definition typedefs.h:119
int numnodes
Definition typedefs.h:99
int numplanes
Definition typedefs.h:96
unsigned short * leafbrushes
Definition typedefs.h:107
cBspBrushSide_t * brushsides
Definition typedefs.h:91
cBspBrush_t * brushes
Definition typedefs.h:113
ipos3_t wpMins
Definition typedefs.h:130
static void CMod_LoadBrushSides(MapTile &tile, const byte *base, const lump_t *lump)
Definition bsp.cpp:276
void CM_GetInlineModelAABB(mapTiles_t *mapTiles, const char *name, AABB &aabb)
This function calculates a model's aabb in world coordinates.
Definition bsp.cpp:979
static void CMod_LoadLeafBrushes(MapTile &tile, const byte *base, const lump_t *lump)
Definition bsp.cpp:254
static void CMod_LoadPlanes(MapTile &tile, const byte *base, const lump_t *lump, const vec3_t shift)
Definition bsp.cpp:224
static void CMod_LoadSubmodels(MapTile &tile, const byte *base, const lump_t *lump, const vec3_t shift)
Loads brush entities like func_door and func_breakable.
Definition bsp.cpp:68
static void CMod_LoadSurfaces(MapTile &tile, const byte *base, const lump_t *lump)
Definition bsp.cpp:97
static void CM_AddMapTile(const char *name, const char *entityString, const bool day, const int sX, const int sY, const byte sZ, mapData_t *mapData, mapTiles_t *mapTiles)
Adds in a single map tile.
Definition bsp.cpp:674
static void CMod_LoadRouting(MapTile &tile, mapData_t *mapData, const byte *base, const char *name, const lump_t *lump, const int sX, const int sY, const int sZ)
Definition bsp.cpp:380
static void CMod_LoadLighting(MapTile &tile, const byte *base, const lump_t *lump)
Loads the lightmap for server side visibility lookup.
Definition bsp.cpp:576
cBspModel_t * CM_SetInlineModelOrientation(mapTiles_t *mapTiles, const char *name, const vec3_t origin, const vec3_t angles)
This function updates a model's orientation.
Definition bsp.cpp:963
static void CM_MakeTracingNodes(MapTile &tile)
Use the bsp node structure to reconstruct efficient tracing structures that are used for fast visibil...
Definition bsp.cpp:345
void CM_LoadMap(const char *tiles, bool day, const char *pos, const char *entityString, mapData_t *mapData, mapTiles_t *mapTiles)
Loads in the map and all submodels.
Definition bsp.cpp:860
static void CMod_LoadEntityString(MapTile &tile, const char *entityString, mapData_t *mapData, const byte *base, const lump_t *l, const vec3_t shift)
Definition bsp.cpp:488
static int CMod_DeCompressRouting(const byte **source, byte *dataStart)
Definition bsp.cpp:304
float CM_GetVisibility(const mapTiles_t *mapTiles, const pos3_t position)
Checks how well a position is visible.
Definition bsp.cpp:991
static void CMod_LoadBrushes(MapTile &tile, const byte *base, const lump_t *lump)
Definition bsp.cpp:160
void CM_LoadBsp(MapTile &tile, const dBspHeader_t &header, const vec3_t shift, const byte *base)
Definition bsp.cpp:644
cBspModel_t * CM_InlineModel(const mapTiles_t *mapTiles, const char *name)
Searches all inline models and return the cBspModel_t pointer for the given modelnumber or -name.
Definition bsp.cpp:929
static void CMod_RerouteMap(mapTiles_t *mapTiles, mapData_t *mapData)
Recalculate the seams of the tiles after an RMA.
Definition bsp.cpp:745
static void CMod_LoadLeafs(MapTile &tile, const byte *base, const lump_t *lump)
Definition bsp.cpp:185
static void CMod_LoadNodes(MapTile &tile, const byte *base, const lump_t *lump, const vec3_t shift)
Definition bsp.cpp:123
static int CMod_ValidateLump(const lump_t *lump, const char *functionName, size_t elementSize, const char *elementName, int elementMaxCount)
Definition bsp.cpp:41
static void CM_InitBoxHull(MapTile &tile)
Set up the planes and nodes so that the six floats of a bounding box can just be stored out and get a...
Definition bsp.cpp:589
static cBspSurface_t nullSurface
Definition bsp.cpp:33
void RT_GetMapSize(mapTiles_t *mapTiles, AABB &mapBox)
Calculate the map size via model data and store grid size in map_min and map_max. This is done with e...
Definition routing.cpp:253
int RT_CheckCell(mapTiles_t *mapTiles, Routing &routing, const int actorSize, const int x, const int y, const int z, const char **list)
This function looks to see if an actor of a given size can occupy a cell(s) and if so identifies the ...
Definition routing.cpp:360
void RT_UpdateConnectionColumn(mapTiles_t *mapTiles, Routing &routing, const int actorSize, const int x, const int y, const int dir, const char **list, const int minZ, const int maxZ)
Routing Function to update the connection between two fields.
Definition routing.cpp:1292
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition common.cpp:440
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
memPool_t * com_cmodelSysPool
Definition common.cpp:69
definitions common between client and server, but not game lib
#define S_COLOR_GREEN
Definition common.h:219
#define ERR_DROP
Definition common.h:211
#define ERR_FATAL
Definition common.h:210
#define CONTENTS_WEAPONCLIP
Definition defines.h:249
#define LEVEL_MAX
Definition defines.h:353
#define ROUTING_NOT_REACHABLE
Definition defines.h:283
#define LUMP_LEAFS
Definition defines.h:176
#define LUMP_LEAFBRUSHES
Definition defines.h:177
#define LUMP_LIGHTING_NIGHT
Definition defines.h:174
#define ACTOR_MAX_SIZE
Definition defines.h:305
#define MAX_MAP_BRUSHSIDES
Definition defines.h:141
#define MAX_MAP_LEAFS
Definition defines.h:142
#define LUMP_ROUTING
Definition defines.h:170
#define LEAFNODE
Definition defines.h:44
#define LUMP_BRUSHES
Definition defines.h:181
#define MAX_MAP_MODELS
Definition defines.h:134
#define MAX_MAP_TEXINFO
Definition defines.h:138
#define PATHFINDING_WIDTH
absolute max
Definition defines.h:292
#define MAX_MAP_ENTSTRING
Definition defines.h:137
#define DEBUG_ENGINE
Definition defines.h:56
#define LUMP_PLANES
Definition defines.h:168
#define UNIT_HEIGHT
Definition defines.h:122
#define NUM_REGULAR_MODELS
Definition defines.h:354
#define UNIT_SIZE
Definition defines.h:121
#define LUMP_TEXINFO
Definition defines.h:172
#define LUMP_LIGHTING_DAY
Definition defines.h:175
#define LUMP_MODELS
Definition defines.h:180
#define CONTENTS_SOLID
Definition defines.h:223
#define MAX_MAP_NODES
Definition defines.h:140
#define PLANENUM_LEAF
Definition defines.h:45
#define MAX_MAP_LEAFBRUSHES
Definition defines.h:145
#define MAX_MAP_BRUSHES
Definition defines.h:135
#define MAX_MAP_PLANES
Definition defines.h:139
#define PATHFINDING_HEIGHT
15 max, adjusting above 8 will require a rewrite to the DV code
Definition defines.h:294
#define LUMP_BRUSHSIDES
Definition defines.h:182
#define DEBUG_ROUTING
Definition defines.h:66
#define ACTOR_SIZE_INVALID
Definition defines.h:301
#define PLANE_ANYX
Definition defines.h:196
#define LUMP_NODES
Definition defines.h:171
#define LUMP_ENTITIES
Definition defines.h:167
#define MAX_MODELS
Definition defines.h:100
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition files.cpp:384
void FS_FreeFile(void *buffer)
Definition files.cpp:411
#define MAX_QPATH
Definition filesys.h:40
voidpf void uLong size
Definition ioapi.h:42
voidpf uLong int origin
Definition ioapi.h:45
const char * filename
Definition ioapi.h:41
voidpf void * buf
Definition ioapi.h:42
const vec4_t dvecs[PATHFINDING_DIRECTIONS]
Definition mathlib.cpp:58
void CalculateMinsMaxs(const vec3_t angles, const AABB &relBox, const vec3_t origin, AABB &absBox)
Calculates the bounding box in absolute coordinates, also for rotating objects. WARNING: do not use t...
Definition mathlib.cpp:546
#define CORE_DIRECTIONS
Definition mathlib.h:88
unsigned Com_BlockChecksum(const void *buffer, int length)
Definition md4.cpp:202
#define Mem_FreePool(pool)
Definition mem.h:37
#define Mem_PoolAllocTypeN(type, n, pool)
Definition mem.h:42
#define Mem_Free(ptr)
Definition mem.h:35
#define Mem_Alloc(size)
Definition mem.h:40
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Definition parse.cpp:107
Shared parsing functions.
Header for various formats like pak, and model formats as well as bsp format.
#define BSPVERSION
Definition qfiles.h:253
#define BSP_SwapHeader(header, name)
Definition qfiles.h:269
QGL_EXTERN GLuint count
Definition r_gl.h:99
QGL_EXTERN int GLboolean GLfloat * v
Definition r_gl.h:120
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition r_gl.h:110
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
static ipos3_t shift
The shift array is used for random map assemblies (RMA) to shift the mins/maxs and stuff like that.
grid pathfinding and routing
#define Q_strvalid(string)
Definition shared.h:141
#define Q_streq(a, b)
Definition shared.h:136
#define OBJZERO(obj)
Definition shared.h:178
#define MAX_VAR
Definition shared.h:36
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition shared.cpp:475
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
int firstbrushside
Definition typedefs.h:62
uint32_t brushContentFlags
Definition typedefs.h:60
int numsides
Definition typedefs.h:61
cBspSurface_t * surface
Definition typedefs.h:50
cBspPlane_t * plane
Definition typedefs.h:49
unsigned short firstleafbrush
Definition typedefs.h:55
uint32_t contentFlags
Definition typedefs.h:54
unsigned short numleafbrushes
Definition typedefs.h:56
int32_t headnode
Definition typedefs.h:29
vec3_t shift
Definition typedefs.h:28
vec3_t angles
Definition typedefs.h:28
AABB cbmBox
Definition typedefs.h:27
vec3_t origin
Definition typedefs.h:28
int32_t children[2]
Definition typedefs.h:45
vec3_t mins
Definition typedefs.h:44
vec3_t maxs
Definition typedefs.h:44
cBspPlane_t * plane
Definition typedefs.h:43
plane_t structure
Definition typedefs.h:20
byte type
Definition typedefs.h:23
float dist
Definition typedefs.h:22
vec3_t normal
Definition typedefs.h:21
uint32_t surfaceFlags
Definition typedefs.h:39
char name[MAX_QPATH]
Definition typedefs.h:38
int firstbrushside
Definition typedefs.h:435
uint32_t brushContentFlags
Definition typedefs.h:437
uint16_t planenum
Definition typedefs.h:429
The BSP header definition with the data block directory.
Definition qfiles.h:262
uint32_t version
Definition qfiles.h:264
lump_t lumps[HEADER_LUMPS]
Definition qfiles.h:265
convex region of space in the BSP tree
Definition typedefs.h:416
uint16_t numleafbrushes
Definition typedefs.h:425
uint32_t contentFlags
Definition typedefs.h:417
uint16_t firstleafbrush
Definition typedefs.h:424
int32_t headnode
Definition typedefs.h:357
AABB dbmBox
Definition typedefs.h:355
int32_t planenum
Definition typedefs.h:379
short maxs[3]
Definition typedefs.h:382
short mins[3]
Definition typedefs.h:381
int32_t children[2]
Definition typedefs.h:380
vec3_t normal
Definition typedefs.h:373
float dist
Definition typedefs.h:374
char texture[32]
Definition typedefs.h:392
uint32_t surfaceFlags
Definition typedefs.h:390
Directory of the different data blocks.
Definition qfiles.h:256
uint32_t filelen
Definition qfiles.h:258
uint32_t fileofs
Definition qfiles.h:257
Data for line tracing (?).
Definition typedefs.h:69
static mapTiles_t mapTiles
static mapData_t mapData
void TR_BuildTracingNode_r(TR_TILE_TYPE *tile, tnode_t **tnode, int32_t nodenum, int level)
Definition tracing.cpp:122
Tracing functions.
pos_t pos3_t[3]
Definition ufotypes.h:58
vec_t vec3_t[3]
Definition ufotypes.h:39
ipos_t ipos3_t[3]
Definition ufotypes.h:70
int32_t actorSizeEnum_t
Definition ufotypes.h:77
#define UFO_SIZE_T
Definition ufotypes.h:89
#define VectorClear(a)
Definition vector.h:55
#define VectorSubtract(a, b, dest)
Definition vector.h:45
#define VectorInside(vec, mins, maxs)
Definition vector.h:56
#define VectorCopy(src, dest)
Definition vector.h:51
#define VectorAdd(a, b, dest)
Definition vector.h:47
#define VectorSet(v, x, y, z)
Definition vector.h:59