2016. 4. 29.

본 인디스(Bone Indices)에 관한 명확한 설명

글쓴이 Lina Halper

애니메이션 코드 작업을 하고 있으면, 주로 본 인덱스를 보고 있게 됩니다. 여러 다른 본 인디스(indices)들이 있으면 애니메이션 코드에서 헛갈릴 수 있습니다. 이런 문제 때문에 어째서 본 인디스가 여러개이고 그것들 사이에서는 어떤 차이가 있는지를 설명해 드리고자 합니다.

BI_1

애니메이션 코드에서 중요한 본 인디스는 3종류가 있습니다.

  1. 메시 본 인덱스(Mesh Bone Index)
  2. 스켈레톤 본 인덱스(Skeleton Bone Index)
  3. FCompactPoseBoneIndex

 

Mesh Bone Index는 스켈레탈 메시의 일부분입니다. 여기에는 모든 메시 조인트, 계층구조(Hierarchy)가 들어 있고 스켈레탈 메시를 랜더링 하는 데에 사용됩니다. 메시 본 인덱스를 보기 위해서는 스켈레탈 메시를 임포트 해야 하고 페르소나에서 열어야 합니다. 여기에서 여러분은 여기에 포함된 모든 조인트를 볼 수 있습니다.

스켈레탈 메시 컴포넌트 속의 SpateBases 나 LocalAtoms에 접근하려면 메시 본 인덱스를 사용해야 할 것입니다.

B_-2

메시 본 인덱스가 스켈레탈 메시의 부분이라면 스켈레톤 본 인덱스는 도대체 뭘까요? 페르소나를 사용하여 본 적이 있으시다면 USkeleton 애셋에 관해서 알고 계실 것입니다. 이것들은 여러분이 스켈레탈메시를 임포트 하거나 이미 존재하는 것에 할당(Assign) 한 경우에 생성됩니다. 만약 스켈레톤이 왜 여러가지의 메시와 조인트들을 갖게 되는지 확실히 이해가 되지 않으시는 경우에는 Wes Bunn의 영상을 시청하시기 바랍니다. 여기에서 더 자세하게 설명해 드립니다.

언리얼 엔진 4에서, USkeleton 애셋은 스켈레톤이 가지고 있는 모든 본마다 레퍼런스 포즈를 포함하고 있습니다. (USkeleton.ReferenceSkeleton) 스켈레톤 본 인덱스는 이 본 리스트의 인덱스를 말합니다. UAnimSequence 각각에는 내부 트랙 인디스(internal track indices)와 맞는 스켈레톤 본 인덱스 사이의 매핑이 저장되어 있습니다. 에픽은 이 것을 해당 본에 적합한 애니메이션을 적용할 지를 확인하는 과정에서 사용하지만 여기에 따라 스켈레톤이 바뀌면 애니메이션의 데이터를 업데이트 해야 합니다. 이 것은 애니메이션이 ‘지저분한(dirty)’상태로 마킹되는 이유이며 스켈레톤이 변경되었을 때 다시 저장되어야 합니다.

USkeleton의 원래 계획은 애니메이션 데이터만을 추출하고 적당한 스켈레탈 메시 컴포넌트에 리타게팅이 될 수 있는지를 확인하는 데 사용하는 것이었습니다. 아주 멋진 아이디어처럼 들리지만, 제대로 작동하지 않았는데 왜냐하면 SkeletalControls를 가지고 작업할 때에는 정확한 메시 데이터가 필요했기 때문입니다. 예를 들어 IK를 사용할 때 여러분은 다양한 메시를 묶는데, 이는 스켈레톤의 본 트랜스폼이 더이상 사용되지 않음을 의미합니다.

스켈레톤의 참조 포즈 본 트랜스폼은 애니메이션 스케일 변경 리타게팅에서만 사용됩니다.

페르소나에서 스켈레톤 탭을 열면 아래와 같은 것들을 볼 수 있습니다.

BI_3

기본 값으로, USKeleton속의 모든 본이 표시됩니다. “메시 본 보기(Show Mesh Bones)”로 변경하면 현재 프리뷰 메시에 속한 본들만을 보여 줍니다.

그럼 USkeleton 본 인덱스가 USkeletalMesh 본 인덱스와 일치하지 않는다는 것을 알 수 있습니다. 그렇다면 FCompactPoseBoneIndex는 어디에 속하게 될까요?

