mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 02:39:17 +00:00
Added dependency tree system, methods for generating dependency trees from resources, and saving/loading dependency trees to the project cache folder
This commit is contained in:
@@ -10,7 +10,7 @@ CGameArea::CGameArea(CResourceEntry *pEntry /*= 0*/)
|
||||
, mTerrainMerged(false)
|
||||
, mOriginalWorldMeshCount(0)
|
||||
, mUsesCompression(false)
|
||||
, mMaterialSet(nullptr)
|
||||
, mpMaterialSet(nullptr)
|
||||
, mpGeneratorLayer(nullptr)
|
||||
, mpCollision(nullptr)
|
||||
{
|
||||
@@ -31,6 +31,32 @@ CGameArea::~CGameArea()
|
||||
delete mLightLayers[iLyr][iLight];
|
||||
}
|
||||
|
||||
CDependencyTree* CGameArea::BuildDependencyTree() const
|
||||
{
|
||||
// Base dependencies
|
||||
CAreaDependencyTree *pTree = new CAreaDependencyTree(ResID());
|
||||
|
||||
for (u32 iMat = 0; iMat < mpMaterialSet->NumMaterials(); iMat++)
|
||||
{
|
||||
CMaterial *pMat = mpMaterialSet->MaterialByIndex(iMat);
|
||||
pTree->AddDependency(pMat->IndTexture());
|
||||
|
||||
for (u32 iPass = 0; iPass < pMat->PassCount(); iPass++)
|
||||
pTree->AddDependency(pMat->Pass(iPass)->Texture());
|
||||
}
|
||||
|
||||
pTree->AddDependency(mpPoiToWorldMap);
|
||||
Log::Warning("CGameArea::FindDependencies not handling PATH/PTLA");
|
||||
|
||||
// Layer dependencies
|
||||
for (u32 iLayer = 0; iLayer < mScriptLayers.size(); iLayer++)
|
||||
pTree->AddScriptLayer(mScriptLayers[iLayer]);
|
||||
|
||||
pTree->AddScriptLayer(mpGeneratorLayer);
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
void CGameArea::AddWorldModel(CModel *pModel)
|
||||
{
|
||||
mWorldModels.push_back(pModel);
|
||||
@@ -52,7 +78,7 @@ void CGameArea::MergeTerrain()
|
||||
for (u32 iSurf = 0; iSurf < SubmeshCount; iSurf++)
|
||||
{
|
||||
SSurface *pSurf = pMdl->GetSurface(iSurf);
|
||||
CMaterial *pMat = mMaterialSet->MaterialByIndex(pSurf->MaterialID);
|
||||
CMaterial *pMat = mpMaterialSet->MaterialByIndex(pSurf->MaterialID);
|
||||
|
||||
bool NewMat = true;
|
||||
for (std::vector<CStaticModel*>::iterator it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++)
|
||||
@@ -93,7 +119,7 @@ void CGameArea::ClearTerrain()
|
||||
delete mStaticWorldModels[iStatic];
|
||||
mStaticWorldModels.clear();
|
||||
|
||||
if (mMaterialSet) delete mMaterialSet;
|
||||
if (mpMaterialSet) delete mpMaterialSet;
|
||||
|
||||
mVertexCount = 0;
|
||||
mTriangleCount = 0;
|
||||
|
||||
@@ -45,7 +45,7 @@ class CGameArea : public CResource
|
||||
std::vector<SSectionNumber> mSectionNumbers;
|
||||
|
||||
// Geometry
|
||||
CMaterialSet *mMaterialSet;
|
||||
CMaterialSet *mpMaterialSet;
|
||||
std::vector<CModel*> mWorldModels; // TerrainModels is the original version of each model; this is currently mainly used in the POI map editor
|
||||
std::vector<CStaticModel*> mStaticWorldModels; // StaticTerrainModels is the merged terrain for faster rendering in the world editor
|
||||
// Script
|
||||
@@ -62,6 +62,7 @@ class CGameArea : public CResource
|
||||
public:
|
||||
CGameArea(CResourceEntry *pEntry = 0);
|
||||
~CGameArea();
|
||||
CDependencyTree* BuildDependencyTree() const;
|
||||
|
||||
void AddWorldModel(CModel *pModel);
|
||||
void MergeTerrain();
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
// Accessors
|
||||
inline EGame Version() const { return mGame; }
|
||||
inline CUniqueID ID() const { return mCharacter.ID(); }
|
||||
inline CAnimSet* AnimSet() const { return (CAnimSet*) mCharacter.Load(); }
|
||||
inline u32 CharacterIndex() const { return mCharIndex; }
|
||||
inline u32 AnimIndex() const { return mAnimIndex; }
|
||||
|
||||
33
src/Core/Resource/CDependencyGroup.h
Normal file
33
src/Core/Resource/CDependencyGroup.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef CDEPENDENCYGROUP
|
||||
#define CDEPENDENCYGROUP
|
||||
|
||||
#include "CResource.h"
|
||||
|
||||
class CDependencyGroup : public CResource
|
||||
{
|
||||
DECLARE_RESOURCE_TYPE(eDependencyGroup)
|
||||
std::set<CUniqueID> mDependencies;
|
||||
|
||||
public:
|
||||
CDependencyGroup(CResourceEntry *pEntry = 0) : CResource(pEntry) {}
|
||||
inline void AddDependency(const CUniqueID& rkID) { mDependencies.insert(rkID); }
|
||||
inline void AddDependency(CResource *pRes) { if (pRes) mDependencies.insert(pRes->ResID()); }
|
||||
inline void RemoveDependency(const CUniqueID& rkID) { mDependencies.erase(rkID); }
|
||||
inline void Clear() { mDependencies.clear(); }
|
||||
inline bool HasDependency(const CUniqueID& rkID) const { return mDependencies.find(rkID) != mDependencies.end(); }
|
||||
inline u32 NumDependencies() const { return mDependencies.size(); }
|
||||
inline CUniqueID DependencyByIndex(u32 Index) const { return *std::next(mDependencies.begin(), Index); }
|
||||
|
||||
CDependencyTree* BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree *pTree = new CDependencyTree(ResID());
|
||||
|
||||
for (auto DepIt = mDependencies.begin(); DepIt != mDependencies.end(); DepIt++)
|
||||
pTree->AddDependency(*DepIt);
|
||||
|
||||
return pTree;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CDEPENDENCYGROUP
|
||||
|
||||
@@ -22,6 +22,13 @@ inline float PtsToFloat(s32 Pt)
|
||||
return 0.00208333f * Pt;
|
||||
}
|
||||
|
||||
CDependencyTree* CFont::BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree *pOut = new CDependencyTree(ResID());
|
||||
pOut->AddDependency(mpFontTexture);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
CVector2f CFont::RenderString(const TString& rkString, CRenderer* /*pRenderer*/, float /*AspectRatio*/,
|
||||
CVector2f /*Position*/, CColor FillColor, CColor StrokeColor, u32 FontSize)
|
||||
{
|
||||
|
||||
@@ -60,6 +60,7 @@ class CFont : public CResource
|
||||
public:
|
||||
CFont(CResourceEntry *pEntry = 0);
|
||||
~CFont();
|
||||
CDependencyTree* BuildDependencyTree() const;
|
||||
CVector2f RenderString(const TString& rkString, CRenderer *pRenderer, float AspectRatio,
|
||||
CVector2f Position = CVector2f(0,0),
|
||||
CColor FillColor = CColor::skWhite, CColor StrokeColor = CColor::skBlack,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CRESOURCE_H
|
||||
|
||||
#include "EResType.h"
|
||||
#include "Core/GameProject/CDependencyTree.h"
|
||||
#include "Core/GameProject/CResourceEntry.h"
|
||||
#include "Core/GameProject/CResourceStore.h"
|
||||
#include <Common/CFourCC.h>
|
||||
@@ -39,7 +40,8 @@ public:
|
||||
}
|
||||
|
||||
virtual ~CResource() {}
|
||||
|
||||
virtual CDependencyTree* BuildDependencyTree() const { return new CDependencyTree(ResID()); }
|
||||
|
||||
inline CResourceEntry* Entry() const { return mpEntry; }
|
||||
inline TString Source() const { return mpEntry ? mpEntry->CookedAssetPath(true).GetFileName() : ""; }
|
||||
inline TString FullSource() const { return mpEntry ? mpEntry->CookedAssetPath(true) : ""; }
|
||||
|
||||
@@ -40,6 +40,17 @@ public:
|
||||
, mCategory(eNone)
|
||||
{}
|
||||
|
||||
CDependencyTree* BuildDependencyTree() const
|
||||
{
|
||||
if (Game() >= eEchoesDemo)
|
||||
Log::Warning("CScan::BuildDependencyTree not handling Echoes/Corruption dependencies");
|
||||
|
||||
CDependencyTree *pTree = new CDependencyTree(ResID());
|
||||
pTree->AddDependency(mpFrame);
|
||||
pTree->AddDependency(mpStringTable);
|
||||
return pTree;
|
||||
}
|
||||
|
||||
EGame Version() const { return mVersion; }
|
||||
CStringTable* ScanText() const { return mpStringTable; }
|
||||
bool IsImportant() const { return mIsImportant; }
|
||||
|
||||
@@ -17,6 +17,28 @@ CWorld::~CWorld()
|
||||
{
|
||||
}
|
||||
|
||||
CDependencyTree* CWorld::BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree *pTree = new CDependencyTree(ResID());
|
||||
|
||||
for (u32 iArea = 0; iArea < mAreas.size(); iArea++)
|
||||
{
|
||||
pTree->AddDependency(mAreas[iArea].FileID);
|
||||
pTree->AddDependency(mAreas[iArea].pAreaName);
|
||||
}
|
||||
|
||||
pTree->AddDependency(mpWorldName);
|
||||
pTree->AddDependency(mpDarkWorldName);
|
||||
pTree->AddDependency(mpSaveWorld);
|
||||
pTree->AddDependency(mpDefaultSkybox);
|
||||
pTree->AddDependency(mpMapWorld);
|
||||
|
||||
if (Game() <= ePrime)
|
||||
Log::Warning("CWorld::BuildDependencyTree not handling audio groups");
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
void CWorld::SetAreaLayerInfo(CGameArea *pArea)
|
||||
{
|
||||
// The AreaIndex parameter is a placeholder until an improved world loader is implemented.
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
CWorld(CResourceEntry *pEntry = 0);
|
||||
~CWorld();
|
||||
|
||||
CDependencyTree* BuildDependencyTree() const;
|
||||
void SetAreaLayerInfo(CGameArea *pArea);
|
||||
|
||||
// Accessors
|
||||
|
||||
@@ -73,7 +73,7 @@ void CAreaLoader::ReadGeometryPrime()
|
||||
mpSectionMgr->ToSection(mGeometryBlockNum);
|
||||
|
||||
// Materials
|
||||
mpArea->mMaterialSet = CMaterialLoader::LoadMaterialSet(*mpMREA, mVersion);
|
||||
mpArea->mpMaterialSet = CMaterialLoader::LoadMaterialSet(*mpMREA, mVersion);
|
||||
mpSectionMgr->ToNextSection();
|
||||
|
||||
// Geometry
|
||||
@@ -81,7 +81,7 @@ void CAreaLoader::ReadGeometryPrime()
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||
{
|
||||
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mMaterialSet, mVersion);
|
||||
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, mVersion);
|
||||
FileModels.push_back(pModel);
|
||||
|
||||
if (mVersion <= ePrime)
|
||||
@@ -394,7 +394,7 @@ void CAreaLoader::ReadGeometryCorruption()
|
||||
mpSectionMgr->ToSection(mGeometryBlockNum);
|
||||
|
||||
// Materials
|
||||
mpArea->mMaterialSet = CMaterialLoader::LoadMaterialSet(*mpMREA, mVersion);
|
||||
mpArea->mpMaterialSet = CMaterialLoader::LoadMaterialSet(*mpMREA, mVersion);
|
||||
mpSectionMgr->ToNextSection();
|
||||
|
||||
// Geometry
|
||||
@@ -404,7 +404,7 @@ void CAreaLoader::ReadGeometryCorruption()
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||
{
|
||||
CModel *pWorldModel = CModelLoader::LoadCorruptionWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mMaterialSet, CurWOBJSection, CurGPUSection, mVersion);
|
||||
CModel *pWorldModel = CModelLoader::LoadCorruptionWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, CurWOBJSection, CurGPUSection, mVersion);
|
||||
FileModels.push_back(pWorldModel);
|
||||
|
||||
CurWOBJSection += 4;
|
||||
|
||||
48
src/Core/Resource/Factory/CDependencyGroupLoader.cpp
Normal file
48
src/Core/Resource/Factory/CDependencyGroupLoader.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "CDependencyGroupLoader.h"
|
||||
#include <Common/AssertMacro.h>
|
||||
|
||||
EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, u32 DepCount)
|
||||
{
|
||||
// Only difference between versions is asset ID length. Just check for EOF with 32-bit ID length.
|
||||
u32 Start = rDGRP.Tell();
|
||||
rDGRP.Seek(DepCount * 4, SEEK_CUR);
|
||||
u32 Remaining = rDGRP.Size() - Start;
|
||||
|
||||
EGame Game = ePrimeDemo;
|
||||
|
||||
if (Remaining < 32)
|
||||
{
|
||||
for (u32 iRem = 0; iRem < Remaining; iRem++)
|
||||
{
|
||||
if (rDGRP.ReadByte() != 0xFF)
|
||||
{
|
||||
Game = eCorruptionProto;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rDGRP.Seek(Start, SEEK_SET);
|
||||
return Game;
|
||||
}
|
||||
|
||||
CDependencyGroup* CDependencyGroupLoader::LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry)
|
||||
{
|
||||
if (!rDGRP.IsValid()) return nullptr;
|
||||
|
||||
u32 NumDependencies = rDGRP.ReadLong();
|
||||
EGame Game = VersionTest(rDGRP, NumDependencies);
|
||||
EUIDLength IDLength = (Game < eCorruptionProto ? e32Bit : e64Bit);
|
||||
|
||||
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
|
||||
pGroup->SetGame(Game);
|
||||
|
||||
for (u32 iDep = 0; iDep < NumDependencies; iDep++)
|
||||
{
|
||||
rDGRP.Seek(0x4, SEEK_CUR); // Skip dependency type
|
||||
CUniqueID AssetID(rDGRP, IDLength);
|
||||
pGroup->AddDependency(AssetID);
|
||||
}
|
||||
|
||||
return pGroup;
|
||||
}
|
||||
16
src/Core/Resource/Factory/CDependencyGroupLoader.h
Normal file
16
src/Core/Resource/Factory/CDependencyGroupLoader.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef CDEPENDENCYGROUPLOADER_H
|
||||
#define CDEPENDENCYGROUPLOADER_H
|
||||
|
||||
#include "Core/Resource/CDependencyGroup.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
|
||||
class CDependencyGroupLoader
|
||||
{
|
||||
CDependencyGroupLoader() {}
|
||||
static EGame VersionTest(IInputStream& rDGRP, u32 DepCount);
|
||||
|
||||
public:
|
||||
static CDependencyGroup* LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry);
|
||||
};
|
||||
|
||||
#endif // CDEPENDENCYGROUPLOADER_H
|
||||
@@ -65,7 +65,7 @@ void CMaterialLoader::ReadPrimeMatSet()
|
||||
{
|
||||
mpSet->mMaterials[iMat] = ReadPrimeMaterial();
|
||||
mpSet->mMaterials[iMat]->mVersion = mVersion;
|
||||
mpSet->mMaterials[iMat]->mName = TString("Material #") + std::to_string(iMat + 1);
|
||||
mpSet->mMaterials[iMat]->mName = TString("Material #") + TString::FromInt32(iMat + 1, 0, 10);
|
||||
mpFile->Seek(MatsStart + Offsets[iMat], SEEK_SET);
|
||||
}
|
||||
}
|
||||
@@ -261,7 +261,7 @@ void CMaterialLoader::ReadCorruptionMatSet()
|
||||
u32 Next = mpFile->Tell() + Size;
|
||||
mpSet->mMaterials[iMat] = ReadCorruptionMaterial();
|
||||
mpSet->mMaterials[iMat]->mVersion = mVersion;
|
||||
mpSet->mMaterials[iMat]->mName = TString("Material #") + std::to_string(iMat + 1);
|
||||
mpSet->mMaterials[iMat]->mName = TString("Material #") + TString::FromInt32(iMat + 1, 0, 10);
|
||||
mpFile->Seek(Next, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,31 @@ CModel::~CModel()
|
||||
delete mMaterialSets[iMat];
|
||||
}
|
||||
|
||||
|
||||
CDependencyTree* CModel::BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree *pTree = new CDependencyTree(ResID());
|
||||
|
||||
for (u32 iSet = 0; iSet < mMaterialSets.size(); iSet++)
|
||||
{
|
||||
CMaterialSet *pSet = mMaterialSets[iSet];
|
||||
|
||||
for (u32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
|
||||
{
|
||||
CMaterial *pMat = pSet->MaterialByIndex(iMat);
|
||||
pTree->AddDependency(pMat->IndTexture());
|
||||
|
||||
for (u32 iPass = 0; iPass < pMat->PassCount(); iPass++)
|
||||
{
|
||||
CMaterialPass *pPass = pMat->Pass(iPass);
|
||||
pTree->AddDependency(pPass->Texture());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
void CModel::BufferGL()
|
||||
{
|
||||
if (!mBuffered)
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
CModel(CMaterialSet *pSet, bool OwnsMatSet);
|
||||
~CModel();
|
||||
|
||||
CDependencyTree* BuildDependencyTree() const;
|
||||
void BufferGL();
|
||||
void GenerateMaterialShaders();
|
||||
void ClearGLBuffer();
|
||||
|
||||
@@ -63,6 +63,7 @@ bool CScriptObject::IsEditorProperty(IProperty *pProp)
|
||||
(pProp == mpRotation) ||
|
||||
(pProp == mpScale) ||
|
||||
(pProp == mpActive) ||
|
||||
(pProp == mpLightParameters) ||
|
||||
(pProp->Parent() == mpLightParameters)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user