2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-11-23 05:12:05 +00:00

chore: use const and reference whenever possible

This commit is contained in:
Jan Laupetin
2025-11-09 20:42:03 +01:00
parent 08a8a5cd07
commit e9e0c7f511
21 changed files with 657 additions and 648 deletions

View File

@@ -4,7 +4,8 @@ namespace BSP
{ {
constexpr int MAX_NODE_SIZE = 512; // maximum size a BSP node can be before it becomes a leaf constexpr int MAX_NODE_SIZE = 512; // maximum size a BSP node can be before it becomes a leaf
BSPObject::BSPObject(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int objPartitionIndex) BSPObject::BSPObject(
const float xMin, const float yMin, const float zMin, const float xMax, const float yMax, const float zMax, const int objPartitionIndex)
{ {
min.x = xMin; min.x = xMin;
min.y = yMin; min.y = yMin;
@@ -20,17 +21,17 @@ namespace BSP
objectList.emplace_back(std::move(object)); objectList.emplace_back(std::move(object));
} }
BSPObject* BSPLeaf::getObject(size_t index) BSPObject* BSPLeaf::getObject(const size_t index) const
{ {
return objectList.at(index).get(); return objectList.at(index).get();
} }
size_t BSPLeaf::getObjectCount() size_t BSPLeaf::getObjectCount() const
{ {
return objectList.size(); return objectList.size();
} }
BSPNode::BSPNode(std::unique_ptr<BSPTree> frontTree, std::unique_ptr<BSPTree> backTree, PlaneAxis nodeAxis, float nodeDistance) BSPNode::BSPNode(std::unique_ptr<BSPTree> frontTree, std::unique_ptr<BSPTree> backTree, const PlaneAxis nodeAxis, const float nodeDistance)
{ {
front = std::move(frontTree); front = std::move(frontTree);
back = std::move(backTree); back = std::move(backTree);
@@ -38,25 +39,25 @@ namespace BSP
distance = nodeDistance; distance = nodeDistance;
} }
PlaneSide BSPNode::objectIsInFront(BSPObject* object) PlaneSide BSPNode::objectIsInFront(const BSPObject& object) const
{ {
float minCoord, maxCoord; float minCoord, maxCoord;
// Select the relevant coordinate based on the plane's axis // Select the relevant coordinate based on the plane's axis
if (axis == AXIS_X) if (axis == AXIS_X)
{ {
minCoord = object->min.x; minCoord = object.min.x;
maxCoord = object->max.x; maxCoord = object.max.x;
} }
else if (axis == AXIS_Y) else if (axis == AXIS_Y)
{ {
minCoord = object->min.y; minCoord = object.min.y;
maxCoord = object->max.y; maxCoord = object.max.y;
} }
else // axis == AXIS_Z else // axis == AXIS_Z
{ {
minCoord = object->min.z; minCoord = object.min.z;
maxCoord = object->max.z; maxCoord = object.max.z;
} }
// Compare with the plane's distance // Compare with the plane's distance
@@ -74,7 +75,7 @@ namespace BSP
} }
} }
BSPTree::BSPTree(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int treeLevel) BSPTree::BSPTree(const float xMin, const float yMin, const float zMin, const float xMax, const float yMax, const float zMax, const int treeLevel)
{ {
min.x = xMin; min.x = xMin;
min.y = yMin; min.y = yMin;
@@ -133,7 +134,7 @@ namespace BSP
} }
} }
void BSPTree::addObjectToTree(std::shared_ptr<BSPObject> object) void BSPTree::addObjectToTree(std::shared_ptr<BSPObject> object) const
{ {
if (isLeaf) if (isLeaf)
{ {
@@ -141,7 +142,7 @@ namespace BSP
} }
else else
{ {
PlaneSide side = node->objectIsInFront(object.get()); const PlaneSide side = node->objectIsInFront(*object);
if (side == SIDE_FRONT) if (side == SIDE_FRONT)
{ {
node->front->addObjectToTree(std::move(object)); node->front->addObjectToTree(std::move(object));

View File

@@ -34,8 +34,8 @@ namespace BSP
std::vector<std::shared_ptr<BSPObject>> objectList; std::vector<std::shared_ptr<BSPObject>> objectList;
void addObject(std::shared_ptr<BSPObject> object); void addObject(std::shared_ptr<BSPObject> object);
BSPObject* getObject(size_t index); BSPObject* getObject(size_t index) const;
size_t getObjectCount(); size_t getObjectCount() const;
}; };
class BSPTree; class BSPTree;
@@ -50,7 +50,7 @@ namespace BSP
float distance; // distance from the origin (0, 0, 0) to the plane float distance; // distance from the origin (0, 0, 0) to the plane
BSPNode(std::unique_ptr<BSPTree> frontTree, std::unique_ptr<BSPTree> backTree, PlaneAxis nodeAxis, float nodeDistance); BSPNode(std::unique_ptr<BSPTree> frontTree, std::unique_ptr<BSPTree> backTree, PlaneAxis nodeAxis, float nodeDistance);
PlaneSide objectIsInFront(BSPObject* object); PlaneSide objectIsInFront(const BSPObject& object) const;
}; };
class BSPTree class BSPTree
@@ -66,6 +66,6 @@ namespace BSP
BSPTree(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int treeLevel); BSPTree(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int treeLevel);
void splitTree(); void splitTree();
void addObjectToTree(std::shared_ptr<BSPObject> object); void addObjectToTree(std::shared_ptr<BSPObject> object) const;
}; };
} // namespace BSP } // namespace BSP

View File

