기록

20230923 애니메이션 블렌드

hayo_su 2023. 9. 23. 21:19

애니메이션 블렌드 - 애니메이션 프레임 변경 시 이전 프레임과 현재 프레임 사이 본의 크기, 회전, 위치가 자연스럽게 변화하도록 연결함.

 

before

애니메이션 중간중간이 끊어져서 재생되고있음을 확인할 수 있다.

 

이를 자연스럽게 하기위해 애니메이션이 바뀌기 전 모든 본의 정보를 따로 저장해두고,

바뀔 애니메이션의 본의 정보를 가져온다.

blend time을 두어 이 시간동안 각 애니메이션을 lerp(선형 보간)시켜 업데이트 한다.

for (int i = 0; i < AnimationBoneMatrixs.size(); i++) // 모든 본의 정보
{

	Bone* BoneData = GetFBXMesh()->FindBone(i); // 매쉬의 본 정보를 가져온다


	float LerpTime = CurBlendTime / BlendTime; // BlendTime = 총 애니메이션 블랜드 타임 
    // PrevAnimationBoneDatas = 바뀌기 직전 애니메이션의 본 정보
	FbxExBoneFrameData& NextData = CurAnimation->FBXAnimationData->AniFrameData[i].BoneMatData[CurAnimation->CurFrame]; // 바뀔 애니메이션 프레임의 본정보

	// lerp선형 보간을 이하여 scale rotation, pos를 적용
	AnimationBoneDatas[i].Scale = float4::Lerp(PrevAnimationBoneDatas[i].Scale, NextData.S, LerpTime);
	AnimationBoneDatas[i].RotQuaternion = float4::SLerpQuaternion(PrevAnimationBoneDatas[i].RotQuaternion, NextData.Q, LerpTime);
	AnimationBoneDatas[i].Pos = float4::Lerp(PrevAnimationBoneDatas[i].Pos, NextData.T, LerpTime);
    
    // matrix 연산
	float4x4 Mat = float4x4::Affine(AnimationBoneDatas[i].Scale, AnimationBoneDatas[i].RotQuaternion, AnimationBoneDatas[i].Pos);
    // lerp시킨 본 정보를 적용
	AnimationBoneMatrixs[i] = BoneData->BonePos.Offset * Mat;
}

 

비교