mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-12-07 03:37:48 +00:00
chore: mixed code improvements
This commit is contained in:
@@ -3,12 +3,13 @@
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
enum BSPMaterialType
|
||||
enum class BSPMaterialType : std::uint8_t
|
||||
{
|
||||
MATERIAL_TYPE_COLOUR,
|
||||
MATERIAL_TYPE_TEXTURE,
|
||||
@@ -33,9 +34,9 @@ namespace BSP
|
||||
struct BSPSurface
|
||||
{
|
||||
BSPMaterial material;
|
||||
int triCount;
|
||||
int indexOfFirstVertex;
|
||||
int indexOfFirstIndex;
|
||||
unsigned triCount;
|
||||
unsigned indexOfFirstVertex;
|
||||
unsigned indexOfFirstIndex;
|
||||
};
|
||||
|
||||
struct BSPWorld
|
||||
@@ -58,7 +59,7 @@ namespace BSP
|
||||
// These values are hardcoded ingame and will break the map if they are changed
|
||||
namespace BSPGameConstants
|
||||
{
|
||||
constexpr unsigned int MAX_COLLISION_VERTS = UINT16_MAX;
|
||||
constexpr unsigned int MAX_COLLISION_VERTS = std::numeric_limits<std::uint16_t>::max();
|
||||
|
||||
constexpr size_t MAX_AABB_TREE_CHILDREN = 128;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
constexpr int MAX_NODE_SIZE = 512; // maximum size a BSP node can be before it becomes a leaf
|
||||
constexpr auto MAX_NODE_SIZE = 512u; // maximum size a BSP node can be before it becomes a leaf
|
||||
|
||||
BSPObject::BSPObject(
|
||||
const float xMin, const float yMin, const float zMin, const float xMax, const float yMax, const float zMax, const int objPartitionIndex)
|
||||
@@ -16,17 +16,17 @@ namespace BSP
|
||||
partitionIndex = objPartitionIndex;
|
||||
}
|
||||
|
||||
void BSPLeaf::addObject(std::shared_ptr<BSPObject> object)
|
||||
void BSPLeaf::AddObject(std::shared_ptr<BSPObject> object)
|
||||
{
|
||||
objectList.emplace_back(std::move(object));
|
||||
}
|
||||
|
||||
BSPObject* BSPLeaf::getObject(const size_t index) const
|
||||
BSPObject* BSPLeaf::GetObject(const size_t index) const
|
||||
{
|
||||
return objectList.at(index).get();
|
||||
}
|
||||
|
||||
size_t BSPLeaf::getObjectCount() const
|
||||
size_t BSPLeaf::GetObjectCount() const
|
||||
{
|
||||
return objectList.size();
|
||||
}
|
||||
@@ -39,17 +39,17 @@ namespace BSP
|
||||
distance = nodeDistance;
|
||||
}
|
||||
|
||||
PlaneSide BSPNode::objectIsInFront(const BSPObject& object) const
|
||||
PlaneSide BSPNode::ObjectIsInFront(const BSPObject& object) const
|
||||
{
|
||||
float minCoord, maxCoord;
|
||||
|
||||
// Select the relevant coordinate based on the plane's axis
|
||||
if (axis == AXIS_X)
|
||||
if (axis == PlaneAxis::AXIS_X)
|
||||
{
|
||||
minCoord = object.min.x;
|
||||
maxCoord = object.max.x;
|
||||
}
|
||||
else if (axis == AXIS_Y)
|
||||
else if (axis == PlaneAxis::AXIS_Y)
|
||||
{
|
||||
minCoord = object.min.y;
|
||||
maxCoord = object.max.y;
|
||||
@@ -63,15 +63,15 @@ namespace BSP
|
||||
// Compare with the plane's distance
|
||||
if (maxCoord < distance)
|
||||
{
|
||||
return SIDE_BACK; // Object is entirely on the negative side
|
||||
return PlaneSide::SIDE_BACK; // Object is entirely on the negative side
|
||||
}
|
||||
else if (minCoord > distance)
|
||||
{
|
||||
return SIDE_FRONT; // Object is entirely on the positive side
|
||||
return PlaneSide::SIDE_FRONT; // Object is entirely on the positive side
|
||||
}
|
||||
else
|
||||
{
|
||||
return SIDE_INTERSECTS;
|
||||
return PlaneSide::SIDE_INTERSECTS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,10 +84,11 @@ namespace BSP
|
||||
max.y = yMax;
|
||||
max.z = zMax;
|
||||
level = treeLevel;
|
||||
splitTree();
|
||||
|
||||
SplitTree();
|
||||
}
|
||||
|
||||
void BSPTree::splitTree()
|
||||
void BSPTree::SplitTree()
|
||||
{
|
||||
std::unique_ptr<BSPTree> front;
|
||||
std::unique_ptr<BSPTree> back;
|
||||
@@ -101,7 +102,7 @@ namespace BSP
|
||||
back = std::make_unique<BSPTree>(min.x, min.y, min.z, halfLength, max.y, max.z, level + 1);
|
||||
|
||||
isLeaf = false;
|
||||
node = std::make_unique<BSPNode>(std::move(front), std::move(back), AXIS_X, halfLength);
|
||||
node = std::make_unique<BSPNode>(std::move(front), std::move(back), PlaneAxis::AXIS_X, halfLength);
|
||||
leaf = nullptr;
|
||||
}
|
||||
else if (max.y - min.y > MAX_NODE_SIZE)
|
||||
@@ -112,7 +113,7 @@ namespace BSP
|
||||
back = std::make_unique<BSPTree>(min.x, min.y, min.z, max.x, halfLength, max.z, level + 1);
|
||||
|
||||
isLeaf = false;
|
||||
node = std::make_unique<BSPNode>(std::move(front), std::move(back), AXIS_Y, halfLength);
|
||||
node = std::make_unique<BSPNode>(std::move(front), std::move(back), PlaneAxis::AXIS_Y, halfLength);
|
||||
leaf = nullptr;
|
||||
}
|
||||
else if (max.z - min.z > MAX_NODE_SIZE)
|
||||
@@ -123,7 +124,7 @@ namespace BSP
|
||||
back = std::make_unique<BSPTree>(min.x, min.y, min.z, max.x, max.y, halfLength, level + 1);
|
||||
|
||||
isLeaf = false;
|
||||
node = std::make_unique<BSPNode>(std::move(front), std::move(back), AXIS_Z, halfLength);
|
||||
node = std::make_unique<BSPNode>(std::move(front), std::move(back), PlaneAxis::AXIS_Z, halfLength);
|
||||
leaf = nullptr;
|
||||
}
|
||||
else
|
||||
@@ -134,27 +135,28 @@ namespace BSP
|
||||
}
|
||||
}
|
||||
|
||||
void BSPTree::addObjectToTree(std::shared_ptr<BSPObject> object) const
|
||||
void BSPTree::AddObjectToTree(std::shared_ptr<BSPObject> object) const
|
||||
{
|
||||
if (isLeaf)
|
||||
{
|
||||
leaf->addObject(std::move(object));
|
||||
leaf->AddObject(std::move(object));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto side = node->objectIsInFront(*object);
|
||||
if (side == SIDE_FRONT)
|
||||
const auto side = node->ObjectIsInFront(*object);
|
||||
|
||||
if (side == PlaneSide::SIDE_FRONT)
|
||||
{
|
||||
node->front->addObjectToTree(std::move(object));
|
||||
node->front->AddObjectToTree(std::move(object));
|
||||
}
|
||||
else if (side == SIDE_BACK)
|
||||
else if (side == PlaneSide::SIDE_BACK)
|
||||
{
|
||||
node->back->addObjectToTree(std::move(object));
|
||||
node->back->AddObjectToTree(std::move(object));
|
||||
}
|
||||
else // intersects
|
||||
{
|
||||
node->front->addObjectToTree(object);
|
||||
node->back->addObjectToTree(object);
|
||||
node->front->AddObjectToTree(object);
|
||||
node->back->AddObjectToTree(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,18 @@
|
||||
|
||||
#include "BSP.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
enum PlaneAxis
|
||||
enum class PlaneAxis : std::uint8_t
|
||||
{
|
||||
AXIS_X,
|
||||
AXIS_Y,
|
||||
AXIS_Z
|
||||
};
|
||||
|
||||
enum PlaneSide
|
||||
enum class PlaneSide : std::uint8_t
|
||||
{
|
||||
SIDE_FRONT,
|
||||
SIDE_BACK,
|
||||
@@ -21,21 +23,21 @@ namespace BSP
|
||||
class BSPObject
|
||||
{
|
||||
public:
|
||||
BSPObject(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int objPartitionIndex);
|
||||
|
||||
T6::vec3_t min;
|
||||
T6::vec3_t max;
|
||||
int partitionIndex; // index of the partition the object is contained in
|
||||
|
||||
BSPObject(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int objPartitionIndex);
|
||||
};
|
||||
|
||||
class BSPLeaf
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<BSPObject>> objectList;
|
||||
void AddObject(std::shared_ptr<BSPObject> object);
|
||||
[[nodiscard]] BSPObject* GetObject(size_t index) const;
|
||||
[[nodiscard]] size_t GetObjectCount() const;
|
||||
|
||||
void addObject(std::shared_ptr<BSPObject> object);
|
||||
[[nodiscard]] BSPObject* getObject(size_t index) const;
|
||||
[[nodiscard]] size_t getObjectCount() const;
|
||||
std::vector<std::shared_ptr<BSPObject>> objectList;
|
||||
};
|
||||
|
||||
class BSPTree;
|
||||
@@ -43,19 +45,24 @@ namespace BSP
|
||||
class BSPNode
|
||||
{
|
||||
public:
|
||||
BSPNode(std::unique_ptr<BSPTree> frontTree, std::unique_ptr<BSPTree> backTree, PlaneAxis nodeAxis, float nodeDistance);
|
||||
[[nodiscard]] PlaneSide ObjectIsInFront(const BSPObject& object) const;
|
||||
|
||||
std::unique_ptr<BSPTree> front;
|
||||
std::unique_ptr<BSPTree> back;
|
||||
|
||||
PlaneAxis axis; // axis that the split plane is on
|
||||
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);
|
||||
[[nodiscard]] PlaneSide objectIsInFront(const BSPObject& object) const;
|
||||
};
|
||||
|
||||
class BSPTree
|
||||
{
|
||||
public:
|
||||
BSPTree(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int treeLevel);
|
||||
|
||||
void SplitTree();
|
||||
void AddObjectToTree(std::shared_ptr<BSPObject> object) const;
|
||||
|
||||
bool isLeaf;
|
||||
std::unique_ptr<BSPLeaf> leaf;
|
||||
std::unique_ptr<BSPNode> node;
|
||||
@@ -63,9 +70,5 @@ namespace BSP
|
||||
int level; // level in the BSP tree
|
||||
T6::vec3_t min;
|
||||
T6::vec3_t max;
|
||||
|
||||
BSPTree(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int treeLevel);
|
||||
void splitTree();
|
||||
void addObjectToTree(std::shared_ptr<BSPObject> object) const;
|
||||
};
|
||||
} // namespace BSP
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
|
||||
#include "BSPUtil.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <limits>
|
||||
#include <ufbx.h>
|
||||
|
||||
using namespace BSP;
|
||||
|
||||
namespace
|
||||
{
|
||||
void addFBXMeshToWorld(
|
||||
void AddFBXMeshToWorld(
|
||||
ufbx_node* node, std::vector<BSPSurface>& surfaceVec, std::vector<BSPVertex>& vertexVec, std::vector<uint16_t>& indexVec, bool& hasTangentSpace)
|
||||
{
|
||||
ufbx_mesh* mesh = node->mesh;
|
||||
@@ -17,7 +19,7 @@ namespace
|
||||
assert(node->attrib_type == UFBX_ELEMENT_MESH);
|
||||
|
||||
if (mesh->instances.count != 1)
|
||||
con::warn("mesh {} has {} instances, only the 1st instace will be used.", node->name.data, mesh->instances.count);
|
||||
con::warn("mesh {} has {} instances, only the 1st instance will be used.", node->name.data, mesh->instances.count);
|
||||
|
||||
if (mesh->num_triangles == 0)
|
||||
{
|
||||
@@ -33,9 +35,9 @@ namespace
|
||||
|
||||
for (size_t k = 0; k < mesh->num_indices; k++)
|
||||
{
|
||||
if (mesh->vertex_indices[k] > UINT16_MAX)
|
||||
if (mesh->vertex_indices[k] > std::numeric_limits<std::uint16_t>::max())
|
||||
{
|
||||
con::warn("ignoring mesh {}, it has more than {} indices.", node->name.data, UINT16_MAX);
|
||||
con::warn("ignoring mesh {}, it has more than {} indices.", node->name.data, std::numeric_limits<std::uint16_t>::max());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -61,18 +63,18 @@ namespace
|
||||
|
||||
BSPSurface surface;
|
||||
size_t partTriangleNum = meshPart.num_triangles;
|
||||
surface.triCount = static_cast<int>(partTriangleNum);
|
||||
surface.indexOfFirstVertex = static_cast<int>(vertexVec.size());
|
||||
surface.indexOfFirstIndex = static_cast<int>(indexVec.size());
|
||||
surface.triCount = static_cast<unsigned>(partTriangleNum);
|
||||
surface.indexOfFirstVertex = static_cast<unsigned>(vertexVec.size());
|
||||
surface.indexOfFirstIndex = static_cast<unsigned>(indexVec.size());
|
||||
|
||||
if (mesh->materials.count == 0)
|
||||
{
|
||||
surface.material.materialType = MATERIAL_TYPE_EMPTY;
|
||||
surface.material.materialType = BSPMaterialType::MATERIAL_TYPE_EMPTY;
|
||||
surface.material.materialName = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
surface.material.materialType = MATERIAL_TYPE_TEXTURE;
|
||||
surface.material.materialType = BSPMaterialType::MATERIAL_TYPE_TEXTURE;
|
||||
surface.material.materialName = mesh->materials.data[meshPart.index]->name.data;
|
||||
}
|
||||
|
||||
@@ -84,9 +86,9 @@ namespace
|
||||
ufbx_face* face = &mesh->faces.data[faceIndex];
|
||||
|
||||
// Triangulate the face into the indices vector
|
||||
uint32_t triangluatedTriCount = ufbx_triangulate_face(tempIndices.data(), tempIndices.size(), mesh, *face);
|
||||
uint32_t triangulatedTriCount = ufbx_triangulate_face(tempIndices.data(), tempIndices.size(), mesh, *face);
|
||||
|
||||
for (uint32_t idxOfIndex = 0; idxOfIndex < triangluatedTriCount * 3; idxOfIndex++)
|
||||
for (uint32_t idxOfIndex = 0; idxOfIndex < triangulatedTriCount * 3; idxOfIndex++)
|
||||
{
|
||||
BSPVertex vertex;
|
||||
uint32_t index = tempIndices[idxOfIndex];
|
||||
@@ -98,7 +100,8 @@ namespace
|
||||
blenderCoords.z = static_cast<float>(transformedPos.z);
|
||||
vertex.pos = ConvertToBO2Coords(blenderCoords);
|
||||
|
||||
if (surface.material.materialType == MATERIAL_TYPE_TEXTURE || surface.material.materialType == MATERIAL_TYPE_EMPTY)
|
||||
if (surface.material.materialType == BSPMaterialType::MATERIAL_TYPE_TEXTURE
|
||||
|| surface.material.materialType == BSPMaterialType::MATERIAL_TYPE_EMPTY)
|
||||
{
|
||||
vertex.color.x = 1.0f;
|
||||
vertex.color.y = 1.0f;
|
||||
@@ -171,7 +174,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void loadWorldData(const ufbx_scene& scene, BSPData& bsp, const bool isGfxData)
|
||||
void LoadWorldData(const ufbx_scene& scene, BSPData& bsp, const bool isGfxData)
|
||||
{
|
||||
bool hasTangentSpace = true;
|
||||
for (ufbx_node* node : scene.nodes)
|
||||
@@ -179,9 +182,9 @@ namespace
|
||||
if (node->attrib_type == UFBX_ELEMENT_MESH)
|
||||
{
|
||||
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
|
||||
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
|
||||
{
|
||||
@@ -196,19 +199,18 @@ namespace
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
std::unique_ptr<BSPData> createBSPData(const std::string& mapName, ISearchPath& searchPath)
|
||||
std::unique_ptr<BSPData> CreateBSPData(const std::string& mapName, ISearchPath& searchPath)
|
||||
{
|
||||
std::string gfxFbxFileName = "map_gfx.fbx";
|
||||
std::string gfxFbxPath = GetFileNameForBSPAsset(gfxFbxFileName);
|
||||
auto gfxFile = searchPath.Open(gfxFbxPath);
|
||||
const auto gfxFbxPath = GetFileNameForBSPAsset("map_gfx.fbx");
|
||||
const auto gfxFile = searchPath.Open(gfxFbxPath);
|
||||
if (!gfxFile.IsOpen())
|
||||
{
|
||||
con::error("Failed to open map gfx fbx file: {}", gfxFbxPath);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<char> gfxMapData(new char[static_cast<size_t>(gfxFile.m_length)]);
|
||||
gfxFile.m_stream->read(gfxMapData.get(), gfxFile.m_length);
|
||||
std::vector<char> gfxMapData(static_cast<size_t>(gfxFile.m_length));
|
||||
gfxFile.m_stream->read(gfxMapData.data(), gfxFile.m_length);
|
||||
if (gfxFile.m_stream->gcount() != gfxFile.m_length)
|
||||
{
|
||||
con::error("Read error of gfx fbx file: {}", gfxFbxPath);
|
||||
@@ -220,7 +222,7 @@ namespace BSP
|
||||
optsGfx.target_axes = ufbx_axes_right_handed_y_up;
|
||||
optsGfx.generate_missing_normals = true;
|
||||
optsGfx.allow_missing_vertex_position = false;
|
||||
ufbx_scene* gfxScene = ufbx_load_memory(gfxMapData.get(), static_cast<size_t>(gfxFile.m_length), &optsGfx, &errorGfx);
|
||||
ufbx_scene* gfxScene = ufbx_load_memory(gfxMapData.data(), static_cast<size_t>(gfxFile.m_length), &optsGfx, &errorGfx);
|
||||
if (!gfxScene)
|
||||
{
|
||||
con::error("Failed to load map gfx fbx file: {}", errorGfx.description.data);
|
||||
@@ -228,19 +230,18 @@ namespace BSP
|
||||
}
|
||||
|
||||
ufbx_scene* colScene;
|
||||
std::string colFbxFileName = "map_col.fbx";
|
||||
const auto colFbxPath = GetFileNameForBSPAsset(colFbxFileName);
|
||||
const auto colFbxPath = GetFileNameForBSPAsset("map_col.fbx");
|
||||
const auto colFile = searchPath.Open(colFbxPath);
|
||||
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 collision fbx file: {}. map gfx will be used for collision instead.", colFbxPath);
|
||||
colScene = gfxScene;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_ptr<char> colMapData(new char[static_cast<size_t>(colFile.m_length)]);
|
||||
std::vector<char> colMapData(static_cast<size_t>(colFile.m_length));
|
||||
colFile.m_stream->seekg(0);
|
||||
colFile.m_stream->read(colMapData.get(), colFile.m_length);
|
||||
colFile.m_stream->read(colMapData.data(), colFile.m_length);
|
||||
if (colFile.m_stream->gcount() != colFile.m_length)
|
||||
{
|
||||
con::error("Read error of collision fbx file: {}", colFbxPath);
|
||||
@@ -252,7 +253,7 @@ namespace BSP
|
||||
optsCol.target_axes = ufbx_axes_right_handed_y_up;
|
||||
optsCol.generate_missing_normals = true;
|
||||
optsCol.allow_missing_vertex_position = false;
|
||||
colScene = ufbx_load_memory(colMapData.get(), static_cast<size_t>(colFile.m_length), &optsCol, &errorCol);
|
||||
colScene = ufbx_load_memory(colMapData.data(), static_cast<size_t>(colFile.m_length), &optsCol, &errorCol);
|
||||
if (!colScene)
|
||||
{
|
||||
con::error("Failed to load map collision fbx file: {}", errorCol.description.data);
|
||||
@@ -265,8 +266,8 @@ namespace BSP
|
||||
bsp->name = mapName;
|
||||
bsp->bspName = std::format("maps/mp/{}.d3dbsp", mapName);
|
||||
|
||||
loadWorldData(*gfxScene, *bsp, true);
|
||||
loadWorldData(*colScene, *bsp, false);
|
||||
LoadWorldData(*gfxScene, *bsp, true);
|
||||
LoadWorldData(*colScene, *bsp, false);
|
||||
|
||||
ufbx_free_scene(gfxScene);
|
||||
if (gfxScene != colScene)
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
std::unique_ptr<BSPData> createBSPData(const std::string& mapName, ISearchPath& searchPath);
|
||||
std::unique_ptr<BSPData> CreateBSPData(const std::string& mapName, ISearchPath& searchPath);
|
||||
}; // namespace BSP
|
||||
|
||||
@@ -92,12 +92,12 @@ namespace BSP
|
||||
const auto yRadians = angles->y * conversionValue;
|
||||
const auto zRadians = angles->z * conversionValue;
|
||||
|
||||
const auto cosX = cos(xRadians);
|
||||
const auto sinX = sin(xRadians);
|
||||
const auto cosY = cos(yRadians);
|
||||
const auto sinY = sin(yRadians);
|
||||
const auto cosZ = cos(zRadians);
|
||||
const auto sinZ = sin(zRadians);
|
||||
const auto cosX = std::cos(xRadians);
|
||||
const auto sinX = std::sin(xRadians);
|
||||
const auto cosY = std::cos(yRadians);
|
||||
const auto sinY = std::sin(yRadians);
|
||||
const auto cosZ = std::cos(zRadians);
|
||||
const auto sinZ = std::sin(zRadians);
|
||||
|
||||
axis[0].x = cosX * cosY;
|
||||
axis[0].y = cosX * sinY;
|
||||
|
||||
@@ -13,7 +13,7 @@ using namespace T6;
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
void BSPLinker::addEmptyFootstepTableAsset(const std::string& assetName) const
|
||||
void BSPLinker::AddEmptyFootstepTableAsset(const std::string& assetName) const
|
||||
{
|
||||
if (assetName.empty())
|
||||
return;
|
||||
@@ -25,30 +25,30 @@ namespace BSP
|
||||
m_context.AddAsset<AssetFootstepTable>(assetName, footstepTable);
|
||||
}
|
||||
|
||||
bool BSPLinker::addDefaultRequiredAssets(const BSPData& bsp) const
|
||||
bool BSPLinker::AddDefaultRequiredAssets(const BSPData& bsp) const
|
||||
{
|
||||
if (m_context.LoadDependency<AssetScript>(std::format("maps/mp/{}.gsc", bsp.name)) == nullptr)
|
||||
if (!m_context.LoadDependency<AssetScript>(std::format("maps/mp/{}.gsc", bsp.name)))
|
||||
return false;
|
||||
if (m_context.LoadDependency<AssetScript>(std::format("maps/mp/{}_amb.gsc", bsp.name)) == nullptr)
|
||||
if (!m_context.LoadDependency<AssetScript>(std::format("maps/mp/{}_amb.gsc", bsp.name)))
|
||||
return false;
|
||||
if (m_context.LoadDependency<AssetScript>(std::format("maps/mp/{}_fx.gsc", bsp.name)) == nullptr)
|
||||
if (!m_context.LoadDependency<AssetScript>(std::format("maps/mp/{}_fx.gsc", bsp.name)))
|
||||
return false;
|
||||
|
||||
if (m_context.LoadDependency<AssetScript>(std::format("clientscripts/mp/{}.csc", bsp.name)) == nullptr)
|
||||
if (!m_context.LoadDependency<AssetScript>(std::format("clientscripts/mp/{}.csc", bsp.name)))
|
||||
return false;
|
||||
if (m_context.LoadDependency<AssetScript>(std::format("clientscripts/mp/{}_amb.csc", bsp.name)) == nullptr)
|
||||
if (!m_context.LoadDependency<AssetScript>(std::format("clientscripts/mp/{}_amb.csc", bsp.name)))
|
||||
return false;
|
||||
if (m_context.LoadDependency<AssetScript>(std::format("clientscripts/mp/{}_fx.csc", bsp.name)) == nullptr)
|
||||
if (!m_context.LoadDependency<AssetScript>(std::format("clientscripts/mp/{}_fx.csc", bsp.name)))
|
||||
return false;
|
||||
|
||||
addEmptyFootstepTableAsset("default_1st_person");
|
||||
addEmptyFootstepTableAsset("default_3rd_person");
|
||||
addEmptyFootstepTableAsset("default_1st_person_quiet");
|
||||
addEmptyFootstepTableAsset("default_3rd_person_quiet");
|
||||
addEmptyFootstepTableAsset("default_3rd_person_loud");
|
||||
addEmptyFootstepTableAsset("default_ai");
|
||||
AddEmptyFootstepTableAsset("default_1st_person");
|
||||
AddEmptyFootstepTableAsset("default_3rd_person");
|
||||
AddEmptyFootstepTableAsset("default_1st_person_quiet");
|
||||
AddEmptyFootstepTableAsset("default_3rd_person_quiet");
|
||||
AddEmptyFootstepTableAsset("default_3rd_person_loud");
|
||||
AddEmptyFootstepTableAsset("default_ai");
|
||||
|
||||
if (m_context.LoadDependency<AssetRawFile>("animtrees/fxanim_props.atr") == nullptr)
|
||||
if (!m_context.LoadDependency<AssetRawFile>("animtrees/fxanim_props.atr"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -61,9 +61,9 @@ namespace BSP
|
||||
{
|
||||
}
|
||||
|
||||
bool BSPLinker::linkBSP(const BSPData& bsp) const
|
||||
bool BSPLinker::LinkBSP(const BSPData& bsp) const
|
||||
{
|
||||
if (!addDefaultRequiredAssets(bsp))
|
||||
if (!AddDefaultRequiredAssets(bsp))
|
||||
return false;
|
||||
|
||||
ComWorldLinker comWorldLinker(m_memory, m_search_path, m_context);
|
||||
@@ -73,32 +73,32 @@ namespace BSP
|
||||
MapEntsLinker mapEntsLinker(m_memory, m_search_path, m_context);
|
||||
SkinnedVertsLinker skinnedVertsLinker(m_memory, m_search_path, m_context);
|
||||
|
||||
auto* comWorld = comWorldLinker.linkComWorld(bsp);
|
||||
auto* comWorld = comWorldLinker.LinkComWorld(bsp);
|
||||
if (comWorld == nullptr)
|
||||
return false;
|
||||
m_context.AddAsset<AssetComWorld>(comWorld->name, comWorld);
|
||||
|
||||
auto* mapEnts = mapEntsLinker.linkMapEnts(bsp);
|
||||
auto* mapEnts = mapEntsLinker.LinkMapEnts(bsp);
|
||||
if (mapEnts == nullptr)
|
||||
return false;
|
||||
m_context.AddAsset<AssetMapEnts>(mapEnts->name, mapEnts);
|
||||
|
||||
auto* gameWorldMp = gameWorldMpLinker.linkGameWorldMp(bsp);
|
||||
auto* gameWorldMp = gameWorldMpLinker.LinkGameWorldMp(bsp);
|
||||
if (gameWorldMp == nullptr)
|
||||
return false;
|
||||
m_context.AddAsset<AssetGameWorldMp>(gameWorldMp->name, gameWorldMp);
|
||||
|
||||
auto* skinnedVerts = skinnedVertsLinker.linkSkinnedVerts(bsp);
|
||||
auto* skinnedVerts = skinnedVertsLinker.LinkSkinnedVerts(bsp);
|
||||
if (skinnedVerts == nullptr)
|
||||
return false;
|
||||
m_context.AddAsset<AssetSkinnedVerts>(skinnedVerts->name, skinnedVerts);
|
||||
|
||||
auto* gfxWorld = gfxWorldLinker.linkGfxWorld(bsp); // requires mapents asset
|
||||
auto* gfxWorld = gfxWorldLinker.LinkGfxWorld(bsp); // requires mapents asset
|
||||
if (gfxWorld == nullptr)
|
||||
return false;
|
||||
m_context.AddAsset<AssetGfxWorld>(gfxWorld->name, gfxWorld);
|
||||
|
||||
auto* clipMap = clipMapLinker.linkClipMap(bsp); // requires gfxworld and mapents asset
|
||||
auto* clipMap = clipMapLinker.LinkClipMap(bsp); // requires gfxworld and mapents asset
|
||||
if (clipMap == nullptr)
|
||||
return false;
|
||||
m_context.AddAsset<AssetClipMap>(clipMap->name, clipMap);
|
||||
|
||||
@@ -12,11 +12,11 @@ namespace BSP
|
||||
public:
|
||||
BSPLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
|
||||
|
||||
[[nodiscard]] bool linkBSP(const BSPData& bsp) const;
|
||||
[[nodiscard]] bool LinkBSP(const BSPData& bsp) const;
|
||||
|
||||
private:
|
||||
void addEmptyFootstepTableAsset(const std::string& assetName) const;
|
||||
[[nodiscard]] bool addDefaultRequiredAssets(const BSPData& bsp) const;
|
||||
void AddEmptyFootstepTableAsset(const std::string& assetName) const;
|
||||
[[nodiscard]] bool AddDefaultRequiredAssets(const BSPData& bsp) const;
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Game/T6/BSP/BSPUtil.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
using namespace T6;
|
||||
@@ -15,9 +16,9 @@ namespace BSP
|
||||
{
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadDynEnts(clipMap_t& clipMap) const
|
||||
void ClipMapLinker::LoadDynEnts(clipMap_t& clipMap) const
|
||||
{
|
||||
int dynEntCount = 0;
|
||||
uint16_t dynEntCount = 0;
|
||||
clipMap.originalDynEntCount = dynEntCount;
|
||||
clipMap.dynEntCount[0] = clipMap.originalDynEntCount + 256; // the game allocs 256 empty dynents, as they may be used ingame
|
||||
clipMap.dynEntCount[1] = 0;
|
||||
@@ -42,7 +43,7 @@ namespace BSP
|
||||
clipMap.dynEntDefList[1] = nullptr;
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadVisibility(clipMap_t& clipMap) const
|
||||
void ClipMapLinker::LoadVisibility(clipMap_t& clipMap) const
|
||||
{
|
||||
// Only use one visbility cluster for the entire map
|
||||
clipMap.numClusters = 1;
|
||||
@@ -53,7 +54,7 @@ namespace BSP
|
||||
memset(clipMap.visibility, 0xFF, clipMap.clusterBytes);
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadBoxData(clipMap_t& clipMap) const
|
||||
void ClipMapLinker::LoadBoxData(clipMap_t& clipMap) const
|
||||
{
|
||||
// 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.
|
||||
@@ -114,7 +115,7 @@ namespace BSP
|
||||
clipMap.box_brush->verts = nullptr;
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadRopesAndConstraints(clipMap_t& clipMap) const
|
||||
void ClipMapLinker::LoadRopesAndConstraints(clipMap_t& clipMap) const
|
||||
{
|
||||
clipMap.num_constraints = 0; // max 511
|
||||
clipMap.constraints = nullptr;
|
||||
@@ -124,7 +125,7 @@ namespace BSP
|
||||
clipMap.ropes = m_memory.Alloc<rope_t>(clipMap.max_ropes);
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadSubModelCollision(clipMap_t& clipMap, const BSPData& bsp) const
|
||||
void ClipMapLinker::LoadSubModelCollision(clipMap_t& clipMap, const BSPData& bsp) const
|
||||
{
|
||||
// Submodels are used for the world and map ent collision (triggers, bomb zones, etc)
|
||||
auto gfxWorldAsset = m_context.LoadDependency<AssetGfxWorld>(bsp.bspName);
|
||||
@@ -163,7 +164,7 @@ namespace BSP
|
||||
clipMap.cmodels[0].info = nullptr; // always set to 0
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadXModelCollision(clipMap_t& clipMap) const
|
||||
void ClipMapLinker::LoadXModelCollision(clipMap_t& clipMap) const
|
||||
{
|
||||
// Right now XModels aren't supported
|
||||
clipMap.numStaticModels = 0;
|
||||
@@ -213,11 +214,11 @@ namespace BSP
|
||||
*/
|
||||
}
|
||||
|
||||
void ClipMapLinker::addAABBTreeFromLeaf(clipMap_t& clipMap, const BSPTree& tree, size_t& outParentCount, size_t& outParentStartIndex)
|
||||
void ClipMapLinker::AddAABBTreeFromLeaf(clipMap_t& clipMap, const BSPTree& tree, size_t& outParentCount, size_t& outParentStartIndex)
|
||||
{
|
||||
assert(tree.isLeaf);
|
||||
|
||||
size_t leafObjectCount = tree.leaf->getObjectCount();
|
||||
size_t leafObjectCount = tree.leaf->GetObjectCount();
|
||||
assert(leafObjectCount > 0);
|
||||
highestLeafObjectCount = std::max(leafObjectCount, highestLeafObjectCount);
|
||||
|
||||
@@ -246,7 +247,7 @@ namespace BSP
|
||||
vec3_t parentMaxs;
|
||||
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];
|
||||
for (int uindIdx = 0; uindIdx < partition->nuinds; uindIdx++)
|
||||
{
|
||||
@@ -276,7 +277,7 @@ namespace BSP
|
||||
// add child AABBs
|
||||
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];
|
||||
vec3_t childMins;
|
||||
vec3_t childMaxs;
|
||||
@@ -295,7 +296,7 @@ namespace BSP
|
||||
UpdateAABBWithPoint(vert, childMins, childMaxs);
|
||||
}
|
||||
|
||||
CollisionAabbTree childAABBTree;
|
||||
CollisionAabbTree childAABBTree{};
|
||||
childAABBTree.materialIndex = 0; // always use the first material
|
||||
childAABBTree.childCount = 0;
|
||||
childAABBTree.u.partitionIndex = partitionIndex;
|
||||
@@ -311,15 +312,21 @@ namespace BSP
|
||||
outParentStartIndex = parentAABBArrayIndex;
|
||||
}
|
||||
|
||||
constexpr vec3_t normalX = {1.0f, 0.0f, 0.0f};
|
||||
constexpr vec3_t normalY = {0.0f, 1.0f, 0.0f};
|
||||
constexpr vec3_t normalZ = {0.0f, 0.0f, 1.0f};
|
||||
constexpr vec3_t normalX = {
|
||||
{.x = 1.0f, .y = 0.0f, .z = 0.0f}
|
||||
};
|
||||
constexpr vec3_t normalY = {
|
||||
{.x = 0.0f, .y = 1.0f, .z = 0.0f}
|
||||
};
|
||||
constexpr vec3_t normalZ = {
|
||||
{.x = 0.0f, .y = 0.0f, .z = 1.0f}
|
||||
};
|
||||
|
||||
// returns the index of the node/leaf parsed by the function
|
||||
// Nodes are indexed by their index in the node array
|
||||
// Leafs are indexed by (-1 - <leaf index>)
|
||||
// See https://developer.valvesoftware.com/wiki/BSP_(Source)
|
||||
int16_t ClipMapLinker::loadBSPNode(clipMap_t& clipMap, const BSPTree& tree)
|
||||
int16_t ClipMapLinker::LoadBSPNode(clipMap_t& clipMap, const BSPTree& tree)
|
||||
{
|
||||
if (tree.isLeaf)
|
||||
{
|
||||
@@ -338,11 +345,11 @@ namespace BSP
|
||||
leaf.maxs.z = 0.0f;
|
||||
leaf.leafBrushNode = 0;
|
||||
|
||||
if (tree.leaf->getObjectCount() > 0)
|
||||
if (tree.leaf->GetObjectCount() > 0)
|
||||
{
|
||||
size_t parentCount = 0;
|
||||
size_t parentStartIndex = 0;
|
||||
addAABBTreeFromLeaf(clipMap, tree, parentCount, parentStartIndex);
|
||||
AddAABBTreeFromLeaf(clipMap, tree, parentCount, parentStartIndex);
|
||||
leaf.collAabbCount = static_cast<uint16_t>(parentCount);
|
||||
leaf.firstCollAabbIndex = static_cast<uint16_t>(parentStartIndex);
|
||||
}
|
||||
@@ -361,18 +368,20 @@ namespace BSP
|
||||
{
|
||||
cplane_s plane;
|
||||
plane.dist = tree.node->distance;
|
||||
if (tree.node->axis == AXIS_X)
|
||||
if (tree.node->axis == PlaneAxis::AXIS_X)
|
||||
{
|
||||
plane.normal = normalX;
|
||||
plane.type = 0;
|
||||
}
|
||||
else if (tree.node->axis == AXIS_Y)
|
||||
else if (tree.node->axis == PlaneAxis::AXIS_Y)
|
||||
{
|
||||
plane.normal = normalY;
|
||||
plane.type = 1;
|
||||
}
|
||||
else // tree->node->axis == AXIS_Z
|
||||
else
|
||||
{
|
||||
assert(tree.node->axis == PlaneAxis::AXIS_Z);
|
||||
|
||||
plane.normal = normalZ;
|
||||
plane.type = 2;
|
||||
}
|
||||
@@ -390,14 +399,14 @@ namespace BSP
|
||||
|
||||
planeVec.emplace_back(plane);
|
||||
|
||||
// The recursion of adding the children through loadBSPNode means the parent node needs to be added before the chilren are loaded
|
||||
// The recursion of adding the children through LoadBSPNode means the parent node needs to be added before the children are loaded
|
||||
size_t nodeIndex = nodeVec.size();
|
||||
nodeVec.emplace_back();
|
||||
|
||||
cNode_t node;
|
||||
node.plane = nullptr; // initalised after the BSP tree has been loaded
|
||||
node.children[0] = loadBSPNode(clipMap, *tree.node->front);
|
||||
node.children[1] = loadBSPNode(clipMap, *tree.node->back);
|
||||
node.plane = nullptr; // initialised after the BSP tree has been loaded
|
||||
node.children[0] = LoadBSPNode(clipMap, *tree.node->front);
|
||||
node.children[1] = LoadBSPNode(clipMap, *tree.node->back);
|
||||
|
||||
nodeVec.at(nodeIndex) = node;
|
||||
|
||||
@@ -405,14 +414,14 @@ namespace BSP
|
||||
}
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadBSPTree(clipMap_t& clipMap, const BSPData& bsp)
|
||||
void ClipMapLinker::LoadBSPTree(clipMap_t& clipMap, const BSPData& bsp)
|
||||
{
|
||||
vec3_t worldMins;
|
||||
vec3_t worldMaxs;
|
||||
for (unsigned int vertIdx = 0; vertIdx < clipMap.vertCount; vertIdx++)
|
||||
{
|
||||
vec3_t vertex = clipMap.verts[vertIdx];
|
||||
// initalise AABB with the first vertex
|
||||
// initialise AABB with the first vertex
|
||||
if (vertIdx == 0)
|
||||
{
|
||||
worldMins = vertex;
|
||||
@@ -442,11 +451,11 @@ namespace BSP
|
||||
}
|
||||
auto currObject =
|
||||
std::make_shared<BSPObject>(partitionMins.x, partitionMins.y, partitionMins.z, partitionMaxs.x, partitionMaxs.y, partitionMaxs.z, partitionIdx);
|
||||
tree->addObjectToTree(std::move(currObject));
|
||||
tree->AddObjectToTree(std::move(currObject));
|
||||
}
|
||||
|
||||
// load planes, nodes, leafs, and AABB trees
|
||||
loadBSPNode(clipMap, *tree);
|
||||
LoadBSPNode(clipMap, *tree);
|
||||
|
||||
clipMap.info.planeCount = static_cast<int>(planeVec.size());
|
||||
clipMap.info.planes = m_memory.Alloc<cplane_s>(planeVec.size());
|
||||
@@ -471,7 +480,7 @@ namespace BSP
|
||||
con::info("Highest leaf object count: {}", highestLeafObjectCount);
|
||||
}
|
||||
|
||||
bool ClipMapLinker::loadPartitions(clipMap_t& clipMap, const BSPData& bsp) const
|
||||
bool ClipMapLinker::LoadPartitions(clipMap_t& clipMap, const BSPData& bsp) const
|
||||
{
|
||||
// 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
|
||||
@@ -493,9 +502,9 @@ namespace BSP
|
||||
{
|
||||
const auto indexOfFirstIndex = surface.indexOfFirstIndex;
|
||||
const auto indexOfFirstVertex = surface.indexOfFirstVertex;
|
||||
for (auto indexIdx = 0; indexIdx < surface.triCount * 3; indexIdx++)
|
||||
for (auto indexIdx = 0u; indexIdx < surface.triCount * 3; indexIdx++)
|
||||
{
|
||||
auto triIndex = bsp.colWorld.indices[indexOfFirstIndex + indexIdx] + indexOfFirstVertex;
|
||||
auto triIndex = static_cast<uint16_t>(bsp.colWorld.indices[indexOfFirstIndex + indexIdx] + indexOfFirstVertex);
|
||||
triIndexVec.emplace_back(triIndex);
|
||||
}
|
||||
}
|
||||
@@ -513,12 +522,11 @@ namespace BSP
|
||||
// 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
|
||||
const auto indexOfFirstTri = surface.indexOfFirstIndex / 3;
|
||||
const auto indexOfFirstVertex = surface.indexOfFirstVertex;
|
||||
for (auto triIdx = 0; triIdx < surface.triCount; triIdx++)
|
||||
for (auto triIdx = 0u; triIdx < surface.triCount; triIdx++)
|
||||
{
|
||||
CollisionPartition partition;
|
||||
partition.triCount = 1;
|
||||
partition.firstTri = indexOfFirstTri + triIdx;
|
||||
partition.firstTri = static_cast<int>(indexOfFirstTri + triIdx);
|
||||
|
||||
partition.nuinds = 3;
|
||||
partition.fuind = static_cast<int>(uniqueIndicesVec.size());
|
||||
@@ -583,7 +591,7 @@ namespace BSP
|
||||
*/
|
||||
}
|
||||
|
||||
bool ClipMapLinker::loadWorldCollision(clipMap_t& clipMap, const BSPData& bsp)
|
||||
bool ClipMapLinker::LoadWorldCollision(clipMap_t& clipMap, const BSPData& bsp)
|
||||
{
|
||||
// No support for brushes, only tris right now
|
||||
clipMap.info.numBrushSides = 0;
|
||||
@@ -600,15 +608,15 @@ namespace BSP
|
||||
clipMap.info.brushContents = nullptr;
|
||||
|
||||
// load verts, tris, uinds and partitions
|
||||
if (!loadPartitions(clipMap, bsp))
|
||||
if (!LoadPartitions(clipMap, bsp))
|
||||
return false;
|
||||
|
||||
loadBSPTree(clipMap, bsp);
|
||||
LoadBSPTree(clipMap, bsp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
clipMap_t* ClipMapLinker::linkClipMap(const BSPData& bsp)
|
||||
clipMap_t* ClipMapLinker::LinkClipMap(const BSPData& bsp)
|
||||
{
|
||||
clipMap_t* clipMap = m_memory.Alloc<clipMap_t>();
|
||||
clipMap->name = m_memory.Dup(bsp.bspName.c_str());
|
||||
@@ -622,17 +630,17 @@ namespace BSP
|
||||
assert(mapEntsAsset != nullptr);
|
||||
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)
|
||||
// Right now there is no way to define properties per material so only one material is used
|
||||
@@ -648,7 +656,7 @@ namespace BSP
|
||||
clipMap->triEdgeIsWalkable = new char[walkableEdgeSize];
|
||||
memset(clipMap->triEdgeIsWalkable, 1, walkableEdgeSize * sizeof(char));
|
||||
|
||||
if (!loadWorldCollision(*clipMap, bsp))
|
||||
if (!LoadWorldCollision(*clipMap, bsp))
|
||||
return nullptr;
|
||||
|
||||
return clipMap;
|
||||
|
||||
@@ -13,30 +13,30 @@ namespace BSP
|
||||
public:
|
||||
ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
|
||||
|
||||
[[nodiscard]] T6::clipMap_t* linkClipMap(const BSPData& bsp);
|
||||
[[nodiscard]] T6::clipMap_t* LinkClipMap(const BSPData& bsp);
|
||||
|
||||
private:
|
||||
void LoadBoxData(T6::clipMap_t& clipMap) const;
|
||||
void LoadVisibility(T6::clipMap_t& clipMap) const;
|
||||
void LoadDynEnts(T6::clipMap_t& clipMap) const;
|
||||
void LoadRopesAndConstraints(T6::clipMap_t& clipMap) const;
|
||||
void LoadSubModelCollision(T6::clipMap_t& clipMap, const BSPData& bsp) const;
|
||||
void LoadXModelCollision(T6::clipMap_t& clipMap) const;
|
||||
|
||||
void AddAABBTreeFromLeaf(T6::clipMap_t& clipMap, const BSPTree& tree, size_t& outParentCount, size_t& outParentStartIndex);
|
||||
int16_t LoadBSPNode(T6::clipMap_t& clipMap, const BSPTree& tree);
|
||||
void LoadBSPTree(T6::clipMap_t& clipMap, const BSPData& bsp);
|
||||
bool LoadPartitions(T6::clipMap_t& clipMap, const BSPData& bsp) const;
|
||||
bool LoadWorldCollision(T6::clipMap_t& clipMap, const BSPData& bsp);
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
AssetCreationContext& m_context;
|
||||
|
||||
void loadBoxData(T6::clipMap_t& clipMap) const;
|
||||
void loadVisibility(T6::clipMap_t& clipMap) const;
|
||||
void loadDynEnts(T6::clipMap_t& clipMap) const;
|
||||
void loadRopesAndConstraints(T6::clipMap_t& clipMap) const;
|
||||
void loadSubModelCollision(T6::clipMap_t& clipMap, const BSPData& bsp) const;
|
||||
void loadXModelCollision(T6::clipMap_t& clipMap) const;
|
||||
|
||||
std::vector<T6::cplane_s> planeVec;
|
||||
std::vector<T6::cNode_t> nodeVec;
|
||||
std::vector<T6::cLeaf_s> leafVec;
|
||||
std::vector<T6::CollisionAabbTree> AABBTreeVec;
|
||||
size_t highestLeafObjectCount = 0;
|
||||
|
||||
void addAABBTreeFromLeaf(T6::clipMap_t& clipMap, const BSPTree& tree, size_t& out_parentCount, size_t& out_parentStartIndex);
|
||||
int16_t loadBSPNode(T6::clipMap_t& clipMap, const BSPTree& tree);
|
||||
void loadBSPTree(T6::clipMap_t& clipMap, const BSPData& bsp);
|
||||
bool loadPartitions(T6::clipMap_t& clipMap, const BSPData& bsp) const;
|
||||
bool loadWorldCollision(T6::clipMap_t& clipMap, const BSPData& bsp);
|
||||
};
|
||||
} // namespace BSP
|
||||
|
||||
@@ -11,10 +11,11 @@ namespace BSP
|
||||
{
|
||||
}
|
||||
|
||||
ComWorld* ComWorldLinker::linkComWorld(const BSPData& bsp) const
|
||||
ComWorld* ComWorldLinker::LinkComWorld(const BSPData& bsp) const
|
||||
{
|
||||
// all lights that aren't the sunlight or default light need their own GfxLightDef asset
|
||||
ComWorld* comWorld = m_memory.Alloc<ComWorld>();
|
||||
|
||||
comWorld->name = m_memory.Dup(bsp.bspName.c_str());
|
||||
comWorld->isInUse = 1;
|
||||
comWorld->primaryLightCount = BSPGameConstants::BSP_DEFAULT_LIGHT_COUNT;
|
||||
@@ -25,6 +26,7 @@ namespace BSP
|
||||
ComPrimaryLight* sunLight = &comWorld->primaryLights[1];
|
||||
const vec4_t sunLightColor = BSPEditableConstants::SUNLIGHT_COLOR;
|
||||
const vec3_t sunLightDirection = BSPEditableConstants::SUNLIGHT_DIRECTION;
|
||||
|
||||
sunLight->type = GFX_LIGHT_TYPE_DIR;
|
||||
sunLight->diffuseColor.r = sunLightColor.r;
|
||||
sunLight->diffuseColor.g = sunLightColor.g;
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace BSP
|
||||
{
|
||||
public:
|
||||
ComWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
|
||||
[[nodiscard]] T6::ComWorld* linkComWorld(const BSPData& bsp) const;
|
||||
|
||||
[[nodiscard]] T6::ComWorld* LinkComWorld(const BSPData& bsp) const;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace BSP
|
||||
{
|
||||
}
|
||||
|
||||
GameWorldMp* GameWorldMpLinker::linkGameWorldMp(const BSPData& bsp) const
|
||||
GameWorldMp* GameWorldMpLinker::LinkGameWorldMp(const BSPData& bsp) const
|
||||
{
|
||||
GameWorldMp* gameWorldMp = m_memory.Alloc<GameWorldMp>();
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace BSP
|
||||
gameWorldMp->path.nodeTreeCount = 0;
|
||||
|
||||
// The game has 128 empty nodes allocated
|
||||
const auto extraNodeCount = gameWorldMp->path.nodeCount + 128;
|
||||
const auto extraNodeCount = gameWorldMp->path.nodeCount + 128u;
|
||||
gameWorldMp->path.nodes = m_memory.Alloc<pathnode_t>(extraNodeCount);
|
||||
gameWorldMp->path.basenodes = m_memory.Alloc<pathbasenode_t>(extraNodeCount);
|
||||
gameWorldMp->path.pathVis = nullptr;
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace BSP
|
||||
{
|
||||
public:
|
||||
GameWorldMpLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
|
||||
[[nodiscard]] T6::GameWorldMp* linkGameWorldMp(const BSPData& bsp) const;
|
||||
|
||||
[[nodiscard]] T6::GameWorldMp* LinkGameWorldMp(const BSPData& bsp) const;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace BSP
|
||||
{
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadDrawData(const BSPData& bsp, GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadDrawData(const BSPData& bsp, GfxWorld& gfxWorld) const
|
||||
{
|
||||
size_t vertexCount = bsp.gfxWorld.vertices.size();
|
||||
gfxWorld.draw.vertexCount = static_cast<unsigned int>(vertexCount);
|
||||
@@ -56,9 +56,9 @@ namespace BSP
|
||||
}
|
||||
}
|
||||
|
||||
bool GfxWorldLinker::loadMapSurfaces(const BSPData& bsp, GfxWorld& gfxWorld) const
|
||||
bool GfxWorldLinker::LoadMapSurfaces(const BSPData& bsp, GfxWorld& gfxWorld) const
|
||||
{
|
||||
loadDrawData(bsp, gfxWorld);
|
||||
LoadDrawData(bsp, gfxWorld);
|
||||
|
||||
size_t surfaceCount = bsp.gfxWorld.surfaces.size();
|
||||
gfxWorld.surfaceCount = static_cast<int>(surfaceCount);
|
||||
@@ -75,13 +75,13 @@ namespace BSP
|
||||
gfxSurface->flags = BSPEditableConstants::DEFAULT_SURFACE_FLAGS;
|
||||
|
||||
gfxSurface->tris.triCount = static_cast<uint16_t>(bspSurface.triCount);
|
||||
gfxSurface->tris.baseIndex = bspSurface.indexOfFirstIndex;
|
||||
gfxSurface->tris.baseIndex = static_cast<int>(bspSurface.indexOfFirstIndex);
|
||||
|
||||
gfxSurface->tris.vertexDataOffset0 = bspSurface.indexOfFirstVertex * sizeof(GfxPackedWorldVertex);
|
||||
gfxSurface->tris.vertexDataOffset0 = static_cast<int>(bspSurface.indexOfFirstVertex * sizeof(GfxPackedWorldVertex));
|
||||
gfxSurface->tris.vertexDataOffset1 = 0;
|
||||
|
||||
std::string surfMaterialName;
|
||||
if (bspSurface.material.materialType == MATERIAL_TYPE_TEXTURE)
|
||||
if (bspSurface.material.materialType == BSPMaterialType::MATERIAL_TYPE_TEXTURE)
|
||||
surfMaterialName = bspSurface.material.materialName;
|
||||
else // MATERIAL_TYPE_COLOUR || MATERIAL_TYPE_EMPTY
|
||||
surfMaterialName = BSPLinkingConstants::COLOR_ONLY_IMAGE_NAME;
|
||||
@@ -156,7 +156,7 @@ namespace BSP
|
||||
return true;
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadXModels(const BSPData& bsp, GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadXModels(const BSPData& bsp, GfxWorld& gfxWorld) const
|
||||
{
|
||||
/*
|
||||
Models are unsupported right now
|
||||
@@ -185,10 +185,10 @@ namespace BSP
|
||||
currModel->placement.origin.x = inModel->origin.x;
|
||||
currModel->placement.origin.y = inModel->origin.y;
|
||||
currModel->placement.origin.z = inModel->origin.z;
|
||||
currModel->placement.origin = BSPUtil::convertToBO2Coords(currModel->placement.origin);
|
||||
currModel->placement.origin = ConvertToBO2Coords(currModel->placement.origin);
|
||||
currModel->placement.scale = inModel->scale;
|
||||
|
||||
BSPUtil::convertAnglesToAxis(&inModel->rotation, currModel->placement.axis);
|
||||
ConvertAnglesToAxis(&inModel->rotation, currModel->placement.axis);
|
||||
|
||||
// mins and maxs are calculated in world space not local space
|
||||
// TODO: this does not account for model rotation or scale
|
||||
@@ -200,9 +200,9 @@ namespace BSP
|
||||
currModelInst->maxs.z = currModel->model->maxs.z + currModel->placement.origin.z;
|
||||
|
||||
currModel->cullDist = DEFAULT_SMODEL_CULL_DIST;
|
||||
currModel->flags = DEFAULT_SMODEL_FLAGS;
|
||||
currModel->primaryLightIndex = DEFAULT_SMODEL_LIGHT;
|
||||
currModel->reflectionProbeIndex = DEFAULT_SMODEL_REFLECTION_PROBE;
|
||||
currModel->flags = BSPEditableConstants::DEFAULT_SMODEL_FLAGS;
|
||||
currModel->primaryLightIndex = BSPEditableConstants::DEFAULT_SMODEL_LIGHT;
|
||||
currModel->reflectionProbeIndex = BSPEditableConstants::DEFAULT_SMODEL_REFLECTION_PROBE;
|
||||
|
||||
// unknown use / unused
|
||||
currModel->smid = i;
|
||||
@@ -231,7 +231,7 @@ namespace BSP
|
||||
gfxWorld.dpvs.smodelDrawInsts = m_memory.Alloc<GfxStaticModelDrawInst>(modelCount);
|
||||
|
||||
// visdata is written to by the game
|
||||
// all visdata is alligned by 128
|
||||
// all visdata is aligned by 128
|
||||
const auto alignedModelCount = utils::Align(modelCount, 128uz);
|
||||
gfxWorld.dpvs.smodelVisDataCount = static_cast<unsigned int>(alignedModelCount);
|
||||
gfxWorld.dpvs.smodelVisData[0] = m_memory.Alloc<char>(alignedModelCount);
|
||||
@@ -251,7 +251,7 @@ namespace BSP
|
||||
gfxWorld.dpvs.usageCount = 0;
|
||||
}
|
||||
|
||||
void GfxWorldLinker::cleanGfxWorld(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::CleanGfxWorld(GfxWorld& gfxWorld) const
|
||||
{
|
||||
// checksum is generated by the game
|
||||
gfxWorld.checksum = 0;
|
||||
@@ -337,7 +337,7 @@ namespace BSP
|
||||
gfxWorld.sunLight = m_memory.Alloc<GfxLight>();
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadGfxLights(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadGfxLights(GfxWorld& gfxWorld) const
|
||||
{
|
||||
// there must be 2 or more lights, first is the static light and second is the sun light
|
||||
gfxWorld.primaryLightCount = BSPGameConstants::BSP_DEFAULT_LIGHT_COUNT;
|
||||
@@ -366,7 +366,7 @@ namespace BSP
|
||||
gfxWorld.primaryLightEntityShadowVis = nullptr;
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadLightGrid(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadLightGrid(GfxWorld& gfxWorld) const
|
||||
{
|
||||
// there is almost no basis for the values in this code, they were chosen based on what looks correct when reverse engineering.
|
||||
|
||||
@@ -424,7 +424,7 @@ namespace BSP
|
||||
gfxWorld.lightGrid.skyGridVolumes = nullptr;
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadGfxCells(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadGfxCells(GfxWorld& gfxWorld) const
|
||||
{
|
||||
// Cells are basically data used to determine what can be seen and what cant be seen
|
||||
// Right now custom maps have no optimisation so there is only 1 cell
|
||||
@@ -488,7 +488,7 @@ namespace BSP
|
||||
gfxWorld.dpvsPlanes.planes = nullptr;
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadWorldBounds(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadWorldBounds(GfxWorld& gfxWorld) const
|
||||
{
|
||||
gfxWorld.mins.x = 0.0f;
|
||||
gfxWorld.mins.y = 0.0f;
|
||||
@@ -503,7 +503,7 @@ namespace BSP
|
||||
}
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadModels(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadModels(GfxWorld& gfxWorld) const
|
||||
{
|
||||
// Models (Submodels in the clipmap code) are used for the world and map ent collision (triggers, bomb zones, etc)
|
||||
// Right now there is only one submodel, the world sub model
|
||||
@@ -540,7 +540,7 @@ namespace BSP
|
||||
//}
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadSunData(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadSunData(GfxWorld& gfxWorld) const
|
||||
{
|
||||
// default values taken from mp_dig
|
||||
gfxWorld.sunParse.fogTransitionTime = 0.001f;
|
||||
@@ -586,7 +586,7 @@ namespace BSP
|
||||
gfxWorld.sunParse.initWorldFog->sunFogYaw = 254.0f;
|
||||
}
|
||||
|
||||
bool GfxWorldLinker::loadReflectionProbeData(GfxWorld& gfxWorld) const
|
||||
bool GfxWorldLinker::LoadReflectionProbeData(GfxWorld& gfxWorld) const
|
||||
{
|
||||
gfxWorld.draw.reflectionProbeCount = 1;
|
||||
|
||||
@@ -616,7 +616,7 @@ namespace BSP
|
||||
|
||||
std::string probeImageName = "reflection_probe0";
|
||||
auto probeImageAsset = m_context.LoadDependency<AssetImage>(probeImageName);
|
||||
if (probeImageAsset == nullptr)
|
||||
if (!probeImageAsset)
|
||||
{
|
||||
con::error("ERROR! unable to find reflection probe image {}!", probeImageName);
|
||||
return false;
|
||||
@@ -626,7 +626,7 @@ namespace BSP
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GfxWorldLinker::loadLightmapData(GfxWorld& gfxWorld) const
|
||||
bool GfxWorldLinker::LoadLightmapData(GfxWorld& gfxWorld) const
|
||||
{
|
||||
gfxWorld.draw.lightmapCount = 1;
|
||||
|
||||
@@ -635,7 +635,7 @@ namespace BSP
|
||||
|
||||
std::string secondaryTexture = "lightmap0_secondary";
|
||||
auto secondaryTextureAsset = m_context.LoadDependency<AssetImage>(secondaryTexture);
|
||||
if (secondaryTextureAsset == nullptr)
|
||||
if (!secondaryTextureAsset)
|
||||
{
|
||||
con::error("ERROR! unable to find lightmap image {}!", secondaryTexture);
|
||||
return false;
|
||||
@@ -647,7 +647,7 @@ namespace BSP
|
||||
return true;
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadSkyBox(const BSPData& projInfo, GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadSkyBox(const BSPData& projInfo, GfxWorld& gfxWorld) const
|
||||
{
|
||||
const auto skyBoxName = std::format("skybox_{}", projInfo.name);
|
||||
gfxWorld.skyBoxModel = m_memory.Dup(skyBoxName.c_str());
|
||||
@@ -664,9 +664,9 @@ namespace BSP
|
||||
gfxWorld.skyDynIntensity.factor1 = 1.0f;
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadDynEntData(GfxWorld& gfxWorld) const
|
||||
void GfxWorldLinker::LoadDynEntData(GfxWorld& gfxWorld) const
|
||||
{
|
||||
int dynEntCount = 0;
|
||||
unsigned dynEntCount = 0u;
|
||||
gfxWorld.dpvsDyn.dynEntClientCount[0] = dynEntCount + 256; // the game allocs 256 empty dynents, as they may be used ingame
|
||||
gfxWorld.dpvsDyn.dynEntClientCount[1] = 0;
|
||||
|
||||
@@ -676,11 +676,11 @@ namespace BSP
|
||||
gfxWorld.dpvsDyn.dynEntClientWordCount[1] = 0;
|
||||
gfxWorld.dpvsDyn.usageCount = 0;
|
||||
|
||||
const auto dynEntCellBitsSize = gfxWorld.dpvsDyn.dynEntClientWordCount[0] * gfxWorld.dpvsPlanes.cellCount;
|
||||
const auto dynEntCellBitsSize = gfxWorld.dpvsDyn.dynEntClientWordCount[0] * static_cast<unsigned>(gfxWorld.dpvsPlanes.cellCount);
|
||||
gfxWorld.dpvsDyn.dynEntCellBits[0] = m_memory.Alloc<unsigned int>(dynEntCellBitsSize);
|
||||
gfxWorld.dpvsDyn.dynEntCellBits[1] = nullptr;
|
||||
|
||||
const auto dynEntVisData0Size = gfxWorld.dpvsDyn.dynEntClientWordCount[0] * 32;
|
||||
const auto dynEntVisData0Size = gfxWorld.dpvsDyn.dynEntClientWordCount[0] * 32u;
|
||||
gfxWorld.dpvsDyn.dynEntVisData[0][0] = m_memory.Alloc<char>(dynEntVisData0Size);
|
||||
gfxWorld.dpvsDyn.dynEntVisData[0][1] = m_memory.Alloc<char>(dynEntVisData0Size);
|
||||
gfxWorld.dpvsDyn.dynEntVisData[0][2] = m_memory.Alloc<char>(dynEntVisData0Size);
|
||||
@@ -688,7 +688,7 @@ namespace BSP
|
||||
gfxWorld.dpvsDyn.dynEntVisData[1][1] = nullptr;
|
||||
gfxWorld.dpvsDyn.dynEntVisData[1][2] = nullptr;
|
||||
|
||||
const auto dynEntShadowVisCount = gfxWorld.dpvsDyn.dynEntClientCount[0] * (gfxWorld.primaryLightCount - gfxWorld.sunPrimaryLightIndex - 1);
|
||||
const auto dynEntShadowVisCount = gfxWorld.dpvsDyn.dynEntClientCount[0] * (gfxWorld.primaryLightCount - gfxWorld.sunPrimaryLightIndex - 1u);
|
||||
gfxWorld.primaryLightDynEntShadowVis[0] = m_memory.Alloc<unsigned int>(dynEntShadowVisCount);
|
||||
gfxWorld.primaryLightDynEntShadowVis[1] = nullptr;
|
||||
|
||||
@@ -696,7 +696,7 @@ namespace BSP
|
||||
gfxWorld.sceneDynBrush = nullptr;
|
||||
}
|
||||
|
||||
bool GfxWorldLinker::loadOutdoors(GfxWorld& gfxWorld) const
|
||||
bool GfxWorldLinker::LoadOutdoors(GfxWorld& gfxWorld) const
|
||||
{
|
||||
const auto xRecip = 1.0f / (gfxWorld.maxs.x - gfxWorld.mins.x);
|
||||
const auto xScale = -(xRecip * gfxWorld.mins.x);
|
||||
@@ -717,9 +717,8 @@ namespace BSP
|
||||
gfxWorld.outdoorLookupMatrix[3].z = zScale;
|
||||
gfxWorld.outdoorLookupMatrix[3].w = 1.0f;
|
||||
|
||||
const std::string outdoorImageName = std::string("$outdoor");
|
||||
auto outdoorImageAsset = m_context.LoadDependency<AssetImage>(outdoorImageName);
|
||||
if (outdoorImageAsset == nullptr)
|
||||
const auto outdoorImageAsset = m_context.LoadDependency<AssetImage>("$outdoor");
|
||||
if (!outdoorImageAsset)
|
||||
{
|
||||
con::error("ERROR! unable to find outdoor image $outdoor!");
|
||||
return false;
|
||||
@@ -729,7 +728,7 @@ namespace BSP
|
||||
return true;
|
||||
}
|
||||
|
||||
GfxWorld* GfxWorldLinker::linkGfxWorld(const BSPData& bsp) const
|
||||
GfxWorld* GfxWorldLinker::LinkGfxWorld(const BSPData& bsp) const
|
||||
{
|
||||
GfxWorld* gfxWorld = m_memory.Alloc<GfxWorld>();
|
||||
gfxWorld->baseName = m_memory.Dup(bsp.name.c_str());
|
||||
@@ -739,39 +738,39 @@ namespace BSP
|
||||
gfxWorld->lightingFlags = 0;
|
||||
gfxWorld->lightingQuality = 4096;
|
||||
|
||||
cleanGfxWorld(*gfxWorld);
|
||||
CleanGfxWorld(*gfxWorld);
|
||||
|
||||
if (!loadMapSurfaces(bsp, *gfxWorld))
|
||||
if (!LoadMapSurfaces(bsp, *gfxWorld))
|
||||
return nullptr;
|
||||
|
||||
loadXModels(bsp, *gfxWorld);
|
||||
LoadXModels(bsp, *gfxWorld);
|
||||
|
||||
if (!loadLightmapData(*gfxWorld))
|
||||
if (!LoadLightmapData(*gfxWorld))
|
||||
return nullptr;
|
||||
|
||||
loadSkyBox(bsp, *gfxWorld);
|
||||
LoadSkyBox(bsp, *gfxWorld);
|
||||
|
||||
if (!loadReflectionProbeData(*gfxWorld))
|
||||
if (!LoadReflectionProbeData(*gfxWorld))
|
||||
return nullptr;
|
||||
|
||||
// world bounds are based on loaded surface mins/maxs
|
||||
loadWorldBounds(*gfxWorld);
|
||||
LoadWorldBounds(*gfxWorld);
|
||||
|
||||
if (!loadOutdoors(*gfxWorld))
|
||||
if (!LoadOutdoors(*gfxWorld))
|
||||
return nullptr;
|
||||
|
||||
// gfx cells depend on surface/smodel count
|
||||
loadGfxCells(*gfxWorld);
|
||||
LoadGfxCells(*gfxWorld);
|
||||
|
||||
loadLightGrid(*gfxWorld);
|
||||
LoadLightGrid(*gfxWorld);
|
||||
|
||||
loadGfxLights(*gfxWorld);
|
||||
LoadGfxLights(*gfxWorld);
|
||||
|
||||
loadModels(*gfxWorld);
|
||||
LoadModels(*gfxWorld);
|
||||
|
||||
loadSunData(*gfxWorld);
|
||||
LoadSunData(*gfxWorld);
|
||||
|
||||
loadDynEntData(*gfxWorld);
|
||||
LoadDynEntData(*gfxWorld);
|
||||
|
||||
return gfxWorld;
|
||||
}
|
||||
|
||||
@@ -11,27 +11,28 @@ namespace BSP
|
||||
{
|
||||
public:
|
||||
GfxWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
|
||||
[[nodiscard]] T6::GfxWorld* linkGfxWorld(const BSPData& bsp) const;
|
||||
|
||||
[[nodiscard]] T6::GfxWorld* LinkGfxWorld(const BSPData& bsp) const;
|
||||
|
||||
private:
|
||||
void LoadDrawData(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
bool LoadMapSurfaces(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
void LoadXModels(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
void CleanGfxWorld(T6::GfxWorld& gfxWorld) const;
|
||||
void LoadGfxLights(T6::GfxWorld& gfxWorld) const;
|
||||
void LoadLightGrid(T6::GfxWorld& gfxWorld) const;
|
||||
void LoadGfxCells(T6::GfxWorld& gfxWorld) const;
|
||||
void LoadModels(T6::GfxWorld& gfxWorld) const;
|
||||
bool LoadReflectionProbeData(T6::GfxWorld& gfxWorld) const;
|
||||
bool LoadLightmapData(T6::GfxWorld& gfxWorld) const;
|
||||
void LoadSkyBox(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
void LoadDynEntData(T6::GfxWorld& gfxWorld) const;
|
||||
bool LoadOutdoors(T6::GfxWorld& gfxWorld) const;
|
||||
void LoadSunData(T6::GfxWorld& gfxWorld) const;
|
||||
void LoadWorldBounds(T6::GfxWorld& gfxWorld) const;
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
AssetCreationContext& m_context;
|
||||
|
||||
void loadDrawData(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
bool loadMapSurfaces(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
void loadXModels(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
void cleanGfxWorld(T6::GfxWorld& gfxWorld) const;
|
||||
void loadGfxLights(T6::GfxWorld& gfxWorld) const;
|
||||
void loadLightGrid(T6::GfxWorld& gfxWorld) const;
|
||||
void loadGfxCells(T6::GfxWorld& gfxWorld) const;
|
||||
void loadModels(T6::GfxWorld& gfxWorld) const;
|
||||
bool loadReflectionProbeData(T6::GfxWorld& gfxWorld) const;
|
||||
bool loadLightmapData(T6::GfxWorld& gfxWorld) const;
|
||||
void loadSkyBox(const BSPData& projInfo, T6::GfxWorld& gfxWorld) const;
|
||||
void loadDynEntData(T6::GfxWorld& gfxWorld) const;
|
||||
bool loadOutdoors(T6::GfxWorld& gfxWorld) const;
|
||||
void loadSunData(T6::GfxWorld& gfxWorld) const;
|
||||
void loadWorldBounds(T6::GfxWorld& gfxWorld) const;
|
||||
};
|
||||
} // namespace BSP
|
||||
|
||||
@@ -74,13 +74,12 @@ namespace BSP
|
||||
{
|
||||
}
|
||||
|
||||
MapEnts* MapEntsLinker::linkMapEnts(const BSPData& bsp) const
|
||||
MapEnts* MapEntsLinker::LinkMapEnts(const BSPData& bsp) const
|
||||
{
|
||||
try
|
||||
{
|
||||
json entJs;
|
||||
std::string entityFileName = "entities.json";
|
||||
std::string entityFilePath = GetFileNameForBSPAsset(entityFileName);
|
||||
std::string entityFilePath = GetFileNameForBSPAsset("entities.json");
|
||||
const auto entFile = m_search_path.Open(entityFilePath);
|
||||
if (!entFile.IsOpen())
|
||||
{
|
||||
@@ -108,9 +107,9 @@ namespace BSP
|
||||
{
|
||||
spawnJs = json::parse(*spawnFile.m_stream);
|
||||
}
|
||||
size_t defenderNameCount = std::extent<decltype(BSPGameConstants::DEFENDER_SPAWN_POINT_NAMES)>::value;
|
||||
size_t attackerNameCount = std::extent<decltype(BSPGameConstants::ATTACKER_SPAWN_POINT_NAMES)>::value;
|
||||
size_t ffaNameCount = std::extent<decltype(BSPGameConstants::FFA_SPAWN_POINT_NAMES)>::value;
|
||||
size_t defenderNameCount = std::extent_v<decltype(BSPGameConstants::DEFENDER_SPAWN_POINT_NAMES)>;
|
||||
size_t attackerNameCount = std::extent_v<decltype(BSPGameConstants::ATTACKER_SPAWN_POINT_NAMES)>;
|
||||
size_t ffaNameCount = std::extent_v<decltype(BSPGameConstants::FFA_SPAWN_POINT_NAMES)>;
|
||||
parseSpawnpointJSON(spawnJs["attackers"], entityString, BSPGameConstants::DEFENDER_SPAWN_POINT_NAMES, defenderNameCount);
|
||||
parseSpawnpointJSON(spawnJs["defenders"], entityString, BSPGameConstants::ATTACKER_SPAWN_POINT_NAMES, attackerNameCount);
|
||||
parseSpawnpointJSON(spawnJs["FFA"], entityString, BSPGameConstants::FFA_SPAWN_POINT_NAMES, ffaNameCount);
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace BSP
|
||||
{
|
||||
public:
|
||||
MapEntsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
|
||||
[[nodiscard]] T6::MapEnts* linkMapEnts(const BSPData& bsp) const;
|
||||
|
||||
[[nodiscard]] T6::MapEnts* LinkMapEnts(const BSPData& bsp) const;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace BSP
|
||||
{
|
||||
}
|
||||
|
||||
T6::SkinnedVertsDef* SkinnedVertsLinker::linkSkinnedVerts(const BSPData& bsp) const
|
||||
T6::SkinnedVertsDef* SkinnedVertsLinker::LinkSkinnedVerts(const BSPData& bsp) const
|
||||
{
|
||||
// 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
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace BSP
|
||||
{
|
||||
public:
|
||||
SkinnedVertsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
|
||||
[[nodiscard]] T6::SkinnedVertsDef* linkSkinnedVerts(const BSPData& bsp) const;
|
||||
|
||||
[[nodiscard]] T6::SkinnedVertsDef* LinkSkinnedVerts(const BSPData& bsp) const;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
|
||||
@@ -32,12 +32,12 @@ namespace
|
||||
|
||||
bool FinalizeZone(AssetCreationContext& context) override
|
||||
{
|
||||
const std::unique_ptr<BSPData> bsp = BSP::createBSPData(m_zone.m_name, m_search_path);
|
||||
if (bsp == nullptr)
|
||||
const auto bsp = CreateBSPData(m_zone.m_name, m_search_path);
|
||||
if (!bsp)
|
||||
return false;
|
||||
|
||||
BSPLinker linker(m_memory, m_search_path, context);
|
||||
const auto result = linker.linkBSP(*bsp);
|
||||
const auto result = linker.LinkBSP(*bsp);
|
||||
if (!result)
|
||||
con::error("BSP link has failed.");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user