From b26a8d4d9c840844b7696f0249ee45615b831686 Mon Sep 17 00:00:00 2001 From: LJW-Dev <48092720+LJW-Dev@users.noreply.github.com> Date: Sun, 22 Mar 2026 17:08:30 +0800 Subject: [PATCH] feat: clipmap linker now has support for maps smaller than the minimum BSP node size --- .../Game/T6/BSP/Linker/ClipMapLinker.cpp | 31 +++++++++++++------ .../Game/T6/BSP/Linker/ClipMapLinker.h | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.cpp b/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.cpp index 1bc0d790..00044843 100644 --- a/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.cpp +++ b/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.cpp @@ -390,10 +390,28 @@ namespace BSP // Nodes are indexed by their index in the node array // Leafs are indexed by (-1 - ) // See https://developer.valvesoftware.com/wiki/BSP_(Source) - int16_t ClipMapLinker::loadBSPNode(clipMap_t* clipMap, BSPTree* tree) + int16_t ClipMapLinker::loadBSPNode(clipMap_t* clipMap, BSPTree* tree, bool isRoot) { if (tree->isLeaf) { + if (isRoot) + { + cplane_s plane; + plane.dist = 0; + plane.normal = normalX; + plane.type = 0; + plane.signbits = 0; + plane.pad[0] = 0; + plane.pad[1] = 0; + planeVec.emplace_back(plane); + + cNode_t node; + node.plane = nullptr; // initalised after the BSP tree has been loaded + node.children[0] = -1; + node.children[1] = -1; + nodeVec.emplace_back(node); + } + cLeaf_s leaf; leaf.cluster = 0; // always use cluster 0 @@ -469,8 +487,8 @@ namespace BSP cNode_t node; node.plane = nullptr; // initalised after the BSP tree has been loaded - node.children[0] = loadBSPNode(clipMap, tree->node->front.get()); - node.children[1] = loadBSPNode(clipMap, tree->node->back.get()); + node.children[0] = loadBSPNode(clipMap, tree->node->front.get(), false); + node.children[1] = loadBSPNode(clipMap, tree->node->back.get(), false); nodeVec.at(nodeIndex) = node; @@ -494,11 +512,6 @@ namespace BSP BSPUtil::updateAABBWithPoint(vertex, worldMins, worldMaxs); } std::unique_ptr tree = std::make_unique(worldMins.x, worldMins.y, worldMins.z, worldMaxs.x, worldMaxs.y, worldMaxs.z, 0); - if (tree->isLeaf) - { - con::error("Map size is too small for BSP generation!"); - return false; - } for (int partitionIdx = 0; partitionIdx < clipMap->partitionCount; partitionIdx++) { @@ -512,7 +525,7 @@ namespace BSP } // load planes, nodes, leafs, and AABB trees - loadBSPNode(clipMap, tree.get()); + loadBSPNode(clipMap, tree.get(), true); clipMap->info.planeCount = static_cast(planeVec.size()); clipMap->info.planes = m_memory.Alloc(planeVec.size()); diff --git a/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.h b/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.h index 65328a04..5c8d4842 100644 --- a/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.h +++ b/src/ObjLoading/Game/T6/BSP/Linker/ClipMapLinker.h @@ -33,7 +33,7 @@ namespace BSP size_t highestLeafObjectCount = 0; std::vector partitionToMaterialMap; void addAABBTreeFromLeaf(clipMap_t* clipMap, BSPTree* tree, size_t* out_parentCount, size_t* out_parentStartIndex, int* out_treeContents); - int16_t loadBSPNode(clipMap_t* clipMap, BSPTree* tree); + int16_t loadBSPNode(clipMap_t* clipMap, BSPTree* tree, bool isRoot); bool loadBSPTree(clipMap_t* clipMap, BSPData* bsp); bool loadPartitions(clipMap_t* clipMap, BSPData* bsp); bool loadWorldCollision(clipMap_t* clipMap, BSPData* bsp);