Added support for EGMC and a basic EGMC visualizer dialog

This commit is contained in:
parax0
2016-01-15 16:36:58 -07:00
parent b71e1268fa
commit c0b74c9883
35 changed files with 763 additions and 101 deletions

View File

@@ -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;

View File

@@ -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();
};

View 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);
}
}

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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));

View File

@@ -75,6 +75,7 @@ class CAreaLoader
void ReadCompressedBlocks();
void Decompress();
void ReadCollision();
void ReadEGMC();
void SetUpObjects();
public:

View 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;
}

View 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