mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 18:59:12 +00:00
Added support for editing and resaving EGMC files + improved its preview rendering
This commit is contained in:
@@ -6,22 +6,74 @@ CPoiToWorld::CPoiToWorld()
|
||||
|
||||
CPoiToWorld::~CPoiToWorld()
|
||||
{
|
||||
for (auto it = mMaps.begin(); it != mMaps.end(); it++)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
void CPoiToWorld::LinksForMeshID(std::list<u32>& rOutInstanceIDs, u32 MeshID)
|
||||
void CPoiToWorld::AddPoi(u32 PoiID)
|
||||
{
|
||||
for (u32 iLink = 0; iLink < mMeshLinks.size(); iLink++)
|
||||
// Check if this POI already exists
|
||||
auto it = mPoiLookupMap.find(PoiID);
|
||||
|
||||
if (it == mPoiLookupMap.end())
|
||||
{
|
||||
if (mMeshLinks[iLink].MeshID == MeshID)
|
||||
rOutInstanceIDs.push_back(mMeshLinks[iLink].PoiInstanceID);
|
||||
SPoiMap *pMap = new SPoiMap();
|
||||
pMap->PoiID = PoiID;
|
||||
|
||||
mMaps.push_back(pMap);
|
||||
mPoiLookupMap[PoiID] = pMap;
|
||||
}
|
||||
}
|
||||
|
||||
void CPoiToWorld::LinksForInstanceID(std::list<u32>& rOutMeshIDs, u32 InstanceID)
|
||||
void CPoiToWorld::AddPoiMeshMap(u32 PoiID, u32 ModelID)
|
||||
{
|
||||
for (u32 iLink = 0; iLink < mMeshLinks.size(); iLink++)
|
||||
// Make sure the POI exists; the add function won't do anything if it does
|
||||
AddPoi(PoiID);
|
||||
SPoiMap *pMap = mPoiLookupMap[PoiID];
|
||||
|
||||
// Check whether this model ID is already mapped to this POI
|
||||
for (auto it = pMap->ModelIDs.begin(); it != pMap->ModelIDs.end(); it++)
|
||||
{
|
||||
if (mMeshLinks[iLink].PoiInstanceID == InstanceID)
|
||||
rOutMeshIDs.push_back(mMeshLinks[iLink].MeshID);
|
||||
if (*it == ModelID)
|
||||
return;
|
||||
}
|
||||
|
||||
// We didn't return, so this is a new mapping
|
||||
pMap->ModelIDs.push_back(ModelID);
|
||||
}
|
||||
|
||||
void CPoiToWorld::RemovePoi(u32 PoiID)
|
||||
{
|
||||
for (auto it = mMaps.begin(); it != mMaps.end(); it++)
|
||||
{
|
||||
if ((*it)->PoiID == PoiID)
|
||||
{
|
||||
mMaps.erase(it);
|
||||
mPoiLookupMap.erase(PoiID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPoiToWorld::RemovePoiMeshMap(u32 PoiID, u32 ModelID)
|
||||
{
|
||||
auto MapIt = mPoiLookupMap.find(PoiID);
|
||||
|
||||
if (MapIt != mPoiLookupMap.end())
|
||||
{
|
||||
SPoiMap *pMap = MapIt->second;
|
||||
|
||||
for (auto ListIt = pMap->ModelIDs.begin(); ListIt != pMap->ModelIDs.end(); ListIt++)
|
||||
{
|
||||
if (*ListIt == ModelID)
|
||||
{
|
||||
pMap->ModelIDs.erase(ListIt);
|
||||
|
||||
if (pMap->ModelIDs.empty())
|
||||
RemovePoi(PoiID);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,37 +3,41 @@
|
||||
|
||||
#include "CResource.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class CPoiToWorld : public CResource
|
||||
{
|
||||
DECLARE_RESOURCE_TYPE(ePoiToWorld)
|
||||
friend class CPoiToWorldLoader;
|
||||
|
||||
public:
|
||||
struct SPoiMeshLink
|
||||
struct SPoiMap
|
||||
{
|
||||
u32 MeshID;
|
||||
u32 PoiInstanceID;
|
||||
u32 PoiID;
|
||||
std::list<u32> ModelIDs;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<SPoiMeshLink> mMeshLinks;
|
||||
std::vector<SPoiMap*> mMaps;
|
||||
std::map<u32,SPoiMap*> mPoiLookupMap;
|
||||
|
||||
public:
|
||||
CPoiToWorld();
|
||||
~CPoiToWorld();
|
||||
|
||||
void LinksForMeshID(std::list<u32>& rOutInstanceIDs, u32 MeshID);
|
||||
void LinksForInstanceID(std::list<u32>& rOutMeshIDs, u32 InstanceID);
|
||||
void AddPoi(u32 PoiID);
|
||||
void AddPoiMeshMap(u32 PoiID, u32 ModelID);
|
||||
void RemovePoi(u32 PoiID);
|
||||
void RemovePoiMeshMap(u32 PoiID, u32 ModelID);
|
||||
|
||||
inline u32 NumMeshLinks()
|
||||
inline u32 NumMappedPOIs() const
|
||||
{
|
||||
return mMeshLinks.size();
|
||||
return mMaps.size();
|
||||
}
|
||||
|
||||
inline const SPoiMeshLink& MeshLinkByIndex(u32 Index)
|
||||
inline const SPoiMap* MapByIndex(u32 Index) const
|
||||
{
|
||||
return mMeshLinks[Index];
|
||||
return mMaps[Index];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
36
src/Core/Resource/Cooker/CPoiToWorldCooker.cpp
Normal file
36
src/Core/Resource/Cooker/CPoiToWorldCooker.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "CPoiToWorldCooker.h"
|
||||
|
||||
void CPoiToWorldCooker::WriteEGMC(CPoiToWorld *pPoiToWorld, IOutputStream& rOut)
|
||||
{
|
||||
// Create mappings list
|
||||
struct SPoiMapping
|
||||
{
|
||||
u32 MeshID;
|
||||
u32 PoiID;
|
||||
};
|
||||
std::vector<SPoiMapping> Mappings;
|
||||
|
||||
for (u32 iPoi = 0; iPoi < pPoiToWorld->NumMappedPOIs(); iPoi++)
|
||||
{
|
||||
const CPoiToWorld::SPoiMap *kpMap = pPoiToWorld->MapByIndex(iPoi);
|
||||
|
||||
for (auto it = kpMap->ModelIDs.begin(); it != kpMap->ModelIDs.end(); it++)
|
||||
{
|
||||
SPoiMapping Mapping;
|
||||
Mapping.MeshID = *it;
|
||||
Mapping.PoiID = kpMap->PoiID;
|
||||
Mappings.push_back(Mapping);
|
||||
}
|
||||
}
|
||||
|
||||
// Write EGMC
|
||||
rOut.WriteLong(Mappings.size());
|
||||
|
||||
for (u32 iMap = 0; iMap < Mappings.size(); iMap++)
|
||||
{
|
||||
rOut.WriteLong(Mappings[iMap].MeshID);
|
||||
rOut.WriteLong(Mappings[iMap].PoiID);
|
||||
}
|
||||
|
||||
rOut.WriteToBoundary(32, -1);
|
||||
}
|
||||
14
src/Core/Resource/Cooker/CPoiToWorldCooker.h
Normal file
14
src/Core/Resource/Cooker/CPoiToWorldCooker.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef CPOITOWORLDCOOKER_H
|
||||
#define CPOITOWORLDCOOKER_H
|
||||
|
||||
#include "Core/Resource/CPoiToWorld.h"
|
||||
#include <FileIO/FileIO.h>
|
||||
|
||||
class CPoiToWorldCooker
|
||||
{
|
||||
CPoiToWorldCooker() {}
|
||||
public:
|
||||
static void WriteEGMC(CPoiToWorld *pPoiToWorld, IOutputStream& rOut);
|
||||
};
|
||||
|
||||
#endif // CPOITOWORLDCOOKER_H
|
||||
@@ -239,12 +239,7 @@ void CModelLoader::LoadSurfaceHeaderPrime(IInputStream& Model, SSurface *pSurf)
|
||||
pSurf->ReflectionDirection = CVector3f(Model);
|
||||
|
||||
if (mVersion >= eEchoesDemo)
|
||||
{
|
||||
Model.Seek(0x2, SEEK_CUR); // Skipping unknown value
|
||||
pSurf->MeshID = Model.ReadShort();
|
||||
}
|
||||
else
|
||||
pSurf->MeshID = -1;
|
||||
Model.Seek(0x4, SEEK_CUR); // Skipping unknown values
|
||||
|
||||
bool HasAABox = (ExtraSize >= 0x18); // MREAs have a set of bounding box coordinates here.
|
||||
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
CPoiToWorld* CPoiToWorldLoader::LoadEGMC(IInputStream& rEGMC)
|
||||
{
|
||||
CPoiToWorld *pOut = new CPoiToWorld();
|
||||
u32 NumLinks = rEGMC.ReadLong();
|
||||
u32 NumMappings = rEGMC.ReadLong();
|
||||
|
||||
for (u32 iLink = 0; iLink < NumLinks; iLink++)
|
||||
for (u32 iMap = 0; iMap < NumMappings; iMap++)
|
||||
{
|
||||
CPoiToWorld::SPoiMeshLink Link;
|
||||
Link.MeshID = rEGMC.ReadLong();
|
||||
Link.PoiInstanceID = rEGMC.ReadLong();
|
||||
pOut->mMeshLinks.push_back(Link);
|
||||
u32 MeshID = rEGMC.ReadLong();
|
||||
u32 InstanceID = rEGMC.ReadLong();
|
||||
pOut->AddPoiMeshMap(InstanceID, MeshID);
|
||||
}
|
||||
|
||||
return pOut;
|
||||
|
||||
Reference in New Issue
Block a user