@@ -170,17 +170,17 @@ namespace
} }
} }
void loadWorldData(ufbx_scene* scene, BSPData* bsp, bool isGfxData) void loadWorldData(const ufbx_scene& scene, BSPData& bsp, const bool isGfxData)
{ {
bool hasTangentSpace = true; bool hasTangentSpace = true;
for (ufbx_node* node : scene->nodes) for (ufbx_node* node : scene.nodes)
{ {
if (node->attrib_type == UFBX_ELEMENT_MESH) if (node->attrib_type == UFBX_ELEMENT_MESH)
{ {
if (isGfxData) if (isGfxData)
addFBXMeshToWorld(node, bsp->gfxWorld.surfaces, bsp->gfxWorld.vertices, bsp->gfxWorld.indices, hasTangentSpace); addFBXMeshToWorld(node, bsp.gfxWorld.surfaces, bsp.gfxWorld.vertices, bsp.gfxWorld.indices, hasTangentSpace);
else else
addFBXMeshToWorld(node, bsp->colWorld.surfaces, bsp->colWorld.vertices, bsp->colWorld.indices, hasTangentSpace); addFBXMeshToWorld(node, bsp.colWorld.surfaces, bsp.colWorld.vertices, bsp.colWorld.indices, hasTangentSpace);
} }
else else
{ {
@@ -195,7 +195,7 @@ namespace
namespace BSP namespace BSP
{ {
std::unique_ptr<BSPData> createBSPData(std::string& mapName, ISearchPath& searchPath) std::unique_ptr<BSPData> createBSPData(const std::string& mapName, ISearchPath& searchPath)
{ {
std::string gfxFbxFileName = "map_gfx.fbx"; std::string gfxFbxFileName = "map_gfx.fbx";
std::string gfxFbxPath = BSPUtil::getFileNameForBSPAsset(gfxFbxFileName); std::string gfxFbxPath = BSPUtil::getFileNameForBSPAsset(gfxFbxFileName);
@@ -228,8 +228,8 @@ namespace BSP
ufbx_scene* colScene; ufbx_scene* colScene;
std::string colFbxFileName = "map_col.fbx"; std::string colFbxFileName = "map_col.fbx";
std::string colFbxPath = BSPUtil::getFileNameForBSPAsset(colFbxFileName); const auto colFbxPath = BSPUtil::getFileNameForBSPAsset(colFbxFileName);
auto colFile = searchPath.Open(colFbxPath); const auto colFile = searchPath.Open(colFbxPath);
if (!colFile.IsOpen()) if (!colFile.IsOpen())
{ {
con::warn("Failed to open map collison fbx file: {}. map gfx will be used for collision instead.", colFbxPath); con::warn("Failed to open map collison fbx file: {}. map gfx will be used for collision instead.", colFbxPath);
@@ -264,8 +264,8 @@ namespace BSP
bsp->name = mapName; bsp->name = mapName;
bsp->bspName = "maps/mp/" + mapName + ".d3dbsp"; bsp->bspName = "maps/mp/" + mapName + ".d3dbsp";
loadWorldData(gfxScene, bsp.get(), true); loadWorldData(*gfxScene, *bsp, true);
loadWorldData(colScene, bsp.get(), false); loadWorldData(*colScene, *bsp, false);
ufbx_free_scene(gfxScene); ufbx_free_scene(gfxScene);
if (gfxScene != colScene) if (gfxScene != colScene)

View File

@@ -5,5 +5,5 @@
namespace BSP namespace BSP
{ {
std::unique_ptr<BSPData> createBSPData(std::string& mapName, ISearchPath& searchPath); std::unique_ptr<BSPData> createBSPData(const std::string& mapName, ISearchPath& searchPath);
}; // namespace BSP }; // namespace BSP

View File

@@ -8,12 +8,12 @@ using namespace T6;
namespace BSP namespace BSP
{ {
std::string BSPUtil::getFileNameForBSPAsset(std::string& assetName) std::string BSPUtil::getFileNameForBSPAsset(const std::string& assetName)
{ {
return std::format("BSP/{}", assetName); return std::format("BSP/{}", assetName);
} }
vec3_t BSPUtil::convertToBO2Coords(vec3_t& coordinate) vec3_t BSPUtil::convertToBO2Coords(const vec3_t& coordinate)
{ {
vec3_t result; vec3_t result;
result.x = coordinate.x; result.x = coordinate.x;
@@ -22,7 +22,7 @@ namespace BSP
return result; return result;
} }
vec3_t BSPUtil::convertFromBO2Coords(vec3_t& coordinate) vec3_t BSPUtil::convertFromBO2Coords(const vec3_t& coordinate)
{ {
vec3_t result; vec3_t result;
result.x = coordinate.x; result.x = coordinate.x;
@@ -31,7 +31,7 @@ namespace BSP
return result; return result;
} }
void BSPUtil::updateAABB(vec3_t& newAABBMins, vec3_t& newAABBMaxs, vec3_t& AABBMins, vec3_t& AABBMaxs) void BSPUtil::updateAABB(const vec3_t& newAABBMins, const vec3_t& newAABBMaxs, vec3_t& AABBMins, vec3_t& AABBMaxs)
{ {
AABBMins.x = std::min(AABBMins.x, newAABBMins.x); AABBMins.x = std::min(AABBMins.x, newAABBMins.x);
AABBMaxs.x = std::max(AABBMaxs.x, newAABBMaxs.x); AABBMaxs.x = std::max(AABBMaxs.x, newAABBMaxs.x);
@@ -43,7 +43,7 @@ namespace BSP
AABBMaxs.z = std::max(AABBMaxs.z, newAABBMaxs.z); AABBMaxs.z = std::max(AABBMaxs.z, newAABBMaxs.z);
} }
void BSPUtil::updateAABBWithPoint(vec3_t& point, vec3_t& AABBMins, vec3_t& AABBMaxs) void BSPUtil::updateAABBWithPoint(const vec3_t& point, vec3_t& AABBMins, vec3_t& AABBMaxs)
{ {
AABBMins.x = std::min(AABBMins.x, point.x); AABBMins.x = std::min(AABBMins.x, point.x);
AABBMaxs.x = std::max(AABBMaxs.x, point.x); AABBMaxs.x = std::max(AABBMaxs.x, point.x);
@@ -55,7 +55,7 @@ namespace BSP
AABBMaxs.z = std::max(AABBMaxs.z, point.z); AABBMaxs.z = std::max(AABBMaxs.z, point.z);
} }
vec3_t BSPUtil::calcMiddleOfAABB(vec3_t& mins, vec3_t& maxs) vec3_t BSPUtil::calcMiddleOfAABB(const vec3_t& mins, const vec3_t& maxs)
{ {
vec3_t result; vec3_t result;
result.x = (mins.x + maxs.x) * 0.5f; result.x = (mins.x + maxs.x) * 0.5f;
@@ -64,7 +64,7 @@ namespace BSP
return result; return result;
} }
vec3_t BSPUtil::calcHalfSizeOfAABB(vec3_t& mins, vec3_t& maxs) vec3_t BSPUtil::calcHalfSizeOfAABB(const vec3_t& mins, const vec3_t& maxs)
{ {
vec3_t result; vec3_t result;
result.x = (maxs.x - mins.x) * 0.5f; result.x = (maxs.x - mins.x) * 0.5f;
@@ -73,27 +73,28 @@ namespace BSP
return result; return result;
} }
float BSPUtil::distBetweenPoints(vec3_t& p1, vec3_t& p2) float BSPUtil::distBetweenPoints(const vec3_t& p1, const vec3_t& p2)
{ {
float x = p2.x - p1.x; const float x = p2.x - p1.x;
float y = p2.y - p1.y; const float y = p2.y - p1.y;
float z = p2.z - p1.z; const float z = p2.z - p1.z;
return sqrtf((x * x) + (y * y) + (z * z)); return sqrtf((x * x) + (y * y) + (z * z));
} }
// angles are in euler degrees // angles are in euler degrees
void BSPUtil::convertAnglesToAxis(vec3_t* angles, vec3_t* axis) void BSPUtil::convertAnglesToAxis(const vec3_t* angles, vec3_t* axis)
{ {
float xRadians = angles->x * 0.017453292f; // M_PI / 180.0f const float xRadians = angles->x * 0.017453292f; // M_PI / 180.0f
float yRadians = angles->y * 0.017453292f; // M_PI / 180.0f const float yRadians = angles->y * 0.017453292f; // M_PI / 180.0f
float zRadians = angles->z * 0.017453292f; // M_PI / 180.0f const float zRadians = angles->z * 0.017453292f; // M_PI / 180.0f
float cosX = cos(xRadians); const float cosX = cos(xRadians);
float sinX = sin(xRadians); const float sinX = sin(xRadians);
float cosY = cos(yRadians); const float cosY = cos(yRadians);
float sinY = sin(yRadians); const float sinY = sin(yRadians);
float cosZ = cos(zRadians); const float cosZ = cos(zRadians);
float sinZ = sin(zRadians); const float sinZ = sin(zRadians);
axis[0].x = cosX * cosY; axis[0].x = cosX * cosY;
axis[0].y = cosX * sinY; axis[0].y = cosX * sinY;

View File

@@ -7,15 +7,15 @@ namespace BSP
class BSPUtil class BSPUtil
{ {
public: public:
static std::string getFileNameForBSPAsset(std::string& assetName); static std::string getFileNameForBSPAsset(const std::string& assetName);
static T6::vec3_t convertToBO2Coords(T6::vec3_t& OGL_coordinate); static T6::vec3_t convertToBO2Coords(const T6::vec3_t& OGL_coordinate);
static T6::vec3_t convertFromBO2Coords(T6::vec3_t& bo2_coordinate); static T6::vec3_t convertFromBO2Coords(const T6::vec3_t& bo2_coordinate);
static void updateAABB(T6::vec3_t& newAABBMins, T6::vec3_t& newAABBMaxs, T6::vec3_t& AABBMins, T6::vec3_t& AABBMaxs); static void updateAABB(const T6::vec3_t& newAABBMins, const T6::vec3_t& newAABBMaxs, T6::vec3_t& AABBMins, T6::vec3_t& AABBMaxs);
static void updateAABBWithPoint(T6::vec3_t& point, T6::vec3_t& AABBMins, T6::vec3_t& AABBMaxs); static void updateAABBWithPoint(const T6::vec3_t& point, T6::vec3_t& AABBMins, T6::vec3_t& AABBMaxs);
static T6::vec3_t calcMiddleOfAABB(T6::vec3_t& mins, T6::vec3_t& maxs); static T6::vec3_t calcMiddleOfAABB(const T6::vec3_t& mins, const T6::vec3_t& maxs);
static T6::vec3_t calcHalfSizeOfAABB(T6::vec3_t& mins, T6::vec3_t& maxs); static T6::vec3_t calcHalfSizeOfAABB(const T6::vec3_t& mins, const T6::vec3_t& maxs);
static float distBetweenPoints(T6::vec3_t& p1, T6::vec3_t& p2); static float distBetweenPoints(const T6::vec3_t& p1, const T6::vec3_t& p2);
static void convertAnglesToAxis(T6::vec3_t* angles, T6::vec3_t* axis); static void convertAnglesToAxis(const T6::vec3_t* angles, T6::vec3_t* axis);
static void matrixTranspose3x3(const T6::vec3_t* in, T6::vec3_t* out); static void matrixTranspose3x3(const T6::vec3_t* in, T6::vec3_t* out);
}; };
} // namespace BSP } // namespace BSP

View File

@@ -11,7 +11,7 @@ using namespace T6;
namespace BSP namespace BSP
{ {
FootstepTableDef* BSPLinker::addEmptyFootstepTableAsset(std::string assetName) FootstepTableDef* BSPLinker::addEmptyFootstepTableAsset(const std::string& assetName) const
{ {
if (assetName.length() == 0) if (assetName.length() == 0)
return nullptr; return nullptr;
@@ -25,20 +25,20 @@ namespace BSP
return footstepTable; return footstepTable;
} }
bool BSPLinker::addDefaultRequiredAssets(BSPData* bsp) bool BSPLinker::addDefaultRequiredAssets(const BSPData& bsp) const
{ {
if (m_context.LoadDependency<AssetScript>("maps/mp/" + bsp->name + ".gsc") == nullptr) if (m_context.LoadDependency<AssetScript>("maps/mp/" + bsp.name + ".gsc") == nullptr)
return false; return false;
if (m_context.LoadDependency<AssetScript>("maps/mp/" + bsp->name + "_amb.gsc") == nullptr) if (m_context.LoadDependency<AssetScript>("maps/mp/" + bsp.name + "_amb.gsc") == nullptr)
return false; return false;
if (m_context.LoadDependency<AssetScript>("maps/mp/" + bsp->name + "_fx.gsc") == nullptr) if (m_context.LoadDependency<AssetScript>("maps/mp/" + bsp.name + "_fx.gsc") == nullptr)
return false; return false;
if (m_context.LoadDependency<AssetScript>("clientscripts/mp/" + bsp->name + ".csc") == nullptr) if (m_context.LoadDependency<AssetScript>("clientscripts/mp/" + bsp.name + ".csc") == nullptr)
return false; return false;
if (m_context.LoadDependency<AssetScript>("clientscripts/mp/" + bsp->name + "_amb.csc") == nullptr) if (m_context.LoadDependency<AssetScript>("clientscripts/mp/" + bsp.name + "_amb.csc") == nullptr)
return false; return false;
if (m_context.LoadDependency<AssetScript>("clientscripts/mp/" + bsp->name + "_fx.csc") == nullptr) if (m_context.LoadDependency<AssetScript>("clientscripts/mp/" + bsp.name + "_fx.csc") == nullptr)
return false; return false;
addEmptyFootstepTableAsset("default_1st_person"); addEmptyFootstepTableAsset("default_1st_person");
@@ -61,7 +61,7 @@ namespace BSP
{ {
} }
bool BSPLinker::linkBSP(BSPData* bsp) bool BSPLinker::linkBSP(const BSPData& bsp) const
{ {
if (!addDefaultRequiredAssets(bsp)) if (!addDefaultRequiredAssets(bsp))
return false; return false;

View File

@@ -11,11 +11,12 @@ namespace BSP
{ {
public: public:
BSPLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); BSPLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
bool linkBSP(BSPData* bsp);
bool linkBSP(const BSPData& bsp) const;
private: private:
T6::FootstepTableDef* addEmptyFootstepTableAsset(std::string assetName); T6::FootstepTableDef* addEmptyFootstepTableAsset(const std::string& assetName) const;
bool addDefaultRequiredAssets(BSPData* bsp); bool addDefaultRequiredAssets(const BSPData& bsp) const;
MemoryManager& m_memory; MemoryManager& m_memory;
ISearchPath& m_search_path; ISearchPath& m_search_path;

View File

@@ -2,6 +2,8 @@
#include "Game/T6/BSP/BSPUtil.h" #include "Game/T6/BSP/BSPUtil.h"
#include <cassert>
using namespace T6; using namespace T6;
namespace BSP namespace BSP
@@ -13,45 +15,45 @@ namespace BSP
{ {
} }
void ClipMapLinker::loadDynEnts(clipMap_t* clipMap) void ClipMapLinker::loadDynEnts(clipMap_t& clipMap) const
{ {
int dynEntCount = 0; int dynEntCount = 0;
clipMap->originalDynEntCount = dynEntCount; clipMap.originalDynEntCount = dynEntCount;
clipMap->dynEntCount[0] = clipMap->originalDynEntCount + 256; // the game allocs 256 empty dynents, as they may be used ingame clipMap.dynEntCount[0] = clipMap.originalDynEntCount + 256; // the game allocs 256 empty dynents, as they may be used ingame
clipMap->dynEntCount[1] = 0; clipMap.dynEntCount[1] = 0;
clipMap->dynEntCount[2] = 0; clipMap.dynEntCount[2] = 0;
clipMap->dynEntCount[3] = 0; clipMap.dynEntCount[3] = 0;
clipMap->dynEntClientList[0] = m_memory.Alloc<DynEntityClient>(clipMap->dynEntCount[0]); clipMap.dynEntClientList[0] = m_memory.Alloc<DynEntityClient>(clipMap.dynEntCount[0]);
clipMap->dynEntClientList[1] = nullptr; clipMap.dynEntClientList[1] = nullptr;
clipMap->dynEntServerList[0] = nullptr; clipMap.dynEntServerList[0] = nullptr;
clipMap->dynEntServerList[1] = nullptr; clipMap.dynEntServerList[1] = nullptr;
clipMap->dynEntCollList[0] = m_memory.Alloc<DynEntityColl>(clipMap->dynEntCount[0]); clipMap.dynEntCollList[0] = m_memory.Alloc<DynEntityColl>(clipMap.dynEntCount[0]);
clipMap->dynEntCollList[1] = nullptr; clipMap.dynEntCollList[1] = nullptr;
clipMap->dynEntCollList[2] = nullptr; clipMap.dynEntCollList[2] = nullptr;
clipMap->dynEntCollList[3] = nullptr; clipMap.dynEntCollList[3] = nullptr;
clipMap->dynEntPoseList[0] = m_memory.Alloc<DynEntityPose>(clipMap->dynEntCount[0]); clipMap.dynEntPoseList[0] = m_memory.Alloc<DynEntityPose>(clipMap.dynEntCount[0]);
clipMap->dynEntPoseList[1] = nullptr; clipMap.dynEntPoseList[1] = nullptr;
clipMap->dynEntDefList[0] = m_memory.Alloc<DynEntityDef>(clipMap->dynEntCount[0]); clipMap.dynEntDefList[0] = m_memory.Alloc<DynEntityDef>(clipMap.dynEntCount[0]);
clipMap->dynEntDefList[1] = nullptr; clipMap.dynEntDefList[1] = nullptr;
} }
void ClipMapLinker::loadVisibility(clipMap_t* clipMap) void ClipMapLinker::loadVisibility(clipMap_t& clipMap) const
{ {
// Only use one visbility cluster for the entire map // Only use one visbility cluster for the entire map
clipMap->numClusters = 1; clipMap.numClusters = 1;
clipMap->vised = 0; clipMap.vised = 0;
clipMap->clusterBytes = ((clipMap->numClusters + 63) >> 3) & 0xFFFFFFF8; clipMap.clusterBytes = ((clipMap.numClusters + 63) >> 3) & 0xFFFFFFF8;
clipMap->visibility = m_memory.Alloc<char>(clipMap->clusterBytes); clipMap.visibility = m_memory.Alloc<char>(clipMap.clusterBytes);
// Official maps set visibility to all 0xFF // Official maps set visibility to all 0xFF
memset(clipMap->visibility, 0xFF, clipMap->clusterBytes); memset(clipMap.visibility, 0xFF, clipMap.clusterBytes);
} }
void ClipMapLinker::loadBoxData(clipMap_t* clipMap) void ClipMapLinker::loadBoxData(clipMap_t& clipMap) const
{ {
// box_model and box_brush are what are used by game traces as "temporary" collision when // box_model and box_brush are what are used by game traces as "temporary" collision when
// no brush or model is specified to do the trace with. // no brush or model is specified to do the trace with.
@@ -64,108 +66,108 @@ namespace BSP
// so we use the hex representation and set it using int pointers. // so we use the hex representation and set it using int pointers.
unsigned int box_mins = 0x7F7FFFFF; unsigned int box_mins = 0x7F7FFFFF;
unsigned int box_maxs = 0xFF7FFFFF; unsigned int box_maxs = 0xFF7FFFFF;
*(reinterpret_cast<unsigned int*>(&clipMap->box_model.leaf.mins.x)) = box_mins; *(reinterpret_cast<unsigned int*>(&clipMap.box_model.leaf.mins.x)) = box_mins;
*(reinterpret_cast<unsigned int*>(&clipMap->box_model.leaf.mins.y)) = box_mins; *(reinterpret_cast<unsigned int*>(&clipMap.box_model.leaf.mins.y)) = box_mins;
*(reinterpret_cast<unsigned int*>(&clipMap->box_model.leaf.mins.z)) = box_mins; *(reinterpret_cast<unsigned int*>(&clipMap.box_model.leaf.mins.z)) = box_mins;
*(reinterpret_cast<unsigned int*>(&clipMap->box_model.leaf.maxs.x)) = box_maxs; *(reinterpret_cast<unsigned int*>(&clipMap.box_model.leaf.maxs.x)) = box_maxs;
*(reinterpret_cast<unsigned int*>(&clipMap->box_model.leaf.maxs.y)) = box_maxs; *(reinterpret_cast<unsigned int*>(&clipMap.box_model.leaf.maxs.y)) = box_maxs;
*(reinterpret_cast<unsigned int*>(&clipMap->box_model.leaf.maxs.z)) = box_maxs; *(reinterpret_cast<unsigned int*>(&clipMap.box_model.leaf.maxs.z)) = box_maxs;
clipMap->box_model.leaf.brushContents = -1; clipMap.box_model.leaf.brushContents = -1;
clipMap->box_model.leaf.terrainContents = 0; clipMap.box_model.leaf.terrainContents = 0;
clipMap->box_model.leaf.cluster = 0; clipMap.box_model.leaf.cluster = 0;
clipMap->box_model.leaf.collAabbCount = 0; clipMap.box_model.leaf.collAabbCount = 0;
clipMap->box_model.leaf.firstCollAabbIndex = 0; clipMap.box_model.leaf.firstCollAabbIndex = 0;
clipMap->box_model.leaf.leafBrushNode = 0; clipMap.box_model.leaf.leafBrushNode = 0;
clipMap->box_model.mins.x = 0.0f; clipMap.box_model.mins.x = 0.0f;
clipMap->box_model.mins.y = 0.0f; clipMap.box_model.mins.y = 0.0f;
clipMap->box_model.mins.z = 0.0f; clipMap.box_model.mins.z = 0.0f;
clipMap->box_model.maxs.x = 0.0f; clipMap.box_model.maxs.x = 0.0f;
clipMap->box_model.maxs.y = 0.0f; clipMap.box_model.maxs.y = 0.0f;
clipMap->box_model.maxs.z = 0.0f; clipMap.box_model.maxs.z = 0.0f;
clipMap->box_model.radius = 0.0f; clipMap.box_model.radius = 0.0f;
clipMap->box_model.info = nullptr; clipMap.box_model.info = nullptr;
clipMap->box_brush = m_memory.Alloc<cbrush_t>(); clipMap.box_brush = m_memory.Alloc<cbrush_t>();
clipMap->box_brush->axial_sflags[0][0] = -1; clipMap.box_brush->axial_sflags[0][0] = -1;
clipMap->box_brush->axial_sflags[0][1] = -1; clipMap.box_brush->axial_sflags[0][1] = -1;
clipMap->box_brush->axial_sflags[0][2] = -1; clipMap.box_brush->axial_sflags[0][2] = -1;
clipMap->box_brush->axial_sflags[1][0] = -1; clipMap.box_brush->axial_sflags[1][0] = -1;
clipMap->box_brush->axial_sflags[1][1] = -1; clipMap.box_brush->axial_sflags[1][1] = -1;
clipMap->box_brush->axial_sflags[1][2] = -1; clipMap.box_brush->axial_sflags[1][2] = -1;
clipMap->box_brush->axial_cflags[0][0] = -1; clipMap.box_brush->axial_cflags[0][0] = -1;
clipMap->box_brush->axial_cflags[0][1] = -1; clipMap.box_brush->axial_cflags[0][1] = -1;
clipMap->box_brush->axial_cflags[0][2] = -1; clipMap.box_brush->axial_cflags[0][2] = -1;
clipMap->box_brush->axial_cflags[1][0] = -1; clipMap.box_brush->axial_cflags[1][0] = -1;
clipMap->box_brush->axial_cflags[1][1] = -1; clipMap.box_brush->axial_cflags[1][1] = -1;
clipMap->box_brush->axial_cflags[1][2] = -1; clipMap.box_brush->axial_cflags[1][2] = -1;
clipMap->box_brush->contents = -1; clipMap.box_brush->contents = -1;
clipMap->box_brush->mins.x = 0.0f; clipMap.box_brush->mins.x = 0.0f;
clipMap->box_brush->mins.y = 0.0f; clipMap.box_brush->mins.y = 0.0f;
clipMap->box_brush->mins.z = 0.0f; clipMap.box_brush->mins.z = 0.0f;
clipMap->box_brush->maxs.x = 0.0f; clipMap.box_brush->maxs.x = 0.0f;
clipMap->box_brush->maxs.y = 0.0f; clipMap.box_brush->maxs.y = 0.0f;
clipMap->box_brush->maxs.z = 0.0f; clipMap.box_brush->maxs.z = 0.0f;
clipMap->box_brush->numsides = 0; clipMap.box_brush->numsides = 0;
clipMap->box_brush->numverts = 0; clipMap.box_brush->numverts = 0;
clipMap->box_brush->sides = nullptr; clipMap.box_brush->sides = nullptr;
clipMap->box_brush->verts = nullptr; clipMap.box_brush->verts = nullptr;
} }
void ClipMapLinker::loadRopesAndConstraints(clipMap_t* clipMap) void ClipMapLinker::loadRopesAndConstraints(clipMap_t& clipMap) const
{ {
clipMap->num_constraints = 0; // max 511 clipMap.num_constraints = 0; // max 511
clipMap->constraints = nullptr; clipMap.constraints = nullptr;
// The game allocates 32 empty ropes // The game allocates 32 empty ropes
clipMap->max_ropes = 32; // max 300 clipMap.max_ropes = 32; // max 300
clipMap->ropes = m_memory.Alloc<rope_t>(clipMap->max_ropes); clipMap.ropes = m_memory.Alloc<rope_t>(clipMap.max_ropes);
} }
void ClipMapLinker::loadSubModelCollision(clipMap_t* clipMap, BSPData* bsp) void ClipMapLinker::loadSubModelCollision(clipMap_t& clipMap, const BSPData& bsp) const
{ {
// Submodels are used for the world and map ent collision (triggers, bomb zones, etc) // Submodels are used for the world and map ent collision (triggers, bomb zones, etc)
auto gfxWorldAsset = m_context.LoadDependency<AssetGfxWorld>(bsp->bspName); auto gfxWorldAsset = m_context.LoadDependency<AssetGfxWorld>(bsp.bspName);
assert(gfxWorldAsset != nullptr); assert(gfxWorldAsset != nullptr);
GfxWorld* gfxWorld = gfxWorldAsset->Asset(); GfxWorld* gfxWorld = gfxWorldAsset->Asset();
// Right now there is only one submodel, the world sub model // Right now there is only one submodel, the world sub model
assert(gfxWorld->modelCount == 1); assert(gfxWorld->modelCount == 1);
clipMap->numSubModels = 1; clipMap.numSubModels = 1;
clipMap->cmodels = m_memory.Alloc<cmodel_t>(clipMap->numSubModels); clipMap.cmodels = m_memory.Alloc<cmodel_t>(clipMap.numSubModels);
GfxBrushModel* gfxModel = &gfxWorld->models[0]; GfxBrushModel* gfxModel = &gfxWorld->models[0];
clipMap->cmodels[0].mins.x = gfxModel->bounds[0].x; clipMap.cmodels[0].mins.x = gfxModel->bounds[0].x;
clipMap->cmodels[0].mins.y = gfxModel->bounds[0].y; clipMap.cmodels[0].mins.y = gfxModel->bounds[0].y;
clipMap->cmodels[0].mins.z = gfxModel->bounds[0].z; clipMap.cmodels[0].mins.z = gfxModel->bounds[0].z;
clipMap->cmodels[0].maxs.x = gfxModel->bounds[1].x; clipMap.cmodels[0].maxs.x = gfxModel->bounds[1].x;
clipMap->cmodels[0].maxs.y = gfxModel->bounds[1].y; clipMap.cmodels[0].maxs.y = gfxModel->bounds[1].y;
clipMap->cmodels[0].maxs.z = gfxModel->bounds[1].z; clipMap.cmodels[0].maxs.z = gfxModel->bounds[1].z;
clipMap->cmodels[0].radius = BSPUtil::distBetweenPoints(clipMap->cmodels[0].mins, clipMap->cmodels[0].maxs) / 2; clipMap.cmodels[0].radius = BSPUtil::distBetweenPoints(clipMap.cmodels[0].mins, clipMap.cmodels[0].maxs) / 2;
// The world sub model has no leafs associated with it // The world sub model has no leafs associated with it
clipMap->cmodels[0].leaf.firstCollAabbIndex = 0; clipMap.cmodels[0].leaf.firstCollAabbIndex = 0;
clipMap->cmodels[0].leaf.collAabbCount = 0; clipMap.cmodels[0].leaf.collAabbCount = 0;
clipMap->cmodels[0].leaf.brushContents = 0; clipMap.cmodels[0].leaf.brushContents = 0;
clipMap->cmodels[0].leaf.terrainContents = 0; clipMap.cmodels[0].leaf.terrainContents = 0;
clipMap->cmodels[0].leaf.mins.x = 0.0f; clipMap.cmodels[0].leaf.mins.x = 0.0f;
clipMap->cmodels[0].leaf.mins.y = 0.0f; clipMap.cmodels[0].leaf.mins.y = 0.0f;
clipMap->cmodels[0].leaf.mins.z = 0.0f; clipMap.cmodels[0].leaf.mins.z = 0.0f;
clipMap->cmodels[0].leaf.maxs.x = 0.0f; clipMap.cmodels[0].leaf.maxs.x = 0.0f;
clipMap->cmodels[0].leaf.maxs.y = 0.0f; clipMap.cmodels[0].leaf.maxs.y = 0.0f;
clipMap->cmodels[0].leaf.maxs.z = 0.0f; clipMap.cmodels[0].leaf.maxs.z = 0.0f;
clipMap->cmodels[0].leaf.leafBrushNode = 0; clipMap.cmodels[0].leaf.leafBrushNode = 0;
clipMap->cmodels[0].leaf.cluster = 0; clipMap.cmodels[0].leaf.cluster = 0;
clipMap->cmodels[0].info = nullptr; // always set to 0 clipMap.cmodels[0].info = nullptr; // always set to 0
} }
void ClipMapLinker::loadXModelCollision(clipMap_t* clipMap) void ClipMapLinker::loadXModelCollision(clipMap_t& clipMap) const
{ {
// Right now XModels aren't supported // Right now XModels aren't supported
clipMap->numStaticModels = 0; clipMap.numStaticModels = 0;
clipMap->staticModelList = nullptr; clipMap.staticModelList = nullptr;
// WIP code left in for future support // WIP code left in for future support
/* /*
@@ -211,11 +213,11 @@ namespace BSP
*/ */
} }
void ClipMapLinker::addAABBTreeFromLeaf(clipMap_t* clipMap, BSPTree* tree, size_t* out_parentCount, size_t* out_parentStartIndex) void ClipMapLinker::addAABBTreeFromLeaf(clipMap_t& clipMap, const BSPTree& tree, size_t& outParentCount, size_t& outParentStartIndex)
{ {
assert(tree->isLeaf); assert(tree.isLeaf);
size_t leafObjectCount = tree->leaf->getObjectCount(); size_t leafObjectCount = tree.leaf->getObjectCount();
assert(leafObjectCount > 0); assert(leafObjectCount > 0);
highestLeafObjectCount = std::max(leafObjectCount, highestLeafObjectCount); highestLeafObjectCount = std::max(leafObjectCount, highestLeafObjectCount);
@@ -244,12 +246,12 @@ namespace BSP
vec3_t parentMaxs; vec3_t parentMaxs;
for (size_t objectIdx = 0; objectIdx < childObjectCount; objectIdx++) for (size_t objectIdx = 0; objectIdx < childObjectCount; objectIdx++)
{ {
int partitionIndex = tree->leaf->getObject(addedObjectCount + objectIdx)->partitionIndex; int partitionIndex = tree.leaf->getObject(addedObjectCount + objectIdx)->partitionIndex;
CollisionPartition* partition = &clipMap->partitions[partitionIndex]; CollisionPartition* partition = &clipMap.partitions[partitionIndex];
for (int uindIdx = 0; uindIdx < partition->nuinds; uindIdx++) for (int uindIdx = 0; uindIdx < partition->nuinds; uindIdx++)
{ {
uint16_t uind = clipMap->info.uinds[partition->fuind + uindIdx]; uint16_t uind = clipMap.info.uinds[partition->fuind + uindIdx];
vec3_t vert = clipMap->verts[uind]; vec3_t vert = clipMap.verts[uind];
// initalise the parent AABB with the first vertex // initalise the parent AABB with the first vertex
if (objectIdx == 0 && uindIdx == 0) if (objectIdx == 0 && uindIdx == 0)
@@ -274,14 +276,14 @@ namespace BSP
// add child AABBs // add child AABBs
for (size_t objectIdx = 0; objectIdx < childObjectCount; objectIdx++) for (size_t objectIdx = 0; objectIdx < childObjectCount; objectIdx++)
{ {
int partitionIndex = tree->leaf->getObject(addedObjectCount + objectIdx)->partitionIndex; int partitionIndex = tree.leaf->getObject(addedObjectCount + objectIdx)->partitionIndex;
CollisionPartition* partition = &clipMap->partitions[partitionIndex]; CollisionPartition* partition = &clipMap.partitions[partitionIndex];
vec3_t childMins; vec3_t childMins;
vec3_t childMaxs; vec3_t childMaxs;
for (int uindIdx = 0; uindIdx < partition->nuinds; uindIdx++) for (int uindIdx = 0; uindIdx < partition->nuinds; uindIdx++)
{ {
uint16_t uind = clipMap->info.uinds[partition->fuind + uindIdx]; uint16_t uind = clipMap.info.uinds[partition->fuind + uindIdx];
vec3_t vert = clipMap->verts[uind]; vec3_t vert = clipMap.verts[uind];
// initalise the child AABB with the first vertex // initalise the child AABB with the first vertex
if (uindIdx == 0) if (uindIdx == 0)
@@ -305,8 +307,8 @@ namespace BSP
addedObjectCount += childObjectCount; addedObjectCount += childObjectCount;
} }
*out_parentCount = parentCount; outParentCount = parentCount;
*out_parentStartIndex = parentAABBArrayIndex; outParentStartIndex = parentAABBArrayIndex;
} }
constexpr vec3_t normalX = {1.0f, 0.0f, 0.0f}; constexpr vec3_t normalX = {1.0f, 0.0f, 0.0f};
@@ -317,9 +319,9 @@ namespace BSP
// Nodes are indexed by their index in the node array // Nodes are indexed by their index in the node array
// Leafs are indexed by (-1 - <leaf index>) // Leafs are indexed by (-1 - <leaf index>)
// See https://developer.valvesoftware.com/wiki/BSP_(Source) // See https://developer.valvesoftware.com/wiki/BSP_(Source)
int16_t ClipMapLinker::loadBSPNode(clipMap_t* clipMap, BSPTree* tree) int16_t ClipMapLinker::loadBSPNode(clipMap_t& clipMap, const BSPTree& tree)
{ {
if (tree->isLeaf) if (tree.isLeaf)
{ {
cLeaf_s leaf; cLeaf_s leaf;
@@ -336,11 +338,11 @@ namespace BSP
leaf.maxs.z = 0.0f; leaf.maxs.z = 0.0f;
leaf.leafBrushNode = 0; leaf.leafBrushNode = 0;
if (tree->leaf->getObjectCount() > 0) if (tree.leaf->getObjectCount() > 0)
{ {
size_t parentCount = 0; size_t parentCount = 0;
size_t parentStartIndex = 0; size_t parentStartIndex = 0;
addAABBTreeFromLeaf(clipMap, tree, &parentCount, &parentStartIndex); addAABBTreeFromLeaf(clipMap, tree, parentCount, parentStartIndex);
leaf.collAabbCount = static_cast<uint16_t>(parentCount); leaf.collAabbCount = static_cast<uint16_t>(parentCount);
leaf.firstCollAabbIndex = static_cast<uint16_t>(parentStartIndex); leaf.firstCollAabbIndex = static_cast<uint16_t>(parentStartIndex);
} }
@@ -358,13 +360,13 @@ namespace BSP
else else
{ {
cplane_s plane; cplane_s plane;
plane.dist = tree->node->distance; plane.dist = tree.node->distance;
if (tree->node->axis == AXIS_X) if (tree.node->axis == AXIS_X)
{ {
plane.normal = normalX; plane.normal = normalX;
plane.type = 0; plane.type = 0;
} }
else if (tree->node->axis == AXIS_Y) else if (tree.node->axis == AXIS_Y)
{ {
plane.normal = normalY; plane.normal = normalY;
plane.type = 1; plane.type = 1;
@@ -394,8 +396,8 @@ namespace BSP
cNode_t node; cNode_t node;
node.plane = nullptr; // initalised after the BSP tree has been loaded node.plane = nullptr; // initalised after the BSP tree has been loaded
node.children[0] = loadBSPNode(clipMap, tree->node->front.get()); node.children[0] = loadBSPNode(clipMap, *tree.node->front);
node.children[1] = loadBSPNode(clipMap, tree->node->back.get()); node.children[1] = loadBSPNode(clipMap, *tree.node->back);
nodeVec.at(nodeIndex) = node; nodeVec.at(nodeIndex) = node;
@@ -403,13 +405,13 @@ namespace BSP
} }
} }
void ClipMapLinker::loadBSPTree(clipMap_t* clipMap, BSPData* bsp) void ClipMapLinker::loadBSPTree(clipMap_t& clipMap, const BSPData& bsp)
{ {
vec3_t worldMins; vec3_t worldMins;
vec3_t worldMaxs; vec3_t worldMaxs;
for (unsigned int vertIdx = 0; vertIdx < clipMap->vertCount; vertIdx++) for (unsigned int vertIdx = 0; vertIdx < clipMap.vertCount; vertIdx++)
{ {
vec3_t vertex = clipMap->verts[vertIdx]; vec3_t vertex = clipMap.verts[vertIdx];
// initalise AABB with the first vertex // initalise AABB with the first vertex
if (vertIdx == 0) if (vertIdx == 0)
{ {
@@ -421,15 +423,15 @@ namespace BSP
std::unique_ptr<BSPTree> tree = std::make_unique<BSPTree>(worldMins.x, worldMins.y, worldMins.z, worldMaxs.x, worldMaxs.y, worldMaxs.z, 0); std::unique_ptr<BSPTree> tree = std::make_unique<BSPTree>(worldMins.x, worldMins.y, worldMins.z, worldMaxs.x, worldMaxs.y, worldMaxs.z, 0);
assert(!tree->isLeaf); assert(!tree->isLeaf);
for (int partitionIdx = 0; partitionIdx < clipMap->partitionCount; partitionIdx++) for (int partitionIdx = 0; partitionIdx < clipMap.partitionCount; partitionIdx++)
{ {
vec3_t partitionMins; vec3_t partitionMins;
vec3_t partitionMaxs; vec3_t partitionMaxs;
CollisionPartition* partition = &clipMap->partitions[partitionIdx]; CollisionPartition* partition = &clipMap.partitions[partitionIdx];
for (int uindIdx = 0; uindIdx < partition->nuinds; uindIdx++) for (int uindIdx = 0; uindIdx < partition->nuinds; uindIdx++)
{ {
uint16_t uind = clipMap->info.uinds[partition->fuind + uindIdx]; uint16_t uind = clipMap.info.uinds[partition->fuind + uindIdx];
vec3_t vert = clipMap->verts[uind]; vec3_t vert = clipMap.verts[uind];
// initalise the AABB with the first vertex // initalise the AABB with the first vertex
if (uindIdx == 0) if (uindIdx == 0)
{ {
@@ -444,74 +446,74 @@ namespace BSP
} }
// load planes, nodes, leafs, and AABB trees // load planes, nodes, leafs, and AABB trees
loadBSPNode(clipMap, tree.get()); loadBSPNode(clipMap, *tree);
clipMap->info.planeCount = static_cast<int>(planeVec.size()); clipMap.info.planeCount = static_cast<int>(planeVec.size());
clipMap->info.planes = m_memory.Alloc<cplane_s>(planeVec.size()); clipMap.info.planes = m_memory.Alloc<cplane_s>(planeVec.size());
memcpy(clipMap->info.planes, planeVec.data(), sizeof(cplane_s) * planeVec.size()); memcpy(clipMap.info.planes, planeVec.data(), sizeof(cplane_s) * planeVec.size());
clipMap->numNodes = static_cast<unsigned int>(nodeVec.size()); clipMap.numNodes = static_cast<unsigned int>(nodeVec.size());
clipMap->nodes = m_memory.Alloc<cNode_t>(nodeVec.size()); clipMap.nodes = m_memory.Alloc<cNode_t>(nodeVec.size());
memcpy(clipMap->nodes, nodeVec.data(), sizeof(cNode_t) * nodeVec.size()); memcpy(clipMap.nodes, nodeVec.data(), sizeof(cNode_t) * nodeVec.size());
clipMap->numLeafs = static_cast<unsigned int>(leafVec.size()); clipMap.numLeafs = static_cast<unsigned int>(leafVec.size());
clipMap->leafs = m_memory.Alloc<cLeaf_s>(leafVec.size()); clipMap.leafs = m_memory.Alloc<cLeaf_s>(leafVec.size());
memcpy(clipMap->leafs, leafVec.data(), sizeof(cLeaf_s) * leafVec.size()); memcpy(clipMap.leafs, leafVec.data(), sizeof(cLeaf_s) * leafVec.size());
clipMap->aabbTreeCount = static_cast<unsigned int>(AABBTreeVec.size()); clipMap.aabbTreeCount = static_cast<unsigned int>(AABBTreeVec.size());
clipMap->aabbTrees = m_memory.Alloc<CollisionAabbTree>(AABBTreeVec.size()); clipMap.aabbTrees = m_memory.Alloc<CollisionAabbTree>(AABBTreeVec.size());
memcpy(clipMap->aabbTrees, AABBTreeVec.data(), sizeof(CollisionAabbTree) * AABBTreeVec.size()); memcpy(clipMap.aabbTrees, AABBTreeVec.data(), sizeof(CollisionAabbTree) * AABBTreeVec.size());
// The plane of each node have the same index // The plane of each node have the same index
for (size_t nodeIdx = 0; nodeIdx < nodeVec.size(); nodeIdx++) for (size_t nodeIdx = 0; nodeIdx < nodeVec.size(); nodeIdx++)
clipMap->nodes[nodeIdx].plane = &clipMap->info.planes[nodeIdx]; clipMap.nodes[nodeIdx].plane = &clipMap.info.planes[nodeIdx];
con::info("Highest leaf object count: {}", highestLeafObjectCount); con::info("Highest leaf object count: {}", highestLeafObjectCount);
} }
bool ClipMapLinker::loadPartitions(clipMap_t* clipMap, BSPData* bsp) bool ClipMapLinker::loadPartitions(clipMap_t& clipMap, const BSPData& bsp) const
{ {
// due to tris using uint16_t as the type for indexing the vert array, // due to tris using uint16_t as the type for indexing the vert array,
// any vertex count over the uint16_t max means the vertices above the uint16_t max can't be indexed // any vertex count over the uint16_t max means the vertices above the uint16_t max can't be indexed
if (static_cast<unsigned int>(bsp->colWorld.vertices.size()) > BSPGameConstants::MAX_COLLISION_VERTS) if (static_cast<unsigned int>(bsp.colWorld.vertices.size()) > BSPGameConstants::MAX_COLLISION_VERTS)
{ {
con::error("ERROR: collision vertex count %i exceeds the maximum number: %i!\n", clipMap->vertCount, BSPGameConstants::MAX_COLLISION_VERTS); con::error("ERROR: collision vertex count %i exceeds the maximum number: %i!\n", clipMap.vertCount, BSPGameConstants::MAX_COLLISION_VERTS);
return false; return false;
} }
clipMap->vertCount = static_cast<unsigned int>(bsp->colWorld.vertices.size()); clipMap.vertCount = static_cast<unsigned int>(bsp.colWorld.vertices.size());
clipMap->verts = m_memory.Alloc<vec3_t>(clipMap->vertCount); clipMap.verts = m_memory.Alloc<vec3_t>(clipMap.vertCount);
for (unsigned int vertIdx = 0; vertIdx < clipMap->vertCount; vertIdx++) for (unsigned int vertIdx = 0; vertIdx < clipMap.vertCount; vertIdx++)
clipMap->verts[vertIdx] = bsp->colWorld.vertices[vertIdx].pos; clipMap.verts[vertIdx] = bsp.colWorld.vertices[vertIdx].pos;
// The clipmap index buffer has a unique index for each vertex in the world, compared to the gfxworld's // The clipmap index buffer has a unique index for each vertex in the world, compared to the gfxworld's
// index buffer having a unique index for each vertex on a surface. This code converts gfxworld indices to clipmap indices. // index buffer having a unique index for each vertex on a surface. This code converts gfxworld indices to clipmap indices.
std::vector<uint16_t> triIndexVec; std::vector<uint16_t> triIndexVec;
for (BSPSurface& surface : bsp->colWorld.surfaces) for (const BSPSurface& surface : bsp.colWorld.surfaces)
{ {
int indexOfFirstIndex = surface.indexOfFirstIndex; const int indexOfFirstIndex = surface.indexOfFirstIndex;
int indexOfFirstVertex = surface.indexOfFirstVertex; const int indexOfFirstVertex = surface.indexOfFirstVertex;
for (int indexIdx = 0; indexIdx < surface.triCount * 3; indexIdx++) for (int indexIdx = 0; indexIdx < surface.triCount * 3; indexIdx++)
{ {
int triIndex = bsp->colWorld.indices[indexOfFirstIndex + indexIdx] + indexOfFirstVertex; int triIndex = bsp.colWorld.indices[indexOfFirstIndex + indexIdx] + indexOfFirstVertex;
triIndexVec.emplace_back(triIndex); triIndexVec.emplace_back(triIndex);
} }
} }
// the reinterpret_cast is used as triIndices is just a pointer to an array of indicies, and static_cast can't safely do the conversion // the reinterpret_cast is used as triIndices is just a pointer to an array of indicies, and static_cast can't safely do the conversion
clipMap->triCount = static_cast<int>(triIndexVec.size() / 3); clipMap.triCount = static_cast<int>(triIndexVec.size() / 3);
clipMap->triIndices = reinterpret_cast<uint16_t (*)[3]>(m_memory.Alloc<uint16_t>(triIndexVec.size())); clipMap.triIndices = reinterpret_cast<uint16_t (*)[3]>(m_memory.Alloc<uint16_t>(triIndexVec.size()));
memcpy(clipMap->triIndices, &triIndexVec[0], sizeof(uint16_t) * triIndexVec.size()); memcpy(clipMap.triIndices, triIndexVec.data(), sizeof(uint16_t) * triIndexVec.size());
// partitions are "containers" for vertices. BSP tree leafs contain a list of these partitions to determine the collision within a leaf. // partitions are "containers" for vertices. BSP tree leafs contain a list of these partitions to determine the collision within a leaf.
std::vector<CollisionPartition> partitionVec; std::vector<CollisionPartition> partitionVec;
std::vector<uint16_t> uniqueIndicesVec; std::vector<uint16_t> uniqueIndicesVec;
for (BSPSurface& surface : bsp->colWorld.surfaces) for (const BSPSurface& surface : bsp.colWorld.surfaces)
{ {
// partitions are made for each triangle, not one for each surface. // partitions are made for each triangle, not one for each surface.
// one for each surface causes physics bugs, as the entire bounding box is considered solid instead of the surface itself (for some reason). // one for each surface causes physics bugs, as the entire bounding box is considered solid instead of the surface itself (for some reason).
// so a partition is made for each triangle which removes the physics bugs but likely makes the game run slower // so a partition is made for each triangle which removes the physics bugs but likely makes the game run slower
int indexOfFirstTri = surface.indexOfFirstIndex / 3; const int indexOfFirstTri = surface.indexOfFirstIndex / 3;
int indexOfFirstVertex = surface.indexOfFirstVertex; const int indexOfFirstVertex = surface.indexOfFirstVertex;
for (int triIdx = 0; triIdx < surface.triCount; triIdx++) for (int triIdx = 0; triIdx < surface.triCount; triIdx++)
{ {
CollisionPartition partition; CollisionPartition partition;
@@ -522,7 +524,7 @@ namespace BSP
partition.fuind = static_cast<int>(uniqueIndicesVec.size()); partition.fuind = static_cast<int>(uniqueIndicesVec.size());
// All tri indices are unique since there is only one tri per partition // All tri indices are unique since there is only one tri per partition
uint16_t* tri = clipMap->triIndices[partition.firstTri]; uint16_t* tri = clipMap.triIndices[partition.firstTri];
uniqueIndicesVec.emplace_back(tri[0]); uniqueIndicesVec.emplace_back(tri[0]);
uniqueIndicesVec.emplace_back(tri[1]); uniqueIndicesVec.emplace_back(tri[1]);
uniqueIndicesVec.emplace_back(tri[2]); uniqueIndicesVec.emplace_back(tri[2]);
@@ -530,13 +532,13 @@ namespace BSP
partitionVec.emplace_back(partition); partitionVec.emplace_back(partition);
} }
} }
clipMap->partitionCount = static_cast<int>(partitionVec.size()); clipMap.partitionCount = static_cast<int>(partitionVec.size());
clipMap->partitions = m_memory.Alloc<CollisionPartition>(clipMap->partitionCount); clipMap.partitions = m_memory.Alloc<CollisionPartition>(clipMap.partitionCount);
memcpy(clipMap->partitions, partitionVec.data(), sizeof(CollisionPartition) * partitionVec.size()); memcpy(clipMap.partitions, partitionVec.data(), sizeof(CollisionPartition) * partitionVec.size());
clipMap->info.nuinds = static_cast<int>(uniqueIndicesVec.size()); clipMap.info.nuinds = static_cast<int>(uniqueIndicesVec.size());
clipMap->info.uinds = m_memory.Alloc<uint16_t>(uniqueIndicesVec.size()); clipMap.info.uinds = m_memory.Alloc<uint16_t>(uniqueIndicesVec.size());
memcpy(clipMap->info.uinds, uniqueIndicesVec.data(), sizeof(uint16_t) * uniqueIndicesVec.size()); memcpy(clipMap.info.uinds, uniqueIndicesVec.data(), sizeof(uint16_t) * uniqueIndicesVec.size());
return true; return true;
@@ -581,21 +583,21 @@ namespace BSP
*/ */
} }
bool ClipMapLinker::loadWorldCollision(clipMap_t* clipMap, BSPData* bsp) bool ClipMapLinker::loadWorldCollision(clipMap_t& clipMap, const BSPData& bsp)
{ {
// No support for brushes, only tris right now // No support for brushes, only tris right now
clipMap->info.numBrushSides = 0; clipMap.info.numBrushSides = 0;
clipMap->info.brushsides = nullptr; clipMap.info.brushsides = nullptr;
clipMap->info.leafbrushNodesCount = 0; clipMap.info.leafbrushNodesCount = 0;
clipMap->info.leafbrushNodes = nullptr; clipMap.info.leafbrushNodes = nullptr;
clipMap->info.numLeafBrushes = 0; clipMap.info.numLeafBrushes = 0;
clipMap->info.leafbrushes = nullptr; clipMap.info.leafbrushes = nullptr;
clipMap->info.numBrushVerts = 0; clipMap.info.numBrushVerts = 0;
clipMap->info.brushVerts = nullptr; clipMap.info.brushVerts = nullptr;
clipMap->info.numBrushes = 0; clipMap.info.numBrushes = 0;
clipMap->info.brushes = nullptr; clipMap.info.brushes = nullptr;
clipMap->info.brushBounds = nullptr; clipMap.info.brushBounds = nullptr;
clipMap->info.brushContents = nullptr; clipMap.info.brushContents = nullptr;
// load verts, tris, uinds and partitions // load verts, tris, uinds and partitions
if (!loadPartitions(clipMap, bsp)) if (!loadPartitions(clipMap, bsp))
@@ -606,31 +608,31 @@ namespace BSP
return true; return true;
} }
clipMap_t* ClipMapLinker::linkClipMap(BSPData* bsp) clipMap_t* ClipMapLinker::linkClipMap(const BSPData& bsp)
{ {
clipMap_t* clipMap = m_memory.Alloc<clipMap_t>(); clipMap_t* clipMap = m_memory.Alloc<clipMap_t>();
clipMap->name = m_memory.Dup(bsp->bspName.c_str()); clipMap->name = m_memory.Dup(bsp.bspName.c_str());
clipMap->isInUse = true; clipMap->isInUse = true;
clipMap->checksum = 0; clipMap->checksum = 0;
clipMap->pInfo = nullptr; clipMap->pInfo = nullptr;
std::string mapEntsName = bsp->bspName; std::string mapEntsName = bsp.bspName;
auto mapEntsAsset = m_context.LoadDependency<AssetMapEnts>(mapEntsName); auto mapEntsAsset = m_context.LoadDependency<AssetMapEnts>(mapEntsName);
assert(mapEntsAsset != nullptr); assert(mapEntsAsset != nullptr);
clipMap->mapEnts = mapEntsAsset->Asset(); clipMap->mapEnts = mapEntsAsset->Asset();
loadBoxData(clipMap); loadBoxData(*clipMap);
loadVisibility(clipMap); loadVisibility(*clipMap);
loadRopesAndConstraints(clipMap); loadRopesAndConstraints(*clipMap);
loadSubModelCollision(clipMap, bsp); loadSubModelCollision(*clipMap, bsp);
loadDynEnts(clipMap); loadDynEnts(*clipMap);
loadXModelCollision(clipMap); loadXModelCollision(*clipMap);
// Clipmap materials define the properties of a material (bullet penetration, no collision, water, etc) // Clipmap materials define the properties of a material (bullet penetration, no collision, water, etc)
// Right now there is no way to define properties per material so only one material is used // Right now there is no way to define properties per material so only one material is used
@@ -646,7 +648,7 @@ namespace BSP
clipMap->triEdgeIsWalkable = new char[walkableEdgeSize]; clipMap->triEdgeIsWalkable = new char[walkableEdgeSize];
memset(clipMap->triEdgeIsWalkable, 1, walkableEdgeSize * sizeof(char)); memset(clipMap->triEdgeIsWalkable, 1, walkableEdgeSize * sizeof(char));
if (!loadWorldCollision(clipMap, bsp)) if (!loadWorldCollision(*clipMap, bsp))
return nullptr; return nullptr;
return clipMap; return clipMap;

View File

@@ -12,29 +12,31 @@ namespace BSP
{ {
public: public:
ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
T6::clipMap_t* linkClipMap(BSPData* bsp);
T6::clipMap_t* linkClipMap(const BSPData& bsp);
private: private:
MemoryManager& m_memory; MemoryManager& m_memory;
ISearchPath& m_search_path; ISearchPath& m_search_path;
AssetCreationContext& m_context; AssetCreationContext& m_context;
void loadBoxData(T6::clipMap_t* clipMap); void loadBoxData(T6::clipMap_t& clipMap) const;
void loadVisibility(T6::clipMap_t* clipMap); void loadVisibility(T6::clipMap_t& clipMap) const;
void loadDynEnts(T6::clipMap_t* clipMap); void loadDynEnts(T6::clipMap_t& clipMap) const;
void loadRopesAndConstraints(T6::clipMap_t* clipMap); void loadRopesAndConstraints(T6::clipMap_t& clipMap) const;
void loadSubModelCollision(T6::clipMap_t* clipMap, BSPData* bsp); void loadSubModelCollision(T6::clipMap_t& clipMap, const BSPData& bsp) const;
void loadXModelCollision(T6::clipMap_t* clipMap); void loadXModelCollision(T6::clipMap_t& clipMap) const;
std::vector<T6::cplane_s> planeVec; std::vector<T6::cplane_s> planeVec;
std::vector<T6::cNode_t> nodeVec; std::vector<T6::cNode_t> nodeVec;
std::vector<T6::cLeaf_s> leafVec; std::vector<T6::cLeaf_s> leafVec;
std::vector<T6::CollisionAabbTree> AABBTreeVec; std::vector<T6::CollisionAabbTree> AABBTreeVec;
size_t highestLeafObjectCount = 0; size_t highestLeafObjectCount = 0;
void addAABBTreeFromLeaf(T6::clipMap_t* clipMap, BSPTree* tree, size_t* out_parentCount, size_t* out_parentStartIndex);
int16_t loadBSPNode(T6::clipMap_t* clipMap, BSPTree* tree); void addAABBTreeFromLeaf(T6::clipMap_t& clipMap, const BSPTree& tree, size_t& out_parentCount, size_t& out_parentStartIndex);
void loadBSPTree(T6::clipMap_t* clipMap, BSPData* bsp); int16_t loadBSPNode(T6::clipMap_t& clipMap, const BSPTree& tree);
bool loadPartitions(T6::clipMap_t* clipMap, BSPData* bsp); void loadBSPTree(T6::clipMap_t& clipMap, const BSPData& bsp);
bool loadWorldCollision(T6::clipMap_t* clipMap, BSPData* bsp); bool loadPartitions(T6::clipMap_t& clipMap, const BSPData& bsp) const;
bool loadWorldCollision(T6::clipMap_t& clipMap, const BSPData& bsp);
}; };
} // namespace BSP } // namespace BSP

View File

@@ -11,11 +11,11 @@ namespace BSP
{ {
} }
ComWorld* ComWorldLinker::linkComWorld(BSPData* bsp) ComWorld* ComWorldLinker::linkComWorld(const BSPData& bsp) const
{ {
// all lights that aren't the sunlight or default light need their own GfxLightDef asset // all lights that aren't the sunlight or default light need their own GfxLightDef asset
ComWorld* comWorld = m_memory.Alloc<ComWorld>(); ComWorld* comWorld = m_memory.Alloc<ComWorld>();
comWorld->name = m_memory.Dup(bsp->bspName.c_str()); comWorld->name = m_memory.Dup(bsp.bspName.c_str());
comWorld->isInUse = 1; comWorld->isInUse = 1;
comWorld->primaryLightCount = BSPGameConstants::BSP_DEFAULT_LIGHT_COUNT; comWorld->primaryLightCount = BSPGameConstants::BSP_DEFAULT_LIGHT_COUNT;
comWorld->primaryLights = m_memory.Alloc<ComPrimaryLight>(comWorld->primaryLightCount); comWorld->primaryLights = m_memory.Alloc<ComPrimaryLight>(comWorld->primaryLightCount);

View File

@@ -11,7 +11,7 @@ namespace BSP
{ {
public: public:
ComWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); ComWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
T6::ComWorld* linkComWorld(BSPData* bsp); T6::ComWorld* linkComWorld(const BSPData& bsp) const;
private: private:
MemoryManager& m_memory; MemoryManager& m_memory;

View File

@@ -11,11 +11,11 @@ namespace BSP
{ {
} }
GameWorldMp* GameWorldMpLinker::linkGameWorldMp(BSPData* bsp) GameWorldMp* GameWorldMpLinker::linkGameWorldMp(const BSPData& bsp) const
{ {
GameWorldMp* gameWorldMp = m_memory.Alloc<GameWorldMp>(); GameWorldMp* gameWorldMp = m_memory.Alloc<GameWorldMp>();
gameWorldMp->name = m_memory.Dup(bsp->bspName.c_str()); gameWorldMp->name = m_memory.Dup(bsp.bspName.c_str());
gameWorldMp->path.nodeCount = 0; gameWorldMp->path.nodeCount = 0;
gameWorldMp->path.originalNodeCount = 0; gameWorldMp->path.originalNodeCount = 0;
@@ -24,7 +24,7 @@ namespace BSP
gameWorldMp->path.nodeTreeCount = 0; gameWorldMp->path.nodeTreeCount = 0;
// The game has 128 empty nodes allocated // The game has 128 empty nodes allocated
int extraNodeCount = gameWorldMp->path.nodeCount + 128; const int extraNodeCount = gameWorldMp->path.nodeCount + 128;
gameWorldMp->path.nodes = m_memory.Alloc<pathnode_t>(extraNodeCount); gameWorldMp->path.nodes = m_memory.Alloc<pathnode_t>(extraNodeCount);
gameWorldMp->path.basenodes = m_memory.Alloc<pathbasenode_t>(extraNodeCount); gameWorldMp->path.basenodes = m_memory.Alloc<pathbasenode_t>(extraNodeCount);
gameWorldMp->path.pathVis = nullptr; gameWorldMp->path.pathVis = nullptr;

View File

@@ -11,7 +11,7 @@ namespace BSP
{ {
public: public:
GameWorldMpLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); GameWorldMpLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
T6::GameWorldMp* linkGameWorldMp(BSPData* bsp); T6::GameWorldMp* linkGameWorldMp(const BSPData& bsp) const;
private: private:
MemoryManager& m_memory; MemoryManager& m_memory;

File diff suppressed because it is too large Load Diff

View File

@@ -11,27 +11,27 @@ namespace BSP
{ {
public: public:
GfxWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); GfxWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
T6::GfxWorld* linkGfxWorld(BSPData* bsp); T6::GfxWorld* linkGfxWorld(const BSPData& bsp) const;
private: private:
MemoryManager& m_memory; MemoryManager& m_memory;
ISearchPath& m_search_path; ISearchPath& m_search_path;
AssetCreationContext& m_context; AssetCreationContext& m_context;
void loadDrawData(BSPData* projInfo, T6::GfxWorld* gfxWorld); void loadDrawData(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
bool loadMapSurfaces(BSPData* projInfo, T6::GfxWorld* gfxWorld); bool loadMapSurfaces(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
void loadXModels(BSPData* projInfo, T6::GfxWorld* gfxWorld); void loadXModels(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
void cleanGfxWorld(T6::GfxWorld* gfxWorld); void cleanGfxWorld(T6::GfxWorld& gfxWorld) const;
void loadGfxLights(T6::GfxWorld* gfxWorld); void loadGfxLights(T6::GfxWorld& gfxWorld) const;
void loadLightGrid(T6::GfxWorld* gfxWorld); void loadLightGrid(T6::GfxWorld& gfxWorld) const;
void loadGfxCells(T6::GfxWorld* gfxWorld); void loadGfxCells(T6::GfxWorld& gfxWorld) const;
void loadModels(T6::GfxWorld* gfxWorld); void loadModels(T6::GfxWorld& gfxWorld) const;
bool loadReflectionProbeData(T6::GfxWorld* gfxWorld); bool loadReflectionProbeData(T6::GfxWorld& gfxWorld) const;
bool loadLightmapData(T6::GfxWorld* gfxWorld); bool loadLightmapData(T6::GfxWorld& gfxWorld) const;
void loadSkyBox(BSPData* projInfo, T6::GfxWorld* gfxWorld); void loadSkyBox(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
void loadDynEntData(T6::GfxWorld* gfxWorld); void loadDynEntData(T6::GfxWorld& gfxWorld) const;
bool loadOutdoors(T6::GfxWorld* gfxWorld); bool loadOutdoors(T6::GfxWorld& gfxWorld) const;
void loadSunData(T6::GfxWorld* gfxWorld); void loadSunData(T6::GfxWorld& gfxWorld) const;
void loadWorldBounds(T6::GfxWorld* gfxWorld); void loadWorldBounds(T6::GfxWorld& gfxWorld) const;
}; };
} // namespace BSP } // namespace BSP

View File

@@ -74,7 +74,7 @@ namespace BSP
{ {
} }
MapEnts* MapEntsLinker::linkMapEnts(BSPData* bsp) MapEnts* MapEntsLinker::linkMapEnts(const BSPData& bsp) const
{ {
try try
{ {
@@ -116,7 +116,7 @@ namespace BSP
parseSpawnpointJSON(spawnJs["FFA"], entityString, BSPGameConstants::FFA_SPAWN_POINT_NAMES, ffaNameCount); parseSpawnpointJSON(spawnJs["FFA"], entityString, BSPGameConstants::FFA_SPAWN_POINT_NAMES, ffaNameCount);
MapEnts* mapEnts = m_memory.Alloc<MapEnts>(); MapEnts* mapEnts = m_memory.Alloc<MapEnts>();
mapEnts->name = m_memory.Dup(bsp->bspName.c_str()); mapEnts->name = m_memory.Dup(bsp.bspName.c_str());
mapEnts->entityString = m_memory.Dup(entityString.c_str()); mapEnts->entityString = m_memory.Dup(entityString.c_str());
mapEnts->numEntityChars = static_cast<int>(entityString.length() + 1); // numEntityChars includes the null character mapEnts->numEntityChars = static_cast<int>(entityString.length() + 1); // numEntityChars includes the null character

View File

@@ -11,7 +11,7 @@ namespace BSP
{ {
public: public:
MapEntsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); MapEntsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
T6::MapEnts* linkMapEnts(BSPData* bsp); T6::MapEnts* linkMapEnts(const BSPData& bsp) const;
private: private:
MemoryManager& m_memory; MemoryManager& m_memory;

View File

@@ -9,13 +9,13 @@ namespace BSP
{ {
} }
T6::SkinnedVertsDef* SkinnedVertsLinker::linkSkinnedVerts(BSPData* bsp) T6::SkinnedVertsDef* SkinnedVertsLinker::linkSkinnedVerts(const BSPData& bsp) const
{ {
// Pretty sure maxSkinnedVerts relates to the max amount of xmodel skinned verts a map will have // Pretty sure maxSkinnedVerts relates to the max amount of xmodel skinned verts a map will have
// But setting it to the world vertex count seems to work // But setting it to the world vertex count seems to work
T6::SkinnedVertsDef* skinnedVerts = m_memory.Alloc<T6::SkinnedVertsDef>(); T6::SkinnedVertsDef* skinnedVerts = m_memory.Alloc<T6::SkinnedVertsDef>();
skinnedVerts->name = m_memory.Dup("skinnedverts"); skinnedVerts->name = m_memory.Dup("skinnedverts");
skinnedVerts->maxSkinnedVerts = static_cast<unsigned int>(bsp->gfxWorld.vertices.size()); skinnedVerts->maxSkinnedVerts = static_cast<unsigned int>(bsp.gfxWorld.vertices.size());
return skinnedVerts; return skinnedVerts;
} }

View File

@@ -11,7 +11,7 @@ namespace BSP
{ {
public: public:
SkinnedVertsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); SkinnedVertsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
T6::SkinnedVertsDef* linkSkinnedVerts(BSPData* bsp); T6::SkinnedVertsDef* linkSkinnedVerts(const BSPData& bsp) const;
private: private:
MemoryManager& m_memory; MemoryManager& m_memory;

View File

@@ -32,12 +32,12 @@ namespace
bool FinalizeZone(AssetCreationContext& context) override bool FinalizeZone(AssetCreationContext& context) override
{ {
std::unique_ptr<BSPData> bsp = BSP::createBSPData(m_zone.m_name, m_search_path); const std::unique_ptr<BSPData> bsp = BSP::createBSPData(m_zone.m_name, m_search_path);
if (bsp == nullptr) if (bsp == nullptr)
return false; return false;
BSPLinker linker(m_memory, m_search_path, context); BSPLinker linker(m_memory, m_search_path, context);
bool result = linker.linkBSP(bsp.get()); const bool result = linker.linkBSP(*bsp);
if (!result) if (!result)
con::error("BSP link has failed."); con::error("BSP link has failed.");