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:
@@ -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
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,58 +76,65 @@ 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);
|
||||
if (!entFile.IsOpen())
|
||||
{
|
||||
con::warn("Can't find entity file {}, using default entities instead", entityFilePath);
|
||||
entJs = json::parse(BSPLinkingConstants::DEFAULT_MAP_ENTS_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
entJs = json::parse(*entFile.m_stream);
|
||||
}
|
||||
std::string entityString;
|
||||
if (!parseMapEntsJSON(entJs["entities"], entityString))
|
||||
return AssetCreationResult::Failure();
|
||||
|
||||
json entJs;
|
||||
std::string entityFilePath = BSPUtil::getFileNameForBSPAsset("entities.json");
|
||||
const auto entFile = m_search_path.Open(entityFilePath);
|
||||
if (!entFile.IsOpen())
|
||||
{
|
||||
con::warn("Can't find entity file {}, using default entities instead", entityFilePath);
|
||||
entJs = json::parse(BSPLinkingConstants::DEFAULT_MAP_ENTS_STRING);
|
||||
json spawnJs;
|
||||
std::string spawnFilePath = BSPUtil::getFileNameForBSPAsset("spawns.json");
|
||||
const auto spawnFile = m_search_path.Open(spawnFilePath);
|
||||
if (!spawnFile.IsOpen())
|
||||
{
|
||||
con::warn("Cant find spawn file {}, setting spawns to 0 0 0", spawnFilePath);
|
||||
spawnJs = json::parse(BSPLinkingConstants::DEFAULT_SPAWN_POINT_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
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);
|
||||
|
||||
MapEnts* mapEnts = m_memory.Alloc<MapEnts>();
|
||||
mapEnts->name = m_memory.Dup(bsp->bspName.c_str());
|
||||
|
||||
mapEnts->entityString = m_memory.Dup(entityString.c_str());
|
||||
mapEnts->numEntityChars = entityString.length() + 1; // numEntityChars includes the null character
|
||||
|
||||
// don't need these
|
||||
mapEnts->trigger.count = 0;
|
||||
mapEnts->trigger.models = nullptr;
|
||||
mapEnts->trigger.hullCount = 0;
|
||||
mapEnts->trigger.hulls = nullptr;
|
||||
mapEnts->trigger.slabCount = 0;
|
||||
mapEnts->trigger.slabs = nullptr;
|
||||
|
||||
auto mapEntsAsset = m_context.AddAsset<AssetMapEnts>(mapEnts->name, mapEnts);
|
||||
return AssetCreationResult::Success(mapEntsAsset);
|
||||
}
|
||||
else
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
entJs = json::parse(*entFile.m_stream);
|
||||
}
|
||||
if (!parseMapEntsJSON(entJs["entities"], entityString))
|
||||
con::error("JSON error when parsing map ents and spawns: {}", e.what());
|
||||
return AssetCreationResult::Failure();
|
||||
|
||||
json spawnJs;
|
||||
std::string spawnFilePath = BSPUtil::getFileNameForBSPAsset("spawns.json");
|
||||
const auto spawnFile = m_search_path.Open(spawnFilePath);
|
||||
if (!spawnFile.IsOpen())
|
||||
{
|
||||
con::warn("Cant find spawn file {}, setting spawns to 0 0 0", spawnFilePath);
|
||||
spawnJs = json::parse(BSPLinkingConstants::DEFAULT_SPAWN_POINT_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
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);
|
||||
|
||||
MapEnts* mapEnts = m_memory.Alloc<MapEnts>();
|
||||
mapEnts->name = m_memory.Dup(bsp->bspName.c_str());
|
||||
|
||||
mapEnts->entityString = m_memory.Dup(entityString.c_str());
|
||||
mapEnts->numEntityChars = entityString.length() + 1; // numEntityChars includes the null character
|
||||
|
||||
// don't need these
|
||||
mapEnts->trigger.count = 0;
|
||||
mapEnts->trigger.models = nullptr;
|
||||
mapEnts->trigger.hullCount = 0;
|
||||
mapEnts->trigger.hulls = nullptr;
|
||||
mapEnts->trigger.slabCount = 0;
|
||||
mapEnts->trigger.slabs = nullptr;
|
||||
|
||||
auto mapEntsAsset = m_context.AddAsset<AssetMapEnts>(mapEnts->name, mapEnts);
|
||||
return AssetCreationResult::Success(mapEntsAsset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user