From 50dcc9cc1a9a5d4b55a29f34a31df185735b11a2 Mon Sep 17 00:00:00 2001 From: parax0 Date: Wed, 27 Apr 2016 20:36:50 -0600 Subject: [PATCH] Pre-transform bones with inverse bind instead of sending it to the shader --- src/Core/OpenGL/CShaderGenerator.cpp | 6 ++---- src/Core/Render/CGraphics.cpp | 18 +++--------------- src/Core/Render/CGraphics.h | 3 --- src/Core/Resource/CSkeleton.cpp | 15 +++++++++++---- src/Core/Resource/CSkeleton.h | 7 ++----- src/Core/Resource/Factory/CSkeletonLoader.cpp | 4 +--- src/Core/Scene/CCharacterNode.cpp | 1 - 7 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/Core/OpenGL/CShaderGenerator.cpp b/src/Core/OpenGL/CShaderGenerator.cpp index f3ecb2c1..1de69944 100644 --- a/src/Core/OpenGL/CShaderGenerator.cpp +++ b/src/Core/OpenGL/CShaderGenerator.cpp @@ -227,7 +227,6 @@ bool CShaderGenerator::CreateVertexShader(const CMaterial& rkMat) ShaderCode << "layout(std140) uniform BoneTransformBlock\n" << "{\n" << " mat4 BoneTransforms[100];\n" - << " mat4 InverseBindTransforms[100];\n" << "};\n" << "\n"; } @@ -260,11 +259,10 @@ bool CShaderGenerator::CreateVertexShader(const CMaterial& rkMat) << " \n" << " if (BoneIdx > 0)\n" << " {\n" - << " mat4 BoneSpaceTransform = InverseBindTransforms[BoneIdx] * BoneTransforms[BoneIdx];\n" - << " ModelSpacePos += vec3(vec4(RawPosition, 1) * BoneSpaceTransform * Weight);\n"; + << " ModelSpacePos += vec3(vec4(RawPosition, 1) * BoneTransforms[BoneIdx] * Weight);\n"; if (VtxDesc & eNormal) - ShaderCode << " ModelSpaceNormal += RawNormal.xyz * inverse(transpose(mat3(BoneSpaceTransform))) * Weight;\n"; + ShaderCode << " ModelSpaceNormal += RawNormal.xyz * inverse(transpose(mat3(BoneTransforms[BoneIdx]))) * Weight;\n"; ShaderCode << " }\n" << " }\n" diff --git a/src/Core/Render/CGraphics.cpp b/src/Core/Render/CGraphics.cpp index 997585f3..42bf3d97 100644 --- a/src/Core/Render/CGraphics.cpp +++ b/src/Core/Render/CGraphics.cpp @@ -14,7 +14,6 @@ u32 CGraphics::mActiveContext = -1; bool CGraphics::mInitialized = false; std::vector CGraphics::mVAMs; bool CGraphics::mIdentityBoneTransforms = false; -const CSkeleton *CGraphics::mpkCurrentSkeleton = nullptr; CGraphics::SMVPBlock CGraphics::sMVPBlock; CGraphics::SVertexBlock CGraphics::sVertexBlock; @@ -47,7 +46,7 @@ void CGraphics::Initialize() mpVertexBlockBuffer = new CUniformBuffer(sizeof(sVertexBlock)); mpPixelBlockBuffer = new CUniformBuffer(sizeof(sPixelBlock)); mpLightBlockBuffer = new CUniformBuffer(sizeof(sLightBlock)); - mpBoneTransformBuffer = new CUniformBuffer(sizeof(CTransform4f) * 200); + mpBoneTransformBuffer = new CUniformBuffer(sizeof(CTransform4f) * 100); sLightMode = eWorldLighting; sNumLights = 0; @@ -197,24 +196,13 @@ void CGraphics::LoadBoneTransforms(const CBoneTransformData& rkData) mIdentityBoneTransforms = false; } -void CGraphics::LoadBoneInverseBindTransforms(CSkeleton *pSkel) -{ - if (mpkCurrentSkeleton != pSkel) - { - mpBoneTransformBuffer->BufferRange(pSkel->InverseBindMatricesData(), sizeof(CTransform4f) * 100, pSkel->InverseBindMatricesSize()); - mpkCurrentSkeleton = pSkel; - mIdentityBoneTransforms = false; - } -} - void CGraphics::LoadIdentityBoneTransforms() { - static CTransform4f IdentityTransforms[200]; + static const CTransform4f skIdentityTransforms[100]; if (!mIdentityBoneTransforms) { - mpBoneTransformBuffer->Buffer(&IdentityTransforms); - mpkCurrentSkeleton = nullptr; + mpBoneTransformBuffer->Buffer(&skIdentityTransforms); mIdentityBoneTransforms = true; } } diff --git a/src/Core/Render/CGraphics.h b/src/Core/Render/CGraphics.h index fde3e607..ea94a8fd 100644 --- a/src/Core/Render/CGraphics.h +++ b/src/Core/Render/CGraphics.h @@ -29,9 +29,7 @@ class CGraphics static u32 mActiveContext; static bool mInitialized; static std::vector mVAMs; - static bool mIdentityBoneTransforms; - static const CSkeleton *mpkCurrentSkeleton; public: // SMVPBlock @@ -109,7 +107,6 @@ public: static void SetupAmbientColor(); static void SetIdentityMVP(); static void LoadBoneTransforms(const CBoneTransformData& rkData); - static void LoadBoneInverseBindTransforms(CSkeleton *pSkel); static void LoadIdentityBoneTransforms(); }; diff --git a/src/Core/Resource/CSkeleton.cpp b/src/Core/Resource/CSkeleton.cpp index 32e96e63..84e0a38c 100644 --- a/src/Core/Resource/CSkeleton.cpp +++ b/src/Core/Resource/CSkeleton.cpp @@ -29,6 +29,13 @@ void CBone::UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float for (u32 iChild = 0; iChild < mChildren.size(); iChild++) mChildren[iChild]->UpdateTransform(rData, pAnim, Time, AnchorRoot); + + rTransform *= mInvBind; +} + +CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const +{ + return rkData[mID] * AbsolutePosition(); } bool CBone::IsRoot() const @@ -84,12 +91,12 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData& rkDat for (u32 iBone = 0; iBone < mBones.size(); iBone++) { CBone *pBone = mBones[iBone]; - const CTransform4f& rkBoneTransform = rkData[pBone->ID()]; + CVector3f BonePos = pBone->TransformedPosition(rkData); // Draw bone CTransform4f Transform; Transform.Scale(skSphereRadius); - Transform.Translate(rkBoneTransform.ExtractTranslation()); + Transform.Translate(BonePos); CGraphics::sMVPBlock.ModelMatrix = Transform; CGraphics::UpdateMVPBlock(); CDrawUtil::DrawSphere(CColor::skWhite); @@ -100,8 +107,8 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData& rkDat for (u32 iChild = 0; iChild < pBone->NumChildren(); iChild++) { - const CTransform4f& rkChildTransform = rkData[pBone->ChildByIndex(iChild)->ID()]; - CDrawUtil::DrawLine(rkBoneTransform.ExtractTranslation(), rkChildTransform.ExtractTranslation()); + CVector3f ChildPos = pBone->ChildByIndex(iChild)->TransformedPosition(rkData); + CDrawUtil::DrawLine(BonePos, ChildPos); } } } diff --git a/src/Core/Resource/CSkeleton.h b/src/Core/Resource/CSkeleton.h index f54e3421..ae82fca5 100644 --- a/src/Core/Resource/CSkeleton.h +++ b/src/Core/Resource/CSkeleton.h @@ -19,7 +19,6 @@ class CSkeleton : public CResource CBone *mpRootBone; std::vector mBones; - std::vector mInvBindMatrices; static const float skSphereRadius; @@ -34,9 +33,6 @@ public: std::pair RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData); inline u32 NumBones() const { return mBones.size(); } - inline const CTransform4f& BoneInverseBindMatrix(u32 BoneID) const { return mInvBindMatrices[BoneID]; } - inline const void* InverseBindMatricesData() const { return mInvBindMatrices.data(); } - inline u32 InverseBindMatricesSize() const { return mInvBindMatrices.size() * sizeof(CTransform4f); } }; class CBone @@ -49,10 +45,12 @@ class CBone u32 mID; CVector3f mPosition; TString mName; + CTransform4f mInvBind; public: CBone(CSkeleton *pSkel); void UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot); + CVector3f TransformedPosition(const CBoneTransformData& rkData) const; bool IsRoot() const; // Accessors @@ -64,7 +62,6 @@ public: inline CVector3f Position() const { return mPosition; } inline CVector3f AbsolutePosition() const { return mPosition + (mpParent ? mpParent->AbsolutePosition() : CVector3f::skZero); } inline TString Name() const { return mName; } - inline const CTransform4f& InverseBindMtx() const { return mpSkeleton->BoneInverseBindMatrix(mID); } }; #endif // CSKELETON_H diff --git a/src/Core/Resource/Factory/CSkeletonLoader.cpp b/src/Core/Resource/Factory/CSkeletonLoader.cpp index fb383564..8cd8fea7 100644 --- a/src/Core/Resource/Factory/CSkeletonLoader.cpp +++ b/src/Core/Resource/Factory/CSkeletonLoader.cpp @@ -14,12 +14,10 @@ void CSkeletonLoader::SetLocalBoneCoords(CBone *pBone) void CSkeletonLoader::CalculateBoneInverseBindMatrices() { - mpSkeleton->mInvBindMatrices.resize(mpSkeleton->MaxBoneID() + 1); - for (u32 iBone = 0; iBone < mpSkeleton->mBones.size(); iBone++) { CBone *pBone = mpSkeleton->mBones[iBone]; - mpSkeleton->mInvBindMatrices[pBone->ID()] = CTransform4f::TranslationMatrix(-pBone->AbsolutePosition()); + pBone->mInvBind = CTransform4f::TranslationMatrix(-pBone->AbsolutePosition()); } } diff --git a/src/Core/Scene/CCharacterNode.cpp b/src/Core/Scene/CCharacterNode.cpp index 64d4e056..74d56c9a 100644 --- a/src/Core/Scene/CCharacterNode.cpp +++ b/src/Core/Scene/CCharacterNode.cpp @@ -73,7 +73,6 @@ void CCharacterNode::Draw(FRenderOptions Options, int ComponentIndex, const SVie // Draw surface OR draw entire model CGraphics::LoadBoneTransforms(mTransformData); - CGraphics::LoadBoneInverseBindTransforms(pSkel); CModel *pModel = mpCharacter->NodeModel(mActiveCharSet); if (ComponentIndex < 0)