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 "BSPCreator.h"
#include "BSPUtil.h" #include "BSPUtil.h"
#include "fbx/ufbx.h" #include "fbx/ufbx.h"

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
#include "../BSPUtil.h"
#include "ClipMapLinker.h" #include "ClipMapLinker.h"
#include "../BSPUtil.h"
namespace BSP namespace BSP
{ {
ClipMapLinker::ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context) ClipMapLinker::ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context)
@@ -601,7 +602,7 @@ namespace BSP
return true; return true;
} }
AssetCreationResult ClipMapLinker::linkClipMap(BSPData* bsp) clipMap_t* ClipMapLinker::linkClipMap(BSPData* bsp)
{ {
clipMap_t* clipMap = m_memory.Alloc<clipMap_t>(); clipMap_t* clipMap = m_memory.Alloc<clipMap_t>();
clipMap->name = m_memory.Dup(bsp->bspName.c_str()); clipMap->name = m_memory.Dup(bsp->bspName.c_str());
@@ -642,11 +643,8 @@ namespace BSP
memset(clipMap->triEdgeIsWalkable, 1, walkableEdgeSize * sizeof(char)); memset(clipMap->triEdgeIsWalkable, 1, walkableEdgeSize * sizeof(char));
if (!loadWorldCollision(clipMap, bsp)) if (!loadWorldCollision(clipMap, bsp))
return AssetCreationResult::Failure(); return nullptr;
m_context.AddAsset<AssetClipMapPvs>(clipMap->name, clipMap); return clipMap;
auto clipMapAsset = m_context.AddAsset<AssetClipMap>(clipMap->name, clipMap);
return AssetCreationResult::Success(clipMapAsset);
} }
} // namespace BSP } // namespace BSP

View File

@@ -12,7 +12,7 @@ namespace BSP
{ {
public: public:
ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); ClipMapLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkClipMap(BSPData* bsp); clipMap_t* linkClipMap(BSPData* bsp);
private: private:
MemoryManager& m_memory; 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 // all lights that aren't the sunlight or default light need their own GfxLightDef asset
ComWorld* comWorld = m_memory.Alloc<ComWorld>(); ComWorld* comWorld = m_memory.Alloc<ComWorld>();
@@ -32,7 +32,6 @@ namespace BSP
sunLight->dir.y = sunLightDirection.y; sunLight->dir.y = sunLightDirection.y;
sunLight->dir.z = sunLightDirection.z; sunLight->dir.z = sunLightDirection.z;
auto comWorldAsset = m_context.AddAsset<AssetComWorld>(comWorld->name, comWorld); return comWorld;
return AssetCreationResult::Success(comWorldAsset);
} }
} // namespace BSP } // namespace BSP

View File

@@ -11,7 +11,7 @@ namespace BSP
{ {
public: public:
ComWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); ComWorldLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkComWorld(BSPData* bsp); ComWorld* linkComWorld(BSPData* bsp);
private: private:
MemoryManager& m_memory; 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>(); GameWorldMp* gameWorldMp = m_memory.Alloc<GameWorldMp>();
@@ -29,7 +29,6 @@ namespace BSP
gameWorldMp->path.smoothCache = nullptr; gameWorldMp->path.smoothCache = nullptr;
gameWorldMp->path.nodeTree = nullptr; gameWorldMp->path.nodeTree = nullptr;
auto gameWorldMpAsset = m_context.AddAsset<AssetGameWorldMp>(gameWorldMp->name, gameWorldMp); return gameWorldMp;
return AssetCreationResult::Success(gameWorldMpAsset);
} }
} // namespace BSP } // namespace BSP

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ namespace BSP
{ {
public: public:
MapEntsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context); MapEntsLinker(MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context);
AssetCreationResult linkMapEnts(BSPData* bsp); MapEnts* linkMapEnts(BSPData* bsp);
private: private:
MemoryManager& m_memory; 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"; // Pretty sure maxSkinnedVerts relates to the max amount of xmodel skinned verts a map will have
// I'm 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 // But setting it to the world vertex count seems to work
SkinnedVertsDef* skinnedVerts = m_memory.Alloc<SkinnedVertsDef>(); 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()); skinnedVerts->maxSkinnedVerts = static_cast<unsigned int>(bsp->gfxWorld.vertices.size());
auto skinnedVertsAsset = m_context.AddAsset<AssetSkinnedVerts>(assetName, skinnedVerts); return skinnedVerts;
return AssetCreationResult::Success(skinnedVertsAsset);
} }
} // namespace BSP } // namespace BSP

View File

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

View File

@@ -1,13 +1,14 @@
#include "LoaderBSP_T6.h"
#include "BSPCreator.h" #include "BSPCreator.h"
#include "BSPUtil.h" #include "BSPUtil.h"
#include "Linker/BSPLinker.h" #include "Linker/BSPLinker.h"
#include "LoaderBSP_T6.h"
namespace namespace
{ {
using namespace BSP; using namespace BSP;
class BSPLoader final : public AssetCreator<AssetGfxWorld> class BSPLoader final : public IAssetCreator
{ {
public: public:
BSPLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone) 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 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 // custom maps must have a map_gfx file
std::string mapGfxFileName = "map_gfx.fbx"; std::string mapGfxFileName = "map_gfx.fbx";
auto mapGfxFile = m_search_path.Open(BSPUtil::getFileNameForBSPAsset(mapGfxFileName)); auto mapGfxFile = m_search_path.Open(BSPUtil::getFileNameForBSPAsset(mapGfxFileName));
if (!mapGfxFile.IsOpen()) if (!mapGfxFile.IsOpen())
return AssetCreationResult::NoAction(); return;
std::unique_ptr<BSPData> bsp = BSP::createBSPData(m_zone.m_name, m_search_path); std::unique_ptr<BSPData> bsp = BSP::createBSPData(m_zone.m_name, m_search_path);
if (bsp == nullptr) if (bsp == nullptr)
return AssetCreationResult::Failure(); return;
BSPLinker linker(m_memory, m_search_path, context); 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: private:
@@ -42,7 +58,7 @@ namespace
namespace BSP 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); return std::make_unique<BSPLoader>(memory, searchPath, zone);
} }

View File

@@ -9,5 +9,5 @@
namespace BSP 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 } // namespace BSP