20 #include "shared/shared.h"
21 #include "common/bsp.h"
22 #include "common/cmd.h"
23 #include "common/cmodel.h"
24 #include "common/common.h"
25 #include "common/cvar.h"
26 #include "common/math.h"
27 #include "common/zone.h"
28 #include "system/hunk.h"
54 memset(cm, 0,
sizeof(*cm));
75 cm->floodnums =
Z_TagMallocz(
sizeof(
int) * cm->cache->numareas +
76 sizeof(qboolean) * (cm->cache->lastareaportal + 1), TAG_CMODEL);
77 cm->portalopen = (qboolean *)(cm->floodnums + cm->cache->numareas);
89 return (mnode_t *)cm->cache->leafs;
91 if (number < 0 || number >= cm->cache->numnodes) {
92 Com_EPrintf(
"%s: bad number: %d\n", __func__, number);
95 return cm->cache->nodes + number;
103 if (number < 0 || number >= cm->cache->numleafs) {
104 Com_EPrintf(
"%s: bad number: %d\n", __func__, number);
107 return cm->cache->leafs + number;
143 box_leaf.contents = CONTENTS_MONSTER;
149 for (i = 0; i < 6; i++) {
164 c->children[side ^ 1] = (mnode_t *)&
box_leaf;
170 VectorClear(p->normal);
171 p->normal[i >> 1] = 1;
174 p->type = 3 + (i >> 1);
176 VectorClear(p->normal);
177 p->normal[i >> 1] = -1;
233 while (node->plane) {
236 node = node->children[0];
238 node = node->children[1];
245 node = node->children[1];
255 mnode_t *headnode, mnode_t **topnode)
273 int CM_BoxLeafs(cm_t *cm, vec3_t mins, vec3_t maxs, mleaf_t **list,
int listsize, mnode_t **topnode)
278 listsize, cm->cache->nodes, topnode);
299 return leaf->contents;
322 VectorSubtract(p,
origin, p_l);
326 (angles[0] || angles[1] || angles[2])) {
329 VectorCopy(p_l, temp);
330 p_l[0] = DotProduct(temp,
forward);
331 p_l[1] = -DotProduct(temp,
right);
332 p_l[2] = DotProduct(temp,
up);
337 return leaf->contents;
350 #define DIST_EPSILON (0.03125)
366 trace_t *trace, mbrush_t *brush)
369 cplane_t *plane, *clipplane;
371 float enterfrac, leavefrac;
374 qboolean getout, startout;
376 mbrushside_t *side, *leadside;
382 if (!brush->numsides)
389 side = brush->firstbrushside;
390 for (i = 0; i < brush->numsides; i++, side++) {
401 for (j = 0; j < 3; j++) {
402 if (plane->normal[j] < 0)
407 dist = DotProduct(ofs, plane->normal);
408 dist = plane->dist - dist;
414 d1 = DotProduct(p1, plane->normal) - dist;
415 d2 = DotProduct(p2, plane->normal) - dist;
423 if (d1 > 0 && d2 >= d1)
426 if (d1 <= 0 && d2 <= 0)
448 trace->startsolid = qtrue;
450 trace->allsolid = qtrue;
454 trace->contents = brush->contents;
459 if (enterfrac < leavefrac) {
460 if (enterfrac > -1 && enterfrac < trace->fraction) {
463 trace->fraction = enterfrac;
464 trace->plane = *clipplane;
465 trace->surface = &(leadside->texinfo->c);
466 trace->contents = brush->contents;
477 trace_t *trace, mbrush_t *brush)
486 if (!brush->numsides)
489 side = brush->firstbrushside;
490 for (i = 0; i < brush->numsides; i++, side++) {
500 for (j = 0; j < 3; j++) {
501 if (plane->normal[j] < 0)
506 dist = DotProduct(ofs, plane->normal);
507 dist = plane->dist - dist;
509 d1 = DotProduct(p1, plane->normal) - dist;
518 trace->startsolid = trace->allsolid = qtrue;
520 trace->contents = brush->contents;
532 mbrush_t *b, **leafbrush;
537 leafbrush = leaf->firstleafbrush;
538 for (k = 0; k < leaf->numleafbrushes; k++, leafbrush++) {
562 mbrush_t *b, **leafbrush;
567 leafbrush = leaf->firstleafbrush;
568 for (k = 0; k < leaf->numleafbrushes; k++, leafbrush++) {
593 float t1, t2, offset;
615 if (plane->type < 3) {
616 t1 = p1[plane->type] - plane->dist;
617 t2 = p2[plane->type] - plane->dist;
620 t1 = PlaneDiff(p1, plane);
621 t2 = PlaneDiff(p2, plane);
631 if (t1 >= offset && t2 >= offset) {
632 node = node->children[0];
635 if (t1 < -offset && t2 < -offset) {
636 node = node->children[1];
642 idist = 1.0 / (t1 - t2);
646 }
else if (t1 > t2) {
647 idist = 1.0 / (t1 - t2);
660 midf = p1f + (p2f - p1f) * frac;
661 LerpVector(p1, p2, frac, mid);
668 midf = p1f + (p2f - p1f) * frac2;
669 LerpVector(p1, p2, frac2, mid);
684 vec3_t mins, vec3_t maxs,
685 mnode_t *headnode,
int brushmask)
708 if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2]) {
709 mleaf_t *leafs[1024];
713 VectorAdd(start, mins, c1);
714 VectorAdd(start, maxs, c2);
715 for (i = 0; i < 3; i++) {
721 for (i = 0; i < numleafs; i++) {
733 if (mins[0] == 0 && mins[1] == 0 && mins[2] == 0
734 && maxs[0] == 0 && maxs[1] == 0 && maxs[2] == 0) {
765 vec3_t mins, vec3_t maxs,
766 mnode_t *headnode,
int brushmask,
767 vec3_t
origin, vec3_t angles)
769 vec3_t start_l, end_l;
774 VectorSubtract(start,
origin, start_l);
775 VectorSubtract(end,
origin, end_l);
779 (angles[0] || angles[1] || angles[2]))
785 AnglesToAxis(angles, axis);
786 RotatePoint(start_l, axis);
787 RotatePoint(end_l, axis);
791 CM_BoxTrace(trace, start_l, end_l, mins, maxs, headnode, brushmask);
794 if (rotated && trace->fraction != 1.0) {
796 RotatePoint(trace->plane.normal, axis);
801 LerpVector(start, end, trace->fraction, trace->endpos);
806 dst->allsolid |= src->allsolid;
807 dst->startsolid |= src->startsolid;
808 if (src->fraction < dst->fraction) {
809 dst->fraction = src->fraction;
810 VectorCopy(src->endpos, dst->endpos);
811 dst->plane = src->plane;
812 dst->surface = src->surface;
813 dst->contents |= src->contents;
833 area = &cm->cache->areas[number];
835 if (cm->floodnums[number] == floodnum)
837 Com_Error(ERR_DROP,
"FloodArea_r: reflooded");
840 cm->floodnums[number] = floodnum;
842 p = area->firstareaportal;
843 for (i = 0; i < area->numareaportals; i++, p++) {
844 if (cm->portalopen[p->portalnum])
860 for (i = 1; i < cm->cache->numareas; i++) {
861 area = &cm->cache->areas[i];
875 if (portalnum < 0 || portalnum >= MAX_MAP_AREAPORTALS) {
876 Com_EPrintf(
"%s: portalnum %d is out of range\n", __func__, portalnum);
881 if (portalnum > cm->cache->lastareaportal) {
882 Com_DPrintf(
"%s: portalnum %d is not in use\n", __func__, portalnum);
886 cm->portalopen[portalnum] = open;
892 bsp_t *cache = cm->cache;
900 if (area1 < 1 || area2 < 1) {
903 if (area1 >= cache->numareas || area2 >= cache->numareas) {
904 Com_EPrintf(
"%s: area > numareas\n", __func__);
907 if (cm->floodnums[area1] == cm->floodnums[area2]) {
927 bsp_t *cache = cm->cache;
936 bytes = (cache->numareas + 7) >> 3;
940 memset(buffer, 255, bytes);
942 memset(buffer, 0, bytes);
944 floodnum = cm->floodnums[area];
945 for (i = 0; i < cache->numareas; i++) {
946 if (cm->floodnums[i] == floodnum) {
957 int i, bytes, numportals;
963 numportals = cm->cache->lastareaportal + 1;
964 if (numportals > MAX_MAP_AREAS) {
967 Com_WPrintf(
"%s: too many areaportals\n", __func__);
968 numportals = MAX_MAP_AREAS;
971 bytes = (numportals + 7) >> 3;
972 memset(buffer, 0, bytes);
973 for (i = 0; i < numportals; i++) {
974 if (cm->portalopen[i]) {
991 for (i = 0; i <= cm->cache->lastareaportal; i++) {
992 cm->portalopen[i] = qtrue;
995 numportals = bytes << 3;
996 if (numportals > cm->cache->lastareaportal + 1) {
997 numportals = cm->cache->lastareaportal + 1;
999 for (i = 0; i < numportals; i++) {
1000 cm->portalopen[i] = Q_IsBitSet(buffer, i);
1021 while (node->plane) {
1024 node = node->children[1];
1027 leaf = (mleaf_t *)node;
1028 cluster = leaf->cluster;
1031 if (Q_IsBitSet(visbits, cluster))
1045 byte *
CM_FatPVS(cm_t *cm,
byte *mask,
const vec3_t org,
int vis)
1047 byte temp[VIS_MAX_BYTES];
1050 int i, j, count, longs;
1051 uint_fast32_t *src, *dst;
1055 return memset(mask, 0, VIS_MAX_BYTES);
1057 if (!cm->cache->vis) {
1058 return memset(mask, 0xff, VIS_MAX_BYTES);
1061 for (i = 0; i < 3; i++) {
1062 mins[i] = org[i] - 8;
1063 maxs[i] = org[i] + 8;
1066 count =
CM_BoxLeafs(cm, mins, maxs, leafs, 64, NULL);
1068 Com_Error(ERR_DROP,
"CM_FatPVS: leaf count < 1");
1069 longs = VIS_FAST_LONGS(cm->cache);
1072 for (i = 0; i < count; i++) {
1073 clusters[i] = leafs[i]->cluster;
1079 for (i = 1; i < count; i++) {
1080 for (j = 0; j < i; j++) {
1081 if (clusters[i] == clusters[j]) {
1085 src = (uint_fast32_t *)
BSP_ClusterVis(cm->cache, temp, clusters[i], vis);
1086 dst = (uint_fast32_t *)mask;
1087 for (j = 0; j < longs; j++) {