qbsp: restore bounds expansion for rotators.

Add "_no_bbox_rotation_expansion" key for opting-out of the bounds expansion

Fixes #271
This commit is contained in:
Eric Wasylishen 2019-10-27 23:02:05 -06:00
parent 79d3aa99de
commit d7d797b898
5 changed files with 32 additions and 23 deletions

View File

@ -41,7 +41,7 @@ int Brush_ListCountWithCFlags(const brush_t *brush, int cflags);
int Brush_ListCount(const brush_t *brush);
int Brush_NumFaces(const brush_t *brush);
brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate_offset, const int hullnum);
brush_t *LoadBrush(const mapentity_t *src, const mapbrush_t *mapbrush, int contents, const vec3_t rotate_offset, const int hullnum);
void FreeBrushes(mapentity_t *ent);
int FindPlane(const vec3_t normal, const vec_t dist, int *side);

View File

@ -256,6 +256,12 @@ Generates an LMSHIFT bspx lump for use by a light util. Note that both scaled an
.IP "\fB""_mirrorinside"" ""n""\fP"
Set to 1 to save mirrored inside faces for bmodels, so when the player view is inside the bmodel, they will still see the faces. (e.g. for func_water, or func_illusionary)
.IP "\fB""_no_bbox_rotation_expansion"" ""n""\fP"
By default, when using Hipnotic rotation or adding an "origin" brush to an entity, qbsp will expand the model bounding box to account for all possible rotations.
This is done because Quake doesn't take into account the model rotation when vis culling, so it needs to be done in qbsp to avoid incorrect culling. (see: https://github.com/id-Software/Quake/blob/master/WinQuake/world.c#L387 ).
This behaviour can be opted out of by setting this key to 1.
.SH "OTHER SPECIAL-PURPOSE ENTITIES"
.SS "func_illusionary_visblocker"

View File

