mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-06 08:42:35 +00:00
refactor: remove extra classes from BSP.h and move vars to their respective files
This commit is contained in:
@@ -180,65 +180,10 @@ namespace BSP
|
||||
std::vector<BSPModel> models;
|
||||
};
|
||||
|
||||
// BSPGameConstants:
|
||||
// These values are hardcoded ingame and will break the map if they are changed
|
||||
namespace BSPGameConstants
|
||||
enum BSPDefaultLights
|
||||
{
|
||||
constexpr unsigned int MAX_COLLISION_VERTS = UINT16_MAX;
|
||||
|
||||
constexpr size_t MAX_AABB_TREE_CHILDREN = 128;
|
||||
|
||||
enum BSPDefaultLights
|
||||
{
|
||||
EMPTY_LIGHT_INDEX = 0,
|
||||
SUN_LIGHT_INDEX = 1,
|
||||
BSP_DEFAULT_LIGHT_COUNT = 2
|
||||
};
|
||||
} // namespace BSPGameConstants
|
||||
|
||||
// BSPLinkingConstants:
|
||||
// These values are BSP linking constants that are required for the link to be successful
|
||||
namespace BSPLinkingConstants
|
||||
{
|
||||
constexpr const char* MISSING_IMAGE_NAME = ",mc/lambert1";
|
||||
constexpr const char* COLOR_ONLY_IMAGE_NAME = ",mc/lambert1";
|
||||
} // namespace BSPLinkingConstants
|
||||
|
||||
// BSPEditableConstants:
|
||||
// These values are BSP constants that can be edited and may not break the linker/game if changed
|
||||
namespace BSPEditableConstants
|
||||
{
|
||||
// Default xmodel values
|
||||
// Unused as there is no support for xmodels right now
|
||||
constexpr float DEFAULT_SMODEL_CULL_DIST = 10000.0f;
|
||||
constexpr int DEFAULT_SMODEL_FLAGS = STATIC_MODEL_FLAG_NO_SHADOW;
|
||||
constexpr int DEFAULT_SMODEL_LIGHT = 1;
|
||||
constexpr int DEFAULT_SMODEL_REFLECTION_PROBE = 0;
|
||||
|
||||
// Default surface values
|
||||
constexpr int DEFAULT_SURFACE_LIGHT = 1;
|
||||
constexpr int DEFAULT_SURFACE_LIGHTMAP = 0;
|
||||
constexpr int DEFAULT_SURFACE_REFLECTION_PROBE = 0;
|
||||
constexpr int DEFAULT_SURFACE_FLAGS = 0;
|
||||
|
||||
// material flags determine the features of a surface
|
||||
// unsure which flag type changes what right now
|
||||
// -1 results in: no running, water splashes all the time, low friction, slanted angles make you slide very fast
|
||||
// 1 results in: normal surface features, grenades work, seems normal
|
||||
constexpr int MATERIAL_SURFACE_FLAGS = 1;
|
||||
constexpr int MATERIAL_CONTENT_FLAGS = 1;
|
||||
|
||||
// terrain/world flags: does not change the type of terrain or what features they have
|
||||
// from testing, as long at it isn't 0 things will work correctly
|
||||
constexpr int LEAF_TERRAIN_CONTENTS = 1;
|
||||
constexpr int WORLD_TERRAIN_CONTENTS = 1;
|
||||
|
||||
// lightgrid (global) lighting colour
|
||||
// since lightgrids are not well understood, this colour is used for the R, G and B values right now
|
||||
constexpr unsigned char LIGHTGRID_COLOUR = 128;
|
||||
|
||||
// Sunlight values
|
||||
constexpr vec4_t SUNLIGHT_COLOR = {0.75f, 0.75f, 0.75f, 1.0f};
|
||||
constexpr vec3_t SUNLIGHT_DIRECTION = {0.0f, 0.0f, 0.0f};
|
||||
}; // namespace BSPEditableConstants
|
||||
EMPTY_LIGHT_INDEX = 0,
|
||||
SUN_LIGHT_INDEX = 1,
|
||||
BSP_DEFAULT_LIGHT_COUNT = 2
|
||||
};
|
||||
} // namespace BSP
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
|
||||
#include "../BSPUtil.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct uniqueMatData
|
||||
{
|
||||
size_t materialIndex;
|
||||
std::vector<int> partitionIndexes;
|
||||
};
|
||||
|
||||
constexpr size_t MAX_AABB_TREE_CHILDREN = 128;
|
||||
} // namespace
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
ClipMapLinker::ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context)
|
||||
@@ -202,179 +213,6 @@ namespace BSP
|
||||
return true;
|
||||
}
|
||||
|
||||
void calculatePartitionAABB(clipMap_t* clipMap, CollisionPartition* partition, vec3_t& out_mins, vec3_t& out_maxs);
|
||||
void addAABBTreeFromPartitions(
|
||||
clipMap_t* clipMap, std::vector<int>& partitions, size_t* out_parentCount, size_t* out_parentStartIndex, int* out_treeContents);
|
||||
|
||||
void ClipMapLinker::loadSubModelCollision(clipMap_t* clipMap, BSPData* bsp)
|
||||
{
|
||||
// Submodels are used for the world and map ent collision (triggers, bomb zones, etc)
|
||||
clipMap->numSubModels = static_cast<unsigned int>(bsp->models.size() + 1);
|
||||
clipMap->cmodels = m_memory.Alloc<cmodel_t>(clipMap->numSubModels);
|
||||
|
||||
// first model is always the world model
|
||||
for (unsigned int vertIdx = 0; vertIdx < clipMap->vertCount; vertIdx++)
|
||||
{
|
||||
vec3_t vertex = clipMap->verts[vertIdx];
|
||||
if (vertIdx == 0)
|
||||
{
|
||||
clipMap->cmodels[0].mins = vertex;
|
||||
clipMap->cmodels[0].maxs = vertex;
|
||||
}
|
||||
else
|
||||
BSPUtil::updateAABBWithPoint(vertex, clipMap->cmodels[0].mins, clipMap->cmodels[0].maxs);
|
||||
}
|
||||
clipMap->cmodels[0].radius = BSPUtil::distBetweenPoints(clipMap->cmodels[0].mins, clipMap->cmodels[0].maxs) / 2;
|
||||
// The world sub model has no data apart from the bounds
|
||||
clipMap->cmodels[0].leaf.firstCollAabbIndex = 0;
|
||||
clipMap->cmodels[0].leaf.collAabbCount = 0;
|
||||
clipMap->cmodels[0].leaf.brushContents = 0;
|
||||
clipMap->cmodels[0].leaf.terrainContents = 0;
|
||||
clipMap->cmodels[0].leaf.mins.x = 0.0f;
|
||||
clipMap->cmodels[0].leaf.mins.y = 0.0f;
|
||||
clipMap->cmodels[0].leaf.mins.z = 0.0f;
|
||||
clipMap->cmodels[0].leaf.maxs.x = 0.0f;
|
||||
clipMap->cmodels[0].leaf.maxs.y = 0.0f;
|
||||
clipMap->cmodels[0].leaf.maxs.z = 0.0f;
|
||||
clipMap->cmodels[0].leaf.leafBrushNode = 0;
|
||||
clipMap->cmodels[0].leaf.cluster = 0;
|
||||
clipMap->cmodels[0].info = nullptr;
|
||||
|
||||
for (size_t modelIdx = 0; modelIdx < bsp->models.size(); modelIdx++)
|
||||
{
|
||||
auto clipModel = &clipMap->cmodels[modelIdx + 1];
|
||||
auto& bspModel = bsp->models.at(modelIdx);
|
||||
|
||||
if (bspModel.isGfxModel)
|
||||
{
|
||||
memset(clipModel, 0, sizeof(cmodel_t));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bspModel.surfaceCount != 0)
|
||||
{
|
||||
std::vector<int> partitionIndexes;
|
||||
for (size_t surfIdx = 0; surfIdx < bspModel.surfaceCount; surfIdx++)
|
||||
{
|
||||
ColSurface& surf = collisionSurfaceVec.at(bsp->colWorld.staticSurfaces.size() + bspModel.surfaceIndex + surfIdx);
|
||||
for (size_t partitionIdx = 0; partitionIdx < surf.partitionCount; partitionIdx++)
|
||||
{
|
||||
size_t clipMapPartitionIndex = surf.partitionStartIndex + partitionIdx;
|
||||
partitionIndexes.emplace_back(clipMapPartitionIndex);
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
calculatePartitionAABB(clipMap, &clipMap->partitions[clipMapPartitionIndex], mins, maxs);
|
||||
if (surfIdx == 0 && partitionIdx == 0)
|
||||
{
|
||||
clipModel->mins = mins;
|
||||
clipModel->maxs = maxs;
|
||||
}
|
||||
else
|
||||
BSPUtil::updateAABB(mins, maxs, clipModel->mins, clipModel->maxs);
|
||||
}
|
||||
}
|
||||
|
||||
int terrainContents = 0;
|
||||
size_t firstCollAabbIndex = 0;
|
||||
size_t collAabbCount = 0;
|
||||
addAABBTreeFromPartitions(clipMap, partitionIndexes, &collAabbCount, &firstCollAabbIndex, &terrainContents);
|
||||
clipModel->leaf.terrainContents = terrainContents;
|
||||
clipModel->leaf.firstCollAabbIndex = static_cast<uint16_t>(firstCollAabbIndex);
|
||||
clipModel->leaf.collAabbCount = static_cast<uint16_t>(collAabbCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
clipModel->leaf.terrainContents = 0;
|
||||
clipModel->leaf.firstCollAabbIndex = 0;
|
||||
clipModel->leaf.collAabbCount = 0;
|
||||
}
|
||||
|
||||
if (bspModel.hasBrush)
|
||||
{
|
||||
|
||||
BSPBoxBrush& bspBrush = bsp->colWorld.scriptBoxBrushes.at(bspModel.brushIndex);
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
for (size_t vertIdx = 0; vertIdx < bspBrush.vertexCount; vertIdx++)
|
||||
{
|
||||
vec3_t* vertex = &clipMap->info.brushVerts[bspBrush.vertexIndex + vertIdx];
|
||||
if (vertIdx == 0)
|
||||
{
|
||||
mins = *vertex;
|
||||
maxs = *vertex;
|
||||
}
|
||||
else
|
||||
BSPUtil::updateAABBWithPoint(*vertex, mins, maxs);
|
||||
}
|
||||
|
||||
clipModel->leaf.mins = mins;
|
||||
clipModel->leaf.maxs = maxs;
|
||||
clipModel->leaf.brushContents = bspBrush.contentFlags;
|
||||
clipModel->leaf.leafBrushNode = static_cast<int>(brushNodeVec.size());
|
||||
assert(clipModel->leaf.leafBrushNode != 0);
|
||||
|
||||
cLeafBrushNode_s brushNode;
|
||||
brushNode.axis = 0;
|
||||
brushNode.contents = bspBrush.contentFlags;
|
||||
brushNode.leafBrushCount = 1;
|
||||
brushNode.data.leaf.brushes = m_memory.Alloc<LeafBrush>(1);
|
||||
brushNode.data.leaf.brushes[0] = static_cast<unsigned short>(brushVec.size());
|
||||
brushNodeVec.emplace_back(brushNode);
|
||||
|
||||
cbrush_array_t brush;
|
||||
memset(&brush, 0, sizeof(cbrush_array_t)); // if not sides or verts are given, the mins/maxs are used instead
|
||||
brush.numverts = static_cast<unsigned int>(bspBrush.vertexCount);
|
||||
brush.verts = &clipMap->info.brushVerts[bspBrush.vertexIndex];
|
||||
brush.contents = bspBrush.contentFlags;
|
||||
brush.mins = mins;
|
||||
brush.maxs = maxs;
|
||||
brush.axial_cflags[0][0] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[0][1] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[0][2] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[1][0] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[1][1] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[1][2] = bspBrush.contentFlags;
|
||||
brush.axial_sflags[0][0] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[0][1] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[0][2] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[1][0] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[1][1] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[1][2] = bspBrush.surfaceFlags;
|
||||
brushVec.emplace_back(brush);
|
||||
|
||||
if (bspModel.surfaceCount != 0)
|
||||
BSPUtil::updateAABB(mins, maxs, clipModel->mins, clipModel->maxs);
|
||||
else
|
||||
{
|
||||
clipModel->mins = mins;
|
||||
clipModel->maxs = maxs;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clipModel->leaf.brushContents = 0;
|
||||
clipModel->leaf.mins.x = 0.0f;
|
||||
clipModel->leaf.mins.y = 0.0f;
|
||||
clipModel->leaf.mins.z = 0.0f;
|
||||
clipModel->leaf.maxs.x = 0.0f;
|
||||
clipModel->leaf.maxs.y = 0.0f;
|
||||
clipModel->leaf.maxs.z = 0.0f;
|
||||
clipModel->leaf.leafBrushNode = 0;
|
||||
}
|
||||
|
||||
if (bspModel.surfaceCount == 0 && !bspModel.hasBrush)
|
||||
{
|
||||
clipModel->mins = {0.0f, 0.0f, 0.0f};
|
||||
clipModel->maxs = {0.0f, 0.0f, 0.0f};
|
||||
clipModel->radius = 0.0f;
|
||||
}
|
||||
else
|
||||
clipModel->radius = BSPUtil::distBetweenPoints(clipModel->mins, clipModel->maxs) / 2;
|
||||
clipModel->leaf.cluster = 0;
|
||||
clipModel->info = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// out_mins and out_maxs are initialised in the function
|
||||
void calculatePartitionAABB(clipMap_t* clipMap, CollisionPartition* partition, vec3_t& out_mins, vec3_t& out_maxs)
|
||||
{
|
||||
@@ -394,12 +232,6 @@ namespace BSP
|
||||
}
|
||||
}
|
||||
|
||||
struct uniqueMatData
|
||||
{
|
||||
size_t materialIndex;
|
||||
std::vector<int> partitionIndexes;
|
||||
};
|
||||
|
||||
void ClipMapLinker::addAABBTreeFromPartitions(
|
||||
clipMap_t* clipMap, std::vector<int>& partitions, size_t* out_parentCount, size_t* out_parentStartIndex, int* out_treeContents)
|
||||
{
|
||||
@@ -438,8 +270,8 @@ namespace BSP
|
||||
for (auto& matData : uniqueMaterials)
|
||||
{
|
||||
size_t objCount = matData.partitionIndexes.size();
|
||||
size_t result = objCount / BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||
size_t remainder = objCount % BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||
size_t result = objCount / MAX_AABB_TREE_CHILDREN;
|
||||
size_t remainder = objCount % MAX_AABB_TREE_CHILDREN;
|
||||
if (remainder > 0)
|
||||
result++;
|
||||
totalParentCount += result;
|
||||
@@ -454,8 +286,8 @@ namespace BSP
|
||||
for (auto& matData : uniqueMaterials)
|
||||
{
|
||||
size_t matPartCount = matData.partitionIndexes.size();
|
||||
size_t parentCount = matPartCount / BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||
size_t remainder = matPartCount % BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||
size_t parentCount = matPartCount / MAX_AABB_TREE_CHILDREN;
|
||||
size_t remainder = matPartCount % MAX_AABB_TREE_CHILDREN;
|
||||
if (remainder > 0)
|
||||
parentCount++;
|
||||
|
||||
@@ -463,11 +295,11 @@ namespace BSP
|
||||
size_t addedObjectCount = 0;
|
||||
for (size_t parentIdx = 0; parentIdx < parentCount; parentIdx++)
|
||||
{
|
||||
size_t currChildObjectCount = BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||
if (unaddedObjectCount <= BSPGameConstants::MAX_AABB_TREE_CHILDREN)
|
||||
size_t currChildObjectCount = MAX_AABB_TREE_CHILDREN;
|
||||
if (unaddedObjectCount <= MAX_AABB_TREE_CHILDREN)
|
||||
currChildObjectCount = unaddedObjectCount;
|
||||
else
|
||||
unaddedObjectCount -= BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||
unaddedObjectCount -= MAX_AABB_TREE_CHILDREN;
|
||||
|
||||
vec3_t parentMins;
|
||||
vec3_t parentMaxs;
|
||||
@@ -680,10 +512,9 @@ namespace BSP
|
||||
{
|
||||
// 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
|
||||
if (static_cast<unsigned int>(bsp->colWorld.vertices.size()) > BSPGameConstants::MAX_COLLISION_VERTS)
|
||||
if (static_cast<unsigned int>(bsp->colWorld.vertices.size()) > UINT16_MAX)
|
||||
{
|
||||
con::error(
|
||||
"ERROR: collision vertex count {} exceeds the maximum number: {}!\n", bsp->colWorld.vertices.size(), BSPGameConstants::MAX_COLLISION_VERTS);
|
||||
con::error("ERROR: collision vertex count {} exceeds the maximum number: {}!\n", bsp->colWorld.vertices.size(), UINT16_MAX);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -826,6 +657,175 @@ namespace BSP
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClipMapLinker::loadSubModelCollision(clipMap_t* clipMap, BSPData* bsp)
|
||||
{
|
||||
// Submodels are used for the world and map ent collision (triggers, bomb zones, etc)
|
||||
clipMap->numSubModels = static_cast<unsigned int>(bsp->models.size() + 1);
|
||||
clipMap->cmodels = m_memory.Alloc<cmodel_t>(clipMap->numSubModels);
|
||||
|
||||
// first model is always the world model
|
||||
for (unsigned int vertIdx = 0; vertIdx < clipMap->vertCount; vertIdx++)
|
||||
{
|
||||
vec3_t vertex = clipMap->verts[vertIdx];
|
||||
if (vertIdx == 0)
|
||||
{
|
||||
clipMap->cmodels[0].mins = vertex;
|
||||
clipMap->cmodels[0].maxs = vertex;
|
||||
}
|
||||
else
|
||||
BSPUtil::updateAABBWithPoint(vertex, clipMap->cmodels[0].mins, clipMap->cmodels[0].maxs);
|
||||
}
|
||||
clipMap->cmodels[0].radius = BSPUtil::distBetweenPoints(clipMap->cmodels[0].mins, clipMap->cmodels[0].maxs) / 2;
|
||||
// The world sub model has no data apart from the bounds
|
||||
clipMap->cmodels[0].leaf.firstCollAabbIndex = 0;
|
||||
clipMap->cmodels[0].leaf.collAabbCount = 0;
|
||||
clipMap->cmodels[0].leaf.brushContents = 0;
|
||||
clipMap->cmodels[0].leaf.terrainContents = 0;
|
||||
clipMap->cmodels[0].leaf.mins.x = 0.0f;
|
||||
clipMap->cmodels[0].leaf.mins.y = 0.0f;
|
||||
clipMap->cmodels[0].leaf.mins.z = 0.0f;
|
||||
clipMap->cmodels[0].leaf.maxs.x = 0.0f;
|
||||
clipMap->cmodels[0].leaf.maxs.y = 0.0f;
|
||||
clipMap->cmodels[0].leaf.maxs.z = 0.0f;
|
||||
clipMap->cmodels[0].leaf.leafBrushNode = 0;
|
||||
clipMap->cmodels[0].leaf.cluster = 0;
|
||||
clipMap->cmodels[0].info = nullptr;
|
||||
|
||||
for (size_t modelIdx = 0; modelIdx < bsp->models.size(); modelIdx++)
|
||||
{
|
||||
auto clipModel = &clipMap->cmodels[modelIdx + 1];
|
||||
auto& bspModel = bsp->models.at(modelIdx);
|
||||
|
||||
if (bspModel.isGfxModel)
|
||||
{
|
||||
memset(clipModel, 0, sizeof(cmodel_t));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bspModel.surfaceCount != 0)
|
||||
{
|
||||
std::vector<int> partitionIndexes;
|
||||
for (size_t surfIdx = 0; surfIdx < bspModel.surfaceCount; surfIdx++)
|
||||
{
|
||||
ColSurface& surf = collisionSurfaceVec.at(bsp->colWorld.staticSurfaces.size() + bspModel.surfaceIndex + surfIdx);
|
||||
for (size_t partitionIdx = 0; partitionIdx < surf.partitionCount; partitionIdx++)
|
||||
{
|
||||
size_t clipMapPartitionIndex = surf.partitionStartIndex + partitionIdx;
|
||||
partitionIndexes.emplace_back(clipMapPartitionIndex);
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
calculatePartitionAABB(clipMap, &clipMap->partitions[clipMapPartitionIndex], mins, maxs);
|
||||
if (surfIdx == 0 && partitionIdx == 0)
|
||||
{
|
||||
clipModel->mins = mins;
|
||||
clipModel->maxs = maxs;
|
||||
}
|
||||
else
|
||||
BSPUtil::updateAABB(mins, maxs, clipModel->mins, clipModel->maxs);
|
||||
}
|
||||
}
|
||||
|
||||
int terrainContents = 0;
|
||||
size_t firstCollAabbIndex = 0;
|
||||
size_t collAabbCount = 0;
|
||||
addAABBTreeFromPartitions(clipMap, partitionIndexes, &collAabbCount, &firstCollAabbIndex, &terrainContents);
|
||||
clipModel->leaf.terrainContents = terrainContents;
|
||||
clipModel->leaf.firstCollAabbIndex = static_cast<uint16_t>(firstCollAabbIndex);
|
||||
clipModel->leaf.collAabbCount = static_cast<uint16_t>(collAabbCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
clipModel->leaf.terrainContents = 0;
|
||||
clipModel->leaf.firstCollAabbIndex = 0;
|
||||
clipModel->leaf.collAabbCount = 0;
|
||||
}
|
||||
|
||||
if (bspModel.hasBrush)
|
||||
{
|
||||
|
||||
BSPBoxBrush& bspBrush = bsp->colWorld.scriptBoxBrushes.at(bspModel.brushIndex);
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
for (size_t vertIdx = 0; vertIdx < bspBrush.vertexCount; vertIdx++)
|
||||
{
|
||||
vec3_t* vertex = &clipMap->info.brushVerts[bspBrush.vertexIndex + vertIdx];
|
||||
if (vertIdx == 0)
|
||||
{
|
||||
mins = *vertex;
|
||||
maxs = *vertex;
|
||||
}
|
||||
else
|
||||
BSPUtil::updateAABBWithPoint(*vertex, mins, maxs);
|
||||
}
|
||||
|
||||
clipModel->leaf.mins = mins;
|
||||
clipModel->leaf.maxs = maxs;
|
||||
clipModel->leaf.brushContents = bspBrush.contentFlags;
|
||||
clipModel->leaf.leafBrushNode = static_cast<int>(brushNodeVec.size());
|
||||
assert(clipModel->leaf.leafBrushNode != 0);
|
||||
|
||||
cLeafBrushNode_s brushNode;
|
||||
brushNode.axis = 0;
|
||||
brushNode.contents = bspBrush.contentFlags;
|
||||
brushNode.leafBrushCount = 1;
|
||||
brushNode.data.leaf.brushes = m_memory.Alloc<LeafBrush>(1);
|
||||
brushNode.data.leaf.brushes[0] = static_cast<unsigned short>(brushVec.size());
|
||||
brushNodeVec.emplace_back(brushNode);
|
||||
|
||||
cbrush_array_t brush;
|
||||
memset(&brush, 0, sizeof(cbrush_array_t)); // if not sides or verts are given, the mins/maxs are used instead
|
||||
brush.numverts = static_cast<unsigned int>(bspBrush.vertexCount);
|
||||
brush.verts = &clipMap->info.brushVerts[bspBrush.vertexIndex];
|
||||
brush.contents = bspBrush.contentFlags;
|
||||
brush.mins = mins;
|
||||
brush.maxs = maxs;
|
||||
brush.axial_cflags[0][0] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[0][1] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[0][2] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[1][0] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[1][1] = bspBrush.contentFlags;
|
||||
brush.axial_cflags[1][2] = bspBrush.contentFlags;
|
||||
brush.axial_sflags[0][0] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[0][1] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[0][2] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[1][0] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[1][1] = bspBrush.surfaceFlags;
|
||||
brush.axial_sflags[1][2] = bspBrush.surfaceFlags;
|
||||
brushVec.emplace_back(brush);
|
||||
|
||||
if (bspModel.surfaceCount != 0)
|
||||
BSPUtil::updateAABB(mins, maxs, clipModel->mins, clipModel->maxs);
|
||||
else
|
||||
{
|
||||
clipModel->mins = mins;
|
||||
clipModel->maxs = maxs;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clipModel->leaf.brushContents = 0;
|
||||
clipModel->leaf.mins.x = 0.0f;
|
||||
clipModel->leaf.mins.y = 0.0f;
|
||||
clipModel->leaf.mins.z = 0.0f;
|
||||
clipModel->leaf.maxs.x = 0.0f;
|
||||
clipModel->leaf.maxs.y = 0.0f;
|
||||
clipModel->leaf.maxs.z = 0.0f;
|
||||
clipModel->leaf.leafBrushNode = 0;
|
||||
}
|
||||
|
||||
if (bspModel.surfaceCount == 0 && !bspModel.hasBrush)
|
||||
{
|
||||
clipModel->mins = {0.0f, 0.0f, 0.0f};
|
||||
clipModel->maxs = {0.0f, 0.0f, 0.0f};
|
||||
clipModel->radius = 0.0f;
|
||||
}
|
||||
else
|
||||
clipModel->radius = BSPUtil::distBetweenPoints(clipModel->mins, clipModel->maxs) / 2;
|
||||
clipModel->leaf.cluster = 0;
|
||||
clipModel->info = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClipMapLinker::loadMaterials(clipMap_t* clipMap, BSPData* bsp)
|
||||
{
|
||||
// Clipmap materials define the properties of a material (bullet penetration, no collision, water, etc)
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
|
||||
#include <numbers>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const char* DEFAULT_LIGHTDEF_NAME = "white_light";
|
||||
constexpr short LIGHT_CULLDIST = 10000;
|
||||
} // namespace
|
||||
|
||||
namespace BSP
|
||||
{
|
||||
ComWorldLinker::ComWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context)
|
||||
@@ -16,10 +22,10 @@ namespace BSP
|
||||
bool ComWorldLinker::createLightDefs()
|
||||
{
|
||||
T6::GfxLightDef* lightDef2d = m_memory.Alloc<T6::GfxLightDef>();
|
||||
lightDef2d->name = m_memory.Dup("white_light");
|
||||
lightDef2d->name = m_memory.Dup(DEFAULT_LIGHTDEF_NAME);
|
||||
lightDef2d->lmapLookupStart = 0; // always 0
|
||||
lightDef2d->attenuation.samplerState = 115; // always 115
|
||||
auto image2dAsset = m_context.LoadDependency<T6::AssetImage>("whitesquare");
|
||||
auto image2dAsset = m_context.LoadDependency<T6::AssetImage>(",$white");
|
||||
if (image2dAsset == nullptr)
|
||||
return false;
|
||||
lightDef2d->attenuation.image = image2dAsset->Asset();
|
||||
@@ -36,7 +42,7 @@ namespace BSP
|
||||
comWorld->isInUse = 1;
|
||||
|
||||
// first two lights are the empty light and the sun light.
|
||||
size_t totalLightCount = bsp->lights.size() + BSPGameConstants::BSP_DEFAULT_LIGHT_COUNT;
|
||||
size_t totalLightCount = bsp->lights.size() + BSP_DEFAULT_LIGHT_COUNT;
|
||||
comWorld->primaryLightCount = static_cast<unsigned int>(totalLightCount);
|
||||
comWorld->primaryLights = m_memory.Alloc<ComPrimaryLight>(totalLightCount);
|
||||
|
||||
@@ -49,9 +55,9 @@ namespace BSP
|
||||
for (size_t lightIdx = 0; lightIdx < totalLightCount; lightIdx++)
|
||||
{
|
||||
ComPrimaryLight* light = &comWorld->primaryLights[lightIdx];
|
||||
if (lightIdx == BSPGameConstants::EMPTY_LIGHT_INDEX)
|
||||
if (lightIdx == EMPTY_LIGHT_INDEX)
|
||||
continue; // first (empty) light has no data
|
||||
else if (lightIdx == BSPGameConstants::SUN_LIGHT_INDEX)
|
||||
else if (lightIdx == SUN_LIGHT_INDEX)
|
||||
{
|
||||
BSPLight* bspLight = &bsp->sunlight;
|
||||
|
||||
@@ -68,7 +74,7 @@ namespace BSP
|
||||
}
|
||||
else
|
||||
{
|
||||
BSPLight* bspLight = &bsp->lights.at(lightIdx - BSPGameConstants::BSP_DEFAULT_LIGHT_COUNT);
|
||||
BSPLight* bspLight = &bsp->lights.at(lightIdx - BSP_DEFAULT_LIGHT_COUNT);
|
||||
|
||||
light->type = GFX_LIGHT_TYPE_SPOT;
|
||||
|
||||
@@ -103,8 +109,8 @@ namespace BSP
|
||||
light->aAbB.z = 0.75f;
|
||||
light->aAbB.w = 1.0f;
|
||||
|
||||
light->cullDist = 10000;
|
||||
light->defName = "white_light";
|
||||
light->cullDist = LIGHT_CULLDIST;
|
||||
light->defName = DEFAULT_LIGHTDEF_NAME;
|
||||
light->rotationLimit = 1.0f; // 1.0f - doesn't rotate, -1.0f - unclamped rotation
|
||||
light->translationLimit = 0.0f; // 0.0f - doesn't translate, above 0.0f - distance per game update translated
|
||||
light->roundness = 1.0f; // 0.0f - light is a square. 1.0f - light is a circle
|
||||
|
||||
@@ -19,6 +19,12 @@ namespace
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr const char* DEFAULT_IMAGE_NAME = ",mc/lambert1";
|
||||
constexpr char EMPTY_LIGHTMAP_INDEX = 0;
|
||||
constexpr char EMPTY_RPROBE_INDEX = 0;
|
||||
constexpr float XMODEL_CULL_DIST = 10000.0f;
|
||||
constexpr char DEFAULT_LIGHTGRID_COLOUR = 32;
|
||||
} // namespace
|
||||
|
||||
namespace BSP
|
||||
@@ -99,12 +105,12 @@ namespace BSP
|
||||
if (bspMaterial.materialType == MATERIAL_TYPE_TEXTURE)
|
||||
materialName = bspMaterial.materialName;
|
||||
else // MATERIAL_TYPE_COLOUR
|
||||
materialName = BSPLinkingConstants::COLOR_ONLY_IMAGE_NAME;
|
||||
materialName = DEFAULT_IMAGE_NAME;
|
||||
|
||||
auto surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(materialName);
|
||||
if (surfMaterialAsset == nullptr)
|
||||
{
|
||||
surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(BSPLinkingConstants::MISSING_IMAGE_NAME);
|
||||
surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(DEFAULT_IMAGE_NAME);
|
||||
assert(surfMaterialAsset != nullptr);
|
||||
}
|
||||
gfxSurface->material = surfMaterialAsset->Asset();
|
||||
@@ -138,9 +144,9 @@ namespace BSP
|
||||
if ((bspMaterial.surfaceFlags & BSPFlags::surfaceTypeToFlagMap[BSPFlags::SURF_TYPE_NOCASTSHADOW].surfaceFlags) == 0)
|
||||
gfxSurface->flags |= GFX_SURFACE_CASTS_SHADOW;
|
||||
|
||||
gfxSurface->primaryLightIndex = BSPEditableConstants::DEFAULT_SURFACE_LIGHT;
|
||||
gfxSurface->lightmapIndex = BSPEditableConstants::DEFAULT_SURFACE_LIGHTMAP;
|
||||
gfxSurface->reflectionProbeIndex = BSPEditableConstants::DEFAULT_SURFACE_REFLECTION_PROBE;
|
||||
gfxSurface->primaryLightIndex = SUN_LIGHT_INDEX;
|
||||
gfxSurface->lightmapIndex = EMPTY_LIGHTMAP_INDEX;
|
||||
gfxSurface->reflectionProbeIndex = EMPTY_RPROBE_INDEX;
|
||||
|
||||
// unknown value
|
||||
gfxSurface->tris.himipRadiusInvSq = 0.0f;
|
||||
@@ -210,9 +216,9 @@ namespace BSP
|
||||
if (!bspModel.doesCastShadow)
|
||||
currModel->flags |= STATIC_MODEL_FLAG_NO_SHADOW;
|
||||
|
||||
currModel->cullDist = 10000.0f;
|
||||
currModel->primaryLightIndex = 1;
|
||||
currModel->reflectionProbeIndex = 0;
|
||||
currModel->cullDist = XMODEL_CULL_DIST;
|
||||
currModel->primaryLightIndex = SUN_LIGHT_INDEX;
|
||||
currModel->reflectionProbeIndex = EMPTY_LIGHTMAP_INDEX;
|
||||
currModel->smid = modelIdx;
|
||||
|
||||
// unknown use / unused
|
||||
@@ -392,8 +398,8 @@ namespace BSP
|
||||
void GfxWorldLinker::loadGfxLights(BSPData* bsp, GfxWorld* gfxWorld)
|
||||
{
|
||||
// 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 + static_cast<unsigned int>(bsp->lights.size());
|
||||
gfxWorld->sunPrimaryLightIndex = BSPGameConstants::SUN_LIGHT_INDEX;
|
||||
gfxWorld->primaryLightCount = BSP_DEFAULT_LIGHT_COUNT + static_cast<unsigned int>(bsp->lights.size());
|
||||
gfxWorld->sunPrimaryLightIndex = SUN_LIGHT_INDEX;
|
||||
|
||||
gfxWorld->shadowGeom = m_memory.Alloc<GfxShadowGeometry>(gfxWorld->primaryLightCount);
|
||||
for (unsigned int lightIdx = 0; lightIdx < gfxWorld->primaryLightCount; lightIdx++)
|
||||
@@ -446,7 +452,7 @@ namespace BSP
|
||||
|
||||
gfxWorld->lightGrid.rowAxis = 0; // default value
|
||||
gfxWorld->lightGrid.colAxis = 1; // default value
|
||||
gfxWorld->lightGrid.sunPrimaryLightIndex = BSPGameConstants::SUN_LIGHT_INDEX;
|
||||
gfxWorld->lightGrid.sunPrimaryLightIndex = SUN_LIGHT_INDEX;
|
||||
gfxWorld->lightGrid.offset = 0.0f; // default value
|
||||
|
||||
// setting all rowDataStart indexes to 0 will always index the first row in rawRowData
|
||||
@@ -471,12 +477,12 @@ namespace BSP
|
||||
for (unsigned int i = 0; i < gfxWorld->lightGrid.entryCount; i++)
|
||||
{
|
||||
entryArray[i].colorsIndex = 0; // always index first colour
|
||||
entryArray[i].primaryLightIndex = BSPGameConstants::SUN_LIGHT_INDEX;
|
||||
entryArray[i].primaryLightIndex = SUN_LIGHT_INDEX;
|
||||
entryArray[i].visibility = 0;
|
||||
}
|
||||
gfxWorld->lightGrid.entries = entryArray;
|
||||
|
||||
char color = 32;
|
||||
char color = DEFAULT_LIGHTGRID_COLOUR;
|
||||
float sunIntensity = bsp->sunlight.intensity;
|
||||
if (sunIntensity < 0.0f || sunIntensity > 20000.0f)
|
||||
con::warn("Sun intensity ({}) needs to be between 0 and 20000", sunIntensity);
|
||||
@@ -534,7 +540,7 @@ namespace BSP
|
||||
// there is only 1 reflection probe
|
||||
gfxWorld->cells[0].reflectionProbeCount = 1;
|
||||
gfxWorld->cells[0].reflectionProbes = m_memory.Alloc<char>(gfxWorld->cells[0].reflectionProbeCount);
|
||||
gfxWorld->cells[0].reflectionProbes[0] = BSPEditableConstants::DEFAULT_SURFACE_REFLECTION_PROBE;
|
||||
gfxWorld->cells[0].reflectionProbes[0] = EMPTY_RPROBE_INDEX;
|
||||
|
||||
// AABB trees are used to detect what should be rendered and what shouldn't
|
||||
// Just use the first AABB node to hold all models, no optimisation but all models/surfaces wil lbe drawn
|
||||
|
||||
Reference in New Issue
Block a user