Added experimental code for re-splitting world meshes in MP2/3/DKCR
This commit is contained in:
parent
29bf0234ec
commit
b71e1268fa
|
@ -74,17 +74,33 @@ void CAreaLoader::ReadGeometryPrime()
|
||||||
mBlockMgr->ToNextBlock();
|
mBlockMgr->ToNextBlock();
|
||||||
|
|
||||||
// Geometry
|
// Geometry
|
||||||
|
std::vector<CModel*> FileModels;
|
||||||
|
|
||||||
for (u32 m = 0; m < mNumMeshes; m++) {
|
for (u32 m = 0; m < mNumMeshes; m++) {
|
||||||
std::cout << "\rLoading mesh " << std::dec << m + 1 << "/" << mNumMeshes;
|
std::cout << "\rLoading mesh " << std::dec << m + 1 << "/" << mNumMeshes;
|
||||||
|
|
||||||
CModel *pTerrainModel = CModelLoader::LoadWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, mVersion);
|
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, mVersion);
|
||||||
mpArea->AddWorldModel(pTerrainModel);
|
FileModels.push_back(pModel);
|
||||||
|
|
||||||
|
if (mVersion <= ePrime)
|
||||||
|
mpArea->AddWorldModel(pModel);
|
||||||
|
|
||||||
if (mVersion >= eEchoes) {
|
if (mVersion >= eEchoes) {
|
||||||
mBlockMgr->ToNextBlock();
|
mBlockMgr->ToNextBlock();
|
||||||
mBlockMgr->ToNextBlock();
|
mBlockMgr->ToNextBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Split meshes
|
||||||
|
if (mVersion >= eEchoesDemo)
|
||||||
|
{
|
||||||
|
std::vector<CModel*> SplitModels;
|
||||||
|
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
||||||
|
|
||||||
|
for (u32 iMdl = 0; iMdl < SplitModels.size(); iMdl++)
|
||||||
|
mpArea->AddWorldModel(SplitModels[iMdl]);
|
||||||
|
}
|
||||||
|
|
||||||
mpArea->MergeTerrain();
|
mpArea->MergeTerrain();
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CModelLoader.h"
|
#include "CModelLoader.h"
|
||||||
#include "CMaterialLoader.h"
|
#include "CMaterialLoader.h"
|
||||||
#include "Core/Log.h"
|
#include "Core/Log.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
CModelLoader::CModelLoader()
|
CModelLoader::CModelLoader()
|
||||||
{
|
{
|
||||||
|
@ -236,7 +237,15 @@ void CModelLoader::LoadSurfaceHeaderPrime(IInputStream& Model, SSurface *pSurf)
|
||||||
Model.Seek(0xC, SEEK_CUR);
|
Model.Seek(0xC, SEEK_CUR);
|
||||||
u32 ExtraSize = Model.ReadLong();
|
u32 ExtraSize = Model.ReadLong();
|
||||||
pSurf->ReflectionDirection = CVector3f(Model);
|
pSurf->ReflectionDirection = CVector3f(Model);
|
||||||
if (mVersion >= eEchoesDemo) Model.Seek(0x4, SEEK_CUR); // Extra values in Echoes. Not sure what they are.
|
|
||||||
|
if (mVersion >= eEchoesDemo)
|
||||||
|
{
|
||||||
|
Model.Seek(0x2, SEEK_CUR); // Skipping unknown value
|
||||||
|
pSurf->MeshID = Model.ReadShort();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pSurf->MeshID = -1;
|
||||||
|
|
||||||
bool HasAABox = (ExtraSize >= 0x18); // MREAs have a set of bounding box coordinates here.
|
bool HasAABox = (ExtraSize >= 0x18); // MREAs have a set of bounding box coordinates here.
|
||||||
|
|
||||||
// If this surface has a bounding box, we can just read it here. Otherwise we'll fill it in manually.
|
// If this surface has a bounding box, we can just read it here. Otherwise we'll fill it in manually.
|
||||||
|
@ -555,6 +564,57 @@ CModel* CModelLoader::LoadCorruptionWorldModel(IInputStream &MREA, CBlockMgrIn &
|
||||||
return pModel;
|
return pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CModelLoader::BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vector<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.
|
||||||
|
std::map<u32, CModel*> OutputMap;
|
||||||
|
|
||||||
|
for (u32 iMdl = 0; iMdl < rkIn.size(); iMdl++)
|
||||||
|
{
|
||||||
|
CModel *pModel = rkIn[iMdl];
|
||||||
|
pModel->mHasOwnSurfaces = false;
|
||||||
|
pModel->mHasOwnMaterials = false;
|
||||||
|
|
||||||
|
for (u32 iSurf = 0; iSurf < pModel->mSurfaces.size(); iSurf++)
|
||||||
|
{
|
||||||
|
SSurface *pSurf = pModel->mSurfaces[iSurf];
|
||||||
|
u32 ID = (u32) pSurf->MeshID;
|
||||||
|
auto Iter = OutputMap.find(ID);
|
||||||
|
|
||||||
|
// No model for this ID; create one!
|
||||||
|
if (Iter == OutputMap.end())
|
||||||
|
{
|
||||||
|
CModel *pOutMdl = new CModel();
|
||||||
|
pOutMdl->mMaterialSets.resize(1);
|
||||||
|
pOutMdl->mMaterialSets[0] = pModel->mMaterialSets[0];
|
||||||
|
pOutMdl->mHasOwnMaterials = false;
|
||||||
|
pOutMdl->mSurfaces.push_back(pSurf);
|
||||||
|
pOutMdl->mHasOwnSurfaces = true;
|
||||||
|
pOutMdl->mVertexCount = pSurf->VertexCount;
|
||||||
|
pOutMdl->mTriangleCount = pSurf->TriangleCount;
|
||||||
|
pOutMdl->mAABox.ExpandBounds(pSurf->AABox);
|
||||||
|
|
||||||
|
OutputMap[ID] = pOutMdl;
|
||||||
|
rOut.push_back(pOutMdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing model; add this surface to it
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CModel *pOutMdl = Iter->second;
|
||||||
|
pOutMdl->mSurfaces.push_back(pSurf);
|
||||||
|
pOutMdl->mVertexCount += pSurf->VertexCount;
|
||||||
|
pOutMdl->mTriangleCount += pSurf->TriangleCount;
|
||||||
|
pOutMdl->mAABox.ExpandBounds(pSurf->AABox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done with this model, should we delete it?
|
||||||
|
if (DeleteInputModels)
|
||||||
|
delete pModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CModel* CModelLoader::ImportAssimpNode(const aiNode *pNode, const aiScene *pScene, CMaterialSet& matSet)
|
CModel* CModelLoader::ImportAssimpNode(const aiNode *pNode, const aiScene *pScene, CMaterialSet& matSet)
|
||||||
{
|
{
|
||||||
CModelLoader loader;
|
CModelLoader loader;
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
static CModel* LoadCMDL(IInputStream& CMDL);
|
static CModel* LoadCMDL(IInputStream& CMDL);
|
||||||
static CModel* LoadWorldModel(IInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, EGame Version);
|
static CModel* LoadWorldModel(IInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, EGame Version);
|
||||||
static CModel* LoadCorruptionWorldModel(IInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, u32 HeaderSecNum, u32 GPUSecNum, EGame Version);
|
static CModel* LoadCorruptionWorldModel(IInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, u32 HeaderSecNum, u32 GPUSecNum, EGame Version);
|
||||||
|
static void BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vector<CModel*>& rOut, bool DeleteInputModels);
|
||||||
static CModel* ImportAssimpNode(const aiNode *pNode, const aiScene *pScene, CMaterialSet& matSet);
|
static CModel* ImportAssimpNode(const aiNode *pNode, const aiScene *pScene, CMaterialSet& matSet);
|
||||||
static EGame GetFormatVersion(u32 Version);
|
static EGame GetFormatVersion(u32 Version);
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <Math/CVector3f.h>
|
#include <Math/CVector3f.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
// Should prolly be a class
|
||||||
struct SSurface
|
struct SSurface
|
||||||
{
|
{
|
||||||
u32 VertexCount;
|
u32 VertexCount;
|
||||||
|
@ -20,6 +21,7 @@ struct SSurface
|
||||||
CVector3f CenterPoint;
|
CVector3f CenterPoint;
|
||||||
u32 MaterialID;
|
u32 MaterialID;
|
||||||
CVector3f ReflectionDirection;
|
CVector3f ReflectionDirection;
|
||||||
|
u16 MeshID;
|
||||||
|
|
||||||
struct SPrimitive
|
struct SPrimitive
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue