qbsp: maintain proper precendence ordering of brushes
Need to be a little more careful to order brushes correctly when adding detail to the worldspawn. CSGFaces assumes that the brushes are ordered such that earlier brushes have chunks carved out of them by any later brushes that intersect them. Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
parent
1b3a8b049f
commit
66feee616f
39
qbsp/brush.c
39
qbsp/brush.c
|
|
@ -837,14 +837,24 @@ void
|
|||
Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum)
|
||||
{
|
||||
const char *classname;
|
||||
brush_t *brush, *next, *water, *other;
|
||||
brush_t *brush, *next, *water, *solid;
|
||||
mapbrush_t *mapbrush;
|
||||
vec3_t rotate_offset;
|
||||
int i, contents, cflags = 0;
|
||||
|
||||
/*
|
||||
* The brush list need to be ordered:
|
||||
* 1. detail water
|
||||
* 2. water
|
||||
* 3. detail solid
|
||||
* 4. solid
|
||||
*
|
||||
* We can always just put water on the head of the list, but will need to
|
||||
* insert solid brushes between any existing water and solids on the list.
|
||||
*/
|
||||
solid = NULL;
|
||||
water = dst->brushes;
|
||||
classname = ValueForKey(src, "classname");
|
||||
other = dst->brushes;
|
||||
water = NULL;
|
||||
|
||||
/* Hipnotic rotation */
|
||||
VectorCopy(vec3_origin, rotate_offset);
|
||||
|
|
@ -887,8 +897,8 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum)
|
|||
brush->next = water;
|
||||
water = brush;
|
||||
} else {
|
||||
brush->next = other;
|
||||
other = brush;
|
||||
brush->next = solid;
|
||||
solid = brush;
|
||||
}
|
||||
|
||||
AddToBounds(dst, brush->mins);
|
||||
|
|
@ -897,13 +907,22 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum)
|
|||
Message(msgPercent, i + 1, src->nummapbrushes);
|
||||
}
|
||||
|
||||
// add all of the water textures at the start
|
||||
/* Insert the solid brushes after the water */
|
||||
for (brush = water; brush; brush = next) {
|
||||
next = brush->next;
|
||||
brush->next = other;
|
||||
other = brush;
|
||||
if (!next || next->contents == CONTENTS_SOLID)
|
||||
break;
|
||||
}
|
||||
if (!brush) {
|
||||
dst->brushes = solid; /* No water */
|
||||
return;
|
||||
}
|
||||
brush->next = solid;
|
||||
dst->brushes = water;
|
||||
if (!solid)
|
||||
return;
|
||||
|
||||
// Store the brushes away
|
||||
dst->brushes = other;
|
||||
while (solid->next)
|
||||
solid = solid->next;
|
||||
solid->next = next;
|
||||
}
|
||||
|
|
|
|||
24
qbsp/csg4.c
24
qbsp/csg4.c
|
|
@ -431,33 +431,31 @@ CSGFaces(const mapentity_t *ent)
|
|||
|
||||
Message(msgProgress, "CSGFaces");
|
||||
|
||||
if (validfaces == NULL)
|
||||
validfaces = AllocMem(OTHER, sizeof(face_t *) * map.maxplanes, true);
|
||||
else
|
||||
memset(validfaces, 0, sizeof(face_t *) * map.maxplanes);
|
||||
if (!validfaces)
|
||||
validfaces = AllocMem(OTHER, sizeof(face_t *) * map.maxplanes, false);
|
||||
|
||||
memset(validfaces, 0, sizeof(face_t *) * map.maxplanes);
|
||||
csgfaces = brushfaces = csgmergefaces = 0;
|
||||
|
||||
// do the solid faces
|
||||
for (b1 = ent->brushes; b1; b1 = b1->next) {
|
||||
// set outside to a copy of the brush's faces
|
||||
CopyFacesToOutside(b1);
|
||||
|
||||
// Why is this necessary?
|
||||
overwrite = false;
|
||||
|
||||
for (b2 = ent->brushes; b2; b2 = b2->next) {
|
||||
// check bounding box first
|
||||
if (b1 == b2) {
|
||||
/* Brushes further down the list overried earlier ones */
|
||||
overwrite = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check bounding box first */
|
||||
for (i = 0; i < 3; i++)
|
||||
if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i])
|
||||
break;
|
||||
if (i < 3)
|
||||
continue;
|
||||
|
||||
// see if b2 needs to clip a chunk out of b1
|
||||
if (b1 == b2) {
|
||||
overwrite = true;
|
||||
continue;
|
||||
}
|
||||
// divide faces by the planes of the new brush
|
||||
inside = outside;
|
||||
outside = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue