2015.08.06 22:38

스키닝 애니메이션


​스키닝 애니메이션은 스킨(skin)을 을 이루는 단일 매쉬와 뼈대(bone, joint)로 이루어진 구조를 갖고있다.

bone은 캐릭터 애니메이션을 위한 계층구조를 제공하는데 이 bone이 움직일 때 스킨 매쉬가 따라 움직이며 신축성있는 움직임을 보여준다.


애니메이션 초기에 이 스킨 매쉬는 bind-space를 기준으로 한다.

bind-space는 이 스킨 매쉬가 정의된 로컬 좌표계로써 보통은 계충구조에서의 root-space를 사용한다.

bone이 움직일 떄 스킨 매쉬의 정점들이 부여된 가중치에 따라 움직이며 캐릭터의 애니메이션을 표현하는 방법을 스키닝 애니메이션이라 한다.


To-Root 행렬


이 스키닝 애니메이션에서 중요한 특징들이 있는데 우선 To-Root 행렬이 있다.

일반적으로 단일 매쉬로 이루어진 스킨 매쉬는 위에서 언급한 것처럼 root-space에 저장된다.

따라서 각 프레임을 world-space가 아닌 root-frame-space로 변환하기 위한 행렬이 필요한데 이를 To-root 행렬이라 부른다.


하향식 운행


​두 번째로는 계층구조의 bone들을 운행하는 방식에 있다. 

이전의 계층구조를 설명할 때에는 하나의 bone에서 시작하여 그 부모로, 계속해서 조상을 거슬러올라가 root까지 도달했었다.

하지만 실제로는 위에서 아래로 내려오며 계산하는 방식이 더 효율적이다.


골격을 구성하는 n개의 bone에 정수 번호 0,1,2, ... n-1을 부여할 때 i번 뼈대의 root 변환 공식은 다음과 같다.

toRoot(i) = toParent(i) * toRoot(p) // p는 parent의 번호

 

여기서 toRoot(p)는 bone(p)의 좌표계에서 root의 좌표계로 변경한다.

트리를 하향식으로 위에서 아래로 내려오며 계산하면 목표 노드 i번에 도달할 때 이미 toRoot(p)는 계산된 상태가 될 수 있다.

만약에 상향식으로 계산한다고 가정하면 각 bone마다 모든 조상을 훑어야 하고, 또한 같은 부모를 공유하는 bone에 대해서도 동일한 연산이 중복수행되는 문제가 생긴다.



 

[그림 URL : http://hybridego.net/entry/skindparsingmesh-xfile ]

​offset 변환 


​스키닝에서 움직이고 싶은 bone의 좌표계와 정점을 가지고 있는 스킨 매쉬의 좌표계는 동일하지 않다.

따라서 원하는 뼈대를 Root-space로 변환하기 이전에 스킨 매쉬를 bind-space(대부분의 경우 root-space를 사용)에서 변환하고자하는 bone-space로 변환하는 것이 선행되어야한다.

이러한 변환을 offset 변환이라 부르고 이 변환을 수행하는 행렬을 offset matrix라 부른다.


이 offset 행렬의 정의부터 말하자면 Reference-pose( 또는 T-pose, rest-pose로 불린다)에서의 To-Root행렬의 역행렬이 되겠다.

조금 복잡해보일 수 있으나 차분하게 생각해보면 당연한 말인 것을 알 수 있다.


우리에게 우선적으로 필요한 것은 Reference-pose에서의 움직이고자하는 bone의 좌표계와 스킨 매쉬의 좌표계를 일치시키는 것이다.

스킨 매쉬가 존재하는 bind-space는 대부분  root-space이라고 했던 것을 상기해보자.

우리는 특정한 bone에서의 To-Root의 행렬은 조상을 거슬러 올라가며 To-parent를 곱하는 것으로 구할 수 있는데

지금 알고 싶은 것은 Root-Space인 스킨 매쉬의 좌표계에서 특정한 bone-space로의 변환 행렬을 구하고자 하는 것이다.

bone이 가지고 있는 To-Root 행렬의 역의 의미를 생각해보면 Root-space에서 bone로 변환하는 행렬의 의미가 된다.

이것은 offset 행렬이 추구하는 바와 같은 것이고 따라서 To-Root행렬의 역행렬이 Offset 행렬이 될 수 있는 것이다.


final 변환 

 

​이제 특정 뼈대를 Root로 변환시키기 위한 행렬(To-Root Matrix)도 알고 있고, 스킨 매쉬의 정점을 원하는 bone-space로 변환하는 행렬(Offset Matrix)도 알고 있다. 

남은 일은 움직이고자 하는 bone의 좌표계와 스킨 매쉬의 좌표계를 일치시킨 뒤 그것에 애니메이션 변환 행렬을 곱해 Root-space로 변환하는 것 뿐이다.


수학적으로 i번 뼈대의 최종 변환 행렬은 다음과 같이 표기할 수 있다.

F(i) = offset(i) * toRoot(i);













[참고문헌 : 프랭크 D. 루나 저 류광 역, DirectX 11을 이용한 3D 게임 프로그래밍 입문 ,

원제 : Introduction to 3d game programming with Directx 11 ]


[참고 URL : http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/skinned-mesh-animation-using-matrices-r3577

]

출처 : http://blog.naver.com/jidon333

신고
Posted by 우엉 여왕님!! ghostkyow

티스토리 툴바