C++ Algorithm & Study/Game Math & DirectX 11

[Direct11] 48. 3D Direct Application - Character Animation #3

GameChoi 2023. 7. 4. 19:55

1. 3D Direct Application

1.1 Character Animation

1.1.1 Character Animation Application

1.1.1.1 Skined Model

class SkinnedModel;

 - Basic Model 클래스를 사용하여 Skinned Data 인스턴스를 가진다는 점만 빼고 동일

struct SkinnedModelInstance
{
	shared_ptr<SkinnedModel> Model; float TimePos; std::string ClipName; XMFLOAT4X4 World;
	std::vector<XMFLOAT4X4> FinalTransforms;
	void Update(float dt);
};

   - Skinned Model Instance는 자신의 애니메이션 위치, 애니메이션 중인 클립의 이름, 최종 변환을 유지

     - 매 프레임마다 Update 함수를 호출하면 시간 위치를 증가시키고 현재 애니메이션 클립에 근거해 각 뼈대의 애니메이션을 보간해서 최종 변환을 계산, 이후 정점 셰이더에서 최종 변환들을 정점들에 적용함으로써 애니메이션이 실현

void SkinnedModelInstance::Update(float dt)
{
	TimePos += dt;
	Model->SkinnedData.GetFinalTransforms(ClipName, TimePos, FinalTransforms);
	if (TimePos > Model->SkinnedData.GetClipEndTime(ClipName)) TimePos = 0.0f;
}

1.1.1.2 Skinned Mesh

 - 캐릭터 모델을 생성하여 캐릭터 인스턴스를 통해 2개의 군인 모델인 캐릭터 생성

_characterModel = make_shared<SkinnedModel>(_device, _texMgr, 
		"../Resources/Models/soldier.m3d", L"../Resources/Textures/");
_characterInstance1.Model = _characterModel; _characterInstance2.Model = _characterModel;
_characterInstance1.TimePos = 0.0f; _characterInstance2.TimePos = 0.0f;
_characterInstance1.ClipName = "Take1"; _characterInstance2.ClipName = "Take1";
_characterInstance1.FinalTransforms.resize(_characterModel->SkinnedData.BoneCount());
_characterInstance2.FinalTransforms.resize(_characterModel->SkinnedData.BoneCount());

   - 생성한 캐릭터의 SRT를 설정하고 세계 행렬로 변환

XMMATRIX modelScale = ::XMMatrixScaling(0.05f, 0.05f, -0.05f);
XMMATRIX modelRot = ::XMMatrixRotationY(MathHelper::Pi);
XMMATRIX modelOffset = ::XMMatrixTranslation(-2.0f, 0.0f, -7.0f);
::XMStoreFloat4x4(&_characterInstance1.World, modelScale * modelRot * modelOffset);
modelOffset = ::XMMatrixTranslation(2.0f, 0.0f, -7.0f);
::XMStoreFloat4x4(&_characterInstance2.World, modelScale * modelRot * modelOffset);

   - 이후 Shader Code에 전달하기 위해 밑의 함수를 적용하여 애니메이션 적용

Effects::NormalMapSkinnedFX->SetBoneTransforms(
    &_characterInstance1.FinalTransforms[0], _characterInstance1.FinalTransforms.size());