mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-06 00:32:34 +00:00
refactor: better implementation of static and script surfaces
This commit is contained in:
@@ -64,14 +64,14 @@ namespace BSP
|
||||
|
||||
struct BSPWorld
|
||||
{
|
||||
std::vector<BSPSurface> surfaces;
|
||||
|
||||
std::vector<BSPSurface> staticSurfaces;
|
||||
std::vector<BSPSurface> scriptSurfaces;
|
||||
|
||||
std::vector<BSPVertex> vertices;
|
||||
std::vector<uint16_t> indices;
|
||||
std::vector<BSPMaterial> materials;
|
||||
std::vector<BSPXModel> xmodels;
|
||||
|
||||
size_t staticSurfaceCount;
|
||||
std::vector<BSPSurface> internal_scriptSurfaces;
|
||||
};
|
||||
|
||||
enum BSPLightType
|
||||
|
||||
@@ -461,7 +461,7 @@ namespace
|
||||
vec4_t vertexColour = m_curr_bsp_world->materials.at(surface.materialIndex).materialColour;
|
||||
CreateVertices(accessorsForVertex, nodeMatrix, surface, vertexColour);
|
||||
|
||||
m_curr_bsp_world->surfaces.emplace_back(surface);
|
||||
m_curr_bsp_world->staticSurfaces.emplace_back(surface);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -678,7 +678,7 @@ namespace
|
||||
|
||||
BSPModel model;
|
||||
model.isGfxModel = m_is_world_gfx;
|
||||
model.surfaceIndex = m_curr_bsp_world->internal_scriptSurfaces.size();
|
||||
model.surfaceIndex = m_curr_bsp_world->scriptSurfaces.size();
|
||||
model.surfaceCount = mesh.primitives.size();
|
||||
m_bsp->models.emplace_back(model);
|
||||
|
||||
@@ -709,7 +709,7 @@ namespace
|
||||
vec4_t vertexColour = m_curr_bsp_world->materials.at(surface.materialIndex).materialColour;
|
||||
CreateVertices(accessorsForVertex, nodeMatrix, surface, vertexColour);
|
||||
|
||||
m_curr_bsp_world->internal_scriptSurfaces.emplace_back(surface);
|
||||
m_curr_bsp_world->scriptSurfaces.emplace_back(surface);
|
||||
}
|
||||
|
||||
return m_bsp->models.size(); // script model index starts at 1
|
||||
@@ -1154,13 +1154,6 @@ namespace
|
||||
|
||||
LoadMaterials(jRoot);
|
||||
TraverseNodes(jRoot); // requires materials and lights
|
||||
|
||||
size_t staticSurfaceCount = m_curr_bsp_world->surfaces.size();
|
||||
for (auto& model : m_bsp->models)
|
||||
model.surfaceIndex += staticSurfaceCount;
|
||||
m_curr_bsp_world->staticSurfaceCount = staticSurfaceCount;
|
||||
m_curr_bsp_world->surfaces.insert(
|
||||
m_curr_bsp_world->surfaces.end(), m_curr_bsp_world->internal_scriptSurfaces.begin(), m_curr_bsp_world->internal_scriptSurfaces.end());
|
||||
}
|
||||
catch (const GltfLoadException& e)
|
||||
{
|
||||
|
||||
@@ -270,7 +270,7 @@ namespace BSP
|
||||
std::vector<int> partitionIndexes;
|
||||
for (size_t surfIdx = 0; surfIdx < bspMpdel.surfaceCount; surfIdx++)
|
||||
{
|
||||
ColSurface& surf = collisionSurfaceVec.at(bspMpdel.surfaceIndex + surfIdx);
|
||||
ColSurface& surf = collisionSurfaceVec.at(bsp->colWorld.staticSurfaces.size() + bspMpdel.surfaceIndex + surfIdx);
|
||||
for (size_t partitionIdx = 0; partitionIdx < surf.partitionCount; partitionIdx++)
|
||||
{
|
||||
size_t clipMapPartitionIndex = surf.partitionStartIndex + partitionIdx;
|
||||
@@ -712,7 +712,7 @@ namespace BSP
|
||||
}
|
||||
std::unique_ptr<BSPTree> tree = std::make_unique<BSPTree>(worldMins.x, worldMins.y, worldMins.z, worldMaxs.x, worldMaxs.y, worldMaxs.z, 0);
|
||||
|
||||
for (size_t surfIdx = 0; surfIdx < bsp->colWorld.staticSurfaceCount; surfIdx++) // only add the surfaces the player will collide with
|
||||
for (size_t surfIdx = 0; surfIdx < bsp->colWorld.staticSurfaces.size(); surfIdx++) // only add static surfaces
|
||||
{
|
||||
ColSurface& colSurface = collisionSurfaceVec.at(surfIdx);
|
||||
for (size_t partitionIdx = 0; partitionIdx < colSurface.partitionCount; partitionIdx++)
|
||||
@@ -768,11 +768,23 @@ namespace BSP
|
||||
for (unsigned int vertIdx = 0; vertIdx < clipMap->vertCount; vertIdx++)
|
||||
clipMap->verts[vertIdx] = bsp->colWorld.vertices[vertIdx].pos;
|
||||
|
||||
size_t staticSurfaceCount = bsp->colWorld.staticSurfaces.size();
|
||||
size_t scriptSurfaceCount = bsp->colWorld.scriptSurfaces.size();
|
||||
size_t totalSurfaceCount = staticSurfaceCount + scriptSurfaceCount;
|
||||
|
||||
// TODO: figure out SV_EntityContact and see how it interacts with partitions
|
||||
|
||||
std::vector<uint16_t> triIndexVec;
|
||||
std::vector<CollisionPartition> partitionVec;
|
||||
std::vector<uint16_t> uniqueIndicesVec;
|
||||
for (BSPSurface& surface : bsp->colWorld.surfaces)
|
||||
for (size_t surfIdx = 0; surfIdx < totalSurfaceCount; surfIdx++)
|
||||
{
|
||||
BSPSurface surface;
|
||||
if (surfIdx < staticSurfaceCount)
|
||||
surface = bsp->colWorld.staticSurfaces.at(surfIdx);
|
||||
else
|
||||
surface = bsp->colWorld.scriptSurfaces.at(surfIdx - staticSurfaceCount);
|
||||
|
||||
int indexOfFirstIndex = surface.indexOfFirstIndex;
|
||||
int indexOfFirstTri = surface.indexOfFirstIndex / 3;
|
||||
int indexOfFirstVertex = surface.indexOfFirstVertex;
|
||||
|
||||
@@ -53,13 +53,21 @@ namespace BSP
|
||||
{
|
||||
loadDrawData(bsp, gfxWorld);
|
||||
|
||||
size_t surfaceCount = bsp->gfxWorld.surfaces.size();
|
||||
gfxWorld->surfaceCount = static_cast<int>(surfaceCount);
|
||||
gfxWorld->dpvs.staticSurfaceCount = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.surfaces = m_memory.Alloc<GfxSurface>(surfaceCount);
|
||||
for (size_t surfIdx = 0; surfIdx < surfaceCount; surfIdx++)
|
||||
size_t staticSurfaceCount = bsp->gfxWorld.staticSurfaces.size();
|
||||
size_t scriptSurfaceCount = bsp->gfxWorld.scriptSurfaces.size();
|
||||
size_t totalSurfaceCount = staticSurfaceCount + scriptSurfaceCount;
|
||||
|
||||
// Static surfaces go first in the array then script surfaces after
|
||||
gfxWorld->surfaceCount = static_cast<int>(totalSurfaceCount);
|
||||
gfxWorld->dpvs.staticSurfaceCount = static_cast<unsigned int>(staticSurfaceCount);
|
||||
gfxWorld->dpvs.surfaces = m_memory.Alloc<GfxSurface>(totalSurfaceCount);
|
||||
for (size_t surfIdx = 0; surfIdx < totalSurfaceCount; surfIdx++)
|
||||
{
|
||||
BSPSurface& bspSurface = bsp->gfxWorld.surfaces.at(surfIdx);
|
||||
BSPSurface bspSurface;
|
||||
if (surfIdx < staticSurfaceCount)
|
||||
bspSurface = bsp->gfxWorld.staticSurfaces.at(surfIdx);
|
||||
else
|
||||
bspSurface = bsp->gfxWorld.scriptSurfaces.at(surfIdx - staticSurfaceCount);
|
||||
GfxSurface* gfxSurface = &gfxWorld->dpvs.surfaces[surfIdx];
|
||||
|
||||
gfxSurface->tris.triCount = bspSurface.triCount;
|
||||
@@ -124,26 +132,26 @@ namespace BSP
|
||||
}
|
||||
|
||||
// Some code uses Sorted surfs to index surfaces, so for simplicity keep the indexes sequential and from 0
|
||||
gfxWorld->dpvs.sortedSurfIndex = m_memory.Alloc<uint16_t>(surfaceCount);
|
||||
for (size_t surfIdx = 0; surfIdx < surfaceCount; surfIdx++)
|
||||
gfxWorld->dpvs.sortedSurfIndex = m_memory.Alloc<uint16_t>(staticSurfaceCount);
|
||||
for (size_t surfIdx = 0; surfIdx < staticSurfaceCount; surfIdx++)
|
||||
gfxWorld->dpvs.sortedSurfIndex[surfIdx] = static_cast<uint16_t>(surfIdx);
|
||||
|
||||
// surface materials are written to by the game
|
||||
gfxWorld->dpvs.surfaceMaterials = m_memory.Alloc<GfxDrawSurf_align4>(surfaceCount);
|
||||
gfxWorld->dpvs.surfaceMaterials = m_memory.Alloc<GfxDrawSurf_align4>(staticSurfaceCount);
|
||||
|
||||
// set all surface types to lit opaque
|
||||
gfxWorld->dpvs.litSurfsBegin = 0;
|
||||
gfxWorld->dpvs.litSurfsEnd = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.emissiveOpaqueSurfsBegin = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.emissiveOpaqueSurfsEnd = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.emissiveTransSurfsBegin = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.emissiveTransSurfsEnd = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.litTransSurfsBegin = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.litTransSurfsEnd = static_cast<unsigned int>(surfaceCount);
|
||||
gfxWorld->dpvs.litSurfsEnd = static_cast<unsigned int>(staticSurfaceCount);
|
||||
gfxWorld->dpvs.emissiveOpaqueSurfsBegin = static_cast<unsigned int>(staticSurfaceCount);
|
||||
gfxWorld->dpvs.emissiveOpaqueSurfsEnd = static_cast<unsigned int>(staticSurfaceCount);
|
||||
gfxWorld->dpvs.emissiveTransSurfsBegin = static_cast<unsigned int>(staticSurfaceCount);
|
||||
gfxWorld->dpvs.emissiveTransSurfsEnd = static_cast<unsigned int>(staticSurfaceCount);
|
||||
gfxWorld->dpvs.litTransSurfsBegin = static_cast<unsigned int>(staticSurfaceCount);
|
||||
gfxWorld->dpvs.litTransSurfsEnd = static_cast<unsigned int>(staticSurfaceCount);
|
||||
|
||||
// visdata is written to by the game
|
||||
// all visdata is alligned by 128
|
||||
size_t allignedSurfaceCount = BSPUtil::allignBy128(surfaceCount);
|
||||
size_t allignedSurfaceCount = BSPUtil::allignBy128(staticSurfaceCount);
|
||||
gfxWorld->dpvs.surfaceVisDataCount = static_cast<unsigned int>(allignedSurfaceCount);
|
||||
gfxWorld->dpvs.surfaceVisData[0] = m_memory.Alloc<char>(allignedSurfaceCount);
|
||||
gfxWorld->dpvs.surfaceVisData[1] = m_memory.Alloc<char>(allignedSurfaceCount);
|
||||
@@ -507,7 +515,7 @@ namespace BSP
|
||||
gfxWorld->cells[0].aabbTree[0].childCount = 0;
|
||||
gfxWorld->cells[0].aabbTree[0].childrenOffset = 0;
|
||||
gfxWorld->cells[0].aabbTree[0].startSurfIndex = 0;
|
||||
gfxWorld->cells[0].aabbTree[0].surfaceCount = static_cast<uint16_t>(gfxWorld->surfaceCount);
|
||||
gfxWorld->cells[0].aabbTree[0].surfaceCount = static_cast<uint16_t>(gfxWorld->dpvs.staticSurfaceCount);
|
||||
gfxWorld->cells[0].aabbTree[0].smodelIndexCount = static_cast<uint16_t>(gfxWorld->dpvs.smodelCount);
|
||||
gfxWorld->cells[0].aabbTree[0].smodelIndexes = m_memory.Alloc<unsigned short>(gfxWorld->dpvs.smodelCount);
|
||||
for (unsigned short smodelIdx = 0; smodelIdx < gfxWorld->dpvs.smodelCount; smodelIdx++)
|
||||
@@ -537,16 +545,17 @@ namespace BSP
|
||||
|
||||
void GfxWorldLinker::loadWorldBounds(GfxWorld* gfxWorld)
|
||||
{
|
||||
gfxWorld->mins.x = gfxWorld->dpvs.surfaces[0].bounds[0].x;
|
||||
gfxWorld->mins.y = gfxWorld->dpvs.surfaces[0].bounds[0].y;
|
||||
gfxWorld->mins.z = gfxWorld->dpvs.surfaces[0].bounds[0].z;
|
||||
gfxWorld->maxs.x = gfxWorld->dpvs.surfaces[0].bounds[1].x;
|
||||
gfxWorld->maxs.y = gfxWorld->dpvs.surfaces[0].bounds[1].y;
|
||||
gfxWorld->maxs.z = gfxWorld->dpvs.surfaces[0].bounds[1].z;
|
||||
gfxWorld->mins = gfxWorld->dpvs.surfaces[0].bounds[0];
|
||||
gfxWorld->maxs = gfxWorld->dpvs.surfaces[0].bounds[1];
|
||||
for (int surfIdx = 0; surfIdx < gfxWorld->surfaceCount; surfIdx++)
|
||||
{
|
||||
BSPUtil::updateAABB(gfxWorld->dpvs.surfaces[surfIdx].bounds[0], gfxWorld->dpvs.surfaces[surfIdx].bounds[1], gfxWorld->mins, gfxWorld->maxs);
|
||||
}
|
||||
|
||||
for (unsigned int smodeldx = 0; smodeldx < gfxWorld->dpvs.smodelCount; smodeldx++)
|
||||
{
|
||||
BSPUtil::updateAABB(gfxWorld->dpvs.smodelInsts[smodeldx].mins, gfxWorld->dpvs.smodelInsts[smodeldx].maxs, gfxWorld->mins, gfxWorld->maxs);
|
||||
}
|
||||
}
|
||||
|
||||
void GfxWorldLinker::loadModels(BSPData* bsp, GfxWorld* gfxWorld)
|
||||
@@ -557,27 +566,34 @@ namespace BSP
|
||||
|
||||
// first model is always the world model
|
||||
gfxWorld->models[0].startSurfIndex = 0;
|
||||
gfxWorld->models[0].surfaceCount = static_cast<unsigned int>(gfxWorld->surfaceCount);
|
||||
gfxWorld->models[0].bounds[0].x = gfxWorld->mins.x;
|
||||
gfxWorld->models[0].bounds[0].y = gfxWorld->mins.y;
|
||||
gfxWorld->models[0].bounds[0].z = gfxWorld->mins.z;
|
||||
gfxWorld->models[0].bounds[1].x = gfxWorld->maxs.x;
|
||||
gfxWorld->models[0].bounds[1].y = gfxWorld->maxs.y;
|
||||
gfxWorld->models[0].bounds[1].z = gfxWorld->maxs.z;
|
||||
gfxWorld->models[0].surfaceCount = static_cast<unsigned int>(gfxWorld->dpvs.staticSurfaceCount);
|
||||
for (unsigned int surfIdx = 0; surfIdx < gfxWorld->dpvs.staticSurfaceCount; surfIdx++)
|
||||
{
|
||||
if (surfIdx == 0)
|
||||
{
|
||||
gfxWorld->models[0].bounds[0] = gfxWorld->dpvs.surfaces[surfIdx].bounds[0];
|
||||
gfxWorld->models[0].bounds[1] = gfxWorld->dpvs.surfaces[surfIdx].bounds[1];
|
||||
}
|
||||
else
|
||||
BSPUtil::updateAABB(gfxWorld->dpvs.surfaces[surfIdx].bounds[0],
|
||||
gfxWorld->dpvs.surfaces[surfIdx].bounds[1],
|
||||
gfxWorld->models[0].bounds[0],
|
||||
gfxWorld->models[0].bounds[1]);
|
||||
}
|
||||
memset(&gfxWorld->models[0].writable, 0, sizeof(GfxBrushModelWritable));
|
||||
|
||||
for (size_t modelIdx = 0; modelIdx < bsp->models.size(); modelIdx++)
|
||||
{
|
||||
auto currEntModel = &gfxWorld->models[modelIdx + 1];
|
||||
auto& bspMpdel = bsp->models.at(modelIdx);
|
||||
auto& bspModel = bsp->models.at(modelIdx);
|
||||
|
||||
if (bspMpdel.isGfxModel)
|
||||
if (bspModel.isGfxModel)
|
||||
{
|
||||
currEntModel->startSurfIndex = bspMpdel.surfaceIndex;
|
||||
currEntModel->surfaceCount = bspMpdel.surfaceCount;
|
||||
for (size_t surfIdx = 0; surfIdx < bspMpdel.surfaceCount; surfIdx++)
|
||||
currEntModel->startSurfIndex = bsp->gfxWorld.staticSurfaces.size() + bspModel.surfaceIndex;
|
||||
currEntModel->surfaceCount = bspModel.surfaceCount;
|
||||
for (size_t surfIdx = 0; surfIdx < bspModel.surfaceCount; surfIdx++)
|
||||
{
|
||||
GfxSurface* surf = &gfxWorld->dpvs.surfaces[bspMpdel.surfaceIndex + surfIdx];
|
||||
GfxSurface* surf = &gfxWorld->dpvs.surfaces[currEntModel->startSurfIndex + surfIdx];
|
||||
if (surfIdx == 0)
|
||||
{
|
||||
currEntModel->bounds[0] = surf->bounds[0];
|
||||
@@ -817,7 +833,7 @@ namespace BSP
|
||||
if (!loadReflectionProbeData(gfxWorld))
|
||||
return nullptr;
|
||||
|
||||
// world bounds are based on loaded surface mins/maxs
|
||||
// world bounds are based on loaded surface mins/maxs and xmodels
|
||||
loadWorldBounds(gfxWorld);
|
||||
|
||||
if (!loadOutdoors(gfxWorld))
|
||||
|
||||
Reference in New Issue
Block a user