[DirectX 11] Animation

2021. 12. 18. 03:44·Graphics

Animation

 

Animation Data는 KeyFrame 기준 Data로 Sampling 되어 저장된다.

일단 KeyFrame 그대로 Local Matrix를 반영하여 출력하면 애니메이션이 나오긴 할텐데, 매우 끊겨보일 것이다.

Animation Data Sampling

그러므로 우리는 Sampling 된 KeyFrame Data 간의 추가적인 보간 작업을 해주어야 하는데, 

 

Lerp / Slerp

Scale, Position은 Lerp(선형보간)을 통해 KeyFrame 간의 보간을 해주면 된다.

하지만 Rotation은 Slerp(구면선형보간)을 통해 KeyFrame 간의 보간을 해주어야 한다.

 

Rotation의 경우 Format 마다 저장되는 방식이 다를 수 있다.

float _time = 0;
float _angle = 0;
Vector3 _rot = Vector3();
_time = (Parsing_NumberFloat() / m_scenedata.m_TicksPerFrame) - m_scenedata.m_FirstFrame;
_rot = Parsing_ChangeNumberVector3();
_angle = Parsing_NumberFloat();

m_Animation->m_AniData.back()->m_Time = _time;

// 현재 Frame Quaternion 추출..
Quaternion nowQT = XMQuaternionRotationAxis(_rot, _angle);

// Quaternion 값은 누적시켜주자..
if (m_Animation->m_AniData.size() > 1)
{
	m_Animation->m_AniData.back()->m_RotQt = XMQuaternionMultiply(m_Animation->m_AniData[m_Animation->m_AniData.size() - 2]->m_RotQt, nowQT);
}
else
{
	m_Animation->m_AniData.back()->m_RotQt = nowQT;
}

ASE의 경우 이전 Frame 기준 변위량이라 계속해서 누적을 해주어야 한다. 이게 무슨말이냐면 Animation Roation 정보가 기본 Mesh 원 상태에서의 Rotation 값이 아닌 현재 Frame 기준 이전 Frame에서의 변위량이라는 소리이다.

예를들어 현재 Frame이 3번째라면 2번째 Frame 기준 변위량인 것이다. 즉, ASE에서의 Rotation 값은 누적시켜서 저장하면 된다.

 

// Animation Data 삽입..
FbxTime::EMode timeMode = pScene->GetGlobalSettings().GetTimeMode();
for (FbxLongLong index = 0; index < m_OneAnimation->m_TotalFrame; index++)
{
	FbxTime takeTime;
	takeTime.SetFrame(m_OneAnimation->m_StartFrame + index, timeMode);

	// Local Transform = 부모 Bone의 Global Transform의 Inverse Transform * 자신 Bone의 Global Transform
	FbxAMatrix nodeTransform = node->EvaluateLocalTransform(takeTime);

	DirectX::SimpleMath::Matrix nodeTRS = ConvertMatrix(nodeTransform);

	XMVECTOR scale;
	XMVECTOR rot;
	XMVECTOR pos;

	XMMatrixDecompose(&scale, &rot, &pos, nodeTRS);

	OneFrame* newAni = new OneFrame;

	newAni->m_Time = (float)index;
	newAni->m_Pos = DirectX::SimpleMath::Vector3(pos);
	newAni->m_RotQt = Quaternion(rot);
	newAni->m_Scale = DirectX::SimpleMath::Vector3(scale);

	m_OneAnimation->m_AniData.push_back(newAni);
}

// 해당 Mesh에 애니메이션 삽입..
if ((m_ParsingMode & ANIMATION_ONLY) != ANIMATION_ONLY)
{
	m_OneMesh->m_Animation = m_OneAnimation;
}

FBX의 경우는 좀 다른데 현재 Frame의 시간을 넣으면 해당 시간대의 Node Matrix가 나오는데 해당 Matrix를

Decompose(Scale, Rot, Pos로 추출) 하여 해당 정보를 저장하면 된다. 즉, 이미 Rotation 값은 이전 Frame 기준이 아닌 초기값 기준 Rotation 값이라는 소리다.

 

이렇게 Animation Data를 저장한 후 해당 KeyFrame 간의 보간을 통해 재생하여 주면 자연스러운 애니메이션이 나올 것이다.

'Graphics' 카테고리의 다른 글

[DirectX 11] Terrain Mesh Blending  (0) 2021.12.20
[DirectX 11] Map / UnMap vs UpdataSubresource  (0) 2021.12.19
[DirectX 11] Skinning Mesh  (0) 2021.12.18
[DirectX 11] Normal Mapping  (0) 2021.12.18
[DirectX 11] Gamma Correction  (0) 2021.12.18
'Graphics' 카테고리의 다른 글
  • [DirectX 11] Terrain Mesh Blending
  • [DirectX 11] Map / UnMap vs UpdataSubresource
  • [DirectX 11] Skinning Mesh
  • [DirectX 11] Normal Mapping
KyuHwang
KyuHwang
  • KyuHwang
    DirectX Engine
    KyuHwang
  • 전체
    오늘
    어제
    • 분류 전체보기 (50)
      • C++ (4)
      • CS (0)
      • Graphics (32)
      • DLL (2)
      • Shader (7)
      • Project (4)
      • ETC (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • YouTube
  • 공지사항

  • 인기 글

  • 태그

    Return Type Operator
    bc format
    Shader Macro
    std::is_base_of
    Directx11
    Implicit Linking
    nvtt
    Shader Resource 관리
    C ++
    dll
    Order Independent Transparency
    Project
    texture block compression
    Define Macro
    mobile format
    Hash Code
    std::enable_if
    Win API
    RunTime Compile Shader
    Alpha Blending
    Define Function
    animation constraint
    Explicit Linking
    animation retargeting
    Shader Reflection
    shader
    DirectX 2D
    hlsl
    rigging chain
    DLL Interface
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
KyuHwang
[DirectX 11] Animation
상단으로

티스토리툴바