FCompactPoseBoneIndex는 FCompactPose에서만 사용될 수 있는 인덱스 입니다. FCompactPose는 확인 과정(evaluation) 동안에서만 사용될 수 있는 런타임 본입니다. 이 것은 현재의 메시 LOD에만 연관된 조인트들만을 포함한 연속적인 리스트 입니다. 다수의 LOD를 가지고 있는 경우 최적화를 위해 조인트의 부분집합만을 가질 수 있습니다. FCompactPose에 앞서 브랜치들이 사용되었지만 브랜치들은 퍼포먼스 이슈를 일으켰는데, 왜냐하면 브랜치의 예측이 잘못되었기 때문입니다. FCompactPoseBoneIndex는 브랜치 없이도 반복 작업을 가능하게 합니다.  
FCompactPoseBoneIndex는 그냥 인티저입니다. 그 이유는 코드의 명확성을 위해서죠. 함수가 FCompactPoseBoneIndex를 받거나 반환하면 어떤 스페이스에 본 인덱스가 작동하는지 알 수 있습니다. 이것은 또한 여러분이 실수로 조밀한 인덱스와 메시나 스켈레톤 인덱스(또는 거꾸로)를 사용하도록 의도된 함수를 호출할 수 없다는 것을 의미합니다. 컴파일러가 에러를 발생시킬 것입니다.
 
핵심 애니메이션 코드들은 모두 FCompactPose를 사용합니다. 여러분은 이러한 세가지 본 인디스들을 API를 이용해 전환할 수 있습니다. 스켈레탈 메시와 스켈레톤을 컨버전하는 대부분의 API는 USkeleton에서 찾을 수 있습니다. (FSkeletonToMeshLinkup)
요약:

  1. 메시 본 인덱스(Mesh Bone Index) - 스켈레탈 메시 본 인덱스는 스켈레탈 메시 컴포넌트의 SpaceBases 또는 LocalAtoms에 사용됩니다.
  2. 스켈레톤 본 인덱스(Skeleton Bone Index) - 스켈레톤 본 인덱스에는 모든 스켈레탈 메시의 조인트 연결이 들어 있습니다. 특히 이 것은 애니메이션 트랙 인덱스 입니다. 애니메이션은 트랙 데이터를 위해 이 인덱스를 참조합니다.
  3. FCompactPoseBoneIndex - 이 것은 메시의 LOD의 일부로 모든 조인트의 부분집합을 갖고 있습니다. 예를 들어 LOD 0 은 메시인덱스(MeshIndex)와 일치할 것입니다. 하지만, LOD 1 또는 LOD 2 로 넘어가면 부분집합만 가질 수 있습니다. 그러므로 더 이상 메시 인덱스와 일치하지 않습니다.

 

아래는 메시 본으로부터 CompactPoseBoneIndex으로 컨버팅 하는 예제입니다.

// 코든 컴팩트 포즈 구간에서 반복
for (FCompactPoseBoneIndex BoneIndex : Output.Pose.ForEachBoneIndex())
{

// 메시 포즈로부터 컴팩트 포즈를 요청
FMeshPoseBoneIndex MeshPoseBoneIndex = Output.Pose.GetBoneContainer().MakeMeshPoseIndex(BoneIndex);

// 로컬 메시 버퍼를 스켈레탈 메시의 버퍼로 간주
Output.Pose[BoneIndex] = LocalMeshBuffer[MeshPoseBoneIndex.GetInt()];

}

마지막으로, USkeleton은 정확한 이름이 붙은 것이 아닙니다. 이 동영상을 보시면 USkeleton에 대해 더 자세히 이해하실 수 있을 것입니다.

이 포스팅이 본 인디스의 종류간 차이의 이해 및 어떻게 사용할 수 있는지에 대해 도움이 되었길 바랍니다.

최근 게시글

이미지를 넘어서: 비주얼 디자인을 경험해보다

디자인 경험이라는 것이 과연 무엇을 뜻할까요? 현재 기업들이 언리얼 엔진을 어떻게 작업물의 새롭고 강력한 테스트 방법으로 활용하고 있는...

언리얼 엔진 웨비나, 리얼타임 시각화를 위한 디자인 제조

실시간 기술을 활용하여 더 빠르고 효율적인 디자인 워크플로우를 경험해 보고 싶으신가요?

2018년 언리얼 엔진 기대작

주요 매체들에서는 새해가 시작되면서 2018년 최고의 기대작들을 꼽고 있으며, 이 기대작 목록에는 언리얼 엔진 타이틀이 가득 들어있습니...