qbsp: fix void faces in qbsp_simple_sealed2.map
This commit is contained in:
parent
f467257f72
commit
d2ae49c976
|
|
@ -523,6 +523,66 @@ void MakeMarkFaces(mapentity_t* entity, node_t* node)
|
|||
MakeMarkFaces(entity, node->children[1]);
|
||||
}
|
||||
|
||||
static std::list<face_t *> ClipFacesToTree_r(node_t *node, std::list<face_t *> faces)
|
||||
{
|
||||
if (node->planenum == PLANENUM_LEAF) {
|
||||
if (node->contents.is_solid(options.target_game)) {
|
||||
// solids eat any faces that reached this point
|
||||
return {};
|
||||
}
|
||||
// other content types let the faces thorugh
|
||||
// fixme-brushbsp: detail?
|
||||
return faces;
|
||||
}
|
||||
|
||||
const qbsp_plane_t &splitplane = map.planes[node->planenum];
|
||||
|
||||
std::list<face_t *> front, back;
|
||||
|
||||
for (auto *face : faces) {
|
||||
auto [frontFragment, backFragment] = SplitFace(face, splitplane);
|
||||
if (frontFragment) {
|
||||
front.push_back(frontFragment);
|
||||
}
|
||||
if (backFragment) {
|
||||
back.push_back(backFragment);
|
||||
}
|
||||
}
|
||||
|
||||
front = ClipFacesToTree_r(node->children[0], front);
|
||||
back = ClipFacesToTree_r(node->children[1], back);
|
||||
|
||||
// merge lists
|
||||
front.splice(front.end(), back);
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
static std::list<face_t*> ClipFacesToTree(node_t* node, std::list<face_t*> faces)
|
||||
{
|
||||
// handles the first level - faces are all supposed to be lying exactly on `node`
|
||||
for (auto *face : faces) {
|
||||
Q_assert(face->planenum == node->planenum);
|
||||
}
|
||||
|
||||
std::list<face_t *> front, back;
|
||||
for (auto *face : faces) {
|
||||
if (face->planeside == 0) {
|
||||
front.push_back(face);
|
||||
} else {
|
||||
back.push_back(face);
|
||||
}
|
||||
}
|
||||
|
||||
front = ClipFacesToTree_r(node->children[0], front);
|
||||
back = ClipFacesToTree_r(node->children[1], back);
|
||||
|
||||
// merge lists
|
||||
front.splice(front.end(), back);
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
static void AddFaceToTree_r(mapentity_t* entity, face_t *face, brush_t *srcbrush, node_t* node)
|
||||
{
|
||||
if (node->planenum == PLANENUM_LEAF) {
|
||||
|
|
@ -537,9 +597,13 @@ static void AddFaceToTree_r(mapentity_t* entity, face_t *face, brush_t *srcbrush
|
|||
++c_nodefaces;
|
||||
|
||||
// csg it
|
||||
auto csgfaces = CSGFace(face, entity, srcbrush, node);
|
||||
std::list<face_t *> faces = CSGFace(face, entity, srcbrush, node);
|
||||
|
||||
for (face_t *csgface : csgfaces) {
|
||||
// clip them to the descendant parts of the BSP
|
||||
// (otherwise we could have faces floating in the void on this node)
|
||||
faces = ClipFacesToTree(node, faces);
|
||||
|
||||
for (face_t *csgface : faces) {
|
||||
// subdivide large faces
|
||||
// fixme-brushbsp: weird calling convention
|
||||
auto parts = std::list<face_t *>{csgface};
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ static mbsp_t LoadTestmap(const std::filesystem::path &name)
|
|||
{
|
||||
map.reset();
|
||||
|
||||
options.nopercent.setValue(true);
|
||||
options.noprogress.setValue(true);
|
||||
|
||||
options.szMapName = std::filesystem::path(testmaps_dir) / name;
|
||||
options.szBSPName = options.szMapName;
|
||||
options.szBSPName.replace_extension(".bsp");
|
||||
|
|
@ -265,4 +268,8 @@ TEST(qsbsp, simple_sealed2)
|
|||
ASSERT_EQ(result.dleafs[0].contents, CONTENTS_SOLID);
|
||||
ASSERT_EQ(result.dleafs[1].contents, CONTENTS_EMPTY);
|
||||
ASSERT_EQ(result.dleafs[2].contents, CONTENTS_EMPTY);
|
||||
|
||||
// L-shaped room
|
||||
// 2 ceiling + 2 floor + 6 wall faces
|
||||
ASSERT_EQ(result.dfaces.size(), 10);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue