CVertex: Make use of std::array where applicable
Allows dehardcoding sizes and simplifies comparison code.
This commit is contained in:
parent
a17d43a87d
commit
3d1ced47e2
|
@ -3,11 +3,8 @@
|
||||||
#include "CSectionMgrOut.h"
|
#include "CSectionMgrOut.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
CModelCooker::CModelCooker()
|
CModelCooker::CModelCooker() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModelCooker::GenerateSurfaceData()
|
void CModelCooker::GenerateSurfaceData()
|
||||||
{
|
{
|
||||||
|
@ -71,7 +68,7 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
rOut.WriteLong(NumSections);
|
rOut.WriteLong(NumSections);
|
||||||
rOut.WriteLong(mNumMatSets);
|
rOut.WriteLong(mNumMatSets);
|
||||||
|
|
||||||
uint32 SectionSizesOffset = rOut.Tell();
|
const uint32 SectionSizesOffset = rOut.Tell();
|
||||||
for (uint32 iSec = 0; iSec < NumSections; iSec++)
|
for (uint32 iSec = 0; iSec < NumSections; iSec++)
|
||||||
rOut.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
|
|
||||||
|
@ -85,7 +82,7 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
SectionMgr.Init(rOut);
|
SectionMgr.Init(rOut);
|
||||||
|
|
||||||
// Materials
|
// Materials
|
||||||
for (uint32 iSet = 0; iSet < mNumMatSets; iSet++)
|
for (size_t iSet = 0; iSet < mNumMatSets; iSet++)
|
||||||
{
|
{
|
||||||
CMaterialCooker::WriteCookedMatSet(mpModel->mMaterialSets[iSet], mVersion, rOut);
|
CMaterialCooker::WriteCookedMatSet(mpModel->mMaterialSets[iSet], mVersion, rOut);
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
|
@ -93,34 +90,34 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertices
|
// Vertices
|
||||||
for (uint32 iPos = 0; iPos < mNumVertices; iPos++)
|
for (size_t iPos = 0; iPos < mNumVertices; iPos++)
|
||||||
mVertices[iPos].Position.Write(rOut);
|
mVertices[iPos].Position.Write(rOut);
|
||||||
|
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(rOut);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
for (uint32 iNrm = 0; iNrm < mNumVertices; iNrm++)
|
for (size_t iNrm = 0; iNrm < mNumVertices; iNrm++)
|
||||||
mVertices[iNrm].Normal.Write(rOut);
|
mVertices[iNrm].Normal.Write(rOut);
|
||||||
|
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(rOut);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
for (uint32 iColor = 0; iColor < mNumVertices; iColor++)
|
for (size_t iColor = 0; iColor < mNumVertices; iColor++)
|
||||||
mVertices[iColor].Color[0].Write(rOut);
|
mVertices[iColor].Color[0].Write(rOut);
|
||||||
|
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(rOut);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Float UV coordinates
|
// Float UV coordinates
|
||||||
for (uint32 iTexSlot = 0; iTexSlot < 8; iTexSlot++)
|
for (size_t iTexSlot = 0; iTexSlot < 8; iTexSlot++)
|
||||||
{
|
{
|
||||||
uint TexSlotBit = ((uint) (EVertexAttribute::Tex0)) << iTexSlot;
|
const auto TexSlotBit = static_cast<uint32>(EVertexAttribute::Tex0 << iTexSlot);
|
||||||
bool HasTexSlot = (mVtxAttribs & TexSlotBit) != 0;
|
const bool HasTexSlot = (mVtxAttribs & TexSlotBit) != 0;
|
||||||
if (HasTexSlot)
|
if (HasTexSlot)
|
||||||
{
|
{
|
||||||
for (uint32 iTex = 0; iTex < mNumVertices; iTex++)
|
for (size_t iTex = 0; iTex < mNumVertices; iTex++)
|
||||||
mVertices[iTex].Tex[iTexSlot].Write(rOut);
|
mVertices[iTex].Tex[iTexSlot].Write(rOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +128,7 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
|
|
||||||
// Surface offsets
|
// Surface offsets
|
||||||
rOut.WriteLong(mNumSurfaces);
|
rOut.WriteLong(mNumSurfaces);
|
||||||
uint32 SurfaceOffsetsStart = rOut.Tell();
|
const uint32 SurfaceOffsetsStart = rOut.Tell();
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
for (uint32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
||||||
rOut.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
|
@ -140,7 +137,7 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
SectionMgr.AddSize(rOut);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Surfaces
|
// Surfaces
|
||||||
uint32 SurfacesStart = rOut.Tell();
|
const uint32 SurfacesStart = rOut.Tell();
|
||||||
std::vector<uint32> SurfaceEndOffsets(mNumSurfaces);
|
std::vector<uint32> SurfaceEndOffsets(mNumSurfaces);
|
||||||
|
|
||||||
for (size_t iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
for (size_t iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
||||||
|
@ -149,40 +146,37 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
|
|
||||||
pSurface->CenterPoint.Write(rOut);
|
pSurface->CenterPoint.Write(rOut);
|
||||||
rOut.WriteLong(pSurface->MaterialID);
|
rOut.WriteLong(pSurface->MaterialID);
|
||||||
rOut.WriteShort((uint16) 0x8000);
|
rOut.WriteShort(static_cast<uint16>(0x8000));
|
||||||
uint32 PrimTableSizeOffset = rOut.Tell();
|
const uint32 PrimTableSizeOffset = rOut.Tell();
|
||||||
rOut.WriteShort(0);
|
rOut.WriteShort(0);
|
||||||
rOut.WriteLongLong(0);
|
rOut.WriteLongLong(0);
|
||||||
rOut.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
pSurface->ReflectionDirection.Write(rOut);
|
pSurface->ReflectionDirection.Write(rOut);
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
|
|
||||||
uint32 PrimTableStart = rOut.Tell();
|
const uint32 PrimTableStart = rOut.Tell();
|
||||||
FVertexDescription VtxAttribs = mpModel->GetMaterialBySurface(0, iSurf)->VtxDesc();
|
const FVertexDescription VtxAttribs = mpModel->GetMaterialBySurface(0, iSurf)->VtxDesc();
|
||||||
|
|
||||||
for (uint32 iPrim = 0; iPrim < pSurface->Primitives.size(); iPrim++)
|
for (const SSurface::SPrimitive& pPrimitive : pSurface->Primitives)
|
||||||
{
|
{
|
||||||
SSurface::SPrimitive *pPrimitive = &pSurface->Primitives[iPrim];
|
rOut.WriteByte(static_cast<uint8>(pPrimitive.Type));
|
||||||
rOut.WriteByte((uint8) pPrimitive->Type);
|
rOut.WriteShort(static_cast<uint16>(pPrimitive.Vertices.size()));
|
||||||
rOut.WriteShort((uint16) pPrimitive->Vertices.size());
|
|
||||||
|
|
||||||
for (uint32 iVert = 0; iVert < pPrimitive->Vertices.size(); iVert++)
|
for (const CVertex& pVert : pPrimitive.Vertices)
|
||||||
{
|
{
|
||||||
CVertex *pVert = &pPrimitive->Vertices[iVert];
|
|
||||||
|
|
||||||
if (mVersion == EGame::Echoes)
|
if (mVersion == EGame::Echoes)
|
||||||
{
|
{
|
||||||
for (uint32 iMtxAttribs = 0; iMtxAttribs < 8; iMtxAttribs++)
|
for (size_t iMtxAttribs = 0; iMtxAttribs < pVert.MatrixIndices.size(); iMtxAttribs++)
|
||||||
{
|
{
|
||||||
uint MatrixBit = ((uint) (EVertexAttribute::PosMtx) << iMtxAttribs);
|
const auto MatrixBit = static_cast<uint32>(EVertexAttribute::PosMtx << iMtxAttribs);
|
||||||
if (VtxAttribs & MatrixBit)
|
if (VtxAttribs & MatrixBit)
|
||||||
{
|
{
|
||||||
rOut.WriteByte(pVert->MatrixIndices[iMtxAttribs]);
|
rOut.WriteByte(pVert.MatrixIndices[iMtxAttribs]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 VertexIndex = (uint16) pVert->ArrayPosition;
|
const auto VertexIndex = static_cast<uint16>(pVert.ArrayPosition);
|
||||||
|
|
||||||
if (VtxAttribs & EVertexAttribute::Position)
|
if (VtxAttribs & EVertexAttribute::Position)
|
||||||
rOut.WriteShort(VertexIndex);
|
rOut.WriteShort(VertexIndex);
|
||||||
|
@ -199,22 +193,22 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
uint16 TexOffset = 0;
|
uint16 TexOffset = 0;
|
||||||
for (uint32 iTex = 0; iTex < 8; iTex++)
|
for (uint32 iTex = 0; iTex < 8; iTex++)
|
||||||
{
|
{
|
||||||
uint TexBit = ((uint) EVertexAttribute::Tex0) << iTex;
|
const auto TexBit = static_cast<uint32>(EVertexAttribute::Tex0 << iTex);
|
||||||
|
|
||||||
if (VtxAttribs & TexBit)
|
if (VtxAttribs & TexBit)
|
||||||
{
|
{
|
||||||
rOut.WriteShort(VertexIndex + TexOffset);
|
rOut.WriteShort(VertexIndex + TexOffset);
|
||||||
TexOffset += (uint16) mNumVertices;
|
TexOffset += static_cast<uint16>(mNumVertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
uint32 PrimTableEnd = rOut.Tell();
|
const uint32 PrimTableEnd = rOut.Tell();
|
||||||
uint32 PrimTableSize = PrimTableEnd - PrimTableStart;
|
const uint32 PrimTableSize = PrimTableEnd - PrimTableStart;
|
||||||
rOut.Seek(PrimTableSizeOffset, SEEK_SET);
|
rOut.Seek(PrimTableSizeOffset, SEEK_SET);
|
||||||
rOut.WriteShort((uint16) PrimTableSize);
|
rOut.WriteShort(static_cast<uint16>(PrimTableSize));
|
||||||
rOut.Seek(PrimTableEnd, SEEK_SET);
|
rOut.Seek(PrimTableEnd, SEEK_SET);
|
||||||
|
|
||||||
SectionMgr.AddSize(rOut);
|
SectionMgr.AddSize(rOut);
|
||||||
|
@ -224,7 +218,7 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
// Done writing the file - now we go back to fill in surface offsets + section sizes
|
// Done writing the file - now we go back to fill in surface offsets + section sizes
|
||||||
rOut.Seek(SurfaceOffsetsStart, SEEK_SET);
|
rOut.Seek(SurfaceOffsetsStart, SEEK_SET);
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
for (size_t iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
||||||
rOut.WriteLong(SurfaceEndOffsets[iSurf]);
|
rOut.WriteLong(SurfaceEndOffsets[iSurf]);
|
||||||
|
|
||||||
rOut.Seek(SectionSizesOffset, SEEK_SET);
|
rOut.Seek(SectionSizesOffset, SEEK_SET);
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
class CModelCooker
|
class CModelCooker
|
||||||
{
|
{
|
||||||
TResPtr<CModel> mpModel;
|
TResPtr<CModel> mpModel;
|
||||||
EGame mVersion;
|
EGame mVersion{};
|
||||||
uint32 mNumMatSets;
|
uint32 mNumMatSets = 0;
|
||||||
uint32 mNumSurfaces;
|
uint32 mNumSurfaces = 0;
|
||||||
uint32 mNumVertices;
|
uint32 mNumVertices = 0;
|
||||||
uint8 mVertexFormat;
|
uint8 mVertexFormat = 0;
|
||||||
std::vector<CVertex> mVertices;
|
std::vector<CVertex> mVertices;
|
||||||
FVertexDescription mVtxAttribs;
|
FVertexDescription mVtxAttribs{};
|
||||||
|
|
||||||
CModelCooker();
|
CModelCooker();
|
||||||
void GenerateSurfaceData();
|
void GenerateSurfaceData();
|
||||||
|
|
|
@ -3,15 +3,9 @@
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
CModelLoader::CModelLoader()
|
CModelLoader::CModelLoader() = default;
|
||||||
: mFlags(EModelLoaderFlag::None)
|
|
||||||
, mNumVertices(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CModelLoader::~CModelLoader()
|
CModelLoader::~CModelLoader() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModelLoader::LoadWorldMeshHeader(IInputStream& rModel)
|
void CModelLoader::LoadWorldMeshHeader(IInputStream& rModel)
|
||||||
{
|
{
|
||||||
|
@ -27,23 +21,21 @@ void CModelLoader::LoadAttribArrays(IInputStream& rModel)
|
||||||
if (mFlags & EModelLoaderFlag::HalfPrecisionPositions) // 16-bit (DKCR only)
|
if (mFlags & EModelLoaderFlag::HalfPrecisionPositions) // 16-bit (DKCR only)
|
||||||
{
|
{
|
||||||
mPositions.resize(mpSectionMgr->CurrentSectionSize() / 0x6);
|
mPositions.resize(mpSectionMgr->CurrentSectionSize() / 0x6);
|
||||||
float Divisor = 8192.f; // Might be incorrect! Needs verification via size comparison.
|
constexpr float Divisor = 8192.f; // Might be incorrect! Needs verification via size comparison.
|
||||||
|
|
||||||
for (uint32 iVtx = 0; iVtx < mPositions.size(); iVtx++)
|
for (auto& position : mPositions)
|
||||||
{
|
{
|
||||||
float X = rModel.ReadShort() / Divisor;
|
position.X = rModel.ReadShort() / Divisor;
|
||||||
float Y = rModel.ReadShort() / Divisor;
|
position.Y = rModel.ReadShort() / Divisor;
|
||||||
float Z = rModel.ReadShort() / Divisor;
|
position.Z = rModel.ReadShort() / Divisor;
|
||||||
mPositions[iVtx] = CVector3f(X, Y, Z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else // 32-bit
|
else // 32-bit
|
||||||
{
|
{
|
||||||
mPositions.resize(mpSectionMgr->CurrentSectionSize() / 0xC);
|
mPositions.resize(mpSectionMgr->CurrentSectionSize() / 0xC);
|
||||||
|
|
||||||
for (uint32 iVtx = 0; iVtx < mPositions.size(); iVtx++)
|
for (auto& position : mPositions)
|
||||||
mPositions[iVtx] = CVector3f(rModel);
|
position = CVector3f(rModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
@ -52,54 +44,52 @@ void CModelLoader::LoadAttribArrays(IInputStream& rModel)
|
||||||
if (mFlags & EModelLoaderFlag::HalfPrecisionNormals) // 16-bit
|
if (mFlags & EModelLoaderFlag::HalfPrecisionNormals) // 16-bit
|
||||||
{
|
{
|
||||||
mNormals.resize(mpSectionMgr->CurrentSectionSize() / 0x6);
|
mNormals.resize(mpSectionMgr->CurrentSectionSize() / 0x6);
|
||||||
float Divisor = (mVersion < EGame::DKCReturns) ? 32768.f : 16384.f;
|
const float Divisor = (mVersion < EGame::DKCReturns) ? 32768.f : 16384.f;
|
||||||
|
|
||||||
for (uint32 iVtx = 0; iVtx < mNormals.size(); iVtx++)
|
for (auto& normal : mNormals)
|
||||||
{
|
{
|
||||||
float X = rModel.ReadShort() / Divisor;
|
normal.X = rModel.ReadShort() / Divisor;
|
||||||
float Y = rModel.ReadShort() / Divisor;
|
normal.Y = rModel.ReadShort() / Divisor;
|
||||||
float Z = rModel.ReadShort() / Divisor;
|
normal.Z = rModel.ReadShort() / Divisor;
|
||||||
mNormals[iVtx] = CVector3f(X, Y, Z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // 32-bit
|
else // 32-bit
|
||||||
{
|
{
|
||||||
mNormals.resize(mpSectionMgr->CurrentSectionSize() / 0xC);
|
mNormals.resize(mpSectionMgr->CurrentSectionSize() / 0xC);
|
||||||
|
|
||||||
for (uint32 iVtx = 0; iVtx < mNormals.size(); iVtx++)
|
for (auto& normal : mNormals)
|
||||||
mNormals[iVtx] = CVector3f(rModel);
|
normal = CVector3f(rModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
mColors.resize(mpSectionMgr->CurrentSectionSize() / 4);
|
mColors.resize(mpSectionMgr->CurrentSectionSize() / 4);
|
||||||
|
for (auto& color : mColors)
|
||||||
for (uint32 iVtx = 0; iVtx < mColors.size(); iVtx++)
|
{
|
||||||
mColors[iVtx] = CColor(rModel);
|
color = CColor(rModel);
|
||||||
|
}
|
||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
|
||||||
|
|
||||||
// UVs
|
// UVs
|
||||||
mTex0.resize(mpSectionMgr->CurrentSectionSize() / 0x8);
|
mTex0.resize(mpSectionMgr->CurrentSectionSize() / 0x8);
|
||||||
|
for (auto& vec : mTex0)
|
||||||
for (uint32 iVtx = 0; iVtx < mTex0.size(); iVtx++)
|
{
|
||||||
mTex0[iVtx] = CVector2f(rModel);
|
vec = CVector2f(rModel);
|
||||||
|
}
|
||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
|
||||||
// Lightmap UVs
|
// Lightmap UVs
|
||||||
if (mFlags & EModelLoaderFlag::LightmapUVs)
|
if (mFlags & EModelLoaderFlag::LightmapUVs)
|
||||||
{
|
{
|
||||||
mTex1.resize(mpSectionMgr->CurrentSectionSize() / 0x4);
|
mTex1.resize(mpSectionMgr->CurrentSectionSize() / 0x4);
|
||||||
float Divisor = (mVersion < EGame::DKCReturns) ? 32768.f : 8192.f;
|
const float Divisor = (mVersion < EGame::DKCReturns) ? 32768.f : 8192.f;
|
||||||
|
|
||||||
for (uint32 iVtx = 0; iVtx < mTex1.size(); iVtx++)
|
for (auto& vec : mTex1)
|
||||||
{
|
{
|
||||||
float X = rModel.ReadShort() / Divisor;
|
vec.X = rModel.ReadShort() / Divisor;
|
||||||
float Y = rModel.ReadShort() / Divisor;
|
vec.Y = rModel.ReadShort() / Divisor;
|
||||||
mTex1[iVtx] = CVector2f(X, Y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
@ -111,7 +101,7 @@ void CModelLoader::LoadSurfaceOffsets(IInputStream& rModel)
|
||||||
mSurfaceCount = rModel.ReadLong();
|
mSurfaceCount = rModel.ReadLong();
|
||||||
mSurfaceOffsets.resize(mSurfaceCount);
|
mSurfaceOffsets.resize(mSurfaceCount);
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < mSurfaceCount; iSurf++)
|
for (size_t iSurf = 0; iSurf < mSurfaceCount; iSurf++)
|
||||||
mSurfaceOffsets[iSurf] = rModel.ReadLong();
|
mSurfaceOffsets[iSurf] = rModel.ReadLong();
|
||||||
|
|
||||||
mpSectionMgr->ToNextSection();
|
mpSectionMgr->ToNextSection();
|
||||||
|
@ -127,18 +117,18 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
|
||||||
else
|
else
|
||||||
LoadSurfaceHeaderDKCR(rModel, pSurf);
|
LoadSurfaceHeaderDKCR(rModel, pSurf);
|
||||||
|
|
||||||
bool HasAABB = (pSurf->AABox != CAABox::skInfinite);
|
const bool HasAABB = (pSurf->AABox != CAABox::skInfinite);
|
||||||
CMaterial *pMat = mMaterials[0]->MaterialByIndex(pSurf->MaterialID, false);
|
CMaterial *pMat = mMaterials[0]->MaterialByIndex(pSurf->MaterialID, false);
|
||||||
|
|
||||||
// Primitive table
|
// Primitive table
|
||||||
uint8 Flag = rModel.ReadByte();
|
uint8 Flag = rModel.ReadByte();
|
||||||
uint32 NextSurface = mpSectionMgr->NextOffset();
|
const uint32 NextSurface = mpSectionMgr->NextOffset();
|
||||||
|
|
||||||
while ((Flag != 0) && ((uint32) rModel.Tell() < NextSurface))
|
while (Flag != 0 && (static_cast<uint32>(rModel.Tell()) < NextSurface))
|
||||||
{
|
{
|
||||||
SSurface::SPrimitive Prim;
|
SSurface::SPrimitive Prim;
|
||||||
Prim.Type = EPrimitiveType(Flag & 0xF8);
|
Prim.Type = EPrimitiveType(Flag & 0xF8);
|
||||||
uint16 VertexCount = rModel.ReadShort();
|
const uint16 VertexCount = rModel.ReadShort();
|
||||||
|
|
||||||
for (uint16 iVtx = 0; iVtx < VertexCount; iVtx++)
|
for (uint16 iVtx = 0; iVtx < VertexCount; iVtx++)
|
||||||
{
|
{
|
||||||
|
@ -146,7 +136,10 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
|
||||||
FVertexDescription VtxDesc = pMat->VtxDesc();
|
FVertexDescription VtxDesc = pMat->VtxDesc();
|
||||||
|
|
||||||
for (uint32 iMtxAttr = 0; iMtxAttr < 8; iMtxAttr++)
|
for (uint32 iMtxAttr = 0; iMtxAttr < 8; iMtxAttr++)
|
||||||
if (VtxDesc & ((uint) EVertexAttribute::PosMtx << iMtxAttr)) rModel.Seek(0x1, SEEK_CUR);
|
{
|
||||||
|
if (VtxDesc & static_cast<uint>(EVertexAttribute::PosMtx << iMtxAttr))
|
||||||
|
rModel.Seek(0x1, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
// Only thing to do here is check whether each attribute is present, and if so, read it.
|
// Only thing to do here is check whether each attribute is present, and if so, read it.
|
||||||
// A couple attributes have special considerations; normals can be floats or shorts, as can tex0, depending on vtxfmt.
|
// A couple attributes have special considerations; normals can be floats or shorts, as can tex0, depending on vtxfmt.
|
||||||
|
@ -159,7 +152,8 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
|
||||||
Vtx.Position = mPositions[PosIndex];
|
Vtx.Position = mPositions[PosIndex];
|
||||||
Vtx.ArrayPosition = PosIndex;
|
Vtx.ArrayPosition = PosIndex;
|
||||||
|
|
||||||
if (!HasAABB) pSurf->AABox.ExpandBounds(Vtx.Position);
|
if (!HasAABB)
|
||||||
|
pSurf->AABox.ExpandBounds(Vtx.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal
|
// Normal
|
||||||
|
@ -167,9 +161,11 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
|
||||||
Vtx.Normal = mNormals[rModel.ReadShort() & 0xFFFF];
|
Vtx.Normal = mNormals[rModel.ReadShort() & 0xFFFF];
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
for (uint32 iClr = 0; iClr < 2; iClr++)
|
for (size_t iClr = 0; iClr < Vtx.Color.size(); iClr++)
|
||||||
if (VtxDesc & ((uint) EVertexAttribute::Color0 << iClr))
|
{
|
||||||
|
if (VtxDesc & static_cast<uint32>(EVertexAttribute::Color0 << iClr))
|
||||||
Vtx.Color[iClr] = mColors[rModel.ReadShort() & 0xFFFF];
|
Vtx.Color[iClr] = mColors[rModel.ReadShort() & 0xFFFF];
|
||||||
|
}
|
||||||
|
|
||||||
// Tex Coords - these are done a bit differently in DKCR than in the Prime series
|
// Tex Coords - these are done a bit differently in DKCR than in the Prime series
|
||||||
if (mVersion < EGame::DKCReturns)
|
if (mVersion < EGame::DKCReturns)
|
||||||
|
@ -184,17 +180,18 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tex1-7
|
// Tex1-7
|
||||||
for (uint32 iTex = 1; iTex < 7; iTex++)
|
for (size_t iTex = 1; iTex < 7; iTex++)
|
||||||
if (VtxDesc & ((uint) EVertexAttribute::Tex0 << iTex))
|
{
|
||||||
|
if (VtxDesc & static_cast<uint32>(EVertexAttribute::Tex0 << iTex))
|
||||||
Vtx.Tex[iTex] = mTex0[rModel.ReadShort() & 0xFFFF];
|
Vtx.Tex[iTex] = mTex0[rModel.ReadShort() & 0xFFFF];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Tex0-7
|
// Tex0-7
|
||||||
for (uint32 iTex = 0; iTex < 7; iTex++)
|
for (size_t iTex = 0; iTex < 7; iTex++)
|
||||||
{
|
{
|
||||||
if (VtxDesc & ((uint) EVertexAttribute::Tex0 << iTex))
|
if (VtxDesc & static_cast<uint32>(EVertexAttribute::Tex0 << iTex))
|
||||||
{
|
{
|
||||||
if (!mSurfaceUsingTex1)
|
if (!mSurfaceUsingTex1)
|
||||||
Vtx.Tex[iTex] = mTex0[rModel.ReadShort() & 0xFFFF];
|
Vtx.Tex[iTex] = mTex0[rModel.ReadShort() & 0xFFFF];
|
||||||
|
@ -243,7 +240,7 @@ void CModelLoader::LoadSurfaceHeaderPrime(IInputStream& rModel, SSurface *pSurf)
|
||||||
if (mVersion >= EGame::EchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
rModel.Seek(0x4, SEEK_CUR); // Skipping unknown values
|
rModel.Seek(0x4, SEEK_CUR); // Skipping unknown values
|
||||||
|
|
||||||
bool HasAABox = (ExtraSize >= 0x18); // MREAs have a set of bounding box coordinates here.
|
const 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.
|
||||||
if (HasAABox)
|
if (HasAABox)
|
||||||
|
@ -252,7 +249,9 @@ void CModelLoader::LoadSurfaceHeaderPrime(IInputStream& rModel, SSurface *pSurf)
|
||||||
pSurf->AABox = CAABox(rModel);
|
pSurf->AABox = CAABox(rModel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pSurf->AABox = CAABox::skInfinite;
|
pSurf->AABox = CAABox::skInfinite;
|
||||||
|
}
|
||||||
|
|
||||||
rModel.Seek(ExtraSize, SEEK_CUR);
|
rModel.Seek(ExtraSize, SEEK_CUR);
|
||||||
rModel.SeekToBoundary(32);
|
rModel.SeekToBoundary(32);
|
||||||
|
@ -262,7 +261,7 @@ void CModelLoader::LoadSurfaceHeaderDKCR(IInputStream& rModel, SSurface *pSurf)
|
||||||
{
|
{
|
||||||
pSurf->CenterPoint = CVector3f(rModel);
|
pSurf->CenterPoint = CVector3f(rModel);
|
||||||
rModel.Seek(0xE, SEEK_CUR);
|
rModel.Seek(0xE, SEEK_CUR);
|
||||||
pSurf->MaterialID = (uint32) rModel.ReadShort();
|
pSurf->MaterialID = static_cast<uint32>(rModel.ReadShort());
|
||||||
rModel.Seek(0x2, SEEK_CUR);
|
rModel.Seek(0x2, SEEK_CUR);
|
||||||
mSurfaceUsingTex1 = (rModel.ReadByte() == 1);
|
mSurfaceUsingTex1 = (rModel.ReadByte() == 1);
|
||||||
uint32 ExtraSize = rModel.ReadByte();
|
uint32 ExtraSize = rModel.ReadByte();
|
||||||
|
@ -273,7 +272,9 @@ void CModelLoader::LoadSurfaceHeaderDKCR(IInputStream& rModel, SSurface *pSurf)
|
||||||
pSurf->AABox = CAABox(rModel);
|
pSurf->AABox = CAABox(rModel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pSurf->AABox = CAABox::skInfinite;
|
pSurf->AABox = CAABox::skInfinite;
|
||||||
|
}
|
||||||
|
|
||||||
rModel.Seek(ExtraSize, SEEK_CUR);
|
rModel.Seek(ExtraSize, SEEK_CUR);
|
||||||
rModel.SeekToBoundary(32);
|
rModel.SeekToBoundary(32);
|
||||||
|
@ -285,13 +286,15 @@ SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet)
|
||||||
CMaterial *pMat = pSet->MaterialByIndex(pkMesh->mMaterialIndex, false);
|
CMaterial *pMat = pSet->MaterialByIndex(pkMesh->mMaterialIndex, false);
|
||||||
FVertexDescription Desc = pMat->VtxDesc();
|
FVertexDescription Desc = pMat->VtxDesc();
|
||||||
|
|
||||||
if (Desc == (FVertexDescription) EVertexAttribute::None)
|
if (Desc == static_cast<FVertexDescription>(EVertexAttribute::None))
|
||||||
{
|
{
|
||||||
if (pkMesh->HasPositions()) Desc |= EVertexAttribute::Position;
|
if (pkMesh->HasPositions())
|
||||||
if (pkMesh->HasNormals()) Desc |= EVertexAttribute::Normal;
|
Desc |= EVertexAttribute::Position;
|
||||||
|
if (pkMesh->HasNormals())
|
||||||
|
Desc |= EVertexAttribute::Normal;
|
||||||
|
|
||||||
for (uint32 iUV = 0; iUV < pkMesh->GetNumUVChannels(); iUV++)
|
for (size_t iUV = 0; iUV < pkMesh->GetNumUVChannels(); iUV++)
|
||||||
Desc |= ((uint) EVertexAttribute::Tex0 << iUV);
|
Desc |= static_cast<uint32>(EVertexAttribute::Tex0 << iUV);
|
||||||
|
|
||||||
pMat->SetVertexDescription(Desc);
|
pMat->SetVertexDescription(Desc);
|
||||||
|
|
||||||
|
@ -314,29 +317,32 @@ SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet)
|
||||||
SSurface::SPrimitive& rPrim = pSurf->Primitives[0];
|
SSurface::SPrimitive& rPrim = pSurf->Primitives[0];
|
||||||
|
|
||||||
// Check primitive type on first face
|
// Check primitive type on first face
|
||||||
uint32 NumIndices = pkMesh->mFaces[0].mNumIndices;
|
const uint32 NumIndices = pkMesh->mFaces[0].mNumIndices;
|
||||||
if (NumIndices == 1) rPrim.Type = EPrimitiveType::Points;
|
if (NumIndices == 1)
|
||||||
else if (NumIndices == 2) rPrim.Type = EPrimitiveType::Lines;
|
rPrim.Type = EPrimitiveType::Points;
|
||||||
else if (NumIndices == 3) rPrim.Type = EPrimitiveType::Triangles;
|
else if (NumIndices == 2)
|
||||||
|
rPrim.Type = EPrimitiveType::Lines;
|
||||||
|
else if (NumIndices == 3)
|
||||||
|
rPrim.Type = EPrimitiveType::Triangles;
|
||||||
|
|
||||||
// Generate bounding box, center point, and reflection projection
|
// Generate bounding box, center point, and reflection projection
|
||||||
pSurf->CenterPoint = CVector3f::skZero;
|
pSurf->CenterPoint = CVector3f::skZero;
|
||||||
pSurf->ReflectionDirection = CVector3f::skZero;
|
pSurf->ReflectionDirection = CVector3f::skZero;
|
||||||
|
|
||||||
for (uint32 iVtx = 0; iVtx < pkMesh->mNumVertices; iVtx++)
|
for (size_t iVtx = 0; iVtx < pkMesh->mNumVertices; iVtx++)
|
||||||
{
|
{
|
||||||
aiVector3D AiPos = pkMesh->mVertices[iVtx];
|
const aiVector3D AiPos = pkMesh->mVertices[iVtx];
|
||||||
pSurf->AABox.ExpandBounds(CVector3f(AiPos.x, AiPos.y, AiPos.z));
|
pSurf->AABox.ExpandBounds(CVector3f(AiPos.x, AiPos.y, AiPos.z));
|
||||||
|
|
||||||
if (pkMesh->HasNormals()) {
|
if (pkMesh->HasNormals()) {
|
||||||
aiVector3D aiNrm = pkMesh->mNormals[iVtx];
|
const aiVector3D aiNrm = pkMesh->mNormals[iVtx];
|
||||||
pSurf->ReflectionDirection += CVector3f(aiNrm.x, aiNrm.y, aiNrm.z);
|
pSurf->ReflectionDirection += CVector3f(aiNrm.x, aiNrm.y, aiNrm.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pSurf->CenterPoint = pSurf->AABox.Center();
|
pSurf->CenterPoint = pSurf->AABox.Center();
|
||||||
|
|
||||||
if (pkMesh->HasNormals())
|
if (pkMesh->HasNormals())
|
||||||
pSurf->ReflectionDirection /= (float) pkMesh->mNumVertices;
|
pSurf->ReflectionDirection /= static_cast<float>(pkMesh->mNumVertices);
|
||||||
else
|
else
|
||||||
pSurf->ReflectionDirection = CVector3f(1.f, 0.f, 0.f);
|
pSurf->ReflectionDirection = CVector3f(1.f, 0.f, 0.f);
|
||||||
|
|
||||||
|
@ -345,11 +351,11 @@ SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet)
|
||||||
pSurf->TriangleCount = (rPrim.Type == EPrimitiveType::Triangles ? pkMesh->mNumFaces : 0);
|
pSurf->TriangleCount = (rPrim.Type == EPrimitiveType::Triangles ? pkMesh->mNumFaces : 0);
|
||||||
|
|
||||||
// Create primitive
|
// Create primitive
|
||||||
for (uint32 iFace = 0; iFace < pkMesh->mNumFaces; iFace++)
|
for (size_t iFace = 0; iFace < pkMesh->mNumFaces; iFace++)
|
||||||
{
|
{
|
||||||
for (uint32 iIndex = 0; iIndex < NumIndices; iIndex++)
|
for (size_t iIndex = 0; iIndex < NumIndices; iIndex++)
|
||||||
{
|
{
|
||||||
uint32 Index = pkMesh->mFaces[iFace].mIndices[iIndex];
|
const uint32 Index = pkMesh->mFaces[iFace].mIndices[iIndex];
|
||||||
|
|
||||||
// Create vertex and add it to the primitive
|
// Create vertex and add it to the primitive
|
||||||
CVertex Vert;
|
CVertex Vert;
|
||||||
|
@ -357,19 +363,19 @@ SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet)
|
||||||
|
|
||||||
if (pkMesh->HasPositions())
|
if (pkMesh->HasPositions())
|
||||||
{
|
{
|
||||||
aiVector3D AiPos = pkMesh->mVertices[Index];
|
const aiVector3D AiPos = pkMesh->mVertices[Index];
|
||||||
Vert.Position = CVector3f(AiPos.x, AiPos.y, AiPos.z);
|
Vert.Position = CVector3f(AiPos.x, AiPos.y, AiPos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkMesh->HasNormals())
|
if (pkMesh->HasNormals())
|
||||||
{
|
{
|
||||||
aiVector3D AiNrm = pkMesh->mNormals[Index];
|
const aiVector3D AiNrm = pkMesh->mNormals[Index];
|
||||||
Vert.Normal = CVector3f(AiNrm.x, AiNrm.y, AiNrm.z);
|
Vert.Normal = CVector3f(AiNrm.x, AiNrm.y, AiNrm.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32 iTex = 0; iTex < pkMesh->GetNumUVChannels(); iTex++)
|
for (size_t iTex = 0; iTex < pkMesh->GetNumUVChannels(); iTex++)
|
||||||
{
|
{
|
||||||
aiVector3D AiTex = pkMesh->mTextureCoords[iTex][Index];
|
const aiVector3D AiTex = pkMesh->mTextureCoords[iTex][Index];
|
||||||
Vert.Tex[iTex] = CVector2f(AiTex.x, AiTex.y);
|
Vert.Tex[iTex] = CVector2f(AiTex.x, AiTex.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,7 +395,7 @@ std::unique_ptr<CModel> CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEnt
|
||||||
CModelLoader Loader;
|
CModelLoader Loader;
|
||||||
|
|
||||||
// CMDL header - same across the three Primes, but different structure in DKCR
|
// CMDL header - same across the three Primes, but different structure in DKCR
|
||||||
uint32 Magic = rCMDL.ReadLong();
|
const uint32 Magic = rCMDL.ReadLong();
|
||||||
|
|
||||||
uint32 Version, BlockCount, MatSetCount;
|
uint32 Version, BlockCount, MatSetCount;
|
||||||
CAABox AABox;
|
CAABox AABox;
|
||||||
|
@ -403,35 +409,40 @@ std::unique_ptr<CModel> CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEnt
|
||||||
BlockCount = rCMDL.ReadLong();
|
BlockCount = rCMDL.ReadLong();
|
||||||
MatSetCount = rCMDL.ReadLong();
|
MatSetCount = rCMDL.ReadLong();
|
||||||
|
|
||||||
if (Flags & 0x1) Loader.mFlags |= EModelLoaderFlag::Skinned;
|
if (Flags & 0x1)
|
||||||
if (Flags & 0x2) Loader.mFlags |= EModelLoaderFlag::HalfPrecisionNormals;
|
Loader.mFlags |= EModelLoaderFlag::Skinned;
|
||||||
if (Flags & 0x4) Loader.mFlags |= EModelLoaderFlag::LightmapUVs;
|
if (Flags & 0x2)
|
||||||
|
Loader.mFlags |= EModelLoaderFlag::HalfPrecisionNormals;
|
||||||
|
if (Flags & 0x4)
|
||||||
|
Loader.mFlags |= EModelLoaderFlag::LightmapUVs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x9381000A - Donkey Kong Country Returns
|
// 0x9381000A - Donkey Kong Country Returns
|
||||||
else if (Magic == 0x9381000A)
|
else if (Magic == 0x9381000A)
|
||||||
{
|
{
|
||||||
Version = Magic & 0xFFFF;
|
Version = Magic & 0xFFFF;
|
||||||
uint32 Flags = rCMDL.ReadLong();
|
const uint32 Flags = rCMDL.ReadLong();
|
||||||
AABox = CAABox(rCMDL);
|
AABox = CAABox(rCMDL);
|
||||||
BlockCount = rCMDL.ReadLong();
|
BlockCount = rCMDL.ReadLong();
|
||||||
MatSetCount = rCMDL.ReadLong();
|
MatSetCount = rCMDL.ReadLong();
|
||||||
|
|
||||||
// todo: unknown flags
|
// todo: unknown flags
|
||||||
Loader.mFlags = EModelLoaderFlag::HalfPrecisionNormals | EModelLoaderFlag::LightmapUVs;
|
Loader.mFlags = EModelLoaderFlag::HalfPrecisionNormals | EModelLoaderFlag::LightmapUVs;
|
||||||
if (Flags & 0x10) Loader.mFlags |= EModelLoaderFlag::VisibilityGroups;
|
if (Flags & 0x10)
|
||||||
if (Flags & 0x20) Loader.mFlags |= EModelLoaderFlag::HalfPrecisionPositions;
|
Loader.mFlags |= EModelLoaderFlag::VisibilityGroups;
|
||||||
|
if (Flags & 0x20)
|
||||||
|
Loader.mFlags |= EModelLoaderFlag::HalfPrecisionPositions;
|
||||||
|
|
||||||
// Visibility group data
|
// Visibility group data
|
||||||
// Skipping for now - should read in eventually
|
// Skipping for now - should read in eventually
|
||||||
if (Flags & 0x10)
|
if (Flags & 0x10)
|
||||||
{
|
{
|
||||||
rCMDL.Seek(0x4, SEEK_CUR);
|
rCMDL.Seek(0x4, SEEK_CUR);
|
||||||
uint32 VisGroupCount = rCMDL.ReadLong();
|
const uint32 VisGroupCount = rCMDL.ReadLong();
|
||||||
|
|
||||||
for (uint32 iVis = 0; iVis < VisGroupCount; iVis++)
|
for (uint32 iVis = 0; iVis < VisGroupCount; iVis++)
|
||||||
{
|
{
|
||||||
uint32 NameLength = rCMDL.ReadLong();
|
const uint32 NameLength = rCMDL.ReadLong();
|
||||||
rCMDL.Seek(NameLength, SEEK_CUR);
|
rCMDL.Seek(NameLength, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +472,7 @@ std::unique_ptr<CModel> CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEnt
|
||||||
|
|
||||||
// Materials
|
// Materials
|
||||||
Loader.mMaterials.resize(MatSetCount);
|
Loader.mMaterials.resize(MatSetCount);
|
||||||
for (uint32 iSet = 0; iSet < MatSetCount; iSet++)
|
for (size_t iSet = 0; iSet < MatSetCount; iSet++)
|
||||||
{
|
{
|
||||||
Loader.mMaterials[iSet] = CMaterialLoader::LoadMaterialSet(rCMDL, Loader.mVersion);
|
Loader.mMaterials[iSet] = CMaterialLoader::LoadMaterialSet(rCMDL, Loader.mVersion);
|
||||||
|
|
||||||
|
@ -478,7 +489,7 @@ std::unique_ptr<CModel> CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEnt
|
||||||
Loader.LoadSurfaceOffsets(rCMDL);
|
Loader.LoadSurfaceOffsets(rCMDL);
|
||||||
pModel->mSurfaces.reserve(Loader.mSurfaceCount);
|
pModel->mSurfaces.reserve(Loader.mSurfaceCount);
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < Loader.mSurfaceCount; iSurf++)
|
for (size_t iSurf = 0; iSurf < Loader.mSurfaceCount; iSurf++)
|
||||||
{
|
{
|
||||||
SSurface *pSurf = Loader.LoadSurface(rCMDL);
|
SSurface *pSurf = Loader.LoadSurface(rCMDL);
|
||||||
pModel->mSurfaces.push_back(pSurf);
|
pModel->mSurfaces.push_back(pSurf);
|
||||||
|
@ -500,7 +511,8 @@ std::unique_ptr<CModel> CModelLoader::LoadWorldModel(IInputStream& rMREA, CSecti
|
||||||
Loader.mpSectionMgr = &rBlockMgr;
|
Loader.mpSectionMgr = &rBlockMgr;
|
||||||
Loader.mVersion = Version;
|
Loader.mVersion = Version;
|
||||||
Loader.mFlags = EModelLoaderFlag::HalfPrecisionNormals;
|
Loader.mFlags = EModelLoaderFlag::HalfPrecisionNormals;
|
||||||
if (Version != EGame::CorruptionProto) Loader.mFlags |= EModelLoaderFlag::LightmapUVs;
|
if (Version != EGame::CorruptionProto)
|
||||||
|
Loader.mFlags |= EModelLoaderFlag::LightmapUVs;
|
||||||
Loader.mMaterials.resize(1);
|
Loader.mMaterials.resize(1);
|
||||||
Loader.mMaterials[0] = &rMatSet;
|
Loader.mMaterials[0] = &rMatSet;
|
||||||
|
|
||||||
|
@ -515,7 +527,7 @@ std::unique_ptr<CModel> CModelLoader::LoadWorldModel(IInputStream& rMREA, CSecti
|
||||||
pModel->mSurfaces.reserve(Loader.mSurfaceCount);
|
pModel->mSurfaces.reserve(Loader.mSurfaceCount);
|
||||||
pModel->mHasOwnSurfaces = true;
|
pModel->mHasOwnSurfaces = true;
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < Loader.mSurfaceCount; iSurf++)
|
for (size_t iSurf = 0; iSurf < Loader.mSurfaceCount; iSurf++)
|
||||||
{
|
{
|
||||||
SSurface *pSurf = Loader.LoadSurface(rMREA);
|
SSurface *pSurf = Loader.LoadSurface(rMREA);
|
||||||
pModel->mSurfaces.push_back(pSurf);
|
pModel->mSurfaces.push_back(pSurf);
|
||||||
|
@ -552,7 +564,7 @@ std::unique_ptr<CModel> CModelLoader::LoadCorruptionWorldModel(IInputStream& rMR
|
||||||
pModel->mSurfaces.reserve(Loader.mSurfaceCount);
|
pModel->mSurfaces.reserve(Loader.mSurfaceCount);
|
||||||
pModel->mHasOwnSurfaces = true;
|
pModel->mHasOwnSurfaces = true;
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < Loader.mSurfaceCount; iSurf++)
|
for (size_t iSurf = 0; iSurf < Loader.mSurfaceCount; iSurf++)
|
||||||
{
|
{
|
||||||
SSurface *pSurf = Loader.LoadSurface(rMREA);
|
SSurface *pSurf = Loader.LoadSurface(rMREA);
|
||||||
pModel->mSurfaces.push_back(pSurf);
|
pModel->mSurfaces.push_back(pSurf);
|
||||||
|
@ -569,20 +581,19 @@ void CModelLoader::BuildWorldMeshes(std::vector<std::unique_ptr<CModel>>& rkIn,
|
||||||
// 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 (size_t iMdl = 0; iMdl < rkIn.size(); iMdl++)
|
||||||
{
|
{
|
||||||
auto& pModel = rkIn[iMdl];
|
auto& pModel = rkIn[iMdl];
|
||||||
pModel->mHasOwnSurfaces = false;
|
pModel->mHasOwnSurfaces = false;
|
||||||
pModel->mHasOwnMaterials = false;
|
pModel->mHasOwnMaterials = false;
|
||||||
|
|
||||||
for (uint32 iSurf = 0; iSurf < pModel->mSurfaces.size(); iSurf++)
|
for (SSurface* pSurf : pModel->mSurfaces)
|
||||||
{
|
{
|
||||||
SSurface *pSurf = pModel->mSurfaces[iSurf];
|
uint32 ID = static_cast<uint32>(pSurf->MeshID);
|
||||||
uint32 ID = (uint32) pSurf->MeshID;
|
const auto Iter = OutputMap.find(ID);
|
||||||
auto Iter = OutputMap.find(ID);
|
|
||||||
|
|
||||||
// No model for this ID; create one!
|
// No model for this ID; create one!
|
||||||
if (Iter == OutputMap.end())
|
if (Iter == OutputMap.cend())
|
||||||
{
|
{
|
||||||
auto pOutMdl = std::make_unique<CModel>();
|
auto pOutMdl = std::make_unique<CModel>();
|
||||||
pOutMdl->mMaterialSets.resize(1);
|
pOutMdl->mMaterialSets.resize(1);
|
||||||
|
@ -619,9 +630,9 @@ CModel* CModelLoader::ImportAssimpNode(const aiNode *pkNode, const aiScene *pkSc
|
||||||
Loader.mpModel = new CModel(&rMatSet, true);
|
Loader.mpModel = new CModel(&rMatSet, true);
|
||||||
Loader.mpModel->mSurfaces.reserve(pkNode->mNumMeshes);
|
Loader.mpModel->mSurfaces.reserve(pkNode->mNumMeshes);
|
||||||
|
|
||||||
for (uint32 iMesh = 0; iMesh < pkNode->mNumMeshes; iMesh++)
|
for (size_t iMesh = 0; iMesh < pkNode->mNumMeshes; iMesh++)
|
||||||
{
|
{
|
||||||
uint32 MeshIndex = pkNode->mMeshes[iMesh];
|
const uint32 MeshIndex = pkNode->mMeshes[iMesh];
|
||||||
const aiMesh *pkMesh = pkScene->mMeshes[MeshIndex];
|
const aiMesh *pkMesh = pkScene->mMeshes[MeshIndex];
|
||||||
SSurface *pSurf = Loader.LoadAssimpMesh(pkMesh, &rMatSet);
|
SSurface *pSurf = Loader.LoadAssimpMesh(pkMesh, &rMatSet);
|
||||||
|
|
||||||
|
|
|
@ -35,22 +35,22 @@ class CModelLoader
|
||||||
private:
|
private:
|
||||||
TResPtr<CModel> mpModel;
|
TResPtr<CModel> mpModel;
|
||||||
std::vector<CMaterialSet*> mMaterials;
|
std::vector<CMaterialSet*> mMaterials;
|
||||||
CSectionMgrIn *mpSectionMgr;
|
CSectionMgrIn *mpSectionMgr = nullptr;
|
||||||
CAABox mAABox;
|
CAABox mAABox;
|
||||||
EGame mVersion;
|
EGame mVersion{};
|
||||||
|
|
||||||
uint32 mNumVertices;
|
uint32 mNumVertices = 0;
|
||||||
std::vector<CVector3f> mPositions;
|
std::vector<CVector3f> mPositions;
|
||||||
std::vector<CVector3f> mNormals;
|
std::vector<CVector3f> mNormals;
|
||||||
std::vector<CColor> mColors;
|
std::vector<CColor> mColors;
|
||||||
std::vector<CVector2f> mTex0;
|
std::vector<CVector2f> mTex0;
|
||||||
std::vector<CVector2f> mTex1;
|
std::vector<CVector2f> mTex1;
|
||||||
bool mSurfaceUsingTex1;
|
bool mSurfaceUsingTex1 = false;
|
||||||
|
|
||||||
uint32 mSurfaceCount;
|
uint32 mSurfaceCount = 0;
|
||||||
std::vector<uint32> mSurfaceOffsets;
|
std::vector<uint32> mSurfaceOffsets;
|
||||||
|
|
||||||
FModelLoaderFlags mFlags;
|
FModelLoaderFlags mFlags{EModelLoaderFlag::None};
|
||||||
|
|
||||||
CModelLoader();
|
CModelLoader();
|
||||||
~CModelLoader();
|
~CModelLoader();
|
||||||
|
|
|
@ -12,37 +12,28 @@ using TBoneWeights = std::array<float, 4>;
|
||||||
class CVertex
|
class CVertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint32 ArrayPosition; // Position of this vertex in the input model file.
|
uint32 ArrayPosition = 0; // Position of this vertex in the input model file.
|
||||||
// This is needed to resave without breaking rigging.
|
// This is needed to resave without breaking rigging.
|
||||||
CVector3f Position;
|
CVector3f Position;
|
||||||
CVector3f Normal;
|
CVector3f Normal;
|
||||||
CColor Color[2];
|
std::array<CColor, 2> Color;
|
||||||
CVector2f Tex[8];
|
std::array<CVector2f, 8> Tex;
|
||||||
TBoneIndices BoneIndices;
|
TBoneIndices BoneIndices{};
|
||||||
TBoneWeights BoneWeights;
|
TBoneWeights BoneWeights{};
|
||||||
uint8 MatrixIndices[8];
|
std::array<uint8, 8> MatrixIndices{};
|
||||||
|
|
||||||
CVertex() {}
|
constexpr CVertex() = default;
|
||||||
|
constexpr CVertex(const CVector3f& pos) : Position{pos}
|
||||||
CVertex(const CVector3f& rPos) : Position{rPos}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const CVertex& rkOther) const {
|
bool operator==(const CVertex& other) const {
|
||||||
return ((Position == rkOther.Position) &&
|
return Position == other.Position &&
|
||||||
(Normal == rkOther.Normal) &&
|
Normal == other.Normal &&
|
||||||
(Color[0] == rkOther.Color[0]) &&
|
Color == other.Color &&
|
||||||
(Color[1] == rkOther.Color[1]) &&
|
Tex == other.Tex &&
|
||||||
(Tex[0] == rkOther.Tex[0]) &&
|
BoneIndices == other.BoneIndices &&
|
||||||
(Tex[1] == rkOther.Tex[1]) &&
|
BoneWeights == other.BoneWeights;
|
||||||
(Tex[2] == rkOther.Tex[2]) &&
|
|
||||||
(Tex[3] == rkOther.Tex[3]) &&
|
|
||||||
(Tex[4] == rkOther.Tex[4]) &&
|
|
||||||
(Tex[5] == rkOther.Tex[5]) &&
|
|
||||||
(Tex[6] == rkOther.Tex[6]) &&
|
|
||||||
(Tex[7] == rkOther.Tex[7]) &&
|
|
||||||
(BoneIndices == rkOther.BoneIndices) &&
|
|
||||||
(BoneWeights == rkOther.BoneWeights));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const CVertex& other) const
|
bool operator!=(const CVertex& other) const
|
||||||
|
|
Loading…
Reference in New Issue