CSkeleton: Make use of unique_ptr where applicable
Makes ownership semantics explicit.
This commit is contained in:
parent
4dcb539763
commit
e49315a645
|
@ -5,12 +5,12 @@
|
||||||
#include <Common/Macros.h>
|
#include <Common/Macros.h>
|
||||||
#include <Common/Math/MathUtil.h>
|
#include <Common/Math/MathUtil.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
|
||||||
// ************ CBone ************
|
// ************ CBone ************
|
||||||
CBone::CBone(CSkeleton *pSkel)
|
CBone::CBone(CSkeleton *pSkel)
|
||||||
: mpSkeleton(pSkel)
|
: mpSkeleton(pSkel)
|
||||||
, mSelected(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ void CBone::UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo&
|
||||||
rTransform *= mInvBind;
|
rTransform *= mInvBind;
|
||||||
|
|
||||||
// Calculate children
|
// Calculate children
|
||||||
for (uint32 iChild = 0; iChild < mChildren.size(); iChild++)
|
for (auto* child : mChildren)
|
||||||
mChildren[iChild]->UpdateTransform(rData, TransformInfo, pAnim, Time, AnchorRoot);
|
child->UpdateTransform(rData, TransformInfo, pAnim, Time, AnchorRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const
|
CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const
|
||||||
|
@ -58,57 +58,51 @@ bool CBone::IsRoot() const
|
||||||
// In Retro's engine most skeletons have another bone named Skeleton_Root parented directly under the
|
// In Retro's engine most skeletons have another bone named Skeleton_Root parented directly under the
|
||||||
// actual root bone... that bone sometimes acts as the actual root (transforming the entire skeleton),
|
// actual root bone... that bone sometimes acts as the actual root (transforming the entire skeleton),
|
||||||
// so we need to account for both
|
// so we need to account for both
|
||||||
return (mpParent == nullptr || mpParent->Parent() == nullptr);
|
return mpParent == nullptr || mpParent->Parent() == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CSkeleton ************
|
// ************ CSkeleton ************
|
||||||
const float CSkeleton::skSphereRadius = 0.025f;
|
|
||||||
|
|
||||||
CSkeleton::CSkeleton(CResourceEntry *pEntry /*= 0*/)
|
CSkeleton::CSkeleton(CResourceEntry *pEntry)
|
||||||
: CResource(pEntry)
|
: CResource(pEntry)
|
||||||
, mpRootBone(nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CSkeleton::~CSkeleton()
|
CSkeleton::~CSkeleton() = default;
|
||||||
{
|
|
||||||
for (uint32 iBone = 0; iBone < mBones.size(); iBone++)
|
|
||||||
delete mBones[iBone];
|
|
||||||
}
|
|
||||||
|
|
||||||
CBone* CSkeleton::BoneByID(uint32 BoneID) const
|
CBone* CSkeleton::BoneByID(uint32 BoneID) const
|
||||||
{
|
{
|
||||||
for (uint32 iBone = 0; iBone < mBones.size(); iBone++)
|
const auto iter = std::find_if(mBones.begin(), mBones.end(),
|
||||||
{
|
[BoneID](const auto& bone) { return bone->ID() == BoneID; });
|
||||||
if (mBones[iBone]->ID() == BoneID)
|
|
||||||
return mBones[iBone];
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
if (iter == mBones.cend())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return iter->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
CBone* CSkeleton::BoneByName(const TString& rkBoneName) const
|
CBone* CSkeleton::BoneByName(const TString& name) const
|
||||||
{
|
{
|
||||||
for (uint32 iBone = 0; iBone < mBones.size(); iBone++)
|
const auto iter = std::find_if(mBones.begin(), mBones.end(),
|
||||||
{
|
[&name](const auto& bone) { return bone->Name() == name; });
|
||||||
if (mBones[iBone]->Name() == rkBoneName)
|
|
||||||
return mBones[iBone];
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
if (iter == mBones.cend())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return iter->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 CSkeleton::MaxBoneID() const
|
uint32 CSkeleton::MaxBoneID() const
|
||||||
{
|
{
|
||||||
uint32 ID = 0;
|
const auto iter = std::max_element(mBones.cbegin(), mBones.cend(),
|
||||||
|
[](const auto& a, const auto& b) { return a->ID() < b->ID(); });
|
||||||
|
|
||||||
for (uint32 iBone = 0; iBone < mBones.size(); iBone++)
|
if (iter == mBones.cend())
|
||||||
{
|
{
|
||||||
if (mBones[iBone]->ID() > ID)
|
return 0;
|
||||||
ID = mBones[iBone]->ID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ID;
|
return (*iter)->ID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSkeleton::UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot)
|
void CSkeleton::UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot)
|
||||||
|
@ -123,15 +117,14 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData *pkDat
|
||||||
glLineWidth(1.f);
|
glLineWidth(1.f);
|
||||||
|
|
||||||
// Draw all child links first to minimize model matrix swaps.
|
// Draw all child links first to minimize model matrix swaps.
|
||||||
for (uint32 iBone = 0; iBone < mBones.size(); iBone++)
|
for (const auto& pBone : mBones)
|
||||||
{
|
{
|
||||||
CBone *pBone = mBones[iBone];
|
const CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position();
|
||||||
CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position();
|
|
||||||
|
|
||||||
// Draw the bone's local XYZ axes for selected bones
|
// Draw the bone's local XYZ axes for selected bones
|
||||||
if (pBone->IsSelected())
|
if (pBone->IsSelected())
|
||||||
{
|
{
|
||||||
CQuaternion BoneRot = pkData ? pBone->TransformedRotation(*pkData) : pBone->Rotation();
|
const CQuaternion BoneRot = pkData ? pBone->TransformedRotation(*pkData) : pBone->Rotation();
|
||||||
CDrawUtil::DrawLine(BonePos, BonePos + BoneRot.XAxis(), CColor::skRed);
|
CDrawUtil::DrawLine(BonePos, BonePos + BoneRot.XAxis(), CColor::skRed);
|
||||||
CDrawUtil::DrawLine(BonePos, BonePos + BoneRot.YAxis(), CColor::skGreen);
|
CDrawUtil::DrawLine(BonePos, BonePos + BoneRot.YAxis(), CColor::skGreen);
|
||||||
CDrawUtil::DrawLine(BonePos, BonePos + BoneRot.ZAxis(), CColor::skBlue);
|
CDrawUtil::DrawLine(BonePos, BonePos + BoneRot.ZAxis(), CColor::skBlue);
|
||||||
|
@ -140,19 +133,18 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData *pkDat
|
||||||
// Draw child links
|
// Draw child links
|
||||||
for (uint32 iChild = 0; iChild < pBone->NumChildren(); iChild++)
|
for (uint32 iChild = 0; iChild < pBone->NumChildren(); iChild++)
|
||||||
{
|
{
|
||||||
CBone *pChild = pBone->ChildByIndex(iChild);
|
const CBone *pChild = pBone->ChildByIndex(iChild);
|
||||||
CVector3f ChildPos = pkData ? pChild->TransformedPosition(*pkData) : pChild->Position();
|
const CVector3f ChildPos = pkData ? pChild->TransformedPosition(*pkData) : pChild->Position();
|
||||||
CDrawUtil::DrawLine(BonePos, ChildPos);
|
CDrawUtil::DrawLine(BonePos, ChildPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw bone spheres
|
// Draw bone spheres
|
||||||
CTransform4f BaseTransform = CGraphics::sMVPBlock.ModelMatrix;
|
const CTransform4f BaseTransform = CGraphics::sMVPBlock.ModelMatrix;
|
||||||
|
|
||||||
for (uint32 iBone = 0; iBone < mBones.size(); iBone++)
|
for (const auto& pBone : mBones)
|
||||||
{
|
{
|
||||||
CBone *pBone = mBones[iBone];
|
const CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position();
|
||||||
CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position();
|
|
||||||
|
|
||||||
CTransform4f Transform;
|
CTransform4f Transform;
|
||||||
Transform.Scale(skSphereRadius);
|
Transform.Scale(skSphereRadius);
|
||||||
|
@ -163,15 +155,14 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData *pkDat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int32,float> CSkeleton::RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData)
|
std::pair<int32,float> CSkeleton::RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData) const
|
||||||
{
|
{
|
||||||
std::pair<int32,float> Out(-1, FLT_MAX);
|
std::pair<int32,float> Out(-1, FLT_MAX);
|
||||||
|
|
||||||
for (uint32 iBone = 0; iBone < mBones.size(); iBone++)
|
for (const auto& pBone : mBones)
|
||||||
{
|
{
|
||||||
CBone *pBone = mBones[iBone];
|
const CVector3f BonePos = pBone->TransformedPosition(rkData);
|
||||||
CVector3f BonePos = pBone->TransformedPosition(rkData);
|
const std::pair<bool, float> Intersect = Math::RaySphereIntersection(rkRay, BonePos, skSphereRadius);
|
||||||
std::pair<bool,float> Intersect = Math::RaySphereIntersection(rkRay, BonePos, skSphereRadius);
|
|
||||||
|
|
||||||
if (Intersect.first && Intersect.second < Out.second)
|
if (Intersect.first && Intersect.second < Out.second)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <Common/TString.h>
|
#include <Common/TString.h>
|
||||||
#include <Common/Math/CRay.h>
|
#include <Common/Math/CRay.h>
|
||||||
#include <Common/Math/CVector3f.h>
|
#include <Common/Math/CVector3f.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class CBoneTransformData;
|
class CBoneTransformData;
|
||||||
class CBone;
|
class CBone;
|
||||||
|
@ -26,21 +27,21 @@ class CSkeleton : public CResource
|
||||||
DECLARE_RESOURCE_TYPE(Skeleton)
|
DECLARE_RESOURCE_TYPE(Skeleton)
|
||||||
friend class CSkeletonLoader;
|
friend class CSkeletonLoader;
|
||||||
|
|
||||||
CBone *mpRootBone;
|
CBone *mpRootBone = nullptr;
|
||||||
std::vector<CBone*> mBones;
|
std::vector<std::unique_ptr<CBone>> mBones;
|
||||||
|
|
||||||
static const float skSphereRadius;
|
static constexpr float skSphereRadius = 0.025f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CSkeleton(CResourceEntry *pEntry = nullptr);
|
explicit CSkeleton(CResourceEntry *pEntry = nullptr);
|
||||||
~CSkeleton() override;
|
~CSkeleton() override;
|
||||||
void UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot);
|
void UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot);
|
||||||
CBone* BoneByID(uint32 BoneID) const;
|
CBone* BoneByID(uint32 BoneID) const;
|
||||||
CBone* BoneByName(const TString& rkBoneName) const;
|
CBone* BoneByName(const TString& name) const;
|
||||||
uint32 MaxBoneID() const;
|
uint32 MaxBoneID() const;
|
||||||
|
|
||||||
void Draw(FRenderOptions Options, const CBoneTransformData *pkData);
|
void Draw(FRenderOptions Options, const CBoneTransformData *pkData);
|
||||||
std::pair<int32,float> RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData);
|
std::pair<int32, float> RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData) const;
|
||||||
|
|
||||||
uint32 NumBones() const { return mBones.size(); }
|
uint32 NumBones() const { return mBones.size(); }
|
||||||
CBone* RootBone() const { return mpRootBone; }
|
CBone* RootBone() const { return mpRootBone; }
|
||||||
|
@ -51,38 +52,38 @@ class CBone
|
||||||
friend class CSkeletonLoader;
|
friend class CSkeletonLoader;
|
||||||
|
|
||||||
CSkeleton *mpSkeleton;
|
CSkeleton *mpSkeleton;
|
||||||
CBone *mpParent;
|
CBone *mpParent = nullptr;
|
||||||
std::vector<CBone*> mChildren;
|
std::vector<CBone*> mChildren;
|
||||||
uint32 mID;
|
uint32 mID = 0;
|
||||||
CVector3f mPosition;
|
CVector3f mPosition;
|
||||||
CVector3f mLocalPosition;
|
CVector3f mLocalPosition;
|
||||||
CQuaternion mRotation;
|
CQuaternion mRotation;
|
||||||
CQuaternion mLocalRotation;
|
CQuaternion mLocalRotation;
|
||||||
TString mName;
|
TString mName;
|
||||||
CTransform4f mInvBind;
|
CTransform4f mInvBind;
|
||||||
bool mSelected;
|
bool mSelected = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CBone(CSkeleton *pSkel);
|
explicit CBone(CSkeleton *pSkel);
|
||||||
void UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo& rkParentTransform, CAnimation *pAnim, float Time, bool AnchorRoot);
|
void UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo& rkParentTransform, CAnimation *pAnim, float Time, bool AnchorRoot);
|
||||||
CVector3f TransformedPosition(const CBoneTransformData& rkData) const;
|
CVector3f TransformedPosition(const CBoneTransformData& rkData) const;
|
||||||
CQuaternion TransformedRotation(const CBoneTransformData& rkData) const;
|
CQuaternion TransformedRotation(const CBoneTransformData& rkData) const;
|
||||||
bool IsRoot() const;
|
bool IsRoot() const;
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
inline CSkeleton* Skeleton() const { return mpSkeleton; }
|
CSkeleton* Skeleton() const { return mpSkeleton; }
|
||||||
inline CBone* Parent() const { return mpParent; }
|
CBone* Parent() const { return mpParent; }
|
||||||
inline uint32 NumChildren() const { return mChildren.size(); }
|
uint32 NumChildren() const { return mChildren.size(); }
|
||||||
inline CBone* ChildByIndex(uint32 Index) const { return mChildren[Index]; }
|
CBone* ChildByIndex(uint32 Index) const { return mChildren[Index]; }
|
||||||
inline uint32 ID() const { return mID; }
|
uint32 ID() const { return mID; }
|
||||||
inline CVector3f Position() const { return mPosition; }
|
CVector3f Position() const { return mPosition; }
|
||||||
inline CVector3f LocalPosition() const { return mLocalPosition; }
|
CVector3f LocalPosition() const { return mLocalPosition; }
|
||||||
inline CQuaternion Rotation() const { return mRotation; }
|
CQuaternion Rotation() const { return mRotation; }
|
||||||
inline CQuaternion LocalRotation() const { return mLocalRotation; }
|
CQuaternion LocalRotation() const { return mLocalRotation; }
|
||||||
inline TString Name() const { return mName; }
|
TString Name() const { return mName; }
|
||||||
inline bool IsSelected() const { return mSelected; }
|
bool IsSelected() const { return mSelected; }
|
||||||
|
|
||||||
inline void SetSelected(bool Selected) { mSelected = Selected; }
|
void SetSelected(bool Selected) { mSelected = Selected; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSKELETON_H
|
#endif // CSKELETON_H
|
||||||
|
|
|
@ -17,7 +17,7 @@ void CSkeletonLoader::SetLocalBoneCoords(CBone *pBone)
|
||||||
|
|
||||||
void CSkeletonLoader::CalculateBoneInverseBindMatrices()
|
void CSkeletonLoader::CalculateBoneInverseBindMatrices()
|
||||||
{
|
{
|
||||||
for (CBone* bone : mpSkeleton->mBones)
|
for (auto& bone : mpSkeleton->mBones)
|
||||||
{
|
{
|
||||||
bone->mInvBind = CTransform4f::TranslationMatrix(-bone->Position());
|
bone->mInvBind = CTransform4f::TranslationMatrix(-bone->Position());
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,7 @@ std::unique_ptr<CSkeleton> CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResou
|
||||||
|
|
||||||
for (uint32 iBone = 0; iBone < NumBones; iBone++)
|
for (uint32 iBone = 0; iBone < NumBones; iBone++)
|
||||||
{
|
{
|
||||||
CBone *pBone = new CBone(ptr.get());
|
auto& pBone = ptr->mBones.emplace_back(std::make_unique<CBone>(ptr.get()));
|
||||||
ptr->mBones.push_back(pBone);
|
|
||||||
|
|
||||||
pBone->mID = rCINF.ReadLong();
|
pBone->mID = rCINF.ReadLong();
|
||||||
BoneInfo[iBone].ParentID = rCINF.ReadLong();
|
BoneInfo[iBone].ParentID = rCINF.ReadLong();
|
||||||
|
@ -86,7 +85,7 @@ std::unique_ptr<CSkeleton> CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResou
|
||||||
// Fill in bone info
|
// Fill in bone info
|
||||||
for (uint32 iBone = 0; iBone < NumBones; iBone++)
|
for (uint32 iBone = 0; iBone < NumBones; iBone++)
|
||||||
{
|
{
|
||||||
CBone *pBone = ptr->mBones[iBone];
|
CBone *pBone = ptr->mBones[iBone].get();
|
||||||
SBoneInfo& rInfo = BoneInfo[iBone];
|
SBoneInfo& rInfo = BoneInfo[iBone];
|
||||||
|
|
||||||
pBone->mpParent = ptr->BoneByID(rInfo.ParentID);
|
pBone->mpParent = ptr->BoneByID(rInfo.ParentID);
|
||||||
|
|
Loading…
Reference in New Issue