mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 10:49:23 +00:00
Added support for model skinning
This commit is contained in:
@@ -160,6 +160,46 @@ void CModel::DrawWireframe(FRenderOptions Options, CColor WireColor /*= CColor::
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
void CModel::SetSkin(CSkin *pSkin)
|
||||
{
|
||||
if (mpSkin != pSkin)
|
||||
{
|
||||
const FVertexDescription kBoneFlags = (eBoneIndices | eBoneWeights);
|
||||
|
||||
mpSkin = pSkin;
|
||||
mVBO.SetSkin(pSkin);
|
||||
ClearGLBuffer();
|
||||
|
||||
if (pSkin && !mVBO.VertexDesc().HasAllFlags(kBoneFlags))
|
||||
mVBO.SetVertexDesc(mVBO.VertexDesc() | kBoneFlags);
|
||||
else if (!pSkin && mVBO.VertexDesc().HasAnyFlags(kBoneFlags))
|
||||
mVBO.SetVertexDesc(mVBO.VertexDesc() & ~kBoneFlags);
|
||||
|
||||
for (u32 iSet = 0; iSet < mMaterialSets.size(); iSet++)
|
||||
{
|
||||
CMaterialSet *pSet = mMaterialSets[iSet];
|
||||
|
||||
for (u32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
|
||||
{
|
||||
CMaterial *pMat = pSet->MaterialByIndex(iMat);
|
||||
FVertexDescription VtxDesc = pMat->VtxDesc();
|
||||
|
||||
if (pSkin && !VtxDesc.HasAllFlags(kBoneFlags))
|
||||
{
|
||||
VtxDesc |= kBoneFlags;
|
||||
pMat->SetVertexDescription(VtxDesc);
|
||||
}
|
||||
|
||||
else if (!pSkin && VtxDesc.HasAnyFlags(kBoneFlags))
|
||||
{
|
||||
VtxDesc &= ~kBoneFlags;
|
||||
pMat->SetVertexDescription(VtxDesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 CModel::GetMatSetCount()
|
||||
{
|
||||
return mMaterialSets.size();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "CBasicModel.h"
|
||||
#include "SSurface.h"
|
||||
#include "Core/Resource/CMaterialSet.h"
|
||||
#include "Core/Resource/CSkin.h"
|
||||
#include "Core/OpenGL/CIndexBuffer.h"
|
||||
#include "Core/OpenGL/GLCommon.h"
|
||||
#include "Core/Render/FRenderOptions.h"
|
||||
@@ -13,6 +14,7 @@ class CModel : public CBasicModel
|
||||
friend class CModelLoader;
|
||||
friend class CModelCooker;
|
||||
|
||||
TResPtr<CSkin> mpSkin;
|
||||
std::vector<CMaterialSet*> mMaterialSets;
|
||||
std::vector<std::vector<CIndexBuffer>> mSurfaceIndexBuffers;
|
||||
bool mHasOwnMaterials;
|
||||
@@ -28,6 +30,7 @@ public:
|
||||
void Draw(FRenderOptions Options, u32 MatSet);
|
||||
void DrawSurface(FRenderOptions Options, u32 Surface, u32 MatSet);
|
||||
void DrawWireframe(FRenderOptions Options, CColor WireColor = CColor::skWhite);
|
||||
void SetSkin(CSkin *pSkin);
|
||||
|
||||
u32 GetMatSetCount();
|
||||
u32 GetMatCount();
|
||||
@@ -37,6 +40,8 @@ public:
|
||||
bool HasTransparency(u32 MatSet);
|
||||
bool IsSurfaceTransparent(u32 Surface, u32 MatSet);
|
||||
|
||||
bool IsSkinned() const { return (mpSkin != nullptr); }
|
||||
|
||||
private:
|
||||
CIndexBuffer* InternalGetIBO(u32 Surface, EGXPrimitiveType Primitive);
|
||||
};
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#include <Common/CColor.h>
|
||||
#include <Math/CVector2f.h>
|
||||
#include <Math/CVector3f.h>
|
||||
#include <array>
|
||||
|
||||
typedef std::array<u32, 4> TBoneIndices;
|
||||
typedef std::array<float, 4> TBoneWeights;
|
||||
|
||||
class CVertex
|
||||
{
|
||||
@@ -14,6 +18,8 @@ public:
|
||||
CVector3f Normal;
|
||||
CColor Color[2];
|
||||
CVector2f Tex[8];
|
||||
TBoneIndices BoneIndices;
|
||||
TBoneWeights BoneWeights;
|
||||
u8 MatrixIndices[8];
|
||||
|
||||
CVertex() {}
|
||||
@@ -35,7 +41,9 @@ public:
|
||||
(Tex[4] == rkOther.Tex[4]) &&
|
||||
(Tex[5] == rkOther.Tex[5]) &&
|
||||
(Tex[6] == rkOther.Tex[6]) &&
|
||||
(Tex[7] == rkOther.Tex[7]));
|
||||
(Tex[7] == rkOther.Tex[7]) &&
|
||||
(BoneIndices == rkOther.BoneIndices) &&
|
||||
(BoneWeights == rkOther.BoneWeights));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
32
src/Core/Resource/Model/EVertexAttribute.cpp
Normal file
32
src/Core/Resource/Model/EVertexAttribute.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "EVertexAttribute.h"
|
||||
#include <Common/Log.h>
|
||||
|
||||
const u32 gkNumVertexAttribs = 22;
|
||||
|
||||
u32 VertexAttributeSize(EVertexAttribute Attrib)
|
||||
{
|
||||
switch (Attrib)
|
||||
{
|
||||
case ePosition:
|
||||
case eNormal:
|
||||
return 0x0C;
|
||||
case eColor0:
|
||||
case eColor1:
|
||||
case eBoneWeights:
|
||||
return 0x10;
|
||||
case eTex0:
|
||||
case eTex1:
|
||||
case eTex2:
|
||||
case eTex3:
|
||||
case eTex4:
|
||||
case eTex5:
|
||||
case eTex6:
|
||||
case eTex7:
|
||||
return 0x08;
|
||||
case eBoneIndices:
|
||||
return 0x04;
|
||||
default:
|
||||
Log::Error("AttributeSize(): Unknown vertex attribute: " + TString::FromInt32(Attrib, 0, 10));
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
@@ -6,28 +6,33 @@
|
||||
enum EVertexAttribute
|
||||
{
|
||||
eNoAttributes = 0x0,
|
||||
ePosition = 0x3,
|
||||
eNormal = 0xC,
|
||||
eColor0 = 0x30,
|
||||
eColor1 = 0xC0,
|
||||
eTex0 = 0x300,
|
||||
eTex1 = 0xC00,
|
||||
eTex2 = 0x3000,
|
||||
eTex3 = 0xC000,
|
||||
eTex4 = 0x30000,
|
||||
eTex5 = 0xC0000,
|
||||
eTex6 = 0x300000,
|
||||
eTex7 = 0xC00000,
|
||||
ePosMtx = 0x1000000,
|
||||
eTex0Mtx = 0x2000000,
|
||||
eTex1Mtx = 0x4000000,
|
||||
eTex2Mtx = 0x8000000,
|
||||
eTex3Mtx = 0x10000000,
|
||||
eTex4Mtx = 0x20000000,
|
||||
eTex5Mtx = 0x40000000,
|
||||
eTex6Mtx = 0x80000000
|
||||
ePosition = 0x1,
|
||||
eNormal = 0x2,
|
||||
eColor0 = 0x4,
|
||||
eColor1 = 0x8,
|
||||
eTex0 = 0x10,
|
||||
eTex1 = 0x20,
|
||||
eTex2 = 0x40,
|
||||
eTex3 = 0x80,
|
||||
eTex4 = 0x100,
|
||||
eTex5 = 0x200,
|
||||
eTex6 = 0x400,
|
||||
eTex7 = 0x800,
|
||||
eBoneIndices = 0x1000,
|
||||
eBoneWeights = 0x2000,
|
||||
ePosMtx = 0x4000,
|
||||
eTex0Mtx = 0x8000,
|
||||
eTex1Mtx = 0x10000,
|
||||
eTex2Mtx = 0x20000,
|
||||
eTex3Mtx = 0x40000,
|
||||
eTex4Mtx = 0x80000,
|
||||
eTex5Mtx = 0x100000,
|
||||
eTex6Mtx = 0x200000
|
||||
};
|
||||
DECLARE_FLAGS(EVertexAttribute, FVertexDescription)
|
||||
|
||||
extern const u32 gkNumVertexAttribs;
|
||||
u32 VertexAttributeSize(EVertexAttribute Attrib);
|
||||
|
||||
#endif // EVERTEXATTRIBUTE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user