Added support for model importing using assimp
This commit is contained in:
parent
4fc83f735b
commit
2967a483d9
|
@ -162,6 +162,37 @@ void CColor::operator/=(const CColor& other)
|
||||||
*this = (*this / other);
|
*this = (*this / other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ************ STATIC ************
|
||||||
|
CColor CColor::RandomColor(bool transparent)
|
||||||
|
{
|
||||||
|
CColor out;
|
||||||
|
out.r = rand() % 255;
|
||||||
|
out.g = rand() % 255;
|
||||||
|
out.b = rand() % 255;
|
||||||
|
out.a = (transparent ? rand() % 255 : 0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
CColor CColor::RandomLightColor(bool transparent)
|
||||||
|
{
|
||||||
|
CColor out;
|
||||||
|
out.r = 127 + (rand() % 128);
|
||||||
|
out.g = 127 + (rand() % 128);
|
||||||
|
out.b = 127 + (rand() % 128);
|
||||||
|
out.a = (transparent ? 127 + (rand() % 128) : 0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
CColor CColor::RandomDarkColor(bool transparent)
|
||||||
|
{
|
||||||
|
CColor out;
|
||||||
|
out.r = rand() % 128;
|
||||||
|
out.g = rand() % 128;
|
||||||
|
out.b = rand() % 128;
|
||||||
|
out.a = (transparent ? rand() % 128 : 0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// defining predefined colors
|
// defining predefined colors
|
||||||
const CColor CColor::skRed (u32(0xFF0000FF));
|
const CColor CColor::skRed (u32(0xFF0000FF));
|
||||||
const CColor CColor::skGreen (u32(0x00FF00FF));
|
const CColor CColor::skGreen (u32(0x00FF00FF));
|
||||||
|
|
|
@ -36,6 +36,11 @@ public:
|
||||||
CColor operator/(const CColor& other) const;
|
CColor operator/(const CColor& other) const;
|
||||||
void operator/=(const CColor& other);
|
void operator/=(const CColor& other);
|
||||||
|
|
||||||
|
// Static
|
||||||
|
static CColor RandomColor(bool transparent);
|
||||||
|
static CColor RandomLightColor(bool transparent);
|
||||||
|
static CColor RandomDarkColor(bool transparent);
|
||||||
|
|
||||||
// some predefined colors below for ease of use
|
// some predefined colors below for ease of use
|
||||||
static const CColor skRed;
|
static const CColor skRed;
|
||||||
static const CColor skGreen;
|
static const CColor skGreen;
|
||||||
|
|
|
@ -342,3 +342,9 @@ RESOURCES += \
|
||||||
Icons.qrc
|
Icons.qrc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../Libraries/assimp/lib/ -lassimp-vc120-mt
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../Libraries/assimp/lib/ -lassimp-vc120-mtd
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../../Libraries/assimp/include
|
||||||
|
DEPENDPATH += $$PWD/../../Libraries/assimp/include
|
||||||
|
|
|
@ -278,6 +278,12 @@ void CMaterial::SetOptions(EMaterialOptions Options)
|
||||||
mRecalcHash = true;
|
mRecalcHash = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMaterial::SetVertexDescription(EVertexDescription desc)
|
||||||
|
{
|
||||||
|
mVtxDesc = desc;
|
||||||
|
mRecalcHash = true;
|
||||||
|
}
|
||||||
|
|
||||||
void CMaterial::SetBlendMode(GLenum SrcFac, GLenum DstFac)
|
void CMaterial::SetBlendMode(GLenum SrcFac, GLenum DstFac)
|
||||||
{
|
{
|
||||||
mBlendSrcFac = SrcFac;
|
mBlendSrcFac = SrcFac;
|
||||||
|
|
|
@ -99,6 +99,7 @@ public:
|
||||||
// Setters
|
// Setters
|
||||||
void SetName(const std::string& name);
|
void SetName(const std::string& name);
|
||||||
void SetOptions(EMaterialOptions Options);
|
void SetOptions(EMaterialOptions Options);
|
||||||
|
void SetVertexDescription(EVertexDescription desc);
|
||||||
void SetBlendMode(GLenum SrcFac, GLenum DstFac);
|
void SetBlendMode(GLenum SrcFac, GLenum DstFac);
|
||||||
void SetKonst(CColor& Konst, u32 KIndex);
|
void SetKonst(CColor& Konst, u32 KIndex);
|
||||||
void SetIndTexture(CTexture *pTex);
|
void SetIndTexture(CTexture *pTex);
|
||||||
|
|
|
@ -576,6 +576,24 @@ void CMaterialLoader::CreateCorruptionPasses(CMaterial *pMat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMaterial* CMaterialLoader::LoadAssimpMaterial(const aiMaterial *pAiMat)
|
||||||
|
{
|
||||||
|
// todo: generate new material using import values.
|
||||||
|
CMaterial *pMat = new CMaterial(mVersion, eNoAttributes);
|
||||||
|
|
||||||
|
// Create generic custom pass that uses Konst color
|
||||||
|
CMaterialPass *pPass = new CMaterialPass(pMat);
|
||||||
|
pPass->SetColorInputs(eZeroRGB, eRasRGB, eKonstRGB, eZeroRGB);
|
||||||
|
pPass->SetAlphaInputs(eZeroAlpha, eZeroAlpha, eZeroAlpha, eKonstAlpha);
|
||||||
|
pPass->SetKColorSel(eKonst0_RGB);
|
||||||
|
pPass->SetKAlphaSel(eKonstOne);
|
||||||
|
pPass->SetRasSel(eRasColor0A0);
|
||||||
|
pMat->mKonstColors[0] = CColor::RandomLightColor(false);
|
||||||
|
pMat->mPasses.push_back(pPass);
|
||||||
|
|
||||||
|
return pMat;
|
||||||
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CMaterialSet* CMaterialLoader::LoadMaterialSet(CInputStream& Mat, EGame Version)
|
CMaterialSet* CMaterialLoader::LoadMaterialSet(CInputStream& Mat, EGame Version)
|
||||||
{
|
{
|
||||||
|
@ -591,3 +609,20 @@ CMaterialSet* CMaterialLoader::LoadMaterialSet(CInputStream& Mat, EGame Version)
|
||||||
|
|
||||||
return Loader.mpSet;
|
return Loader.mpSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMaterialSet* CMaterialLoader::ImportAssimpMaterials(const aiScene *pScene, EGame targetVersion)
|
||||||
|
{
|
||||||
|
CMaterialLoader loader;
|
||||||
|
loader.mVersion = targetVersion;
|
||||||
|
|
||||||
|
CMaterialSet *pOut = new CMaterialSet();
|
||||||
|
pOut->mMaterials.reserve(pScene->mNumMaterials);
|
||||||
|
|
||||||
|
for (u32 iMat = 0; iMat < pScene->mNumMaterials; iMat++)
|
||||||
|
{
|
||||||
|
CMaterial *pMat = loader.LoadAssimpMaterial(pScene->mMaterials[iMat]);
|
||||||
|
pOut->mMaterials.push_back(pMat);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#ifndef CMATERIALLOADER_H
|
#ifndef CMATERIALLOADER_H
|
||||||
#define CMATERIALLOADER_H
|
#define CMATERIALLOADER_H
|
||||||
|
|
||||||
#include <FileIO/FileIO.h>
|
|
||||||
#include "../CMaterialSet.h"
|
#include "../CMaterialSet.h"
|
||||||
#include "../EFormatVersion.h"
|
#include "../EFormatVersion.h"
|
||||||
#include <Core/CResCache.h>
|
#include <Core/CResCache.h>
|
||||||
|
|
||||||
|
#include <FileIO/FileIO.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
class CMaterialLoader
|
class CMaterialLoader
|
||||||
{
|
{
|
||||||
// Material data
|
// Material data
|
||||||
|
@ -32,9 +34,12 @@ class CMaterialLoader
|
||||||
CMaterial* ReadCorruptionMaterial();
|
CMaterial* ReadCorruptionMaterial();
|
||||||
void CreateCorruptionPasses(CMaterial *pMat);
|
void CreateCorruptionPasses(CMaterial *pMat);
|
||||||
|
|
||||||
|
CMaterial* LoadAssimpMaterial(const aiMaterial *pAiMat);
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
public:
|
public:
|
||||||
static CMaterialSet* LoadMaterialSet(CInputStream& Mat, EGame Version);
|
static CMaterialSet* LoadMaterialSet(CInputStream& Mat, EGame Version);
|
||||||
|
static CMaterialSet* ImportAssimpMaterials(const aiScene *pScene, EGame targetVersion);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CMATERIALLOADER_H
|
#endif // CMATERIALLOADER_H
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
CModelLoader::CModelLoader()
|
CModelLoader::CModelLoader()
|
||||||
{
|
{
|
||||||
mFlags = eNoFlags;
|
mFlags = eNoFlags;
|
||||||
|
mNumVertices = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CModelLoader::~CModelLoader()
|
CModelLoader::~CModelLoader()
|
||||||
|
@ -272,6 +273,99 @@ void CModelLoader::LoadSurfaceHeaderDKCR(CInputStream& Model, SSurface *pSurf)
|
||||||
Model.SeekToBoundary(32);
|
Model.SeekToBoundary(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pMesh, CMaterialSet *pSet)
|
||||||
|
{
|
||||||
|
// Create vertex description and assign it to material
|
||||||
|
CMaterial *pMat = pSet->MaterialByIndex(pMesh->mMaterialIndex);
|
||||||
|
EVertexDescription desc = pMat->VtxDesc();
|
||||||
|
|
||||||
|
if (desc == eNoAttributes)
|
||||||
|
{
|
||||||
|
if (pMesh->HasPositions()) desc |= ePosition;
|
||||||
|
if (pMesh->HasNormals()) desc |= eNormal;
|
||||||
|
|
||||||
|
for (u32 iUV = 0; iUV < pMesh->GetNumUVChannels(); iUV++)
|
||||||
|
desc |= (eTex0 << (iUV * 2));
|
||||||
|
|
||||||
|
pMat->SetVertexDescription(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create surface
|
||||||
|
SSurface *pSurf = new SSurface();
|
||||||
|
pSurf->MaterialID = pMesh->mMaterialIndex;
|
||||||
|
|
||||||
|
if (pMesh->mNumFaces > 0)
|
||||||
|
{
|
||||||
|
pSurf->Primitives.resize(1);
|
||||||
|
SSurface::SPrimitive& prim = pSurf->Primitives[0];
|
||||||
|
|
||||||
|
// Check primitive type on first face
|
||||||
|
u32 numIndices = pMesh->mFaces[0].mNumIndices;
|
||||||
|
if (numIndices == 1) prim.Type = eGX_Points;
|
||||||
|
else if (numIndices == 2) prim.Type = eGX_Lines;
|
||||||
|
else if (numIndices == 3) prim.Type = eGX_Triangles;
|
||||||
|
|
||||||
|
// Generate bounding box, center point, and reflection projection
|
||||||
|
pSurf->CenterPoint = CVector3f::skZero;
|
||||||
|
pSurf->ReflectionDirection = CVector3f::skZero;
|
||||||
|
|
||||||
|
for (u32 iVtx = 0; iVtx < pMesh->mNumVertices; iVtx++)
|
||||||
|
{
|
||||||
|
aiVector3D aiPos = pMesh->mVertices[iVtx];
|
||||||
|
pSurf->AABox.ExpandBounds(CVector3f(aiPos.x, aiPos.y, aiPos.z));
|
||||||
|
|
||||||
|
if (pMesh->HasNormals()) {
|
||||||
|
aiVector3D aiNrm = pMesh->mNormals[iVtx];
|
||||||
|
pSurf->ReflectionDirection += CVector3f(aiNrm.x, aiNrm.y, aiNrm.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pSurf->CenterPoint = pSurf->AABox.Center();
|
||||||
|
|
||||||
|
if (pMesh->HasNormals())
|
||||||
|
pSurf->ReflectionDirection /= pMesh->mNumVertices;
|
||||||
|
else
|
||||||
|
pSurf->ReflectionDirection = CVector3f(1.f, 0.f, 0.f);
|
||||||
|
|
||||||
|
// Set vertex/triangle count
|
||||||
|
pSurf->VertexCount = pMesh->mNumVertices;
|
||||||
|
pSurf->TriangleCount = (prim.Type == eGX_Triangles ? pMesh->mNumFaces : 0);
|
||||||
|
|
||||||
|
// Create primitive
|
||||||
|
for (u32 iFace = 0; iFace < pMesh->mNumFaces; iFace++)
|
||||||
|
{
|
||||||
|
for (u32 iIndex = 0; iIndex < numIndices; iIndex++)
|
||||||
|
{
|
||||||
|
u32 index = pMesh->mFaces[iFace].mIndices[iIndex];
|
||||||
|
|
||||||
|
// Create vertex and add it to the primitive
|
||||||
|
CVertex vert;
|
||||||
|
vert.ArrayPosition = index + mNumVertices;
|
||||||
|
|
||||||
|
if (pMesh->HasPositions()) {
|
||||||
|
aiVector3D aiPos = pMesh->mVertices[index];
|
||||||
|
vert.Position = CVector3f(aiPos.x, aiPos.y, aiPos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMesh->HasNormals()) {
|
||||||
|
aiVector3D aiNrm = pMesh->mNormals[index];
|
||||||
|
vert.Normal = CVector3f(aiNrm.x, aiNrm.y, aiNrm.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 iTex = 0; iTex < pMesh->GetNumUVChannels(); iTex++) {
|
||||||
|
aiVector3D aiTex = pMesh->mTextureCoords[iTex][index];
|
||||||
|
vert.Tex[iTex] = CVector2f(aiTex.x, aiTex.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
prim.Vertices.push_back(vert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mNumVertices += pMesh->mNumVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pSurf;
|
||||||
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CModel* CModelLoader::LoadCMDL(CInputStream& CMDL)
|
CModel* CModelLoader::LoadCMDL(CInputStream& CMDL)
|
||||||
{
|
{
|
||||||
|
@ -451,6 +545,27 @@ CModel* CModelLoader::LoadCorruptionWorldModel(CInputStream &MREA, CBlockMgrIn &
|
||||||
return pModel;
|
return pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CModel* CModelLoader::ImportAssimpNode(const aiNode *pNode, const aiScene *pScene, CMaterialSet& matSet)
|
||||||
|
{
|
||||||
|
CModelLoader loader;
|
||||||
|
loader.mpModel = new CModel(&matSet, true);
|
||||||
|
loader.mpModel->mSurfaces.reserve(pNode->mNumMeshes);
|
||||||
|
|
||||||
|
for (u32 iMesh = 0; iMesh < pNode->mNumMeshes; iMesh++)
|
||||||
|
{
|
||||||
|
u32 meshIndex = pNode->mMeshes[iMesh];
|
||||||
|
const aiMesh *pMesh = pScene->mMeshes[meshIndex];
|
||||||
|
SSurface *pSurf = loader.LoadAssimpMesh(pMesh, &matSet);
|
||||||
|
|
||||||
|
loader.mpModel->mSurfaces.push_back(pSurf);
|
||||||
|
loader.mpModel->mAABox.ExpandBounds(pSurf->AABox);
|
||||||
|
loader.mpModel->mVertexCount += pSurf->VertexCount;
|
||||||
|
loader.mpModel->mTriangleCount += pSurf->TriangleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loader.mpModel;
|
||||||
|
}
|
||||||
|
|
||||||
EGame CModelLoader::GetFormatVersion(u32 Version)
|
EGame CModelLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <FileIO/FileIO.h>
|
#include <FileIO/FileIO.h>
|
||||||
#include <Core/CResCache.h>
|
#include <Core/CResCache.h>
|
||||||
#include <Common/EnumUtil.h>
|
#include <Common/EnumUtil.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
class CModelLoader
|
class CModelLoader
|
||||||
{
|
{
|
||||||
|
@ -28,6 +29,7 @@ private:
|
||||||
CAABox mAABox;
|
CAABox mAABox;
|
||||||
EGame mVersion;
|
EGame mVersion;
|
||||||
|
|
||||||
|
u32 mNumVertices;
|
||||||
std::vector<CVector3f> mPositions;
|
std::vector<CVector3f> mPositions;
|
||||||
std::vector<CVector3f> mNormals;
|
std::vector<CVector3f> mNormals;
|
||||||
std::vector<CColor> mColors;
|
std::vector<CColor> mColors;
|
||||||
|
@ -49,11 +51,13 @@ private:
|
||||||
SSurface* LoadSurface(CInputStream& Model);
|
SSurface* LoadSurface(CInputStream& Model);
|
||||||
void LoadSurfaceHeaderPrime(CInputStream& Model, SSurface *pSurf);
|
void LoadSurfaceHeaderPrime(CInputStream& Model, SSurface *pSurf);
|
||||||
void LoadSurfaceHeaderDKCR(CInputStream& Model, SSurface *pSurf);
|
void LoadSurfaceHeaderDKCR(CInputStream& Model, SSurface *pSurf);
|
||||||
|
SSurface* LoadAssimpMesh(const aiMesh *pMesh, CMaterialSet *pSet);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CModel* LoadCMDL(CInputStream& CMDL);
|
static CModel* LoadCMDL(CInputStream& CMDL);
|
||||||
static CModel* LoadWorldModel(CInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, EGame Version);
|
static CModel* LoadWorldModel(CInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, EGame Version);
|
||||||
static CModel* LoadCorruptionWorldModel(CInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, u32 HeaderSecNum, u32 GPUSecNum, EGame Version);
|
static CModel* LoadCorruptionWorldModel(CInputStream& MREA, CBlockMgrIn& BlockMgr, CMaterialSet& MatSet, u32 HeaderSecNum, u32 GPUSecNum, EGame Version);
|
||||||
|
static CModel* ImportAssimpNode(const aiNode *pNode, const aiScene *pScene, CMaterialSet& matSet);
|
||||||
static EGame GetFormatVersion(u32 Version);
|
static EGame GetFormatVersion(u32 Version);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,17 @@ CModel::CModel() : CBasicModel()
|
||||||
mTriangleCount = 0;
|
mTriangleCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CModel::CModel(CMaterialSet *pSet, bool ownsMatSet)
|
||||||
|
{
|
||||||
|
mHasOwnMaterials = ownsMatSet;
|
||||||
|
mHasOwnSurfaces = true;
|
||||||
|
mVertexCount = 0;
|
||||||
|
mTriangleCount = 0;
|
||||||
|
|
||||||
|
mMaterialSets.resize(1);
|
||||||
|
mMaterialSets[0] = pSet;
|
||||||
|
}
|
||||||
|
|
||||||
CModel::~CModel()
|
CModel::~CModel()
|
||||||
{
|
{
|
||||||
if (mHasOwnMaterials)
|
if (mHasOwnMaterials)
|
||||||
|
@ -99,6 +110,7 @@ void CModel::DrawSurface(ERenderOptions Options, u32 Surface, u32 MatSet)
|
||||||
|
|
||||||
// Draw IBOs
|
// Draw IBOs
|
||||||
mVBO.Bind();
|
mVBO.Bind();
|
||||||
|
glLineWidth(1.f);
|
||||||
|
|
||||||
for (u32 iIBO = 0; iIBO < mSubmeshIndexBuffers[Surface].size(); iIBO++)
|
for (u32 iIBO = 0; iIBO < mSubmeshIndexBuffers[Surface].size(); iIBO++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@ class CModel : public CBasicModel
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CModel();
|
CModel();
|
||||||
CModel(CMaterialSet *pSet);
|
CModel(CMaterialSet *pSet, bool ownsMatSet);
|
||||||
~CModel();
|
~CModel();
|
||||||
|
|
||||||
void BufferGL();
|
void BufferGL();
|
||||||
|
|
Loading…
Reference in New Issue