mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-06-18 04:23:29 +00:00
CGameArea: Simplify allocation handling
Eliminates manual new/delete and also makes the lifecycle of allocations enforced within the interface.
This commit is contained in:
parent
674ae65e56
commit
12ccb2fbd4
@ -18,9 +18,6 @@ CGameArea::CGameArea(CResourceEntry *pEntry /*= 0*/)
|
|||||||
CGameArea::~CGameArea()
|
CGameArea::~CGameArea()
|
||||||
{
|
{
|
||||||
ClearTerrain();
|
ClearTerrain();
|
||||||
|
|
||||||
for (uint32 iSCLY = 0; iSCLY < mScriptLayers.size(); iSCLY++)
|
|
||||||
delete mScriptLayers[iSCLY];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CDependencyTree> CGameArea::BuildDependencyTree() const
|
std::unique_ptr<CDependencyTree> CGameArea::BuildDependencyTree() const
|
||||||
@ -52,18 +49,19 @@ std::unique_ptr<CDependencyTree> CGameArea::BuildDependencyTree() const
|
|||||||
for (uint32 iLayer = 0; iLayer < mScriptLayers.size(); iLayer++)
|
for (uint32 iLayer = 0; iLayer < mScriptLayers.size(); iLayer++)
|
||||||
{
|
{
|
||||||
const std::vector<CAssetID>& rkExtras = (mExtraLayerDeps.size() > iLayer ? mExtraLayerDeps[iLayer] : DummyDeps);
|
const std::vector<CAssetID>& rkExtras = (mExtraLayerDeps.size() > iLayer ? mExtraLayerDeps[iLayer] : DummyDeps);
|
||||||
pTree->AddScriptLayer(mScriptLayers[iLayer], rkExtras);
|
pTree->AddScriptLayer(mScriptLayers[iLayer].get(), rkExtras);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pTree;
|
return pTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameArea::AddWorldModel(CModel *pModel)
|
void CGameArea::AddWorldModel(std::unique_ptr<CModel>&& pModel)
|
||||||
{
|
{
|
||||||
mWorldModels.push_back(pModel);
|
|
||||||
mVertexCount += pModel->GetVertexCount();
|
mVertexCount += pModel->GetVertexCount();
|
||||||
mTriangleCount += pModel->GetTriangleCount();
|
mTriangleCount += pModel->GetTriangleCount();
|
||||||
mAABox.ExpandBounds(pModel->AABox());
|
mAABox.ExpandBounds(pModel->AABox());
|
||||||
|
|
||||||
|
mWorldModels.push_back(std::move(pModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameArea::MergeTerrain()
|
void CGameArea::MergeTerrain()
|
||||||
@ -73,7 +71,7 @@ void CGameArea::MergeTerrain()
|
|||||||
// Nothing really complicated here - iterate through every terrain submesh, add each to a static model
|
// Nothing really complicated here - iterate through every terrain submesh, add each to a static model
|
||||||
for (uint32 iMdl = 0; iMdl < mWorldModels.size(); iMdl++)
|
for (uint32 iMdl = 0; iMdl < mWorldModels.size(); iMdl++)
|
||||||
{
|
{
|
||||||
CModel *pMdl = mWorldModels[iMdl];
|
auto& pMdl = mWorldModels[iMdl];
|
||||||
uint32 SubmeshCount = pMdl->GetSurfaceCount();
|
uint32 SubmeshCount = pMdl->GetSurfaceCount();
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < SubmeshCount; iSurf++)
|
for (uint32 iSurf = 0; iSurf < SubmeshCount; iSurf++)
|
||||||
@ -82,7 +80,7 @@ void CGameArea::MergeTerrain()
|
|||||||
CMaterial *pMat = mpMaterialSet->MaterialByIndex(pSurf->MaterialID, false);
|
CMaterial *pMat = mpMaterialSet->MaterialByIndex(pSurf->MaterialID, false);
|
||||||
|
|
||||||
bool NewMat = true;
|
bool NewMat = true;
|
||||||
for (std::vector<CStaticModel*>::iterator it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++)
|
for (auto it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++)
|
||||||
{
|
{
|
||||||
if ((*it)->GetMaterial() == pMat)
|
if ((*it)->GetMaterial() == pMat)
|
||||||
{
|
{
|
||||||
@ -91,10 +89,10 @@ void CGameArea::MergeTerrain()
|
|||||||
// (particularly with multi-layered transparent meshes)
|
// (particularly with multi-layered transparent meshes)
|
||||||
// so we need to at least try to maintain it.
|
// so we need to at least try to maintain it.
|
||||||
// This is maybe not the most efficient way to do this, but it works.
|
// This is maybe not the most efficient way to do this, but it works.
|
||||||
CStaticModel *pStatic = *it;
|
auto pStatic = std::move(*it);
|
||||||
pStatic->AddSurface(pSurf);
|
pStatic->AddSurface(pSurf);
|
||||||
mStaticWorldModels.erase(it);
|
mStaticWorldModels.erase(it);
|
||||||
mStaticWorldModels.push_back(pStatic);
|
mStaticWorldModels.push_back(std::move(pStatic));
|
||||||
NewMat = false;
|
NewMat = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -102,9 +100,9 @@ void CGameArea::MergeTerrain()
|
|||||||
|
|
||||||
if (NewMat)
|
if (NewMat)
|
||||||
{
|
{
|
||||||
CStaticModel *pStatic = new CStaticModel(pMat);
|
auto pStatic = std::make_unique<CStaticModel>(pMat);
|
||||||
pStatic->AddSurface(pSurf);
|
pStatic->AddSurface(pSurf);
|
||||||
mStaticWorldModels.push_back(pStatic);
|
mStaticWorldModels.push_back(std::move(pStatic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,15 +110,11 @@ void CGameArea::MergeTerrain()
|
|||||||
|
|
||||||
void CGameArea::ClearTerrain()
|
void CGameArea::ClearTerrain()
|
||||||
{
|
{
|
||||||
for (uint32 iModel = 0; iModel < mWorldModels.size(); iModel++)
|
|
||||||
delete mWorldModels[iModel];
|
|
||||||
mWorldModels.clear();
|
mWorldModels.clear();
|
||||||
|
|
||||||
for (uint32 iStatic = 0; iStatic < mStaticWorldModels.size(); iStatic++)
|
|
||||||
delete mStaticWorldModels[iStatic];
|
|
||||||
mStaticWorldModels.clear();
|
mStaticWorldModels.clear();
|
||||||
|
|
||||||
if (mpMaterialSet) delete mpMaterialSet;
|
if (mpMaterialSet)
|
||||||
|
delete mpMaterialSet;
|
||||||
|
|
||||||
mVertexCount = 0;
|
mVertexCount = 0;
|
||||||
mTriangleCount = 0;
|
mTriangleCount = 0;
|
||||||
@ -130,8 +124,6 @@ void CGameArea::ClearTerrain()
|
|||||||
|
|
||||||
void CGameArea::ClearScriptLayers()
|
void CGameArea::ClearScriptLayers()
|
||||||
{
|
{
|
||||||
for (auto it = mScriptLayers.begin(); it != mScriptLayers.end(); it++)
|
|
||||||
delete *it;
|
|
||||||
mScriptLayers.clear();
|
mScriptLayers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
#include <Common/Math/CQuaternion.h>
|
#include <Common/Math/CQuaternion.h>
|
||||||
#include <Common/Math/CTransform4f.h>
|
#include <Common/Math/CTransform4f.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class CScriptLayer;
|
class CScriptLayer;
|
||||||
class CScriptObject;
|
class CScriptObject;
|
||||||
@ -45,10 +47,10 @@ class CGameArea : public CResource
|
|||||||
|
|
||||||
// Geometry
|
// Geometry
|
||||||
CMaterialSet *mpMaterialSet;
|
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<std::unique_ptr<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
|
std::vector<std::unique_ptr<CStaticModel>> mStaticWorldModels; // StaticTerrainModels is the merged terrain for faster rendering in the world editor
|
||||||
// Script
|
// Script
|
||||||
std::vector<CScriptLayer*> mScriptLayers;
|
std::vector<std::unique_ptr<CScriptLayer>> mScriptLayers;
|
||||||
std::unordered_map<uint32, CScriptObject*> mObjectMap;
|
std::unordered_map<uint32, CScriptObject*> mObjectMap;
|
||||||
// Collision
|
// Collision
|
||||||
std::unique_ptr<CCollisionMeshGroup> mpCollision;
|
std::unique_ptr<CCollisionMeshGroup> mpCollision;
|
||||||
@ -69,7 +71,7 @@ public:
|
|||||||
~CGameArea();
|
~CGameArea();
|
||||||
std::unique_ptr<CDependencyTree> BuildDependencyTree() const override;
|
std::unique_ptr<CDependencyTree> BuildDependencyTree() const override;
|
||||||
|
|
||||||
void AddWorldModel(CModel *pModel);
|
void AddWorldModel(std::unique_ptr<CModel>&& pModel);
|
||||||
void MergeTerrain();
|
void MergeTerrain();
|
||||||
void ClearTerrain();
|
void ClearTerrain();
|
||||||
void ClearScriptLayers();
|
void ClearScriptLayers();
|
||||||
@ -91,11 +93,11 @@ public:
|
|||||||
CMaterialSet* Materials() const { return mpMaterialSet; }
|
CMaterialSet* Materials() const { return mpMaterialSet; }
|
||||||
uint32 NumWorldModels() const { return mWorldModels.size(); }
|
uint32 NumWorldModels() const { return mWorldModels.size(); }
|
||||||
uint32 NumStaticModels() const { return mStaticWorldModels.size(); }
|
uint32 NumStaticModels() const { return mStaticWorldModels.size(); }
|
||||||
CModel* TerrainModel(uint32 iMdl) const { return mWorldModels[iMdl]; }
|
CModel* TerrainModel(uint32 iMdl) const { return mWorldModels[iMdl].get(); }
|
||||||
CStaticModel* StaticModel(uint32 iMdl) const { return mStaticWorldModels[iMdl]; }
|
CStaticModel* StaticModel(uint32 iMdl) const { return mStaticWorldModels[iMdl].get(); }
|
||||||
CCollisionMeshGroup* Collision() const { return mpCollision.get(); }
|
CCollisionMeshGroup* Collision() const { return mpCollision.get(); }
|
||||||
uint32 NumScriptLayers() const { return mScriptLayers.size(); }
|
uint32 NumScriptLayers() const { return mScriptLayers.size(); }
|
||||||
CScriptLayer* ScriptLayer(uint32 Index) const { return mScriptLayers[Index]; }
|
CScriptLayer* ScriptLayer(uint32 Index) const { return mScriptLayers[Index].get(); }
|
||||||
uint32 NumLightLayers() const { return mLightLayers.size(); }
|
uint32 NumLightLayers() const { return mLightLayers.size(); }
|
||||||
uint32 NumLights(uint32 LayerIndex) const { return (LayerIndex < mLightLayers.size() ? mLightLayers[LayerIndex].size() : 0); }
|
uint32 NumLights(uint32 LayerIndex) const { return (LayerIndex < mLightLayers.size() ? mLightLayers[LayerIndex].size() : 0); }
|
||||||
CLight* Light(uint32 LayerIndex, uint32 LightIndex) { return &mLightLayers[LayerIndex][LightIndex]; }
|
CLight* Light(uint32 LayerIndex, uint32 LightIndex) { return &mLightLayers[LayerIndex][LightIndex]; }
|
||||||
|
@ -191,7 +191,7 @@ void CAreaCooker::WritePrimeSCLY(IOutputStream& rOut)
|
|||||||
for (uint32 LayerIdx = 0; LayerIdx < NumLayers; LayerIdx++)
|
for (uint32 LayerIdx = 0; LayerIdx < NumLayers; LayerIdx++)
|
||||||
{
|
{
|
||||||
uint32 LayerStart = rOut.Tell();
|
uint32 LayerStart = rOut.Tell();
|
||||||
ScriptCooker.WriteLayer(rOut, mpArea->mScriptLayers[LayerIdx]);
|
ScriptCooker.WriteLayer(rOut, mpArea->mScriptLayers[LayerIdx].get());
|
||||||
|
|
||||||
// Pad the layer to 32 bytes
|
// Pad the layer to 32 bytes
|
||||||
uint32 LayerSize = rOut.Tell() - LayerStart;
|
uint32 LayerSize = rOut.Tell() - LayerStart;
|
||||||
@ -233,7 +233,7 @@ void CAreaCooker::WriteEchoesSCLY(IOutputStream& rOut)
|
|||||||
rOut.WriteFourCC( FOURCC('SCLY') );
|
rOut.WriteFourCC( FOURCC('SCLY') );
|
||||||
rOut.WriteByte(1);
|
rOut.WriteByte(1);
|
||||||
rOut.WriteLong(LayerIdx);
|
rOut.WriteLong(LayerIdx);
|
||||||
ScriptCooker.WriteLayer(rOut, mpArea->mScriptLayers[LayerIdx]);
|
ScriptCooker.WriteLayer(rOut, mpArea->mScriptLayers[LayerIdx].get());
|
||||||
FinishSection(true);
|
FinishSection(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,20 +75,18 @@ void CAreaLoader::ReadGeometryPrime()
|
|||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
|
||||||
// Geometry
|
// Geometry
|
||||||
std::vector<CModel*> FileModels;
|
std::vector<std::unique_ptr<CModel>> FileModels;
|
||||||
|
|
||||||
for (uint32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
for (uint32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||||
{
|
{
|
||||||
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, mVersion);
|
|
||||||
FileModels.push_back(pModel);
|
|
||||||
|
|
||||||
if (mVersion <= EGame::Prime)
|
if (mVersion <= EGame::Prime)
|
||||||
mpArea->AddWorldModel(pModel);
|
|
||||||
|
|
||||||
// For Echoes+, load surface mesh IDs, then skip to the start of the next mesh
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
uint16 NumSurfaces = mpMREA->ReadShort();
|
mpArea->AddWorldModel(CModelLoader::LoadWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, mVersion));
|
||||||
|
}
|
||||||
|
else // For Echoes+, load surface mesh IDs, then skip to the start of the next mesh
|
||||||
|
{
|
||||||
|
auto& pModel = FileModels.emplace_back(CModelLoader::LoadWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, mVersion));
|
||||||
|
const uint16 NumSurfaces = mpMREA->ReadShort();
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < NumSurfaces; iSurf++)
|
for (uint32 iSurf = 0; iSurf < NumSurfaces; iSurf++)
|
||||||
{
|
{
|
||||||
@ -104,11 +102,11 @@ void CAreaLoader::ReadGeometryPrime()
|
|||||||
// Split meshes
|
// Split meshes
|
||||||
if (mVersion >= EGame::EchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
std::vector<CModel*> SplitModels;
|
std::vector<std::unique_ptr<CModel>> SplitModels;
|
||||||
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
||||||
|
|
||||||
for (uint32 iMdl = 0; iMdl < SplitModels.size(); iMdl++)
|
for (auto& model : SplitModels)
|
||||||
mpArea->AddWorldModel(SplitModels[iMdl]);
|
mpArea->AddWorldModel(std::move(model));
|
||||||
}
|
}
|
||||||
|
|
||||||
mpArea->MergeTerrain();
|
mpArea->MergeTerrain();
|
||||||
@ -144,7 +142,7 @@ void CAreaLoader::ReadSCLYPrime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SCGN
|
// SCGN
|
||||||
CScriptLayer *pGenLayer = nullptr;
|
std::unique_ptr<CScriptLayer> pGenLayer;
|
||||||
|
|
||||||
if (mVersion >= EGame::EchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
@ -152,8 +150,9 @@ void CAreaLoader::ReadSCLYPrime()
|
|||||||
CFourCC SCGN = mpMREA->ReadFourCC();
|
CFourCC SCGN = mpMREA->ReadFourCC();
|
||||||
|
|
||||||
if (SCGN != FOURCC('SCGN'))
|
if (SCGN != FOURCC('SCGN'))
|
||||||
|
{
|
||||||
errorf("%s [0x%X]: Invalid SCGN magic: %s", *mpMREA->GetSourceString(), mpMREA->Tell() - 4, *SCGN.ToString());
|
errorf("%s [0x%X]: Invalid SCGN magic: %s", *mpMREA->GetSourceString(), mpMREA->Tell() - 4, *SCGN.ToString());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mpMREA->Seek(0x1, SEEK_CUR);
|
mpMREA->Seek(0x1, SEEK_CUR);
|
||||||
@ -161,8 +160,7 @@ void CAreaLoader::ReadSCLYPrime()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetUpObjects(pGenLayer);
|
SetUpObjects(pGenLayer.get());
|
||||||
delete pGenLayer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAreaLoader::ReadLightsPrime()
|
void CAreaLoader::ReadLightsPrime()
|
||||||
@ -316,9 +314,8 @@ void CAreaLoader::ReadSCLYEchoes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
mpMREA->Seek(0x1, SEEK_CUR); // Skipping unknown
|
mpMREA->Seek(0x1, SEEK_CUR); // Skipping unknown
|
||||||
CScriptLayer *pGeneratedLayer = CScriptLoader::LoadLayer(*mpMREA, mpArea, mVersion);
|
const auto pGeneratedLayer = CScriptLoader::LoadLayer(*mpMREA, mpArea, mVersion);
|
||||||
SetUpObjects(pGeneratedLayer);
|
SetUpObjects(pGeneratedLayer.get());
|
||||||
delete pGeneratedLayer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CORRUPTION ************
|
// ************ CORRUPTION ************
|
||||||
@ -381,14 +378,13 @@ void CAreaLoader::ReadGeometryCorruption()
|
|||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
|
||||||
// Geometry
|
// Geometry
|
||||||
std::vector<CModel*> FileModels;
|
std::vector<std::unique_ptr<CModel>> FileModels;
|
||||||
uint32 CurWOBJSection = 1;
|
uint32 CurWOBJSection = 1;
|
||||||
uint32 CurGPUSection = mGPUBlockNum;
|
uint32 CurGPUSection = mGPUBlockNum;
|
||||||
|
|
||||||
for (uint32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
for (uint32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||||
{
|
{
|
||||||
CModel *pWorldModel = CModelLoader::LoadCorruptionWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, CurWOBJSection, CurGPUSection, mVersion);
|
auto& pWorldModel = FileModels.emplace_back(CModelLoader::LoadCorruptionWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, CurWOBJSection, CurGPUSection, mVersion));
|
||||||
FileModels.push_back(pWorldModel);
|
|
||||||
|
|
||||||
CurWOBJSection += 4;
|
CurWOBJSection += 4;
|
||||||
CurGPUSection = mpSectionMgr->CurrentSection();
|
CurGPUSection = mpSectionMgr->CurrentSection();
|
||||||
@ -404,11 +400,11 @@ void CAreaLoader::ReadGeometryCorruption()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CModel*> SplitModels;
|
std::vector<std::unique_ptr<CModel>> SplitModels;
|
||||||
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
||||||
|
|
||||||
for (uint32 iMdl = 0; iMdl < SplitModels.size(); iMdl++)
|
for (auto& model : SplitModels)
|
||||||
mpArea->AddWorldModel(SplitModels[iMdl]);
|
mpArea->AddWorldModel(std::move(model));
|
||||||
|
|
||||||
mpArea->MergeTerrain();
|
mpArea->MergeTerrain();
|
||||||
}
|
}
|
||||||
@ -648,7 +644,7 @@ void CAreaLoader::SetUpObjects(CScriptLayer *pGenLayer)
|
|||||||
// Create instance map
|
// Create instance map
|
||||||
for (uint32 LayerIdx = 0; LayerIdx < mpArea->NumScriptLayers(); LayerIdx++)
|
for (uint32 LayerIdx = 0; LayerIdx < mpArea->NumScriptLayers(); LayerIdx++)
|
||||||
{
|
{
|
||||||
CScriptLayer *pLayer = mpArea->mScriptLayers[LayerIdx];
|
auto& pLayer = mpArea->mScriptLayers[LayerIdx];
|
||||||
|
|
||||||
for (uint32 InstIdx = 0; InstIdx < pLayer->NumInstances(); InstIdx++)
|
for (uint32 InstIdx = 0; InstIdx < pLayer->NumInstances(); InstIdx++)
|
||||||
{
|
{
|
||||||
|
@ -494,7 +494,7 @@ std::unique_ptr<CModel> CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEnt
|
|||||||
return pModel;
|
return pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
CModel* CModelLoader::LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, EGame Version)
|
std::unique_ptr<CModel> CModelLoader::LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, EGame Version)
|
||||||
{
|
{
|
||||||
CModelLoader Loader;
|
CModelLoader Loader;
|
||||||
Loader.mpSectionMgr = &rBlockMgr;
|
Loader.mpSectionMgr = &rBlockMgr;
|
||||||
@ -508,7 +508,7 @@ CModel* CModelLoader::LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockM
|
|||||||
Loader.LoadAttribArrays(rMREA);
|
Loader.LoadAttribArrays(rMREA);
|
||||||
Loader.LoadSurfaceOffsets(rMREA);
|
Loader.LoadSurfaceOffsets(rMREA);
|
||||||
|
|
||||||
CModel *pModel = new CModel();
|
auto pModel = std::make_unique<CModel>();
|
||||||
pModel->mMaterialSets.resize(1);
|
pModel->mMaterialSets.resize(1);
|
||||||
pModel->mMaterialSets[0] = &rMatSet;
|
pModel->mMaterialSets[0] = &rMatSet;
|
||||||
pModel->mHasOwnMaterials = false;
|
pModel->mHasOwnMaterials = false;
|
||||||
@ -527,7 +527,7 @@ CModel* CModelLoader::LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockM
|
|||||||
return pModel;
|
return pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
CModel* CModelLoader::LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, uint32 HeaderSecNum, uint32 GPUSecNum, EGame Version)
|
std::unique_ptr<CModel> CModelLoader::LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, uint32 HeaderSecNum, uint32 GPUSecNum, EGame Version)
|
||||||
{
|
{
|
||||||
CModelLoader Loader;
|
CModelLoader Loader;
|
||||||
Loader.mpSectionMgr = &rBlockMgr;
|
Loader.mpSectionMgr = &rBlockMgr;
|
||||||
@ -535,7 +535,8 @@ CModel* CModelLoader::LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrI
|
|||||||
Loader.mFlags = EModelLoaderFlag::HalfPrecisionNormals;
|
Loader.mFlags = EModelLoaderFlag::HalfPrecisionNormals;
|
||||||
Loader.mMaterials.resize(1);
|
Loader.mMaterials.resize(1);
|
||||||
Loader.mMaterials[0] = &rMatSet;
|
Loader.mMaterials[0] = &rMatSet;
|
||||||
if (Version == EGame::DKCReturns) Loader.mFlags |= EModelLoaderFlag::LightmapUVs;
|
if (Version == EGame::DKCReturns)
|
||||||
|
Loader.mFlags |= EModelLoaderFlag::LightmapUVs;
|
||||||
|
|
||||||
// Corruption/DKCR MREAs split the mesh header and surface offsets away from the actual geometry data so I need two section numbers to read it
|
// Corruption/DKCR MREAs split the mesh header and surface offsets away from the actual geometry data so I need two section numbers to read it
|
||||||
rBlockMgr.ToSection(HeaderSecNum);
|
rBlockMgr.ToSection(HeaderSecNum);
|
||||||
@ -544,7 +545,7 @@ CModel* CModelLoader::LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrI
|
|||||||
rBlockMgr.ToSection(GPUSecNum);
|
rBlockMgr.ToSection(GPUSecNum);
|
||||||
Loader.LoadAttribArrays(rMREA);
|
Loader.LoadAttribArrays(rMREA);
|
||||||
|
|
||||||
CModel *pModel = new CModel();
|
auto pModel = std::make_unique<CModel>();
|
||||||
pModel->mMaterialSets.resize(1);
|
pModel->mMaterialSets.resize(1);
|
||||||
pModel->mMaterialSets[0] = &rMatSet;
|
pModel->mMaterialSets[0] = &rMatSet;
|
||||||
pModel->mHasOwnMaterials = false;
|
pModel->mHasOwnMaterials = false;
|
||||||
@ -563,14 +564,14 @@ CModel* CModelLoader::LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrI
|
|||||||
return pModel;
|
return pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelLoader::BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vector<CModel*>& rOut, bool DeleteInputModels)
|
void CModelLoader::BuildWorldMeshes(std::vector<std::unique_ptr<CModel>>& rkIn, std::vector<std::unique_ptr<CModel>>& rOut, bool DeleteInputModels)
|
||||||
{
|
{
|
||||||
// This function takes the gigantic models with all surfaces combined from MP2/3/DKCR and splits the surfaces to reform the original uncombined meshes.
|
// This function takes the gigantic models with all surfaces combined from MP2/3/DKCR and splits the surfaces to reform the original uncombined meshes.
|
||||||
std::map<uint32, CModel*> OutputMap;
|
std::map<uint32, CModel*> OutputMap;
|
||||||
|
|
||||||
for (uint32 iMdl = 0; iMdl < rkIn.size(); iMdl++)
|
for (uint32 iMdl = 0; iMdl < rkIn.size(); iMdl++)
|
||||||
{
|
{
|
||||||
CModel *pModel = rkIn[iMdl];
|
auto& pModel = rkIn[iMdl];
|
||||||
pModel->mHasOwnSurfaces = false;
|
pModel->mHasOwnSurfaces = false;
|
||||||
pModel->mHasOwnMaterials = false;
|
pModel->mHasOwnMaterials = false;
|
||||||
|
|
||||||
@ -583,7 +584,7 @@ void CModelLoader::BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vecto
|
|||||||
// No model for this ID; create one!
|
// No model for this ID; create one!
|
||||||
if (Iter == OutputMap.end())
|
if (Iter == OutputMap.end())
|
||||||
{
|
{
|
||||||
CModel *pOutMdl = new CModel();
|
auto pOutMdl = std::make_unique<CModel>();
|
||||||
pOutMdl->mMaterialSets.resize(1);
|
pOutMdl->mMaterialSets.resize(1);
|
||||||
pOutMdl->mMaterialSets[0] = pModel->mMaterialSets[0];
|
pOutMdl->mMaterialSets[0] = pModel->mMaterialSets[0];
|
||||||
pOutMdl->mHasOwnMaterials = false;
|
pOutMdl->mHasOwnMaterials = false;
|
||||||
@ -593,12 +594,10 @@ void CModelLoader::BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vecto
|
|||||||
pOutMdl->mTriangleCount = pSurf->TriangleCount;
|
pOutMdl->mTriangleCount = pSurf->TriangleCount;
|
||||||
pOutMdl->mAABox.ExpandBounds(pSurf->AABox);
|
pOutMdl->mAABox.ExpandBounds(pSurf->AABox);
|
||||||
|
|
||||||
OutputMap[ID] = pOutMdl;
|
OutputMap.insert_or_assign(ID, pOutMdl.get());
|
||||||
rOut.push_back(pOutMdl);
|
rOut.push_back(std::move(pOutMdl));
|
||||||
}
|
}
|
||||||
|
else // Existing model; add this surface to it
|
||||||
// Existing model; add this surface to it
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
CModel *pOutMdl = Iter->second;
|
CModel *pOutMdl = Iter->second;
|
||||||
pOutMdl->mSurfaces.push_back(pSurf);
|
pOutMdl->mSurfaces.push_back(pSurf);
|
||||||
@ -610,7 +609,7 @@ void CModelLoader::BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vecto
|
|||||||
|
|
||||||
// Done with this model, should we delete it?
|
// Done with this model, should we delete it?
|
||||||
if (DeleteInputModels)
|
if (DeleteInputModels)
|
||||||
delete pModel;
|
pModel.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class CMaterialSet;
|
||||||
|
class CResourceEntry;
|
||||||
|
class IInputStream;
|
||||||
|
enum class EGame;
|
||||||
|
struct SSurface;
|
||||||
|
|
||||||
enum class EModelLoaderFlag
|
enum class EModelLoaderFlag
|
||||||
{
|
{
|
||||||
None = 0x0,
|
None = 0x0,
|
||||||
@ -59,9 +65,9 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<CModel> LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry);
|
static std::unique_ptr<CModel> LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry);
|
||||||
static CModel* LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, EGame Version);
|
static std::unique_ptr<CModel> LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, EGame Version);
|
||||||
static CModel* LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, uint32 HeaderSecNum, uint32 GPUSecNum, EGame Version);
|
static std::unique_ptr<CModel> LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, uint32 HeaderSecNum, uint32 GPUSecNum, EGame Version);
|
||||||
static void BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vector<CModel*>& rOut, bool DeleteInputModels);
|
static void BuildWorldMeshes(std::vector<std::unique_ptr<CModel>>& rkIn, std::vector<std::unique_ptr<CModel>>& rOut, bool DeleteInputModels);
|
||||||
static CModel* ImportAssimpNode(const aiNode *pkNode, const aiScene *pkScene, CMaterialSet& rMatSet);
|
static CModel* ImportAssimpNode(const aiNode *pkNode, const aiScene *pkScene, CMaterialSet& rMatSet);
|
||||||
static EGame GetFormatVersion(uint32 Version);
|
static EGame GetFormatVersion(uint32 Version);
|
||||||
};
|
};
|
||||||
|
@ -338,14 +338,16 @@ CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& rSCLY)
|
|||||||
return mpObj;
|
return mpObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream& rSCLY)
|
std::unique_ptr<CScriptLayer> CScriptLoader::LoadLayerMP1(IInputStream& rSCLY)
|
||||||
{
|
{
|
||||||
uint32 LayerStart = rSCLY.Tell();
|
uint32 LayerStart = rSCLY.Tell();
|
||||||
|
|
||||||
rSCLY.Seek(0x1, SEEK_CUR); // One unknown byte at the start of each layer
|
rSCLY.Seek(0x1, SEEK_CUR); // One unknown byte at the start of each layer
|
||||||
uint32 NumObjects = rSCLY.ReadLong();
|
uint32 NumObjects = rSCLY.ReadLong();
|
||||||
|
|
||||||
mpLayer = new CScriptLayer(mpArea);
|
auto layer = std::make_unique<CScriptLayer>(mpArea);
|
||||||
|
|
||||||
|
mpLayer = layer.get();
|
||||||
mpLayer->Reserve(NumObjects);
|
mpLayer->Reserve(NumObjects);
|
||||||
|
|
||||||
for (uint32 ObjectIndex = 0; ObjectIndex < NumObjects; ObjectIndex++)
|
for (uint32 ObjectIndex = 0; ObjectIndex < NumObjects; ObjectIndex++)
|
||||||
@ -358,7 +360,8 @@ CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream& rSCLY)
|
|||||||
// Layer sizes are always a multiple of 32 - skip end padding before returning
|
// Layer sizes are always a multiple of 32 - skip end padding before returning
|
||||||
uint32 Remaining = 32 - ((rSCLY.Tell() - LayerStart) & 0x1F);
|
uint32 Remaining = 32 - ((rSCLY.Tell() - LayerStart) & 0x1F);
|
||||||
rSCLY.Seek(Remaining, SEEK_CUR);
|
rSCLY.Seek(Remaining, SEEK_CUR);
|
||||||
return mpLayer;
|
|
||||||
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptLoader::LoadStructMP2(IInputStream& rSCLY, CStructProperty* pStruct)
|
void CScriptLoader::LoadStructMP2(IInputStream& rSCLY, CStructProperty* pStruct)
|
||||||
@ -444,12 +447,14 @@ CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& rSCLY)
|
|||||||
return mpObj;
|
return mpObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& rSCLY)
|
std::unique_ptr<CScriptLayer> CScriptLoader::LoadLayerMP2(IInputStream& rSCLY)
|
||||||
{
|
{
|
||||||
rSCLY.Seek(0x1, SEEK_CUR); // Skipping version. todo: verify this?
|
rSCLY.Seek(0x1, SEEK_CUR); // Skipping version. todo: verify this?
|
||||||
uint32 NumObjects = rSCLY.ReadLong();
|
uint32 NumObjects = rSCLY.ReadLong();
|
||||||
|
|
||||||
mpLayer = new CScriptLayer(mpArea);
|
auto layer = std::make_unique<CScriptLayer>(mpArea);
|
||||||
|
|
||||||
|
mpLayer = layer.get();
|
||||||
mpLayer->Reserve(NumObjects);
|
mpLayer->Reserve(NumObjects);
|
||||||
|
|
||||||
for (uint32 ObjectIdx = 0; ObjectIdx < NumObjects; ObjectIdx++)
|
for (uint32 ObjectIdx = 0; ObjectIdx < NumObjects; ObjectIdx++)
|
||||||
@ -459,13 +464,14 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& rSCLY)
|
|||||||
mpLayer->AddInstance(pObject);
|
mpLayer->AddInstance(pObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mpLayer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CScriptLayer* CScriptLoader::LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version)
|
std::unique_ptr<CScriptLayer> CScriptLoader::LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version)
|
||||||
{
|
{
|
||||||
if (!rSCLY.IsValid()) return nullptr;
|
if (!rSCLY.IsValid())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
CScriptLoader Loader;
|
CScriptLoader Loader;
|
||||||
Loader.mVersion = Version;
|
Loader.mVersion = Version;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "Core/Resource/Script/CScriptObject.h"
|
#include "Core/Resource/Script/CScriptObject.h"
|
||||||
#include "Core/Resource/Script/CScriptLayer.h"
|
#include "Core/Resource/Script/CScriptLayer.h"
|
||||||
#include "Core/Resource/Script/CGameTemplate.h"
|
#include "Core/Resource/Script/CGameTemplate.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class CScriptLoader
|
class CScriptLoader
|
||||||
{
|
{
|
||||||
@ -23,14 +24,14 @@ class CScriptLoader
|
|||||||
|
|
||||||
void LoadStructMP1(IInputStream& rSCLY, CStructProperty* pStruct);
|
void LoadStructMP1(IInputStream& rSCLY, CStructProperty* pStruct);
|
||||||
CScriptObject* LoadObjectMP1(IInputStream& rSCLY);
|
CScriptObject* LoadObjectMP1(IInputStream& rSCLY);
|
||||||
CScriptLayer* LoadLayerMP1(IInputStream& rSCLY);
|
std::unique_ptr<CScriptLayer> LoadLayerMP1(IInputStream& rSCLY);
|
||||||
|
|
||||||
void LoadStructMP2(IInputStream& rSCLY, CStructProperty* pStruct);
|
void LoadStructMP2(IInputStream& rSCLY, CStructProperty* pStruct);
|
||||||
CScriptObject* LoadObjectMP2(IInputStream& rSCLY);
|
CScriptObject* LoadObjectMP2(IInputStream& rSCLY);
|
||||||
CScriptLayer* LoadLayerMP2(IInputStream& rSCLY);
|
std::unique_ptr<CScriptLayer> LoadLayerMP2(IInputStream& rSCLY);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CScriptLayer* LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version);
|
static std::unique_ptr<CScriptLayer> LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version);
|
||||||
static CScriptObject* LoadInstance(IInputStream& rSCLY, CGameArea *pArea, CScriptLayer *pLayer, EGame Version, bool ForceReturnsFormat);
|
static CScriptObject* LoadInstance(IInputStream& rSCLY, CGameArea *pArea, CScriptLayer *pLayer, EGame Version, bool ForceReturnsFormat);
|
||||||
static void LoadStructData(IInputStream& rInput, CStructRef InStruct);
|
static void LoadStructData(IInputStream& rInput, CStructRef InStruct);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user