33#if defined(COMPILE_MAP)
34 #define TR_NODE_TYPE dBspNode_t
35 #define TR_LEAF_TYPE dBspLeaf_t
36 #define TR_BRUSHSIDE_TYPE dBspBrushSide_t
37#elif defined(COMPILE_UFO)
38 #define TR_NODE_TYPE cBspNode_t
39 #define TR_LEAF_TYPE cBspLeaf_t
40 #define TR_BRUSHSIDE_TYPE cBspBrushSide_t
42 #error Either COMPILE_MAP or COMPILE_UFO must be defined in order for tracing.c to work.
46void boxtrace_s::init (TR_TILE_TYPE* _tile,
const int contentmask,
const int brushreject,
const float fraction)
49 trace.surface =
nullptr;
50 contents = contentmask;
51 rejects = brushreject;
53 trace.fraction = std::min(fraction, 1.0f);
57void boxtrace_s::setLineAndBox(
const Line& line,
const AABB& box)
86 TR_NODE_TYPE* node = tile->nodes + nodenum;
89 const TR_PLANE_TYPE* plane = node->plane;
91 const TR_PLANE_TYPE* plane = tile->planes + node->planenum;
94 t->
type = plane->type;
96 t->
dist = plane->dist;
98 for (
int i = 0;
i < 2;
i++) {
99 if (node->children[
i] < 0) {
100 const int32_t leafnum = -(node->children[
i]) - 1;
101 const TR_LEAF_TYPE* leaf = &tile->leafs[leafnum];
102 const uint32_t contentFlags = leaf->contentFlags & ~(1 << 31);
104 t->
children[
i] = -node->children[
i] | (1 << 31);
110 Com_Printf(
"Exceeded allocated memory for tracing structure (%i > %i)\n",
124 assert(nodenum < tile->numnodes + 6);
131 if (!tile->nodes[nodenum].plane) {
135 TR_NODE_TYPE* n = &tile->nodes[nodenum];
141 if (n->children[0] < 0 || n->children[1] < 0)
149 VectorCopy(tile->nodes[n->children[0]].maxs, c0maxs);
150 VectorCopy(tile->nodes[n->children[1]].mins, c1mins);
153 Com_Printf(
"(%i %i : %i %i) (%i %i : %i %i)\n",
154 (
int)tile->nodes[n->children[0]].mins[0], (
int)tile->nodes[n->children[0]].mins[1],
155 (
int)tile->nodes[n->children[0]].maxs[0], (
int)tile->nodes[n->children[0]].maxs[1],
156 (
int)tile->nodes[n->children[1]].mins[0], (
int)tile->nodes[n->children[1]].mins[1],
157 (
int)tile->nodes[n->children[1]].maxs[0], (
int)tile->nodes[n->children[1]].maxs[1]);
160 for (
int i = 0;
i < 2;
i++)
161 if (c0maxs[
i] <= c1mins[
i]) {
165 t->
dist = (c0maxs[
i] + c1mins[
i]) / 2;
167 t->
children[1] = *tnode - tile->tnodes;
169 t->
children[0] = *tnode - tile->tnodes;
177 for (
int i = 0;
i < 2;
i++) {
183 tile->cheads[tile->numcheads].cnode = nodenum;
184 tile->cheads[tile->numcheads].level =
level;
216 if (nodenum & (1 << 31))
217 return nodenum & ~(1 << 31);
219 const tnode_t* tnode = &tile->tnodes[nodenum];
221 switch (tnode->
type) {
225 front = start[tnode->
type] - tnode->
dist;
226 back = end[tnode->
type] - tnode->
dist;
244 const int side = front < 0;
245 const float frac = front / (front - back);
284 for (
int i = 0;
i < tile->numtheads;
i++) {
285 const int level = tile->theadlevel[
i];
286 if (
level && corelevels && !(
level & corelevels))
312 for (
int tile = 0; tile <
mapTiles->numTiles; tile++) {
343 if (nodenum & (1 << 31)) {
344 r = nodenum & ~(1 << 31);
350 const tnode_t* tnode = &tile->tnodes[nodenum];
352 switch (tnode->
type) {
356 front = start[tnode->
type] - tnode->
dist;
357 back = end[tnode->
type] - tnode->
dist;
380 front = (start[0] * tnode->
normal[0] + start[1] * tnode->
normal[1] + start[2] * tnode->
normal[2]) - tnode->
dist;
393 const float frac = front / (front - back);
422 for (
int i = 0;
i < tile->numtheads;
i++) {
424 const int level = tile->theadlevel[
i];
425 if (
level && corelevels && !(
level & levelmask))
465 for (
int tile = 0; tile <
mapTiles->numTiles; tile++) {
478void mapTiles_s::getTilesAt (
int x ,
int y,
byte& fromTile1,
byte& fromTile2,
byte& fromTile3)
480#if defined(COMPILE_UFO)
481 for (
int i = 0;
i < numTiles;
i++) {
498void mapTiles_s::getTileOverlap (
const byte tile1,
const byte tile2,
int& minZ,
int& maxZ)
500#if defined(COMPILE_UFO)
501 const int lowZ1 =
mapTiles[tile1 - 1].wpMins[2];
502 const int lowZ2 =
mapTiles[tile2 - 1].wpMins[2];
503 const int highZ1 =
mapTiles[tile1 - 1].wpMaxs[2];
504 const int highZ2 =
mapTiles[tile2 - 1].wpMaxs[2];
505 minZ = std::max(lowZ1, lowZ2);
508 maxZ = std::min(highZ1, highZ2);
513void mapTiles_s::printTilesAt (
int x ,
int y)
515#if defined(COMPILE_UFO)
519 getTilesAt(x ,y, fromTile1, fromTile2, fromTile3);
557 for (
int i = 0;
i < 3;
i++) {
558 if (plane->normal[
i] < 0) {
559 corners[0][
i] = mins[
i];
560 corners[1][
i] = maxs[
i];
562 corners[1][
i] = mins[
i];
563 corners[0][
i] = maxs[
i];
578typedef struct leaf_check_s {
591 const TR_TILE_TYPE* myTile = traceData->
tile;
603 assert(nodenum < myTile->numnodes + 6);
604 const TR_NODE_TYPE* node = &myTile->nodes[nodenum];
607 const TR_PLANE_TYPE* plane = node->plane;
609 const TR_PLANE_TYPE* plane = myTile->planes + node->planenum;
614 nodenum = node->children[0];
616 nodenum = node->children[1];
621 nodenum = node->children[1];
641 assert(headnode < traceData->tile->numnodes + 6);
662 const TR_BRUSHSIDE_TYPE* leadside =
nullptr;
664 const TR_TILE_TYPE* myTile = traceData->
tile;
666 float enterfrac = -1.0;
667 float leavefrac = 1.0;
669 bool startout =
false;
671 const TR_PLANE_TYPE* clipplane =
nullptr;
672 int clipplanenum = 0;
677 const TR_BRUSHSIDE_TYPE* side = &myTile->brushsides[brush->
firstbrushside +
i];
679 const TR_PLANE_TYPE* plane = side->plane;
681 const TR_PLANE_TYPE* plane = myTile->planes + side->planenum;
687 for (
int j = 0; j < 3; j++) {
688 if (plane->normal[j] < 0)
689 ofs[j] = traceData->
maxs[j];
691 ofs[j] = traceData->
mins[j];
694 dist = plane->dist - dist;
700 const float d2 =
DotProduct(traceData->
end, plane->normal) - dist;
708 if (d1 > 0 && d2 >= d1)
711 if (d1 <= 0 && d2 <= 0)
721 clipplanenum = side->planenum;
740 if (enterfrac < leavefrac) {
741 if (enterfrac > -1 && enterfrac < traceData->trace.fraction) {
762 const TR_TILE_TYPE* myTile = traceData->
tile;
768 const TR_BRUSHSIDE_TYPE* side = &myTile->brushsides[brush->
firstbrushside +
i];
770 const TR_PLANE_TYPE* plane = side->plane;
772 const TR_PLANE_TYPE* plane = myTile->planes + side->planenum;
778 for (
int j = 0; j < 3; j++) {
779 if (plane->normal[j] < 0)
780 ofs[j] = traceData->
maxs[j];
782 ofs[j] = traceData->
mins[j];
784 const float dist = plane->dist -
DotProduct(ofs, plane->normal);
813 TR_TILE_TYPE* myTile = traceData->
tile;
816 assert(leafnum <= myTile->numleafs);
818 TR_LEAF_TYPE* leaf = &myTile->leafs[leafnum];
824 for (
int k = 0; k < leaf->numleafbrushes; k++) {
825 const int brushnum = myTile->leafbrushes[leaf->firstleafbrush + k];
847 TR_TILE_TYPE* myTile = traceData->
tile;
850 assert(leafnum <= myTile->numleafs);
852 const TR_LEAF_TYPE* leaf = &myTile->leafs[leafnum];
854 if (!(leaf->contentFlags & traceData->
contents))
858 for (
int k = 0; k < leaf->numleafbrushes; k++) {
859 const int brushnum = myTile->leafbrushes[leaf->firstleafbrush + k];
906 const TR_TILE_TYPE* myTile = traceData->
tile;
907 const TR_NODE_TYPE* node = myTile->nodes + nodenum;
910 const TR_PLANE_TYPE* plane = node->plane;
913 const TR_PLANE_TYPE* plane = myTile->planes + node->planenum;
918 const int type = plane->type;
919 t1 = p1[
type] - plane->dist;
920 t2 = p2[
type] - plane->dist;
923 t1 =
DotProduct(plane->normal, p1) - plane->dist;
924 t2 =
DotProduct(plane->normal, p2) - plane->dist;
929 + fabs(traceData->
extents[1] * plane->normal[1])
930 + fabs(traceData->
extents[2] * plane->normal[2]);
952 const float idist = 1.0 / (t1 - t2);
956 }
else if (t1 > t2) {
957 const float idist = 1.0 / (t1 - t2);
973 float midf = p1f + (p2f - p1f) * frac;
984 midf = p1f + (p2f - p1f) * frac2;
1008 if (headnode >= traceData.
tile->numnodes + 6)
1011 assert(headnode < traceData.tile->numnodes + 6);
1014 if (!traceData.
tile->numnodes)
1015 return traceData.
trace;
1025 for (
int i = 0;
i < numleafs;
i++) {
1031 return traceData.
trace;
1054 return traceData.
trace;
1077 traceData.
init(myTile, brushmask, brushreject,
tr.fraction);
1080 for (
i = 0, h = myTile->cheads;
i < myTile->numcheads;
i++, h++) {
1088 assert(h->
cnode < myTile->numnodes + 6);
1112trace_t TR_SingleTileBoxTrace (
mapTiles_t*
mapTiles,
const Line& traceLine,
const AABB* traceBox,
const int levelmask,
const int brushmask,
const int brushreject)
void getCenter(vec3_t center) const
Calculates the center of the bounding box.
Stores the data of a map tile, mostly the BSP stuff.
void Com_Error(int code, const char *fmt,...)
void Com_Printf(const char *const fmt,...)
definitions common between client and server, but not game lib
#define TL_FLAG_ACTORCLIP
#define TL_FLAG_REGULAR_LEVELS
#define LEVEL_LASTVISIBLE
#define CONTENTS_PASSABLE
#define PLANESIDE_EPSILON
#define TL_FLAG_WEAPONCLIP
void Sys_Error(const char *error,...)
bool VectorNearer(const vec3_t v1, const vec3_t v2, const vec3_t comp)
Checks whether the given vector v1 is closer to comp as the vector v2.
int VectorCompareEps(const vec3_t v1, const vec3_t v2, float epsilon)
Compare two vectors that may have an epsilon difference but still be the same vectors.
QGL_EXTERN GLint GLenum type
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
void setLineAndBox(const Line &line, const AABB &box)
void init(TR_TILE_TYPE *_tile, const int contentmask, const int brushreject, const float fraction)
uint32_t brushContentFlags
Data for line tracing (?).
static mapTiles_t mapTiles
static void TR_TestInLeaf(boxtrace_t *traceData, int32_t leafnum)
bool TR_TestLine(mapTiles_t *mapTiles, const vec3_t start, const vec3_t end, const int levelmask)
Checks traces against the world.
static void TR_TestBoxInBrush(boxtrace_t *traceData, cBspBrush_t *brush)
static bool TR_TileTestLineDM(TR_TILE_TYPE *tile, const vec3_t start, const vec3_t end, vec3_t hit, const int levelmask)
Checks traces against the world, gives hit position back.
static bool TR_TileTestLine(TR_TILE_TYPE *tile, const vec3_t start, const vec3_t end, const int levelmask)
Tests to see if a line intersects any brushes in a tile.
static int TR_BoxLeafnums_headnode(boxtrace_t *traceData, int32_t *list, int listsize, int32_t headnode)
Fill a list of leafnodes that the trace touches.
void TR_BuildTracingNode_r(TR_TILE_TYPE *tile, tnode_t **tnode, int32_t nodenum, int level)
static void TR_RecursiveHullCheck(boxtrace_t *traceData, int32_t nodenum, float p1f, float p2f, const vec3_t p1, const vec3_t p2)
This recursive function traces through the bsp tree looking to see if a brush can be found that inter...
trace_t TR_BoxTrace(boxtrace_t &traceData, const Line &traceLine, const AABB &traceBox, const int headnode, const float fraction)
This function traces a line from start to end. It returns a trace_t indicating what portion of the li...
static void TR_TraceToLeaf(boxtrace_t *traceData, int32_t leafnum)
This function checks if the specified leaf matches any mask specified in traceData....
static void TR_ClipBoxToBrush(boxtrace_t *traceData, cBspBrush_t *brush, TR_LEAF_TYPE *leaf)
This function checks to see if any sides of a brush intersect the line from p1 to p2 or are located w...
trace_t TR_TileBoxTrace(TR_TILE_TYPE *myTile, const Line &traceLine, const AABB &aabb, const int levelmask, const int brushmask, const int brushreject)
Traces all submodels in the specified tile. Provides for a short circuit if the trace tries to move p...
static void TR_BoxLeafnums_r(boxtrace_t *traceData, int32_t nodenum, leaf_check_t *lc)
Fills in a list of all the leafs touched call with topnode set to the headnode, returns with topnode ...
bool TR_TestLineDM(mapTiles_t *mapTiles, const vec3_t start, const vec3_t end, vec3_t hit, const int levelmask)
Checks traces against the world, gives hit position back.
int TR_TestLine_r(TR_TILE_TYPE *tile, int32_t nodenum, const vec3_t start, const vec3_t end)
int TR_BoxOnPlaneSide(const vec3_t mins, const vec3_t maxs, const TR_PLANE_TYPE *plane)
Returns PSIDE_FRONT, PSIDE_BACK, or PSIDE_BOTH.
static void TR_MakeTracingNode(TR_TILE_TYPE *tile, tnode_t **tnode, int32_t nodenum)
Converts the disk node structure into the efficient tracing structure for LineTraces.
static int TR_TestLineDist_r(TR_TILE_TYPE *tile, int32_t nodenum, const vec3_t start, const vec3_t end, vec3_t tr_end)
#define VectorEqual(a, b)
#define VectorInterpolation(p1, p2, frac, mid)
#define VectorSubtract(a, b, dest)
#define VectorCopy(src, dest)
#define VectorAdd(a, b, dest)
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
#define VectorSet(v, x, y, z)