프레임 단위로 된 여러개의 그림을 빠르게 재생하여 움직이는 것 처럼 보이게 하는 기법
3D 물체에 대한 애니메이션 구동을 위해 프레임 단위로 정점을 만들게 되면 매우 많은 정점을 요구하게 되므로 적절하지 않다.
따라서 3D게임의 애니메이션 구동은 뼈대를 사용해 피부가 뼈대의 움직임에 그대로 따라가도록 하는 Skinning기법을 사용한다.
뼈대를 이용한 애니메이션 구동은 서로 연결된 뼈에 영향을 주도록 설계하여 자연스러운 움직임이 구현 가능 하다.
대부분 사람의 뼈대는 골반이나 몸통 쪽의 뼈대가 Root 역할을 하고 계층 관계로 이루어져 있다.
뼈대 또한 각자의 좌표계를 가지고 있어, 서로의 움직임에 영향을 받는다.
Wolrd 좌표 -> Root 골격 Local 좌표 -> 다른 골격 Local 좌표
T-Pose는 Bind Position의 기준에 대한 좌표를 갖고 있다.
Bind Position 기준의 좌표를 Local 좌표로 변환하는 것을 Offset Transform이라고 한다.
각 정점과 뼈대 사이는 1대1 관계가 아닌 1 대 N 관계를 가지며 정점은 각 뼈대에 대해 가중치를 가진다.
높은 가중치를 가진 뼈대의 움직임에 더 많은 영향을 받도록 구현한다.
// bone 의 size와 프레임 카운트 만큼 곱해 마치 2차원 배열 같이 만들어 사용
(_bones.size() * animClip.frameCount)
```![](https://velog.velcdn.com/images%2Fsansam41%2Fpost%2F1d54e5dc-ea3c-467b-8786-7998fc5aba38%2Fezgif.com-gif-maker%20(1).gif)
* 프레임에 따라 animClip을 갱신한다.
```cpp
void Animator::FinalUpdate()
{
_updateTime += DELTA_TIME;
const AnimClipInfo& animClip = _animClips->at(_clipIndex);
if (_updateTime >= animClip.duration)
_updateTime = 0.f;
const int32 ratio = static_cast<int32>(animClip.frameCount / animClip.duration);
_frame = static_cast<int32>(_updateTime * ratio);
_frame = min(_frame, animClip.frameCount - 1);
_nextFrame = min(_frame + 1, animClip.frameCount - 1);
_frameRatio = static_cast<float>(_frame - _frame);
}