diff --git a/src/Core/Resource/Animation/CSkeleton.cpp b/src/Core/Resource/Animation/CSkeleton.cpp index 212e976d..1be4dc6f 100644 --- a/src/Core/Resource/Animation/CSkeleton.cpp +++ b/src/Core/Resource/Animation/CSkeleton.cpp @@ -5,12 +5,12 @@ #include #include +#include #include // ************ CBone ************ CBone::CBone(CSkeleton *pSkel) : mpSkeleton(pSkel) - , mSelected(false) { } @@ -39,8 +39,8 @@ void CBone::UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo& rTransform *= mInvBind; // Calculate children - for (uint32 iChild = 0; iChild < mChildren.size(); iChild++) - mChildren[iChild]->UpdateTransform(rData, TransformInfo, pAnim, Time, AnchorRoot); + for (auto* child : mChildren) + child->UpdateTransform(rData, TransformInfo, pAnim, Time, AnchorRoot); } 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 // actual root bone... that bone sometimes acts as the actual root (transforming the entire skeleton), // so we need to account for both - return (mpParent == nullptr || mpParent->Parent() == nullptr); + return mpParent == nullptr || mpParent->Parent() == nullptr; } // ************ CSkeleton ************ -const float CSkeleton::skSphereRadius = 0.025f; -CSkeleton::CSkeleton(CResourceEntry *pEntry /*= 0*/) +CSkeleton::CSkeleton(CResourceEntry *pEntry) : CResource(pEntry) - , mpRootBone(nullptr) { } -CSkeleton::~CSkeleton() -{ - for (uint32 iBone = 0; iBone < mBones.size(); iBone++) - delete mBones[iBone]; -} +CSkeleton::~CSkeleton() = default; CBone* CSkeleton::BoneByID(uint32 BoneID) const { - for (uint32 iBone = 0; iBone < mBones.size(); iBone++) - { - if (mBones[iBone]->ID() == BoneID) - return mBones[iBone]; - } + const auto iter = std::find_if(mBones.begin(), mBones.end(), + [BoneID](const auto& bone) { return bone->ID() == BoneID; }); - 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++) - { - if (mBones[iBone]->Name() == rkBoneName) - return mBones[iBone]; - } + const auto iter = std::find_if(mBones.begin(), mBones.end(), + [&name](const auto& bone) { return bone->Name() == name; }); - return nullptr; + if (iter == mBones.cend()) + return nullptr; + + return iter->get(); } 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) - ID = mBones[iBone]->ID(); + return 0; } - return ID; + return (*iter)->ID(); } 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); // 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]; - CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position(); + const CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position(); // Draw the bone's local XYZ axes for selected bones 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.YAxis(), CColor::skGreen); CDrawUtil::DrawLine(BonePos, BonePos + BoneRot.ZAxis(), CColor::skBlue); @@ -140,19 +133,18 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData *pkDat // Draw child links for (uint32 iChild = 0; iChild < pBone->NumChildren(); iChild++) { - CBone *pChild = pBone->ChildByIndex(iChild); - CVector3f ChildPos = pkData ? pChild->TransformedPosition(*pkData) : pChild->Position(); + const CBone *pChild = pBone->ChildByIndex(iChild); + const CVector3f ChildPos = pkData ? pChild->TransformedPosition(*pkData) : pChild->Position(); CDrawUtil::DrawLine(BonePos, ChildPos); } } // 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]; - CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position(); + const CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position(); CTransform4f Transform; Transform.Scale(skSphereRadius); @@ -163,15 +155,14 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData *pkDat } } -std::pair CSkeleton::RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData) +std::pair CSkeleton::RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData) const { std::pair Out(-1, FLT_MAX); - for (uint32 iBone = 0; iBone < mBones.size(); iBone++) + for (const auto& pBone : mBones) { - CBone *pBone = mBones[iBone]; - CVector3f BonePos = pBone->TransformedPosition(rkData); - std::pair Intersect = Math::RaySphereIntersection(rkRay, BonePos, skSphereRadius); + const CVector3f BonePos = pBone->TransformedPosition(rkData); + const std::pair Intersect = Math::RaySphereIntersection(rkRay, BonePos, skSphereRadius); if (Intersect.first && Intersect.second < Out.second) { diff --git a/src/Core/Resource/Animation/CSkeleton.h b/src/Core/Resource/Animation/CSkeleton.h index 9eca4f18..ef4eed7b 100644 --- a/src/Core/Resource/Animation/CSkeleton.h +++ b/src/Core/Resource/Animation/CSkeleton.h @@ -8,6 +8,7 @@ #include #include #include +#include class CBoneTransformData; class CBone; @@ -26,21 +27,21 @@ class CSkeleton : public CResource DECLARE_RESOURCE_TYPE(Skeleton) friend class CSkeletonLoader; - CBone *mpRootBone; - std::vector mBones; + CBone *mpRootBone = nullptr; + std::vector> mBones; - static const float skSphereRadius; + static constexpr float skSphereRadius = 0.025f; public: explicit CSkeleton(CResourceEntry *pEntry = nullptr); ~CSkeleton() override; void UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot); CBone* BoneByID(uint32 BoneID) const; - CBone* BoneByName(const TString& rkBoneName) const; + CBone* BoneByName(const TString& name) const; uint32 MaxBoneID() const; void Draw(FRenderOptions Options, const CBoneTransformData *pkData); - std::pair RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData); + std::pair RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData) const; uint32 NumBones() const { return mBones.size(); } CBone* RootBone() const { return mpRootBone; } @@ -51,38 +52,38 @@ class CBone friend class CSkeletonLoader; CSkeleton *mpSkeleton; - CBone *mpParent; + CBone *mpParent = nullptr; std::vector mChildren; - uint32 mID; + uint32 mID = 0; CVector3f mPosition; CVector3f mLocalPosition; CQuaternion mRotation; CQuaternion mLocalRotation; TString mName; CTransform4f mInvBind; - bool mSelected; + bool mSelected = false; public: - CBone(CSkeleton *pSkel); + explicit CBone(CSkeleton *pSkel); void UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo& rkParentTransform, CAnimation *pAnim, float Time, bool AnchorRoot); CVector3f TransformedPosition(const CBoneTransformData& rkData) const; CQuaternion TransformedRotation(const CBoneTransformData& rkData) const; bool IsRoot() const; // Accessors - inline CSkeleton* Skeleton() const { return mpSkeleton; } - inline CBone* Parent() const { return mpParent; } - inline uint32 NumChildren() const { return mChildren.size(); } - inline CBone* ChildByIndex(uint32 Index) const { return mChildren[Index]; } - inline uint32 ID() const { return mID; } - inline CVector3f Position() const { return mPosition; } - inline CVector3f LocalPosition() const { return mLocalPosition; } - inline CQuaternion Rotation() const { return mRotation; } - inline CQuaternion LocalRotation() const { return mLocalRotation; } - inline TString Name() const { return mName; } - inline bool IsSelected() const { return mSelected; } + CSkeleton* Skeleton() const { return mpSkeleton; } + CBone* Parent() const { return mpParent; } + uint32 NumChildren() const { return mChildren.size(); } + CBone* ChildByIndex(uint32 Index) const { return mChildren[Index]; } + uint32 ID() const { return mID; } + CVector3f Position() const { return mPosition; } + CVector3f LocalPosition() const { return mLocalPosition; } + CQuaternion Rotation() const { return mRotation; } + CQuaternion LocalRotation() const { return mLocalRotation; } + TString Name() const { return mName; } + bool IsSelected() const { return mSelected; } - inline void SetSelected(bool Selected) { mSelected = Selected; } + void SetSelected(bool Selected) { mSelected = Selected; } }; #endif // CSKELETON_H diff --git a/src/Core/Resource/Factory/CSkeletonLoader.cpp b/src/Core/Resource/Factory/CSkeletonLoader.cpp index da8f63f8..84665c2d 100644 --- a/src/Core/Resource/Factory/CSkeletonLoader.cpp +++ b/src/Core/Resource/Factory/CSkeletonLoader.cpp @@ -17,7 +17,7 @@ void CSkeletonLoader::SetLocalBoneCoords(CBone *pBone) void CSkeletonLoader::CalculateBoneInverseBindMatrices() { - for (CBone* bone : mpSkeleton->mBones) + for (auto& bone : mpSkeleton->mBones) { bone->mInvBind = CTransform4f::TranslationMatrix(-bone->Position()); } @@ -49,8 +49,7 @@ std::unique_ptr CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResou for (uint32 iBone = 0; iBone < NumBones; iBone++) { - CBone *pBone = new CBone(ptr.get()); - ptr->mBones.push_back(pBone); + auto& pBone = ptr->mBones.emplace_back(std::make_unique(ptr.get())); pBone->mID = rCINF.ReadLong(); BoneInfo[iBone].ParentID = rCINF.ReadLong(); @@ -86,7 +85,7 @@ std::unique_ptr CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResou // Fill in bone info for (uint32 iBone = 0; iBone < NumBones; iBone++) { - CBone *pBone = ptr->mBones[iBone]; + CBone *pBone = ptr->mBones[iBone].get(); SBoneInfo& rInfo = BoneInfo[iBone]; pBone->mpParent = ptr->BoneByID(rInfo.ParentID);