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.
46 void boxtrace_s::init (TR_TILE_TYPE* _tile,
const int contentmask,
const int brushreject,
const float fraction)
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++) {
480 #if defined(COMPILE_UFO)
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);
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];
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;
928 offset = fabs(traceData->
extents[0] * plane->normal[0])
929 + fabs(traceData->
extents[1] * plane->normal[1])
930 + fabs(traceData->
extents[2] * plane->normal[2]);
934 if (t1 >= offset && t2 >= offset) {
937 }
else if (t1 < -offset && t2 < -offset) {
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);
1112 trace_t TR_SingleTileBoxTrace (
mapTiles_t*
mapTiles,
const Line& traceLine,
const AABB* traceBox,
const int levelmask,
const int brushmask,
const int brushreject)
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 ...
void getTileOverlap(const byte tile1, const byte tile2, int &minZ, int &maxZ)
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...
#define VectorCopy(src, dest)
void setLineAndBox(const Line &line, const AABB &box)
void Sys_Error(const char *error,...)
#define VectorSet(v, x, y, z)
QGL_EXTERN GLint GLenum type
#define CONTENTS_PASSABLE
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.
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.
#define LEVEL_LASTVISIBLE
#define TL_FLAG_REGULAR_LEVELS
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...
struct leaf_check_s leaf_check_t
Data for line tracing (?)
void Com_Printf(const char *const fmt,...)
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...
#define TL_FLAG_ACTORCLIP
void Com_Error(int code, const char *fmt,...)
Stores the data of a map tile, mostly the BSP stuff.
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.
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
void TR_BuildTracingNode_r(TR_TILE_TYPE *tile, tnode_t **tnode, int32_t nodenum, int level)
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.
void init(TR_TILE_TYPE *_tile, const int contentmask, const int brushreject, const float fraction)
int TR_TestLine_r(TR_TILE_TYPE *tile, int32_t nodenum, const vec3_t start, const vec3_t end)
#define VectorInterpolation(p1, p2, frac, mid)
void getTilesAt(int x, int y, byte &fromTile1, byte &fromTile2, byte &fromTile3)
void getCenter(vec3_t center) const
Calculates the center of the bounding box.
uint32_t brushContentFlags
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.
#define PLANESIDE_EPSILON
#define VectorAdd(a, b, dest)
static int TR_TestLineDist_r(TR_TILE_TYPE *tile, int32_t nodenum, const vec3_t start, const vec3_t end, vec3_t tr_end)
static void TR_TestInLeaf(boxtrace_t *traceData, int32_t leafnum)
static void TR_TraceToLeaf(boxtrace_t *traceData, int32_t leafnum)
This function checks if the specified leaf matches any mask specified in traceData.contents. and does not contain any mask specified in traceData.rejects If so, each brush in the leaf is examined to see if it is intersected by the line drawn in TR_RecursiveHullCheck or is within the bounding box set in trace_mins and trace_maxs with the origin on the line.
TR_TILE_TYPE mapTiles[MAX_MAPTILES]
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
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.
bool TR_TestLine(mapTiles_t *mapTiles, const vec3_t start, const vec3_t end, const int levelmask)
Checks traces against the world.
definitions common between client and server, but not game lib
static void TR_TestBoxInBrush(boxtrace_t *traceData, cBspBrush_t *brush)
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.
void printTilesAt(int x, int y)
#define VectorEqual(a, b)
#define TL_FLAG_WEAPONCLIP
#define VectorSubtract(a, b, dest)
static mapTiles_t mapTiles
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...
int TR_BoxOnPlaneSide(const vec3_t mins, const vec3_t maxs, const TR_PLANE_TYPE *plane)
Returns PSIDE_FRONT, PSIDE_BACK, or PSIDE_BOTH.