// GameObject.h의 뼈 관련 필드들
private:
bool _isBoneObject = false; // 이 객체가 뼈인지 표시
bool _hasNonBoneChildren = false; // 뼈가 아닌 자식이 있는지 여부
vector<int> _activeBoneIndices; // 활성화될 뼈 인덱스 목록
weak_ptr<GameObject> _nonBoneChildrenParent; // 비뼈 객체의 부모 뼈
weak_ptr<GameObject> _boneParentObject; // 이 뼈가 속한 부모 객체
int _boneIndex; // 모델의 뼈 배열에서의 인덱스
void Animator::UpdateBoneTransforms()
{
if (auto model = _model.lock()) // weak_ptr를 shared_ptr로 변환
{
if (!_currClip)
return;
shared_ptr<Transition> currTransition = _currClip->transition;
bool isBlending = (currTransition != nullptr && _blendAnimDesc.blendSumTime > 0.0f);
// 핵심: 모든 뼈가 아닌 활성화된 뼈만 순회
for (int boneIndex : GetGameObject()->GetActiveBoneIndices())
{
const auto& bone = model->GetBoneByIndex(boneIndex);
shared_ptr<GameObject> boneObject = FindBoneObjectByIndex(bone->index);
if (!boneObject || bone->index < 0)
continue;
Matrix finalTransform;
// 애니메이션 블렌딩 또는 단일 애니메이션 처리
// ... [애니메이션 계산 코드] ...
// 최종 변환 행렬 분해 및 적용
Vec3 scale, translation;
Quaternion rotation;
finalTransform.Decompose(scale, rotation, translation);
auto boneTransform = boneObject->transform();
boneTransform->SetLocalPosition(translation);
boneTransform->SetQTLocaslRotation(rotation);
boneTransform->SetLocalScale(scale);
}
}
}
void HandleBoneObjectParenting(shared_ptr<GameObject> child, shared_ptr<GameObject> newParent)
{
if (newParent && newParent->GetBoneObjectFlag())
{
// 중요: 뼈 오브젝트에 새로운 자식이 추가될 때 해당 뼈를 활성 뼈 목록에 추가
newParent->GetBoneParentObject().lock()->AddActiveBoneIndex(newParent->GetBoneIndex());
_tempBoneIndex = INT_MAX;
// 자식이 뼈가 아닌 경우 특별 처리
if (!child->GetBoneObjectFlag())
{
newParent->SetHasNoneBoneChildrenFlag(true);
child->SetNonBoneChildrenParent(newParent);
}
}
}