qbsp: fix handling of duplicate planes
fixes spurious leak in e1m4.map
This commit is contained in:
parent
a3cb25b46a
commit
8b9f5ea40a
|
|
@ -37,6 +37,7 @@ class mapbrush_t;
|
||||||
|
|
||||||
int Brush_ListCountWithCFlags(const brush_t *brush, int cflags);
|
int Brush_ListCountWithCFlags(const brush_t *brush, int cflags);
|
||||||
int Brush_ListCount(const brush_t *brush);
|
int Brush_ListCount(const brush_t *brush);
|
||||||
|
int Brush_NumFaces(const brush_t *brush);
|
||||||
|
|
||||||
brush_t *LoadBrush(const mapbrush_t *mapbrush, const vec3_t rotate_offset, const int hullnum);
|
brush_t *LoadBrush(const mapbrush_t *mapbrush, const vec3_t rotate_offset, const int hullnum);
|
||||||
void FreeBrushes(brush_t *brushlist);
|
void FreeBrushes(brush_t *brushlist);
|
||||||
|
|
|
||||||
|
|
@ -929,6 +929,19 @@ Brush_ListCount(const brush_t *brush)
|
||||||
return Brush_ListCountWithCFlags(brush, 0);
|
return Brush_ListCountWithCFlags(brush, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int FaceListCount(const face_t *facelist)
|
||||||
|
{
|
||||||
|
if (facelist)
|
||||||
|
return 1 + FaceListCount(facelist->next);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Brush_NumFaces(const brush_t *brush)
|
||||||
|
{
|
||||||
|
return FaceListCount(brush->faces);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Entity_SortBrushes(mapentity_t *dst)
|
Entity_SortBrushes(mapentity_t *dst)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1476,10 +1476,12 @@ ParseBrush(parser_t *parser, const mapentity_t *entity)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Check for duplicate planes */
|
/* Check for duplicate planes */
|
||||||
|
bool discardFace = false;
|
||||||
for (int i = 0; i<brush.numfaces; i++) {
|
for (int i = 0; i<brush.numfaces; i++) {
|
||||||
const mapface_t &check = brush.face(i);
|
const mapface_t &check = brush.face(i);
|
||||||
if (PlaneEqual(&check.plane, &face->plane)) {
|
if (PlaneEqual(&check.plane, &face->plane)) {
|
||||||
Message(msgWarning, warnBrushDuplicatePlane, parser->linenum);
|
Message(msgWarning, warnBrushDuplicatePlane, parser->linenum);
|
||||||
|
discardFace = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (PlaneInvEqual(&check.plane, &face->plane)) {
|
if (PlaneInvEqual(&check.plane, &face->plane)) {
|
||||||
|
|
@ -1488,6 +1490,8 @@ ParseBrush(parser_t *parser, const mapentity_t *entity)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (discardFace)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Save the face, update progress */
|
/* Save the face, update progress */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ static const mapface_t *Mapbrush_FirstFaceWithTextureName(const mapbrush_t *brus
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::array<qvec4f, 2>
|
static mapentity_t
|
||||||
GetTexvecs(const char *map, const char *texname)
|
LoadMap(const char *map)
|
||||||
{
|
{
|
||||||
parser_t parser;
|
parser_t parser;
|
||||||
ParserInit(&parser, map);
|
ParserInit(&parser, map);
|
||||||
|
|
@ -33,6 +33,14 @@ GetTexvecs(const char *map, const char *texname)
|
||||||
// FIXME: adds the brush to the global map...
|
// FIXME: adds the brush to the global map...
|
||||||
Q_assert(ParseEntity(&parser, &worldspawn));
|
Q_assert(ParseEntity(&parser, &worldspawn));
|
||||||
|
|
||||||
|
return worldspawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::array<qvec4f, 2>
|
||||||
|
GetTexvecs(const char *map, const char *texname)
|
||||||
|
{
|
||||||
|
mapentity_t worldspawn = LoadMap(map);
|
||||||
|
|
||||||
const mapbrush_t *mapbrush = &worldspawn.mapbrush(0);
|
const mapbrush_t *mapbrush = &worldspawn.mapbrush(0);
|
||||||
const mapface_t *mapface = Mapbrush_FirstFaceWithTextureName(mapbrush, "tech02_1");
|
const mapface_t *mapface = Mapbrush_FirstFaceWithTextureName(mapbrush, "tech02_1");
|
||||||
Q_assert(nullptr != mapface);
|
Q_assert(nullptr != mapface);
|
||||||
|
|
@ -84,3 +92,31 @@ TEST(qbsp, testTextureIssue) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(qbsp, duplicatePlanes) {
|
||||||
|
// a brush from e1m4.map with 7 planes, only 6 unique.
|
||||||
|
const char *mapWithDuplicatePlanes = R"(
|
||||||
|
{
|
||||||
|
"classname" "worldspawn"
|
||||||
|
{
|
||||||
|
( 512 120 1184 ) ( 512 104 1184 ) ( 512 8 1088 ) WBRICK1_5 0 0 0 1.000000 1.000000
|
||||||
|
( 1072 104 1184 ) ( 176 104 1184 ) ( 176 8 1088 ) WBRICK1_5 0 0 0 1.000000 1.000000
|
||||||
|
( 896 56 1184 ) ( 896 72 1184 ) ( 896 -24 1088 ) WBRICK1_5 0 0 0 1.000000 1.000000
|
||||||
|
( 176 88 1184 ) ( 1072 88 1184 ) ( 1072 -8 1088 ) WBRICK1_5 0 0 0 1.000000 1.000000
|
||||||
|
( 176 88 1184 ) ( 176 104 1184 ) ( 1072 104 1184 ) WBRICK1_5 0 0 0 1.000000 1.000000
|
||||||
|
( 1072 8 1088 ) ( 176 8 1088 ) ( 176 -8 1088 ) WBRICK1_5 0 0 0 1.000000 1.000000
|
||||||
|
( 960 8 1088 ) ( 864 104 1184 ) ( 848 104 1184 ) WBRICK1_5 0 0 0 1.000000 1.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
mapentity_t worldspawn = LoadMap(mapWithDuplicatePlanes);
|
||||||
|
ASSERT_EQ(1, worldspawn.nummapbrushes);
|
||||||
|
EXPECT_EQ(0, worldspawn.numbrushes);
|
||||||
|
EXPECT_EQ(6, worldspawn.mapbrush(0).numfaces);
|
||||||
|
|
||||||
|
brush_t *brush = LoadBrush(&worldspawn.mapbrush(0), vec3_origin, 0);
|
||||||
|
ASSERT_NE(nullptr, brush);
|
||||||
|
EXPECT_EQ(6, Brush_NumFaces(brush));
|
||||||
|
FreeMem(brush, BRUSH, 1);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue