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

Refactor to improve C++ and safe code use

This commit is contained in:
LJW-Dev
2025-10-26 18:20:04 +08:00
parent 173565c7b3
commit 9d4c32b6b4
10 changed files with 285 additions and 261 deletions

View File

@@ -7096,6 +7096,23 @@ namespace T6
char* stringValue;
};
enum GfxLightType
{
GFX_LIGHT_TYPE_NONE = 0x0,
GFX_LIGHT_TYPE_DIR = 0x1,
GFX_LIGHT_TYPE_SPOT = 0x2,
GFX_LIGHT_TYPE_SPOT_SQUARE = 0x3,
GFX_LIGHT_TYPE_SPOT_ROUND = 0x4,
GFX_LIGHT_TYPE_OMNI = 0x5,
GFX_LIGHT_TYPE_COUNT = 0x6,
GFX_LIGHT_TYPE_DIR_SHADOWMAP = 0x6,
GFX_LIGHT_TYPE_SPOT_SHADOWMAP = 0x7,
GFX_LIGHT_TYPE_SPOT_SQUARE_SHADOWMAP = 0x8,
GFX_LIGHT_TYPE_SPOT_ROUND_SHADOWMAP = 0x9,
GFX_LIGHT_TYPE_OMNI_SHADOWMAP = 0xA,
GFX_LIGHT_TYPE_COUNT_WITH_SHADOWMAP_VERSIONS = 0xB,
};
#ifndef __zonecodegenerator
} // namespace T6
#endif

View File

@@ -64,8 +64,12 @@ namespace BSP
{
constexpr int MAX_COLLISION_VERTS = UINT16_MAX;
constexpr int STATIC_LIGHT_INDEX = 0;
constexpr int SUN_LIGHT_INDEX = 1;
enum BSPDefaultLights
{
STATIC_LIGHT_INDEX = 0,
SUN_LIGHT_INDEX = 1,
BSP_DEFAULT_LIGHT_COUNT = 2
};
inline const char* DEFENDER_SPAWN_POINT_NAMES[] = {
"mp_ctf_spawn_allies",
@@ -182,5 +186,9 @@ namespace BSP
// 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 };
};
}

View File

@@ -59,87 +59,85 @@ namespace
if (meshPart.num_faces == 0)
continue;
surfaceVec.emplace_back();
BSPSurface* surface = &surfaceVec[surfaceVec.size() - 1];
BSPSurface surface;
size_t partTriangleNum = meshPart.num_triangles;
surface->triCount = static_cast<int>(partTriangleNum);
surface->indexOfFirstVertex = vertexVec.size();
surface->indexOfFirstIndex = indexVec.size();
surface.triCount = static_cast<int>(partTriangleNum);
surface.indexOfFirstVertex = static_cast<int>(vertexVec.size());
surface.indexOfFirstIndex = static_cast<int>(indexVec.size());
if (mesh->materials.count == 0)
{
surface->material.materialType = MATERIAL_TYPE_EMPTY;
surface->material.materialName = "";
surface.material.materialType = MATERIAL_TYPE_EMPTY;
surface.material.materialName = "";
}
else
{
surface->material.materialType = MATERIAL_TYPE_TEXTURE;
surface->material.materialName = mesh->materials.data[meshPart.index]->name.data;
surface.material.materialType = MATERIAL_TYPE_TEXTURE;
surface.material.materialName = mesh->materials.data[meshPart.index]->name.data;
}
std::vector<BSPVertex> vertices;
std::vector<uint32_t> indices;
indices.resize(mesh->max_face_triangles * 3);
std::vector<BSPVertex> tempVertices;
std::vector<uint32_t> tempIndices;
tempIndices.resize(mesh->max_face_triangles * 3);
for (uint32_t faceIndex : meshPart.face_indices)
{
ufbx_face* face = &mesh->faces.data[faceIndex];
// Triangulate the face into the indices vector
uint32_t triangluatedTriCount = ufbx_triangulate_face(indices.data(), indices.size(), mesh, *face);
uint32_t triangluatedTriCount = ufbx_triangulate_face(tempIndices.data(), tempIndices.size(), mesh, *face);
// Iterate over each triangle corner contiguously.
for (uint32_t idxOfIndex = 0; idxOfIndex < triangluatedTriCount * 3; idxOfIndex++)
{
vertices.emplace_back();
BSPVertex* vertex = &vertices[vertices.size() - 1];
uint32_t index = indices[idxOfIndex];
BSPVertex vertex;
uint32_t index = tempIndices[idxOfIndex];
ufbx_vec3 transformedPos = ufbx_transform_position(&meshMatrix, ufbx_get_vertex_vec3(&mesh->vertex_position, index));
vertex->pos.x = static_cast<float>(transformedPos.x);
vertex->pos.y = static_cast<float>(transformedPos.y);
vertex->pos.z = static_cast<float>(transformedPos.z);
vertex.pos.x = static_cast<float>(transformedPos.x);
vertex.pos.y = static_cast<float>(transformedPos.y);
vertex.pos.z = static_cast<float>(transformedPos.z);
if (surface->material.materialType == MATERIAL_TYPE_TEXTURE || surface->material.materialType == MATERIAL_TYPE_EMPTY)
if (surface.material.materialType == MATERIAL_TYPE_TEXTURE || surface.material.materialType == MATERIAL_TYPE_EMPTY)
{
vertex->color.x = 1.0f;
vertex->color.y = 1.0f;
vertex->color.z = 1.0f;
vertex->color.w = 1.0f;
vertex.color.x = 1.0f;
vertex.color.y = 1.0f;
vertex.color.z = 1.0f;
vertex.color.w = 1.0f;
}
else // surface->material.materialType == MATERIAL_TYPE_COLOUR
{
float factor = static_cast<float>(mesh->materials.data[meshPart.index]->fbx.diffuse_factor.value_real);
ufbx_vec4 diffuse = mesh->materials.data[meshPart.index]->fbx.diffuse_color.value_vec4;
vertex->color.x = static_cast<float>(diffuse.x * factor);
vertex->color.y = static_cast<float>(diffuse.y * factor);
vertex->color.z = static_cast<float>(diffuse.z * factor);
vertex->color.w = static_cast<float>(diffuse.w * factor);
vertex.color.x = static_cast<float>(diffuse.x * factor);
vertex.color.y = static_cast<float>(diffuse.y * factor);
vertex.color.z = static_cast<float>(diffuse.z * factor);
vertex.color.w = static_cast<float>(diffuse.w * factor);
}
// 1.0f - uv.y reason: https://gamedev.stackexchange.com/questions/92886/fbx-uv-coordinates-is-strange
ufbx_vec2 uv = ufbx_get_vertex_vec2(&mesh->vertex_uv, index);
vertex->texCoord.x = static_cast<float>(uv.x);
vertex->texCoord.y = static_cast<float>(1.0f - uv.y);
vertex.texCoord.x = static_cast<float>(uv.x);
vertex.texCoord.y = static_cast<float>(1.0f - uv.y);
ufbx_vec3 normal = ufbx_get_vertex_vec3(&mesh->vertex_normal, index);
vertex->normal.x = static_cast<float>(normal.x);
vertex->normal.y = static_cast<float>(normal.y);
vertex->normal.z = static_cast<float>(normal.z);
vertex.normal.x = static_cast<float>(normal.x);
vertex.normal.y = static_cast<float>(normal.y);
vertex.normal.z = static_cast<float>(normal.z);
if (mesh->vertex_tangent.exists)
{
ufbx_vec3 tangent = ufbx_get_vertex_vec3(&mesh->vertex_tangent, index);
vertex->tangent.x = static_cast<float>(tangent.x);
vertex->tangent.y = static_cast<float>(tangent.y);
vertex->tangent.z = static_cast<float>(tangent.z);
vertex.tangent.x = static_cast<float>(tangent.x);
vertex.tangent.y = static_cast<float>(tangent.y);
vertex.tangent.z = static_cast<float>(tangent.z);
}
else
{
vertex->tangent.x = 0.0f;
vertex->tangent.y = 0.0f;
vertex->tangent.z = 0.0f;
vertex.tangent.x = 0.0f;
vertex.tangent.y = 0.0f;
vertex.tangent.z = 0.0f;
}
tempVertices.emplace_back(vertex);
}
}
@@ -147,7 +145,7 @@ namespace
// ufbx_generate_indices will deduplicate vertices, modifying the arrays passed in streams,
// indices are written to outIndices and the number of unique vertices is returned.
ufbx_vertex_stream streams[1] = {
{vertices.data(), vertices.size(), sizeof(BSPVertex)},
{tempVertices.data(), tempVertices.size(), sizeof(BSPVertex)},
};
std::vector<uint32_t> outIndices;
outIndices.resize(partTriangleNum * 3);
@@ -155,14 +153,16 @@ namespace
assert(numGeneratedVertices != 0);
// trim non-unique vertexes and add to the world vertex vector
vertices.resize(numGeneratedVertices);
vertexVec.insert(vertexVec.end(), vertices.begin(), vertices.end());
tempVertices.resize(numGeneratedVertices);
vertexVec.insert(vertexVec.end(), tempVertices.begin(), tempVertices.end());
// T6 uses unsigned shorts as their index type so we have to loop and convert them from an unsigned int
for (size_t idx = 0; idx < outIndices.size(); idx++)
{
indexVec.emplace_back(static_cast<uint16_t>(outIndices[idx]));
}
surfaceVec.emplace_back(surface);
}
}

View File

@@ -10,79 +10,73 @@ std::string BSPUtil::getFileNameForBSPAsset(std::string assetName)
return std::format("BSP/{}", assetName);
}
// BO2 uses a different coordinate system, so this converts it back from OpenGLs default
vec3_t BSPUtil::convertToBO2Coords(vec3_t OGL_coordinate)
vec3_t BSPUtil::convertToBO2Coords(vec3_t coordinate)
{
vec3_t result;
result.x = OGL_coordinate.x;
result.y = -OGL_coordinate.z;
result.z = OGL_coordinate.y;
result.x = coordinate.x;
result.y = -coordinate.z;
result.z = coordinate.y;
return result;
}
// BO2 uses a weird coordinate system, so this converts it to OpenGLs default
vec3_t BSPUtil::convertFromBO2Coords(vec3_t bo2_coordinate)
vec3_t BSPUtil::convertFromBO2Coords(vec3_t coordinate)
{
vec3_t result;
result.x = bo2_coordinate.x;
result.y = bo2_coordinate.z;
result.z = -bo2_coordinate.y;
result.x = coordinate.x;
result.y = coordinate.z;
result.z = -coordinate.y;
return result;
}
void BSPUtil::calcNewBounds(vec3_t* newmins, vec3_t* newmaxs, vec3_t* currmins, vec3_t* currmaxs)
void BSPUtil::updateAABB(vec3_t* newAABBMins, vec3_t* newAABBMaxs, vec3_t* AABBMins, vec3_t* AABBMaxs)
{
if (currmins->x > newmins->x)
currmins->x = newmins->x;
if (AABBMins->x > newAABBMins->x)
AABBMins->x = newAABBMins->x;
if (newmaxs->x > currmaxs->x)
currmaxs->x = newmaxs->x;
if (newAABBMaxs->x > AABBMaxs->x)
AABBMaxs->x = newAABBMaxs->x;
if (currmins->y > newmins->y)
currmins->y = newmins->y;
if (AABBMins->y > newAABBMins->y)
AABBMins->y = newAABBMins->y;
if (newmaxs->y > currmaxs->y)
currmaxs->y = newmaxs->y;
if (newAABBMaxs->y > AABBMaxs->y)
AABBMaxs->y = newAABBMaxs->y;
if (currmins->z > newmins->z)
currmins->z = newmins->z;
if (AABBMins->z > newAABBMins->z)
AABBMins->z = newAABBMins->z;
if (newmaxs->z > currmaxs->z)
currmaxs->z = newmaxs->z;
if (newAABBMaxs->z > AABBMaxs->z)
AABBMaxs->z = newAABBMaxs->z;
}
void BSPUtil::calcNewBoundsWithPoint(vec3_t* point, vec3_t* currmins, vec3_t* currmaxs)
void BSPUtil::updateAABBWithpoint(vec3_t* point, vec3_t* AABBMins, vec3_t* AABBMaxs)
{
if (currmins->x > point->x)
currmins->x = point->x;
if (AABBMins->x > point->x)
AABBMins->x = point->x;
if (point->x > currmaxs->x)
currmaxs->x = point->x;
if (point->x > AABBMaxs->x)
AABBMaxs->x = point->x;
if (currmins->y > point->y)
currmins->y = point->y;
if (AABBMins->y > point->y)
AABBMins->y = point->y;
if (point->y > currmaxs->y)
currmaxs->y = point->y;
if (point->y > AABBMaxs->y)
AABBMaxs->y = point->y;
if (currmins->z > point->z)
currmins->z = point->z;
if (AABBMins->z > point->z)
AABBMins->z = point->z;
if (point->z > currmaxs->z)
currmaxs->z = point->z;
if (point->z > AABBMaxs->z)
AABBMaxs->z = point->z;
}
vec3_t BSPUtil::calcMiddleOfBounds(vec3_t* mins, vec3_t* maxs)
{
// Origin is the midpoint: (min + max) / 2
vec3_t temp;
temp.x = mins->x + maxs->x;
temp.y = mins->y + maxs->y;
temp.z = mins->z + maxs->z;
temp.x *= 0.5f;
temp.y *= 0.5f;
temp.z *= 0.5f;
return temp;
vec3_t result;
result.x = (mins->x + maxs->x) * 0.5f;
result.y = (mins->y + maxs->y) * 0.5f;
result.z = (mins->z + maxs->z) * 0.5f;
return result;
}
int BSPUtil::allignBy128(int size)

View File

@@ -9,8 +9,8 @@ public:
static std::string getFileNameForBSPAsset(std::string assetName);
static vec3_t convertToBO2Coords(vec3_t OGL_coordinate);
static vec3_t convertFromBO2Coords(vec3_t bo2_coordinate);
static void calcNewBounds(vec3_t* newmins, vec3_t* newmaxs, vec3_t* currmins, vec3_t* currmaxs);
static void calcNewBoundsWithPoint(vec3_t* point, vec3_t* currmins, vec3_t* currmaxs);
static void updateAABB(vec3_t* newAABBMins, vec3_t* newAABBMaxs, vec3_t* AABBMins, vec3_t* AABBMaxs);
static void updateAABBWithpoint(vec3_t* point, vec3_t* AABBMins, vec3_t* AABBMaxs);
static vec3_t calcMiddleOfBounds(vec3_t* mins, vec3_t* maxs);
static int allignBy128(int size);
static float distBetweenPoints(vec3_t p1, vec3_t p2);

View File

@@ -27,7 +27,6 @@ namespace BSP
clipMap->dynEntClientList[0] = m_memory.Alloc<DynEntityClient>(clipMap->dynEntCount[0]);
clipMap->dynEntClientList[1] = nullptr;
memset(clipMap->dynEntClientList[0], 0, sizeof(DynEntityClient) * clipMap->dynEntCount[0]);
clipMap->dynEntServerList[0] = nullptr;
clipMap->dynEntServerList[1] = nullptr;
@@ -36,15 +35,12 @@ namespace BSP
clipMap->dynEntCollList[1] = nullptr;
clipMap->dynEntCollList[2] = nullptr;
clipMap->dynEntCollList[3] = nullptr;
memset(clipMap->dynEntCollList[0], 0, sizeof(DynEntityColl) * clipMap->dynEntCount[0]);
clipMap->dynEntPoseList[0] = m_memory.Alloc<DynEntityPose>(clipMap->dynEntCount[0]);
clipMap->dynEntPoseList[1] = nullptr;
memset(clipMap->dynEntPoseList[0], 0, sizeof(DynEntityPose) * clipMap->dynEntCount[0]);
clipMap->dynEntDefList[0] = m_memory.Alloc<DynEntityDef>(clipMap->dynEntCount[0]);
clipMap->dynEntDefList[1] = nullptr;
memset(clipMap->dynEntDefList[0], 0, sizeof(DynEntityDef) * clipMap->dynEntCount[0]);
}
void ClipMapLinker::loadVisibility(clipMap_t* clipMap)
@@ -122,19 +118,18 @@ namespace BSP
void ClipMapLinker::loadRopesAndConstraints(clipMap_t* clipMap)
{
clipMap->num_constraints = 0; // max 511
clipMap->constraints = NULL;
clipMap->constraints = nullptr;
// The game allocates 32 empty ropes
clipMap->max_ropes = 32; // max 300
clipMap->ropes = m_memory.Alloc <rope_t> (clipMap->max_ropes);
memset(clipMap->ropes, 0, sizeof(rope_t) * clipMap->max_ropes);
}
void ClipMapLinker::loadSubModelCollision(clipMap_t* clipMap, BSPData* bsp)
{
// Submodels are used for the world and map ent collision (triggers, bomb zones, etc)
auto gfxWorldAsset = m_context.LoadDependency<AssetGfxWorld>(bsp->bspName);
assert(gfxWorldAsset != NULL);
assert(gfxWorldAsset != nullptr);
GfxWorld* gfxWorld = gfxWorldAsset->Asset();
// Right now there is only one submodel, the world sub model
@@ -166,7 +161,7 @@ namespace BSP
clipMap->cmodels[0].leaf.leafBrushNode = 0;
clipMap->cmodels[0].leaf.cluster = 0;
clipMap->cmodels[0].info = NULL; // always set to 0
clipMap->cmodels[0].info = nullptr; // always set to 0
}
void ClipMapLinker::loadXModelCollision(clipMap_t* clipMap)
@@ -178,7 +173,7 @@ namespace BSP
// WIP code left in for future support
/*
auto gfxWorldAsset = m_context.LoadDependency<AssetGfxWorld>(bsp->bspName);
assert(gfxWorldAsset != NULL);
assert(gfxWorldAsset != nullptr);
GfxWorld* gfxWorld = gfxWorldAsset->Asset();
clipMap->numStaticModels = gfxWorld->dpvs.smodelCount;
@@ -306,7 +301,7 @@ namespace BSP
{
uint16_t vertIndex = tri[l];
vec3_t vertCoord = clipMap->verts[vertIndex];
BSPUtil::calcNewBoundsWithPoint(&vertCoord, &aabbMins, &aabbMaxs);
BSPUtil::updateAABBWithpoint(&vertCoord, &aabbMins, &aabbMaxs);
}
}
}
@@ -343,7 +338,7 @@ namespace BSP
uint16_t currUind = clipMap->info.uinds[aabbPartition->fuind + i];
vec3_t* currVertex = &clipMap->verts[currUind];
BSPUtil::calcNewBoundsWithPoint(currVertex, &mins, &maxs);
BSPUtil::updateAABBWithpoint(currVertex, &mins, &maxs);
}
aabbCalcOriginAndHalfSize(&mins, &maxs, &currAabbTree->origin, &currAabbTree->halfSize);
@@ -631,17 +626,17 @@ namespace BSP
{
// No support for brushes, only tris right now
clipMap->info.numBrushSides = 0;
clipMap->info.brushsides = NULL;
clipMap->info.brushsides = nullptr;
clipMap->info.leafbrushNodesCount = 0;
clipMap->info.leafbrushNodes = NULL;
clipMap->info.leafbrushNodes = nullptr;
clipMap->info.numLeafBrushes = 0;
clipMap->info.leafbrushes = NULL;
clipMap->info.leafbrushes = nullptr;
clipMap->info.numBrushVerts = 0;
clipMap->info.brushVerts = NULL;
clipMap->info.numBrushes = NULL;
clipMap->info.brushes = NULL;
clipMap->info.brushBounds = NULL;
clipMap->info.brushContents = NULL;
clipMap->info.brushVerts = nullptr;
clipMap->info.numBrushes = 0;
clipMap->info.brushes = nullptr;
clipMap->info.brushBounds = nullptr;
clipMap->info.brushContents = nullptr;
// clipmap BSP creation must go last as it depends on unids, tris and verts already being populated
// HACK:
@@ -667,7 +662,7 @@ namespace BSP
for (unsigned int i = 1; i < clipMap->vertCount; i++)
{
vec3_t vertCoord = BSPUtil::convertFromBO2Coords(clipMap->verts[i]);
BSPUtil::calcNewBoundsWithPoint(&vertCoord, &clipMins, &clipMaxs);
BSPUtil::updateAABBWithpoint(&vertCoord, &clipMins, &clipMaxs);
}
BSPTree* tree = new BSPTree(clipMins.x, clipMins.y, clipMins.z, clipMaxs.x, clipMaxs.y, clipMaxs.z, 0);
@@ -697,7 +692,7 @@ namespace BSP
{
uint16_t vertIndex = tri[l];
vec3_t vertCoord = BSPUtil::convertFromBO2Coords(clipMap->verts[vertIndex]);
BSPUtil::calcNewBoundsWithPoint(&vertCoord, &mins, &maxs);
BSPUtil::updateAABBWithpoint(&vertCoord, &mins, &maxs);
}
}

View File

@@ -15,23 +15,22 @@ namespace BSP
ComWorld* comWorld = m_memory.Alloc<ComWorld>();
comWorld->name = m_memory.Dup(bsp->bspName.c_str());
comWorld->isInUse = 1;
comWorld->primaryLightCount = 2;
comWorld->primaryLightCount = BSPGameConstants::BSP_DEFAULT_LIGHT_COUNT;
comWorld->primaryLights = m_memory.Alloc<ComPrimaryLight>(comWorld->primaryLightCount);
// static light is always empty
ComPrimaryLight* staticLight = &comWorld->primaryLights[0];
memset(staticLight, 0, sizeof(ComPrimaryLight));
// first (static) light is always empty
ComPrimaryLight* sunLight = &comWorld->primaryLights[1];
memset(sunLight, 0, sizeof(ComPrimaryLight));
sunLight->type = 1;
sunLight->diffuseColor.r = 0.75f;
sunLight->diffuseColor.g = 0.75f;
sunLight->diffuseColor.b = 0.75f;
sunLight->diffuseColor.a = 1.0f;
sunLight->dir.x = 0.0f;
sunLight->dir.y = 0.0f;
sunLight->dir.z = 0.0f;
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;
sunLight->diffuseColor.b = sunLightColor.b;
sunLight->diffuseColor.a = sunLightColor.a;
sunLight->dir.x = sunLightDirection.x;
sunLight->dir.y = sunLightDirection.y;
sunLight->dir.z = sunLightDirection.z;
auto comWorldAsset = m_context.AddAsset<AssetComWorld>(comWorld->name, comWorld);
return AssetCreationResult::Success(comWorldAsset);

View File

@@ -21,12 +21,10 @@ namespace BSP
gameWorldMp->path.smoothBytes = 0;
gameWorldMp->path.nodeTreeCount = 0;
int nodeCount = gameWorldMp->path.nodeCount + 128;
gameWorldMp->path.nodes = m_memory.Alloc<pathnode_t>(nodeCount);
gameWorldMp->path.basenodes = m_memory.Alloc<pathbasenode_t>(nodeCount);
memset(gameWorldMp->path.nodes, 0, nodeCount * sizeof(pathnode_t));
memset(gameWorldMp->path.basenodes, 0, nodeCount * sizeof(pathbasenode_t));
// The game has 128 empty nodes allocated
int extraNodeCount = gameWorldMp->path.nodeCount + 128;
gameWorldMp->path.nodes = m_memory.Alloc<pathnode_t>(extraNodeCount);
gameWorldMp->path.basenodes = m_memory.Alloc<pathbasenode_t>(extraNodeCount);
gameWorldMp->path.pathVis = nullptr;
gameWorldMp->path.smoothCache = nullptr;
gameWorldMp->path.nodeTree = nullptr;

View File

@@ -130,7 +130,7 @@ namespace BSP
for (int k = 0; k < currSurface->tris.triCount * 3; k++)
{
uint16_t vertIndex = gfxWorld->draw.indices[currSurface->tris.baseIndex + k];
BSPUtil::calcNewBoundsWithPoint(&firstVert[vertIndex].xyz, &currSurface->bounds[0], &currSurface->bounds[1]);
BSPUtil::updateAABBWithpoint(&firstVert[vertIndex].xyz, &currSurface->bounds[0], &currSurface->bounds[1]);
}
// unused values
@@ -191,68 +191,69 @@ namespace BSP
/*
Models are unsupported right now
Code is left in in case it is supported later on
unsigned int modelCount = projInfo->modelCount;
gfxWorld->dpvs.smodelCount = modelCount;
gfxWorld->dpvs.smodelInsts = new GfxStaticModelInst[modelCount];
gfxWorld->dpvs.smodelDrawInsts = new GfxStaticModelDrawInst[modelCount];
for (unsigned int i = 0; i < modelCount; i++)
{
auto currModel = &gfxWorld->dpvs.smodelDrawInsts[i];
auto currModelInst = &gfxWorld->dpvs.smodelInsts[i];
customMapModel* inModel = &projInfo->models[i];
auto xModelAsset = m_context.LoadDependency<AssetXModel>(inModel->name);
if (xModelAsset == NULL)
{
printf("XModel %s not found!\n", inModel->name.c_str());
currModel->model = NULL;
}
else
currModel->model = (XModel*)xModelAsset->Asset();
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.scale = inModel->scale;
BSPUtil::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
currModelInst->mins.x = currModel->model->mins.x + currModel->placement.origin.x;
currModelInst->mins.y = currModel->model->mins.y + currModel->placement.origin.y;
currModelInst->mins.z = currModel->model->mins.z + currModel->placement.origin.z;
currModelInst->maxs.x = currModel->model->maxs.x + currModel->placement.origin.x;
currModelInst->maxs.y = currModel->model->maxs.y + currModel->placement.origin.y;
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;
// unknown use / unused
currModel->smid = i;
memset(&currModel->lightingSH, 0, sizeof(GfxLightingSHQuantized));
currModel->invScaleSq = 0.0f;
currModel->lightingHandle = 0;
currModel->colorsIndex = 0;
currModel->visibility = 0;
// setting these to NULL makes any static/baked lighting go black when not rendered by real-time lighting or in a shadow
// TODO: calculate lighting and store it here
currModel->lmapVertexInfo[0].numLmapVertexColors = 0;
currModel->lmapVertexInfo[0].lmapVertexColors = NULL;
currModel->lmapVertexInfo[1].numLmapVertexColors = 0;
currModel->lmapVertexInfo[1].lmapVertexColors = NULL;
currModel->lmapVertexInfo[2].numLmapVertexColors = 0;
currModel->lmapVertexInfo[2].lmapVertexColors = NULL;
currModel->lmapVertexInfo[3].numLmapVertexColors = 0;
currModel->lmapVertexInfo[3].lmapVertexColors = NULL;
}
*/
//unsigned int modelCount = projInfo->modelCount;
//gfxWorld->dpvs.smodelCount = modelCount;
//gfxWorld->dpvs.smodelInsts = new GfxStaticModelInst[modelCount];
//gfxWorld->dpvs.smodelDrawInsts = new GfxStaticModelDrawInst[modelCount];
//
//for (unsigned int i = 0; i < modelCount; i++)
//{
// auto currModel = &gfxWorld->dpvs.smodelDrawInsts[i];
// auto currModelInst = &gfxWorld->dpvs.smodelInsts[i];
// customMapModel* inModel = &projInfo->models[i];
//
// auto xModelAsset = m_context.LoadDependency<AssetXModel>(inModel->name);
// if (xModelAsset == NULL)
// {
// printf("XModel %s not found!\n", inModel->name.c_str());
// currModel->model = NULL;
// }
// else
// currModel->model = (XModel*)xModelAsset->Asset();
//
// 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.scale = inModel->scale;
//
// BSPUtil::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
// currModelInst->mins.x = currModel->model->mins.x + currModel->placement.origin.x;
// currModelInst->mins.y = currModel->model->mins.y + currModel->placement.origin.y;
// currModelInst->mins.z = currModel->model->mins.z + currModel->placement.origin.z;
// currModelInst->maxs.x = currModel->model->maxs.x + currModel->placement.origin.x;
// currModelInst->maxs.y = currModel->model->maxs.y + currModel->placement.origin.y;
// 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;
//
// // unknown use / unused
// currModel->smid = i;
// memset(&currModel->lightingSH, 0, sizeof(GfxLightingSHQuantized));
// currModel->invScaleSq = 0.0f;
// currModel->lightingHandle = 0;
// currModel->colorsIndex = 0;
// currModel->visibility = 0;
//
// // setting these to NULL makes any static/baked lighting go black when not rendered by real-time lighting or in a shadow
// // TODO: calculate lighting and store it here
// currModel->lmapVertexInfo[0].numLmapVertexColors = 0;
// currModel->lmapVertexInfo[0].lmapVertexColors = NULL;
// currModel->lmapVertexInfo[1].numLmapVertexColors = 0;
// currModel->lmapVertexInfo[1].lmapVertexColors = NULL;
// currModel->lmapVertexInfo[2].numLmapVertexColors = 0;
// currModel->lmapVertexInfo[2].lmapVertexColors = NULL;
// currModel->lmapVertexInfo[3].numLmapVertexColors = 0;
// currModel->lmapVertexInfo[3].lmapVertexColors = NULL;
//}
unsigned int modelCount = 0;
gfxWorld->dpvs.smodelCount = modelCount;
@@ -546,7 +547,7 @@ namespace BSP
for (int i = 0; i < gfxWorld->surfaceCount; i++)
{
BSPUtil::calcNewBounds(&gfxWorld->dpvs.surfaces[i].bounds[0], &gfxWorld->dpvs.surfaces[i].bounds[1], &gfxWorld->mins, &gfxWorld->maxs);
BSPUtil::updateAABB(&gfxWorld->dpvs.surfaces[i].bounds[0], &gfxWorld->dpvs.surfaces[i].bounds[1], &gfxWorld->mins, &gfxWorld->maxs);
}
}
@@ -665,7 +666,7 @@ namespace BSP
gfxWorld->draw.reflectionProbes[0].probeVolumeCount = 0;
gfxWorld->draw.reflectionProbes[0].probeVolumes = NULL;
std::string probeImageName = "*reflection_probe0";
std::string probeImageName = "reflection_probe0";
auto probeImageAsset = m_context.LoadDependency<AssetImage>(probeImageName);
if (probeImageAsset == NULL)
{
@@ -689,7 +690,7 @@ namespace BSP
memset(gfxWorld->draw.lightmapPrimaryTextures, 0, sizeof(GfxTexture) * gfxWorld->draw.lightmapCount);
memset(gfxWorld->draw.lightmapSecondaryTextures, 0, sizeof(GfxTexture) * gfxWorld->draw.lightmapCount);
std::string secondaryTexture = "*lightmap0_secondary";
std::string secondaryTexture = "lightmap0_secondary";
auto secondaryTextureAsset = m_context.LoadDependency<AssetImage>(secondaryTexture);
if (secondaryTextureAsset == NULL)
{

View File

@@ -8,14 +8,14 @@ namespace
{
bool parseMapEntsJSON(json& entArrayJs, std::string& entityString)
{
int entityCount = entArrayJs.size();
for (int i = 0; i < entityCount; i++)
for (size_t entIdx = 0; entIdx < entArrayJs.size(); entIdx++)
{
auto currEntity = entArrayJs[i];
auto& entity = entArrayJs[entIdx];
if (i == 0)
if (entIdx == 0)
{
std::string className = currEntity["classname"];
std::string className;
entity.at("classname").get_to(className);
if (className.compare("worldspawn") != 0)
{
con::error("ERROR: first entity in the map entity string must be the worldspawn class!");
@@ -25,7 +25,7 @@ namespace
entityString.append("{\n");
for (auto& element : currEntity.items())
for (auto& element : entity.items())
{
std::string key = element.key();
std::string value = element.value();
@@ -38,26 +38,31 @@ namespace
return true;
}
void parseSpawnpointJSON(json& entArrayJs, std::string& entityString, const char* spawnpointNames[], int nameCount)
void parseSpawnpointJSON(json& entArrayJs, std::string& entityString, const char* spawnpointNames[], size_t nameCount)
{
int entityCount = entArrayJs.size();
for (int i = 0; i < entityCount; i++)
for (auto& element : entArrayJs.items())
{
auto currEntity = entArrayJs[i];
std::string origin;
std::string angles;
auto& entity = element.value();
entity.at("origin").get_to(origin);
entity.at("angles").get_to(angles);
std::string origin = currEntity["origin"];
std::string angles = currEntity["angles"];
for (int k = 0; k < nameCount; k++)
for (size_t nameIdx = 0; nameIdx < nameCount; nameIdx++)
{
entityString.append("{\n");
entityString.append(std::format("\"origin\" \"{}\"\n", origin));
entityString.append(std::format("\"angles\" \"{}\"\n", angles));
entityString.append(std::format("\"classname\" \"{}\"\n", spawnpointNames[k]));
entityString.append(std::format("\"classname\" \"{}\"\n", spawnpointNames[nameIdx]));
entityString.append("}\n");
}
}
}
std::string loadMapEnts()
{
}
}
namespace BSP
@@ -71,8 +76,8 @@ namespace BSP
AssetCreationResult MapEntsLinker::linkMapEnts(BSPData* bsp)
{
std::string entityString;
try
{
json entJs;
std::string entityFilePath = BSPUtil::getFileNameForBSPAsset("entities.json");
const auto entFile = m_search_path.Open(entityFilePath);
@@ -85,6 +90,7 @@ namespace BSP
{
entJs = json::parse(*entFile.m_stream);
}
std::string entityString;
if (!parseMapEntsJSON(entJs["entities"], entityString))
return AssetCreationResult::Failure();
@@ -100,9 +106,9 @@ namespace BSP
{
spawnJs = json::parse(*spawnFile.m_stream);
}
int defenderNameCount = std::extent<decltype(BSPGameConstants::DEFENDER_SPAWN_POINT_NAMES)>::value;
int attackerNameCount = std::extent<decltype(BSPGameConstants::ATTACKER_SPAWN_POINT_NAMES)>::value;
int ffaNameCount = std::extent<decltype(BSPGameConstants::FFA_SPAWN_POINT_NAMES)>::value;
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;
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);
@@ -124,5 +130,11 @@ namespace BSP
auto mapEntsAsset = m_context.AddAsset<AssetMapEnts>(mapEnts->name, mapEnts);
return AssetCreationResult::Success(mapEntsAsset);
}
catch (const json::exception& e)
{
con::error("JSON error when parsing map ents and spawns: {}", e.what());
return AssetCreationResult::Failure();
}
}
}