diff --git a/include/Nazara/Utility/Joint.hpp b/include/Nazara/Utility/Joint.hpp index 6740d1e52..64f48f034 100644 --- a/include/Nazara/Utility/Joint.hpp +++ b/include/Nazara/Utility/Joint.hpp @@ -21,18 +21,26 @@ class NAZARA_API NzJoint : public NzNode NzJoint(const NzJoint& joint); ~NzJoint() = default; - NzMatrix4f GetInverseBindMatrix() const; + void EnsureSkinningMatrixUpdate() const; + + const NzMatrix4f& GetInverseBindMatrix() const; NzString GetName() const; NzSkeleton* GetSkeleton(); const NzSkeleton* GetSkeleton() const; + const NzMatrix4f& GetSkinningMatrix() const; void SetInverseBindMatrix(const NzMatrix4f& matrix); void SetName(const NzString& name); private: + void InvalidateNode(); + void UpdateSkinningMatrix() const; + NzMatrix4f m_inverseBindMatrix; + mutable NzMatrix4f m_skinningMatrix; NzString m_name; NzSkeleton* m_skeleton; + mutable bool m_skinningMatrixUpdated; }; #endif // NAZARA_JOINT_HPP diff --git a/src/Nazara/Utility/Joint.cpp b/src/Nazara/Utility/Joint.cpp index 060b5eb52..8a46ff227 100644 --- a/src/Nazara/Utility/Joint.cpp +++ b/src/Nazara/Utility/Joint.cpp @@ -7,7 +7,8 @@ #include NzJoint::NzJoint(NzSkeleton* skeleton) : -m_skeleton(skeleton) +m_skeleton(skeleton), +m_skinningMatrixUpdated(false) { } @@ -15,11 +16,18 @@ NzJoint::NzJoint(const NzJoint& joint) : NzNode(joint), m_inverseBindMatrix(joint.m_inverseBindMatrix), m_name(joint.m_name), -m_skeleton(joint.m_skeleton) +m_skeleton(joint.m_skeleton), +m_skinningMatrixUpdated(false) { } -NzMatrix4f NzJoint::GetInverseBindMatrix() const +void NzJoint::EnsureSkinningMatrixUpdate() const +{ + if (!m_skinningMatrixUpdated) + UpdateSkinningMatrix(); +} + +const NzMatrix4f& NzJoint::GetInverseBindMatrix() const { return m_inverseBindMatrix; } @@ -39,9 +47,18 @@ const NzSkeleton* NzJoint::GetSkeleton() const return m_skeleton; } +const NzMatrix4f& NzJoint::GetSkinningMatrix() const +{ + if (!m_skinningMatrixUpdated) + UpdateSkinningMatrix(); + + return m_skinningMatrix; +} + void NzJoint::SetInverseBindMatrix(const NzMatrix4f& matrix) { m_inverseBindMatrix = matrix; + m_skinningMatrixUpdated = false; } void NzJoint::SetName(const NzString& name) @@ -50,3 +67,20 @@ void NzJoint::SetName(const NzString& name) m_skeleton->InvalidateJointMap(); } + +void NzJoint::InvalidateNode() +{ + NzNode::InvalidateNode(); + + m_skinningMatrixUpdated = false; +} + +void NzJoint::UpdateSkinningMatrix() const +{ + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_skinningMatrix.Set(m_inverseBindMatrix); + m_skinningMatrix.ConcatenateAffine(m_transformMatrix); + m_skinningMatrixUpdated = true; +}