mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-20 10:25:40 +00:00
Added support for editing and resaving EGMC files + improved its preview rendering
This commit is contained in:
@@ -184,7 +184,8 @@ HEADERS += \
|
||||
Scene/CSceneIterator.h \
|
||||
Resource/CResourceInfo.h \
|
||||
Resource/CPoiToWorld.h \
|
||||
Resource/Factory/CPoiToWorldLoader.h
|
||||
Resource/Factory/CPoiToWorldLoader.h \
|
||||
Resource/Cooker/CPoiToWorldCooker.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
@@ -272,4 +273,5 @@ SOURCES += \
|
||||
Scene/CScene.cpp \
|
||||
Scene/CSceneIterator.cpp \
|
||||
Resource/CPoiToWorld.cpp \
|
||||
Resource/Factory/CPoiToWorldLoader.cpp
|
||||
Resource/Factory/CPoiToWorldLoader.cpp \
|
||||
Resource/Cooker/CPoiToWorldCooker.cpp
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -10,6 +10,7 @@ CModelNode::CModelNode(CScene *pScene, CSceneNode *pParent, CModel *pModel) : CS
|
||||
mScale = CVector3f(1.f);
|
||||
mLightingEnabled = true;
|
||||
mForceAlphaOn = false;
|
||||
mEnableScanOverlay = false;
|
||||
mTintColor = CColor::skWhite;
|
||||
}
|
||||
|
||||
@@ -59,6 +60,18 @@ void CModelNode::Draw(FRenderOptions Options, int ComponentIndex, const SViewInf
|
||||
mpModel->Draw(Options, mActiveMatSet);
|
||||
else
|
||||
mpModel->DrawSurface(Options, ComponentIndex, mActiveMatSet);
|
||||
|
||||
if (mEnableScanOverlay)
|
||||
{
|
||||
CDrawUtil::UseColorShader(mScanOverlayColor);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ZERO);
|
||||
Options |= eNoMaterialSetup;
|
||||
|
||||
if (ComponentIndex < 0)
|
||||
mpModel->Draw(Options, 0);
|
||||
else
|
||||
mpModel->DrawSurface(Options, ComponentIndex, mActiveMatSet);
|
||||
}
|
||||
}
|
||||
|
||||
void CModelNode::DrawSelection()
|
||||
|
||||
@@ -11,6 +11,8 @@ class CModelNode : public CSceneNode
|
||||
bool mLightingEnabled;
|
||||
bool mForceAlphaOn;
|
||||
CColor mTintColor;
|
||||
bool mEnableScanOverlay;
|
||||
CColor mScanOverlayColor;
|
||||
|
||||
public:
|
||||
explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
|
||||
@@ -26,15 +28,17 @@ public:
|
||||
// Setters
|
||||
void SetModel(CModel *pModel);
|
||||
|
||||
inline void SetMatSet(u32 MatSet) { mActiveMatSet = MatSet; }
|
||||
inline void SetDynamicLighting(bool Enable) { mLightingEnabled = Enable; }
|
||||
inline void ForceAlphaEnabled(bool Enable) { mForceAlphaOn = Enable; }
|
||||
inline void SetTintColor(const CColor& rkTintColor) { mTintColor = rkTintColor; }
|
||||
inline void ClearTintColor() { mTintColor = CColor::skWhite; }
|
||||
inline CModel* Model() const { return mpModel; }
|
||||
inline u32 MatSet() const { return mActiveMatSet; }
|
||||
inline bool IsDynamicLightingEnabled() const { return mLightingEnabled; }
|
||||
inline u32 FindMeshID() const { return mpModel->GetSurface(0)->MeshID; }
|
||||
inline void SetMatSet(u32 MatSet) { mActiveMatSet = MatSet; }
|
||||
inline void SetDynamicLighting(bool Enable) { mLightingEnabled = Enable; }
|
||||
inline void ForceAlphaEnabled(bool Enable) { mForceAlphaOn = Enable; }
|
||||
inline void SetTintColor(const CColor& rkTintColor) { mTintColor = rkTintColor; }
|
||||
inline void ClearTintColor() { mTintColor = CColor::skWhite; }
|
||||
inline void SetScanOverlayEnabled(bool Enable) { mEnableScanOverlay = Enable; }
|
||||
inline void SetScanOverlayColor(const CColor& rkColor) { mScanOverlayColor = rkColor; }
|
||||
inline CModel* Model() const { return mpModel; }
|
||||
inline u32 MatSet() const { return mActiveMatSet; }
|
||||
inline bool IsDynamicLightingEnabled() const { return mLightingEnabled; }
|
||||
inline u32 FindMeshID() const { return mpModel->GetSurface(0)->MeshID; }
|
||||
};
|
||||
|
||||
#endif // CMODELNODE_H
|
||||
|
||||
Reference in New Issue
Block a user