diff --git a/qbsp/surfaces.cc b/qbsp/surfaces.cc index b20db449..add1e069 100644 --- a/qbsp/surfaces.cc +++ b/qbsp/surfaces.cc @@ -502,6 +502,27 @@ int MakeFaceEdges(mapentity_t *entity, node_t *headnode) static int c_nodefaces; +static node_t *FirstClusterLeaf_R(node_t *node, int cluster) +{ + if (node->planenum == PLANENUM_LEAF) { + if (node->viscluster == cluster) { + return node; + } + } + + for (int32_t i = 0; i < 2; i++) { + if (node->children[i]) { + node_t *child = FirstClusterLeaf_R(node->children[i], cluster); + + if (child) { + return child; + } + } + } + + return nullptr; +} + /* ================ AddMarksurfaces_r @@ -514,6 +535,16 @@ fixme-brushbsp: all leafs in a cluster can share the same marksurfaces, right? static void AddMarksurfaces_r(face_t *face, face_t *face_copy, node_t *node) { if (node->planenum == PLANENUM_LEAF) { + + if (node->viscluster >= 0) { + node_t *head; + + for (head = node; head->parent; head = head->parent) + ; + + node = FirstClusterLeaf_R(head, node->viscluster); + } + node->markfaces.push_back(face); return; } diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index f32ff3d1..a1c354e9 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -165,25 +165,40 @@ static void ExportLeaf(mapentity_t *entity, node_t *node) dleaf.visofs = -1; // no vis info yet // write the marksurfaces - dleaf.firstmarksurface = static_cast(map.bsp.dleaffaces.size()); + bool clustered = false; - for (auto &face : node->markfaces) { - if (!options.includeskip.value() && map.mtexinfos.at(face->texinfo).flags.is_skip) - continue; - // FIXME: this can happen when compiling some Q2 maps - // as Q1. - if (!face->outputnumber.has_value()) - continue; - - /* emit a marksurface */ - map.bsp.dleaffaces.push_back(face->outputnumber.value()); - - /* grab tjunction split faces */ - for (auto &fragment : face->fragments) { - map.bsp.dleaffaces.push_back(fragment.outputnumber.value()); + if (node->viscluster >= 0) { + for (auto &leaf : map.bsp.dleafs) { + if (&leaf != &dleaf && leaf.cluster == node->viscluster) { + clustered = true; + dleaf.firstmarksurface = leaf.firstmarksurface; + dleaf.nummarksurfaces = leaf.nummarksurfaces; + break; + } } } - dleaf.nummarksurfaces = static_cast(map.bsp.dleaffaces.size()) - dleaf.firstmarksurface; + + if (!clustered) { + dleaf.firstmarksurface = static_cast(map.bsp.dleaffaces.size()); + + for (auto &face : node->markfaces) { + if (!options.includeskip.value() && map.mtexinfos.at(face->texinfo).flags.is_skip) + continue; + // FIXME: this can happen when compiling some Q2 maps + // as Q1. + if (!face->outputnumber.has_value()) + continue; + + /* emit a marksurface */ + map.bsp.dleaffaces.push_back(face->outputnumber.value()); + + /* grab tjunction split faces */ + for (auto &fragment : face->fragments) { + map.bsp.dleaffaces.push_back(fragment.outputnumber.value()); + } + } + dleaf.nummarksurfaces = static_cast(map.bsp.dleaffaces.size()) - dleaf.firstmarksurface; + } dleaf.area = node->area; dleaf.cluster = node->viscluster;