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);
|
||||
}
|
||||
|
||||
// ************ 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
|
||||
const CColor CColor::skRed (u32(0xFF0000FF));
|
||||
const CColor CColor::skGreen (u32(0x00FF00FF));
|
||||
|
|
|
@ -36,6 +36,11 @@ public:
|
|||
CColor operator/(const CColor& other) const;
|
||||
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
|
||||
static const CColor skRed;
|
||||
static const CColor skGreen;
|
||||
|
|
|
@ -342,3 +342,9 @@ RESOURCES += \
|
|||
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;
|
||||
}
|
||||
|
||||
void CMaterial::SetVertexDescription(EVertexDescription desc)
|
||||
{
|
||||
mVtxDesc = desc;
|
||||
mRecalcHash = true;
|
||||
}
|
||||
|
||||
void CMaterial::SetBlendMode(GLenum SrcFac, GLenum DstFac)
|
||||
{
|
||||
mBlendSrcFac = SrcFac;
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
// Setters
|
||||
void SetName(const std::string& name);
|
||||
void SetOptions(EMaterialOptions Options);
|
||||
void SetVertexDescription(EVertexDescription desc);
|
||||
void SetBlendMode(GLenum SrcFac, GLenum DstFac);
|
||||
void SetKonst(CColor& Konst, u32 KIndex);
|
||||
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 ************
|
||||
CMaterialSet* CMaterialLoader::LoadMaterialSet(CInputStream& Mat, EGame Version)
|
||||
{
|
||||
|
@ -591,3 +609,20 @@ CMaterialSet* CMaterialLoader::LoadMaterialSet(CInputStream& Mat, EGame Version)
|
|||
|
||||
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
|
||||
#define CMATERIALLOADER_H
|
||||
|
||||
#include <FileIO/FileIO.h>
|
||||
#include "../CMaterialSet.h"
|
||||
#include "../EFormatVersion.h"
|
||||
#include <Core/CResCache.h>
|
||||
|
||||
#include <FileIO/FileIO.h>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
class CMaterialLoader
|
||||
{
|
||||
// Material data
|
||||
|
@ -32,9 +34,12 @@ class CMaterialLoader
|
|||
CMaterial* ReadCorruptionMaterial();
|
||||
void CreateCorruptionPasses(CMaterial *pMat);
|
||||
|
||||
CMaterial* LoadAssimpMaterial(const aiMaterial *pAiMat);
|
||||
|
||||
// Static
|
||||
public:
|
||||
static CMaterialSet* LoadMaterialSet(CInputStream& Mat, EGame Version);
|
||||
static CMaterialSet* ImportAssimpMaterials(const aiScene *pScene, EGame targetVersion);
|
||||
};
|
||||
|
||||
#endif // CMATERIALLOADER_H
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
CModelLoader::CModelLoader()
|
||||
{
|
||||
mFlags = eNoFlags;
|
||||
mNumVertices = 0;
|
||||
}
|
||||
|
||||
CModelLoader::~CModelLoader()
|
||||
|
@ -272,6 +273,99 @@ void CModelLoader::LoadSurfaceHeaderDKCR(CInputStream& Model, SSurface *pSurf)
|
|||
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 ************
|
||||
CModel* CModelLoader::LoadCMDL(CInputStream& CMDL)
|
||||
{
|
||||
|
@ -451,6 +545,27 @@ CModel* CModelLoader::LoadCorruptionWorldModel(CInputStream &MREA, CBlockMgrIn &
|
|||
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)
|
||||
{
|
||||
switch (Version)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <FileIO/FileIO.h>
|
||||
#include <Core/CResCache.h>
|
||||
#include <Common/EnumUtil.h>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
class CModelLoader
|
||||
{
|
||||
|
@ -28,6 +29,7 @@ private:
|
|||
CAABox mAABox;
|
||||
EGame mVersion;
|
||||
|
||||
u32 mNumVertices;
|
||||
std::vector<CVector3f> mPositions;
|
||||
std::vector<CVector3f> mNormals;
|
||||
std::vector<CColor> mColors;
|
||||
|
@ -49,11 +51,13 @@ private:
|
|||
SSurface* LoadSurface(CInputStream& Model);
|
||||
void LoadSurfaceHeaderPrime(CInputStream& Model, SSurface *pSurf);
|
||||
void LoadSurfaceHeaderDKCR(CInputStream& Model, SSurface *pSurf);
|
||||
SSurface* LoadAssimpMesh(const aiMesh *pMesh, CMaterialSet *pSet);
|
||||
|
||||
public:
|
||||
static CModel* LoadCMDL(CInputStream& CMDL);
|
||||
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* ImportAssimpNode(const aiNode *pNode, const aiScene *pScene, CMaterialSet& matSet);
|
||||
static EGame GetFormatVersion(u32 Version);
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,17 @@ CModel::CModel() : CBasicModel()
|
|||
mTriangleCount = 0;
|
||||
}
|
||||
|
||||
CModel::CModel(CMaterialSet *pSet, bool ownsMatSet)
|
||||
{
|
||||
mHasOwnMaterials = ownsMatSet;
|
||||
mHasOwnSurfaces = true;
|
||||
mVertexCount = 0;
|
||||
mTriangleCount = 0;
|
||||
|
||||
mMaterialSets.resize(1);
|
||||
mMaterialSets[0] = pSet;
|
||||
}
|
||||
|
||||
CModel::~CModel()
|
||||
{
|
||||
if (mHasOwnMaterials)
|
||||
|
@ -99,6 +110,7 @@ void CModel::DrawSurface(ERenderOptions Options, u32 Surface, u32 MatSet)
|
|||
|
||||
// Draw IBOs
|
||||
mVBO.Bind();
|
||||
glLineWidth(1.f);
|
||||
|
||||
for (u32 iIBO = 0; iIBO < mSubmeshIndexBuffers[Surface].size(); iIBO++)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@ class CModel : public CBasicModel
|
|||
|
||||
public:
|
||||
CModel();
|
||||
CModel(CMaterialSet *pSet);
|
||||
CModel(CMaterialSet *pSet, bool ownsMatSet);
|
||||
~CModel();
|
||||
|
||||
void BufferGL();
|
||||
|
|
Loading…
Reference in New Issue