mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 10:49:23 +00:00
Added support for EGMC and a basic EGMC visualizer dialog
This commit is contained in:
@@ -179,6 +179,11 @@ CLight* CGameArea::GetLight(u32 layer, u32 light)
|
||||
return mLightLayers[layer][light];
|
||||
}
|
||||
|
||||
CPoiToWorld* CGameArea::GetPoiToWorldMap()
|
||||
{
|
||||
return mpPoiToWorldMap;
|
||||
}
|
||||
|
||||
CAABox CGameArea::AABox()
|
||||
{
|
||||
return mAABox;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "CCollisionMeshGroup.h"
|
||||
#include "CLight.h"
|
||||
#include "CMaterialSet.h"
|
||||
#include "CPoiToWorld.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include "Core/Resource/Model/CStaticModel.h"
|
||||
#include <Common/types.h>
|
||||
@@ -40,6 +41,8 @@ class CGameArea : public CResource
|
||||
CCollisionMeshGroup *mCollision;
|
||||
// Lights
|
||||
std::vector<std::vector<CLight*>> mLightLayers;
|
||||
// Object to Static Geometry Map
|
||||
TResPtr<CPoiToWorld> mpPoiToWorldMap;
|
||||
|
||||
public:
|
||||
CGameArea();
|
||||
@@ -65,6 +68,7 @@ public:
|
||||
u32 GetLightLayerCount();
|
||||
u32 GetLightCount(u32 layer);
|
||||
CLight* GetLight(u32 layer, u32 light);
|
||||
CPoiToWorld* GetPoiToWorldMap();
|
||||
CAABox AABox();
|
||||
};
|
||||
|
||||
|
||||
27
src/Core/Resource/CPoiToWorld.cpp
Normal file
27
src/Core/Resource/CPoiToWorld.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "CPoiToWorld.h"
|
||||
|
||||
CPoiToWorld::CPoiToWorld()
|
||||
{
|
||||
}
|
||||
|
||||
CPoiToWorld::~CPoiToWorld()
|
||||
{
|
||||
}
|
||||
|
||||
void CPoiToWorld::LinksForMeshID(std::list<u32>& rOutInstanceIDs, u32 MeshID)
|
||||
{
|
||||
for (u32 iLink = 0; iLink < mMeshLinks.size(); iLink++)
|
||||
{
|
||||
if (mMeshLinks[iLink].MeshID == MeshID)
|
||||
rOutInstanceIDs.push_back(mMeshLinks[iLink].PoiInstanceID);
|
||||
}
|
||||
}
|
||||
|
||||
void CPoiToWorld::LinksForInstanceID(std::list<u32>& rOutMeshIDs, u32 InstanceID)
|
||||
{
|
||||
for (u32 iLink = 0; iLink < mMeshLinks.size(); iLink++)
|
||||
{
|
||||
if (mMeshLinks[iLink].PoiInstanceID == InstanceID)
|
||||
rOutMeshIDs.push_back(mMeshLinks[iLink].MeshID);
|
||||
}
|
||||
}
|
||||
40
src/Core/Resource/CPoiToWorld.h
Normal file
40
src/Core/Resource/CPoiToWorld.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef CPOITOWORLD_H
|
||||
#define CPOITOWORLD_H
|
||||
|
||||
#include "CResource.h"
|
||||
#include <list>
|
||||
|
||||
class CPoiToWorld : public CResource
|
||||
{
|
||||
DECLARE_RESOURCE_TYPE(ePoiToWorld)
|
||||
friend class CPoiToWorldLoader;
|
||||
|
||||
public:
|
||||
struct SPoiMeshLink
|
||||
{
|
||||
u32 MeshID;
|
||||
u32 PoiInstanceID;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<SPoiMeshLink> mMeshLinks;
|
||||
|
||||
public:
|
||||
CPoiToWorld();
|
||||
~CPoiToWorld();
|
||||
|
||||
void LinksForMeshID(std::list<u32>& rOutInstanceIDs, u32 MeshID);
|
||||
void LinksForInstanceID(std::list<u32>& rOutMeshIDs, u32 InstanceID);
|
||||
|
||||
inline u32 NumMeshLinks()
|
||||
{
|
||||
return mMeshLinks.size();
|
||||
}
|
||||
|
||||
inline const SPoiMeshLink& MeshLinkByIndex(u32 Index)
|
||||
{
|
||||
return mMeshLinks[Index];
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CPOITOWORLD_H
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Core/Resource/Factory/CCollisionLoader.h"
|
||||
#include "Core/Resource/Factory/CFontLoader.h"
|
||||
#include "Core/Resource/Factory/CModelLoader.h"
|
||||
#include "Core/Resource/Factory/CPoiToWorldLoader.h"
|
||||
#include "Core/Resource/Factory/CScanLoader.h"
|
||||
#include "Core/Resource/Factory/CStringLoader.h"
|
||||
#include "Core/Resource/Factory/CTextureDecoder.h"
|
||||
@@ -145,6 +146,7 @@ CResource* CResCache::GetResource(CUniqueID ResID, CFourCC type)
|
||||
else if (type == "FONT") Res = CFontLoader::LoadFONT(mem);
|
||||
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(mem);
|
||||
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(mem);
|
||||
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(mem);
|
||||
else SupportedFormat = false;
|
||||
|
||||
// Log errors
|
||||
@@ -197,6 +199,7 @@ CResource* CResCache::GetResource(const TString& ResPath)
|
||||
else if (type == "FONT") Res = CFontLoader::LoadFONT(file);
|
||||
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(file);
|
||||
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(file);
|
||||
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(file);
|
||||
else SupportedFormat = false;
|
||||
|
||||
if (!Res) Res = new CResource(); // Default for unsupported formats
|
||||
|
||||
@@ -33,18 +33,19 @@ enum EResType
|
||||
eParticle = 27,
|
||||
eParticleElectric = 28,
|
||||
eParticleSwoosh = 29,
|
||||
eProjectile = 30,
|
||||
eResource = 31,
|
||||
eSaveWorld = 32,
|
||||
eScan = 33,
|
||||
eSkeleton = 34,
|
||||
eSkin = 35,
|
||||
eStateMachine = 36,
|
||||
eStringTable = 37,
|
||||
eTexture = 38,
|
||||
eTweak = 39,
|
||||
eVideo = 40,
|
||||
eWorld = 41
|
||||
ePoiToWorld = 30,
|
||||
eProjectile = 31,
|
||||
eResource = 32,
|
||||
eSaveWorld = 33,
|
||||
eScan = 34,
|
||||
eSkeleton = 35,
|
||||
eSkin = 36,
|
||||
eStateMachine = 37,
|
||||
eStringTable = 38,
|
||||
eTexture = 39,
|
||||
eTweak = 40,
|
||||
eVideo = 41,
|
||||
eWorld = 42
|
||||
};
|
||||
|
||||
#endif // ERESTYPE
|
||||
|
||||
@@ -76,16 +76,25 @@ void CAreaLoader::ReadGeometryPrime()
|
||||
// Geometry
|
||||
std::vector<CModel*> FileModels;
|
||||
|
||||
for (u32 m = 0; m < mNumMeshes; m++) {
|
||||
std::cout << "\rLoading mesh " << std::dec << m + 1 << "/" << mNumMeshes;
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||
{
|
||||
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, mVersion);
|
||||
FileModels.push_back(pModel);
|
||||
|
||||
if (mVersion <= ePrime)
|
||||
mpArea->AddWorldModel(pModel);
|
||||
|
||||
if (mVersion >= eEchoes) {
|
||||
// For Echoes+, load surface mesh IDs, then skip to the start of the next mesh
|
||||
else
|
||||
{
|
||||
u16 NumSurfaces = mpMREA->ReadShort();
|
||||
|
||||
for (u32 iSurf = 0; iSurf < NumSurfaces; iSurf++)
|
||||
{
|
||||
mpMREA->Seek(0x2, SEEK_CUR);
|
||||
pModel->GetSurface(iSurf)->MeshID = mpMREA->ReadShort();
|
||||
}
|
||||
|
||||
mBlockMgr->ToNextBlock();
|
||||
mBlockMgr->ToNextBlock();
|
||||
}
|
||||
@@ -102,7 +111,6 @@ void CAreaLoader::ReadGeometryPrime()
|
||||
}
|
||||
|
||||
mpArea->MergeTerrain();
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void CAreaLoader::ReadSCLYPrime()
|
||||
@@ -341,22 +349,36 @@ void CAreaLoader::ReadGeometryCorruption()
|
||||
mBlockMgr->ToNextBlock();
|
||||
|
||||
// Geometry
|
||||
std::vector<CModel*> FileModels;
|
||||
u32 CurWOBJSection = 1;
|
||||
u32 CurGPUSection = mGPUBlockNum;
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||
{
|
||||
std::cout << "\rLoading mesh " << std::dec << iMesh + 1 << "/" << mNumMeshes;
|
||||
|
||||
CModel *pWorldModel = CModelLoader::LoadCorruptionWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, CurWOBJSection, CurGPUSection, mVersion);
|
||||
mpArea->AddWorldModel(pWorldModel);
|
||||
FileModels.push_back(pWorldModel);
|
||||
|
||||
CurWOBJSection += 4;
|
||||
CurGPUSection = mBlockMgr->CurrentBlock();
|
||||
|
||||
// Load surface mesh IDs
|
||||
mBlockMgr->ToBlock(CurWOBJSection - 2);
|
||||
u16 NumSurfaces = mpMREA->ReadShort();
|
||||
|
||||
for (u32 iSurf = 0; iSurf < NumSurfaces; iSurf++)
|
||||
{
|
||||
mpMREA->Seek(0x2, SEEK_CUR);
|
||||
pWorldModel->GetSurface(iSurf)->MeshID = mpMREA->ReadShort();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CModel*> SplitModels;
|
||||
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
||||
|
||||
for (u32 iMdl = 0; iMdl < SplitModels.size(); iMdl++)
|
||||
mpArea->AddWorldModel(SplitModels[iMdl]);
|
||||
|
||||
mpArea->MergeTerrain();
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void CAreaLoader::ReadLightsCorruption()
|
||||
@@ -511,6 +533,14 @@ void CAreaLoader::ReadCollision()
|
||||
mpArea->mCollision = CCollisionLoader::LoadAreaCollision(*mpMREA);
|
||||
}
|
||||
|
||||
void CAreaLoader::ReadEGMC()
|
||||
{
|
||||
Log::FileWrite(mpMREA->GetSourceString(), "Reading EGMC");
|
||||
mBlockMgr->ToBlock(mEGMCBlockNum);
|
||||
CUniqueID EGMC(*mpMREA, (mVersion <= eEchoes ? e32Bit : e64Bit));
|
||||
mpArea->mpPoiToWorldMap = gResCache.GetResource(EGMC, "EGMC");
|
||||
}
|
||||
|
||||
void CAreaLoader::SetUpObjects()
|
||||
{
|
||||
// Iterate over all objects
|
||||
@@ -598,6 +628,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||
Loader.ReadSCLYPrime();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eEchoes:
|
||||
Loader.ReadHeaderEchoes();
|
||||
@@ -605,6 +636,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eCorruptionProto:
|
||||
Loader.ReadHeaderCorruption();
|
||||
@@ -612,6 +644,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsCorruption();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eCorruption:
|
||||
case eReturns:
|
||||
@@ -619,7 +652,11 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||
Loader.ReadGeometryCorruption();
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
if (Loader.mVersion == eCorruption) Loader.ReadLightsCorruption();
|
||||
if (Loader.mVersion == eCorruption)
|
||||
{
|
||||
Loader.ReadLightsCorruption();
|
||||
Loader.ReadEGMC();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log::FileError(MREA.GetSourceString(), "Unsupported MREA version: " + TString::HexString(version));
|
||||
|
||||
@@ -75,6 +75,7 @@ class CAreaLoader
|
||||
void ReadCompressedBlocks();
|
||||
void Decompress();
|
||||
void ReadCollision();
|
||||
void ReadEGMC();
|
||||
void SetUpObjects();
|
||||
|
||||
public:
|
||||
|
||||
17
src/Core/Resource/Factory/CPoiToWorldLoader.cpp
Normal file
17
src/Core/Resource/Factory/CPoiToWorldLoader.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "CPoiToWorldLoader.h"
|
||||
|
||||
CPoiToWorld* CPoiToWorldLoader::LoadEGMC(IInputStream& rEGMC)
|
||||
{
|
||||
CPoiToWorld *pOut = new CPoiToWorld();
|
||||
u32 NumLinks = rEGMC.ReadLong();
|
||||
|
||||
for (u32 iLink = 0; iLink < NumLinks; iLink++)
|
||||
{
|
||||
CPoiToWorld::SPoiMeshLink Link;
|
||||
Link.MeshID = rEGMC.ReadLong();
|
||||
Link.PoiInstanceID = rEGMC.ReadLong();
|
||||
pOut->mMeshLinks.push_back(Link);
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
17
src/Core/Resource/Factory/CPoiToWorldLoader.h
Normal file
17
src/Core/Resource/Factory/CPoiToWorldLoader.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef CPOITOWORLDLOADER_H
|
||||
#define CPOITOWORLDLOADER_H
|
||||
|
||||
#include "Core/Resource/CPoiToWorld.h"
|
||||
#include "Core/Resource/TResPtr.h"
|
||||
|
||||
class CPoiToWorldLoader
|
||||
{
|
||||
TResPtr<CPoiToWorld> mpPoiToWorld;
|
||||
|
||||
CPoiToWorldLoader() {}
|
||||
|
||||
public:
|
||||
static CPoiToWorld* LoadEGMC(IInputStream& rEGMC);
|
||||
};
|
||||
|
||||
#endif // CPOITOWORLDLOADER_H
|
||||
Reference in New Issue
Block a user