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

Updated BSP linker to load assets on the FinalizeZone step.

This commit is contained in:
LJW-Dev
2025-11-01 17:06:08 +08:00
parent 3d2e890e34
commit 81e0331252
17 changed files with 87 additions and 66 deletions

View File

@@ -1,4 +1,5 @@
#include "BSPCreator.h"
#include "BSPUtil.h"
#include "fbx/ufbx.h"

View File

@@ -1,4 +1,5 @@
#include "BSPLinker.h"
#include "ClipMapLinker.h"
#include "ComWorldLinker.h"
#include "GameWorldMpLinker.h"
@@ -58,10 +59,10 @@ namespace BSP
{
}
AssetCreationResult BSPLinker::linkBSP(BSPData* bsp)
bool BSPLinker::linkBSP(BSPData* bsp)
{
if (!addDefaultRequiredAssets(bsp))
return AssetCreationResult::Failure();
return false;
ComWorldLinker comWorldLinker(m_memory, m_search_path, m_context);
ClipMapLinker clipMapLinker(m_memory, m_search_path, m_context);
@@ -70,26 +71,36 @@ namespace BSP
MapEntsLinker mapEntsLinker(m_memory, m_search_path, m_context);
SkinnedVertsLinker skinnedVertsLinker(m_memory, m_search_path, m_context);
if (comWorldLinker.linkComWorld(bsp).HasFailed())
return AssetCreationResult::Failure();
ComWorld* comWorld = comWorldLinker.linkComWorld(bsp);
if (comWorld == nullptr)
return false;
m_context.AddAsset<AssetComWorld>(comWorld->name, comWorld);
if (mapEntsLinker.linkMapEnts(bsp).HasFailed())
return AssetCreationResult::Failure();
MapEnts* mapEnts = mapEntsLinker.linkMapEnts(bsp);
if (mapEnts == nullptr)
return false;
m_context.AddAsset<AssetMapEnts>(mapEnts->name, mapEnts);
gameWorldMpLinker.linkGameWorldMp(bsp);
if (gameWorldMpLinker.linkGameWorldMp(bsp).HasFailed())
return AssetCreationResult::Failure();
GameWorldMp* gameWorldMp = gameWorldMpLinker.linkGameWorldMp(bsp);
if (gameWorldMp == nullptr)
return false;
m_context.AddAsset<AssetGameWorldMp>(gameWorldMp->name, gameWorldMp);
if (skinnedVertsLinker.linkSkinnedVerts(bsp).HasFailed())
return AssetCreationResult::Failure();
SkinnedVertsDef* skinnedVerts = skinnedVertsLinker.linkSkinnedVerts(bsp);
if (skinnedVerts == nullptr)
return false;
m_context.AddAsset<AssetSkinnedVerts>(skinnedVerts->name, skinnedVerts);
auto result = gfxWorldLinker.linkGfxWorld(bsp); // requires mapents asset
if (result.HasFailed())
return AssetCreationResult::Failure();
GfxWorld* gfxWorld = gfxWorldLinker.linkGfxWorld(bsp); // requires mapents asset
if (gfxWorld == nullptr)
return false;
m_context.AddAsset<AssetGfxWorld>(gfxWorld->name, gfxWorld);
if (clipMapLinker.linkClipMap(bsp).HasFailed()) // requires gfxworld and mapents asset
return AssetCreationResult::Failure();
clipMap_t* clipMap = clipMapLinker.linkClipMap(bsp); // requires gfxworld and mapents asset
if (clipMap == nullptr)
return false;
m_context.AddAsset<AssetClipMap>(clipMap->name, clipMap);
return result;
return true;
}
} // namespace BSP

View File

@@ -11,7 +11,7 @@ namespace BSP
{
public:
BSPLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkBSP(BSPData* bsp);
bool linkBSP(BSPData* bsp);
private:
FootstepTableDef* addEmptyFootstepTableAsset(std::string assetName);

View File

@@ -1,6 +1,7 @@
#include "../BSPUtil.h"
#include "ClipMapLinker.h"
#include "../BSPUtil.h"
namespace BSP
{
ClipMapLinker::ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context)
@@ -494,7 +495,7 @@ namespace BSP
}
// the reinterpret_cast is used as triIndices is just a pointer to an array of indicies, and static_cast can't safely do the conversion
clipMap->triCount = static_cast<int>(triIndexVec.size() / 3);
clipMap->triIndices = reinterpret_cast<uint16_t (*)[3]>(m_memory.Alloc<uint16_t>(triIndexVec.size()));
clipMap->triIndices = reinterpret_cast<uint16_t(*)[3]>(m_memory.Alloc<uint16_t>(triIndexVec.size()));
memcpy(clipMap->triIndices, &triIndexVec[0], sizeof(uint16_t) * triIndexVec.size());
// partitions are "containers" for vertices. BSP tree leafs contain a list of these partitions to determine the collision within a leaf.
@@ -601,7 +602,7 @@ namespace BSP
return true;
}
AssetCreationResult ClipMapLinker::linkClipMap(BSPData* bsp)
clipMap_t* ClipMapLinker::linkClipMap(BSPData* bsp)
{
clipMap_t* clipMap = m_memory.Alloc<clipMap_t>();
clipMap->name = m_memory.Dup(bsp->bspName.c_str());
@@ -642,11 +643,8 @@ namespace BSP
memset(clipMap->triEdgeIsWalkable, 1, walkableEdgeSize * sizeof(char));
if (!loadWorldCollision(clipMap, bsp))
return AssetCreationResult::Failure();
return nullptr;
m_context.AddAsset<AssetClipMapPvs>(clipMap->name, clipMap);
auto clipMapAsset = m_context.AddAsset<AssetClipMap>(clipMap->name, clipMap);
return AssetCreationResult::Success(clipMapAsset);
return clipMap;
}
} // namespace BSP

View File

@@ -12,7 +12,7 @@ namespace BSP
{
public:
ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkClipMap(BSPData* bsp);
clipMap_t* linkClipMap(BSPData* bsp);
private:
MemoryManager& m_memory;

View File

@@ -9,7 +9,7 @@ namespace BSP
{
}
AssetCreationResult ComWorldLinker::linkComWorld(BSPData* bsp)
ComWorld* ComWorldLinker::linkComWorld(BSPData* bsp)
{
// all lights that aren't the sunlight or default light need their own GfxLightDef asset
ComWorld* comWorld = m_memory.Alloc<ComWorld>();
@@ -32,7 +32,6 @@ namespace BSP
sunLight->dir.y = sunLightDirection.y;
sunLight->dir.z = sunLightDirection.z;
auto comWorldAsset = m_context.AddAsset<AssetComWorld>(comWorld->name, comWorld);
return AssetCreationResult::Success(comWorldAsset);
return comWorld;
}
} // namespace BSP

View File

@@ -11,7 +11,7 @@ namespace BSP
{
public:
ComWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkComWorld(BSPData* bsp);
ComWorld* linkComWorld(BSPData* bsp);
private:
MemoryManager& m_memory;

View File

@@ -9,7 +9,7 @@ namespace BSP
{
}
AssetCreationResult GameWorldMpLinker::linkGameWorldMp(BSPData* bsp)
GameWorldMp* GameWorldMpLinker::linkGameWorldMp(BSPData* bsp)
{
GameWorldMp* gameWorldMp = m_memory.Alloc<GameWorldMp>();
@@ -29,7 +29,6 @@ namespace BSP
gameWorldMp->path.smoothCache = nullptr;
gameWorldMp->path.nodeTree = nullptr;
auto gameWorldMpAsset = m_context.AddAsset<AssetGameWorldMp>(gameWorldMp->name, gameWorldMp);
return AssetCreationResult::Success(gameWorldMpAsset);
return gameWorldMp;
}
} // namespace BSP

View File

@@ -11,7 +11,7 @@ namespace BSP
{
public:
GameWorldMpLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkGameWorldMp(BSPData* bsp);
GameWorldMp* linkGameWorldMp(BSPData* bsp);
private:
MemoryManager& m_memory;

View File

@@ -1,5 +1,6 @@
#include "../BSPUtil.h"
#include "GfxWorldLinker.h"
#include "../BSPUtil.h"
#include "Utils/Pack.h"
namespace BSP
@@ -725,7 +726,7 @@ namespace BSP
return true;
}
AssetCreationResult GfxWorldLinker::linkGfxWorld(BSPData* bsp)
GfxWorld* GfxWorldLinker::linkGfxWorld(BSPData* bsp)
{
GfxWorld* gfxWorld = m_memory.Alloc<GfxWorld>();
gfxWorld->baseName = m_memory.Dup(bsp->name.c_str());
@@ -738,23 +739,23 @@ namespace BSP
cleanGfxWorld(gfxWorld);
if (!loadMapSurfaces(bsp, gfxWorld))
return AssetCreationResult::Failure();
return nullptr;
loadXModels(bsp, gfxWorld);
if (!loadLightmapData(gfxWorld))
return AssetCreationResult::Failure();
return nullptr;
loadSkyBox(bsp, gfxWorld);
if (!loadReflectionProbeData(gfxWorld))
return AssetCreationResult::Failure();
return nullptr;
// world bounds are based on loaded surface mins/maxs
loadWorldBounds(gfxWorld);
if (!loadOutdoors(gfxWorld))
return AssetCreationResult::Failure();
return nullptr;
// gfx cells depend on surface/smodel count
loadGfxCells(gfxWorld);
@@ -769,7 +770,6 @@ namespace BSP
loadDynEntData(gfxWorld);
auto gfxWorldAsset = m_context.AddAsset<AssetGfxWorld>(gfxWorld->name, gfxWorld);
return AssetCreationResult::Success(gfxWorldAsset);
return gfxWorld;
}
} // namespace BSP

View File

@@ -11,7 +11,7 @@ namespace BSP
{
public:
GfxWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkGfxWorld(BSPData* bsp);
GfxWorld* linkGfxWorld(BSPData* bsp);
private:
MemoryManager& m_memory;

View File

@@ -1,6 +1,7 @@
#include "../BSPUtil.h"
#include "MapEntsLinker.h"
#include "../BSPUtil.h"
#include <nlohmann/json.hpp>
using namespace nlohmann;
@@ -71,7 +72,7 @@ namespace BSP
{
}
AssetCreationResult MapEntsLinker::linkMapEnts(BSPData* bsp)
MapEnts* MapEntsLinker::linkMapEnts(BSPData* bsp)
{
try
{
@@ -90,7 +91,7 @@ namespace BSP
}
std::string entityString;
if (!parseMapEntsJSON(entJs["entities"], entityString))
return AssetCreationResult::Failure();
return nullptr;
json spawnJs;
std::string spawnFileName = "spawns.json";
@@ -126,13 +127,12 @@ namespace BSP
mapEnts->trigger.slabCount = 0;
mapEnts->trigger.slabs = nullptr;
auto mapEntsAsset = m_context.AddAsset<AssetMapEnts>(mapEnts->name, mapEnts);
return AssetCreationResult::Success(mapEntsAsset);
return mapEnts;
}
catch (const json::exception& e)
{
con::error("JSON error when parsing map ents and spawns: {}", e.what());
return AssetCreationResult::Failure();
return nullptr;
}
}
} // namespace BSP

View File

@@ -11,7 +11,7 @@ namespace BSP
{
public:
MapEntsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkMapEnts(BSPData* bsp);
MapEnts* linkMapEnts(BSPData* bsp);
private:
MemoryManager& m_memory;

View File

@@ -9,17 +9,14 @@ namespace BSP
{
}
AssetCreationResult SkinnedVertsLinker::linkSkinnedVerts(BSPData* bsp)
SkinnedVertsDef* SkinnedVertsLinker::linkSkinnedVerts(BSPData* bsp)
{
std::string assetName = "skinnedverts";
// I'm pretty sure maxSkinnedVerts relates to the max amount of xmodel skinned verts a map will have
// Pretty sure maxSkinnedVerts relates to the max amount of xmodel skinned verts a map will have
// But setting it to the world vertex count seems to work
SkinnedVertsDef* skinnedVerts = m_memory.Alloc<SkinnedVertsDef>();
skinnedVerts->name = m_memory.Dup(assetName.c_str());
skinnedVerts->name = m_memory.Dup("skinnedverts");
skinnedVerts->maxSkinnedVerts = static_cast<unsigned int>(bsp->gfxWorld.vertices.size());
auto skinnedVertsAsset = m_context.AddAsset<AssetSkinnedVerts>(assetName, skinnedVerts);
return AssetCreationResult::Success(skinnedVertsAsset);
return skinnedVerts;
}
} // namespace BSP

View File

@@ -11,7 +11,7 @@ namespace BSP
{
public:
SkinnedVertsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkSkinnedVerts(BSPData* bsp);
SkinnedVertsDef* linkSkinnedVerts(BSPData* bsp);
private:
MemoryManager& m_memory;

View File

@@ -1,13 +1,14 @@
#include "LoaderBSP_T6.h"
#include "BSPCreator.h"
#include "BSPUtil.h"
#include "Linker/BSPLinker.h"
#include "LoaderBSP_T6.h"
namespace
{
using namespace BSP;
class BSPLoader final : public AssetCreator<AssetGfxWorld>
class BSPLoader final : public IAssetCreator
{
public:
BSPLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
@@ -17,20 +18,35 @@ namespace
{
}
std::optional<asset_type_t> GetHandlingAssetType() const override
{
// don't handle any asset types
return std::nullopt;
}
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
// BSP assets are added in the finalize zone step
return AssetCreationResult::NoAction();
}
void FinalizeZone(AssetCreationContext& context) override
{
// custom maps must have a map_gfx file
std::string mapGfxFileName = "map_gfx.fbx";
auto mapGfxFile = m_search_path.Open(BSPUtil::getFileNameForBSPAsset(mapGfxFileName));
if (!mapGfxFile.IsOpen())
return AssetCreationResult::NoAction();
return;
std::unique_ptr<BSPData> bsp = BSP::createBSPData(m_zone.m_name, m_search_path);
if (bsp == nullptr)
return AssetCreationResult::Failure();
return;
BSPLinker linker(m_memory, m_search_path, context);
return linker.linkBSP(bsp.get());
if (!linker.linkBSP(bsp.get()))
con::error("BSP link has failed.");
return;
}
private:
@@ -42,7 +58,7 @@ namespace
namespace BSP
{
std::unique_ptr<AssetCreator<AssetGfxWorld>> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
std::unique_ptr<IAssetCreator> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
{
return std::make_unique<BSPLoader>(memory, searchPath, zone);
}

View File

@@ -9,5 +9,5 @@
namespace BSP
{
std::unique_ptr<AssetCreator<T6::AssetGfxWorld>> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
std::unique_ptr<IAssetCreator> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace BSP