강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

HeeTae Kim님의 프로필 이미지
HeeTae Kim

작성한 질문수

[게임 프로그래머 도약반] DirectX11 입문

64.애니메이션 강의의, AssimpTool 에서 FBX 애니매이션 데이터를 옮길 때의 강의 오류가 있는 것 같습니다.

작성

·

6

·

수정됨

0

문제는 해결했지만, 강의에 큰 오류가 있는 것 같아, 강의를 듣는 분들에게 공유하는 것이 좋다 생각돼서 글을 작성했습니다.

 

강의의 Transform 코드가 미흡하다 생각해서, [LH, row_major, 요우->피치->롤] 을 전제로 하는 Transform ( Vec3, Vec4, Matrix3x3, Matrix4x4, Quaternion ) 을 다른 교재(이득우저 게임수학) 를 참조하여, 강의 코드에 적용해서 공부하고 있었습니다.

 

문제없이 잘 진행되다, 65.애니매이션 #2 에서 AssimpTool 로 FBX를 변환한 데이터를 애니매이션 진행할시, 로테이션이 반대로 되는 문제가 있었습니다. 이틀에 걸려 문제 원인을 찾았는데,

 

원인 코드는 아래와 같습니다 (강의 코드의 AssimpTool 프로젝트의 Utils 파일의 Converter.cpp 의 내용)

 

/*

std::shared_ptr<asAnimationNode> Converter::ParseAnimationNode(shared_ptr<asAnimation> animation, aiNodeAnim* srcNode)

{

std::shared_ptr<asAnimationNode> node = make_shared<asAnimationNode>();

node->name = srcNode->mNodeName;

uint32 keyCount = max(max(srcNode->mNumPositionKeys, srcNode->mNumScalingKeys), srcNode->mNumRotationKeys);

for (uint32 k = 0; k < keyCount; k++)

{

asKeyframeData frameData;

bool found = false;

uint32 t = node->keyframe.size();

// Position

if (::fabsf((float)srcNode->mPositionKeys[k].mTime - (float)t) <= 0.0001f)

{

aiVectorKey key = srcNode->mPositionKeys[k];

frameData.time = (float)key.mTime;

::memcpy_s(&frameData.translation, sizeof(Vec3), &key.mValue, sizeof(aiVector3D));

found = true;

}

// Rotation

if (::fabsf((float)srcNode->mRotationKeys[k].mTime - (float)t) <= 0.0001f)

{

aiQuatKey key = srcNode->mRotationKeys[k];

frameData.time = (float)key.mTime;

frameData.rotation.x = key.mValue.x;

frameData.rotation.y = key.mValue.y;

frameData.rotation.z = key.mValue.z;

frameData.rotation.w = key.mValue.w;

found = true;

}

 

*/

 

==>> 위 코드에서, Quaternion 로테이션을 전치하기 위해, x, y, z 의 부호를 거꾸로 하는 코드가 필요합니다. 수정한 제 코드에는 아래와 같습니다

frameData.rotation.X = -key.mValue.x;

frameData.rotation.Y = -key.mValue.y;

frameData.rotation.Z = -key.mValue.z;

frameData.rotation.W = key.mValue.w;

 

 

저렇게 코드를 수정하니, (LH, row_major) 를 전제로 하는 Transform 코드에서 잘 작동하더군요.

 

물론 강의의 DirectX::SimpleMath 를 바탕으로 만들어진 Transform 을 사용하면 아무 문제 없습니다.

제가 SimpleMath를 제대로 이해하지 못해서, 어떻게 강의 코드가 잘 작동하는지를 이해하지는 못했고, 여전히 의문이 남습니다.

 

강의에서도 FBX 데이터는 RH 를 전제로 만들어졌고, 강의는 LH 를 전제로 하기에, AssimpTool 에서 본 트랜스폼 데이터를 변환할 때에, 아래 강의 코드인 Converter::ReadModelData 에서,

bone->transform = transform.Transpose();

트랜스폼을 전치합니다.

 

Converter::ReadKeyframeData 에서도, if (findNode == nullptr) 에서도

transform = transform.Transpose();

로 전치를 하는데,

앞서 제가 수정했던 else (애니매이션 데이터가 있는 부분) 에서는 전치 (rotation을 거꾸로 전환하는 코드)

가 누락됐습니다.

 

정리하면, 강의의 일부 코드에서는, RH -> LH 를 위한 전치(로테이션 거꾸로) 코드가 있는데, 일부 코드에서는 전치 코드가 없는데도, 강의 코드는 잘 작동한다는 겁니다.

 

 

아무튼 제 문제는 해결됐습니다. 강의를 보다 혼동하실 분들이 제 글을 참고했으면 좋겠네요.

 

제 코드를 담은 깃허브 링크도 공유합니다

https://github.com/HeeTaeKim996/Learning_DirectX11_3D

 

 

 

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

HeeTae Kim님의 질문과 설명을 통해 DirectX11 강의에서 AssimpTool로 FBX 애니메이션 데이터를 변환할 때 발생할 수 있는 로테이션 문제에 대한 논의가 되었네요. 애니메이션의 변환 과정에서 발생하는 좌표계 차이에 따른 오류 수정 방법을 공유해 주셔서 감사드립니다.

먼저, 애니메이션 변환 시 LH(Left-Handed)와 RH(Right-Handed) 좌표계 차이는 애니메이션 및 그래픽 처리에서 흔히 발생하는 문제 중 하나입니다. 이를 해결하기 위해 강의에서 사용한 Transform 코드에서 일부 누락된 전환 과정(전치 및 회전 반전)이 있었다고 하시니, 다른 수강생 분들께서도 이를 참고하시면 오류를 디버깅 하는 데 큰 도움이 될 것입니다.

강의에서 제시된 DirectX::SimpleMath에서는 내부적으로 이러한 전환을 처리하고 있기 때문에 문제가 발생하지 않았던 듯합니다. 하지만 HeeTae Kim님께서 직접 구현한 Transform 간의 차이로 인해 오류를 발견하신 것은, 실질적인 이해와 디버깅 능력을 높이는 좋은 경험이 되었으리라 생각합니다.

위 내용을 직접 적용해 보고자 하시는 분들은 HeeTae Kim님께서 제공하신 GitHub 링크 Learning_DirectX11_3D를 참고하시면 좋을 것 같습니다. 이 링크에는 문제를 해결하기 위해 변경된 코드가 포함되어 있어, 발생할 수 있는 유사한 문제를 디버깅하는 데 유용할 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

HeeTae Kim님의 프로필 이미지
HeeTae Kim

작성한 질문수

질문하기