@ -363,7 +363,7 @@ CreateBrushFaces
=================
*/
static face_t *
CreateBrushFaces(hullbrush_t *hullbrush, const vec3_t rotate_offset,
CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, const vec3_t rotate_offset,
const int hullnum)
{
int i, j, k;
@ -472,7 +472,10 @@ CreateBrushFaces(hullbrush_t *hullbrush, const vec3_t rotate_offset,
// Rotatable objects must have a bounding box big enough to
// account for all its rotations
if (0 /*rotate_offset[0] || rotate_offset[1] || rotate_offset[2]*/) {
const bool noExpand = static_cast<bool>(
atoi(ValueForKey(src, "_no_bbox_rotation_expansion"))
);
if ((rotate_offset[0] || rotate_offset[1] || rotate_offset[2]) && !noExpand) {
vec_t delta;
delta = fabs(max);
@ -858,7 +861,7 @@ LoadBrush
Converts a mapbrush to a bsp brush
===============
*/
brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate_offset, const int hullnum)
brush_t *LoadBrush(const mapentity_t *src, const mapbrush_t *mapbrush, int contents, const vec3_t rotate_offset, const int hullnum)
{
hullbrush_t hullbrush;
brush_t *brush;
@ -878,11 +881,11 @@ brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate
hullbrush.faces[i] = mapbrush->face(i);
if (hullnum == 0) {
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
} else {
// for clipping hulls, don't apply rotation offset yet..
// it will be applied below
facelist = CreateBrushFaces(&hullbrush, vec3_origin, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, vec3_origin, hullnum);
}
if (!facelist) {
@ -897,19 +900,19 @@ brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate
vec3_t size[2] = { {-16, -16, -36}, {16, 16, 36} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
else if (hullnum == 2) {
vec3_t size[2] = { {-32, -32, -32}, {32, 32, 32} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
else if (hullnum == 3) {
vec3_t size[2] = { {-16, -16, -18}, {16, 16, 18} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
}
else if (options.hexen2)
@ -918,19 +921,19 @@ brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate
vec3_t size[2] = { {-16, -16, -32}, {16, 16, 24} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
else if (hullnum == 2) {
vec3_t size[2] = { {-24, -24, -20}, {24, 24, 20} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
else if (hullnum == 3) {
vec3_t size[2] = { {-16, -16, -12}, {16, 16, 16} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
else if (hullnum == 4) {
#if 0
@ -938,21 +941,21 @@ brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate
vec3_t size[2] = { {-40, -40, -42}, {40, 40, 42} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
} else
#endif
{ /*mission pack*/
vec3_t size[2] = { {-8, -8, -8}, {8, 8, 8} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
}
else if (hullnum == 5) {
vec3_t size[2] = { {-48, -48, -50}, {48, 48, 50} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
}
else
@ -962,13 +965,13 @@ brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
} else if (hullnum == 2) {
vec3_t size[2] = { {-32, -32, -64}, {32, 32, 24} };
ExpandBrush(&hullbrush, size, facelist);
FreeBrushFaces(facelist);
facelist = CreateBrushFaces(&hullbrush, rotate_offset, hullnum);
facelist = CreateBrushFaces(src, &hullbrush, rotate_offset, hullnum);
}
}
@ -1112,7 +1115,7 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum)
continue;
}
brush_t *brush = LoadBrush(mapbrush, contents, vec3_origin, 0);
brush_t *brush = LoadBrush(src, mapbrush, contents, vec3_origin, 0);
if (brush) {
vec3_t origin;
VectorAdd(brush->mins, brush->maxs, origin);
@ -1237,7 +1240,7 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum)
*/
if (contents == CONTENTS_CLIP) {
if (hullnum == 0) {
brush_t *brush = LoadBrush(mapbrush, contents, rotate_offset, hullnum);
brush_t *brush = LoadBrush(src, mapbrush, contents, rotate_offset, hullnum);
if (brush) {
AddToBounds(dst, brush->mins);
AddToBounds(dst, brush->maxs);
@ -1283,7 +1286,7 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum)
if (hullnum > 0 && contents == CONTENTS_SKY)
contents = CONTENTS_SOLID;
brush_t *brush = LoadBrush(mapbrush, contents, rotate_offset, hullnum);
brush_t *brush = LoadBrush(src, mapbrush, contents, rotate_offset, hullnum);
if (!brush)
continue;

View File

@ -2353,7 +2353,7 @@ TestExpandBrushes(const mapentity_t *src)
for (int i = 0; i < src->nummapbrushes; i++) {
const mapbrush_t *mapbrush = &src->mapbrush(i);
brush_t *hull1brush = LoadBrush(mapbrush, CONTENTS_SOLID, vec3_origin, 1);
brush_t *hull1brush = LoadBrush(src, mapbrush, CONTENTS_SOLID, vec3_origin, 1);
if (hull1brush != nullptr)
hull1brushes.push_back(hull1brush);

View File

@ -115,7 +115,7 @@ TEST(qbsp, duplicatePlanes) {
EXPECT_EQ(0, worldspawn.numbrushes);
EXPECT_EQ(6, worldspawn.mapbrush(0).numfaces);
brush_t *brush = LoadBrush(&worldspawn.mapbrush(0), CONTENTS_SOLID, vec3_origin, 0);
brush_t *brush = LoadBrush(&worldspawn, &worldspawn.mapbrush(0), CONTENTS_SOLID, vec3_origin, 0);
ASSERT_NE(nullptr, brush);
EXPECT_EQ(6, Brush_NumFaces(brush));
FreeBrush(brush);
@ -141,7 +141,7 @@ static brush_t *load128x128x32Brush()
mapentity_t worldspawn = LoadMap(map);
Q_assert(1 == worldspawn.nummapbrushes);
brush_t *brush = LoadBrush(&worldspawn.mapbrush(0), CONTENTS_SOLID, vec3_origin, 0);
brush_t *brush = LoadBrush(&worldspawn, &worldspawn.mapbrush(0), CONTENTS_SOLID, vec3_origin, 0);
Q_assert(nullptr != brush);
brush->contents = CONTENTS_SOLID;