summaryrefslogtreecommitdiff
path: root/Runtime/Animation/MecanimAnimation.cpp
blob: 8d8ca20086f5f866b5e7ebd1d970d34279022049 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "UnityPrefix.h"

#include "MecanimAnimation.h"

#include "Animator.h"
#include "Avatar.h"
#include "CalculateAnimatorSkinMatrices.h"
#include "Runtime/mecanim/animation/avatar.h"
#include "Runtime/mecanim/skeleton/skeleton.h"

#include "Runtime/Utilities/LogAssert.h"
#include "Runtime/Utilities/Word.h"

void MecanimAnimation::InitializeClass ()
{
	SetAnimationInterface(new MecanimAnimation());
}

void MecanimAnimation::CleanupClass ()
{
	MecanimAnimation* animation = reinterpret_cast<MecanimAnimation*>(GetAnimationInterface ());
	delete animation;
	SetAnimationInterface(NULL);
}

const void* MecanimAnimation::GetGlobalSpaceSkeletonPose(const Unity::Component& animatorComponent)
{
	const Animator& animator = static_cast<const Animator&>(animatorComponent);
	return animator.GetGlobalSpaceSkeletonPose();
}

CalculateAnimatorSkinMatricesFunc MecanimAnimation::GetCalculateAnimatorSkinMatricesFunc()
{
	return DoCalculateAnimatorSkinMatrices;
}

bool MecanimAnimation::CalculateWorldSpaceMatricesMainThread(Unity::Component& animatorComponent, const UInt16* indices, size_t count, Matrix4x4f* outMatrices)
{
	Animator& animator = static_cast<Animator&>(animatorComponent);
	AssertIf(animator.GetHasTransformHierarchy());

	return CalculateWordSpaceMatrices(&animator, indices, outMatrices, count);
}

bool MecanimAnimation::PathHashesToIndices(Unity::Component& animatorComponent, const BindingHash* bonePathHashes, size_t count, UInt16* outIndices)
{
	Animator& animator = static_cast<Animator&>(animatorComponent);
	if (animator.GetHasTransformHierarchy())
		return false;

	const mecanim::animation::AvatarConstant* avatarConstant = animator.GetAvatarConstant();
	if (!avatarConstant)
		return false;

	const mecanim::skeleton::Skeleton* skel = avatarConstant->m_AvatarSkeleton.Get();
	if (!skel)
		return false;

	bool doMatchSkeleton = true;
	for (int i = 0; i < count && doMatchSkeleton; i++)
	{
		int skeletonIndex = mecanim::skeleton::SkeletonFindNode(skel, bonePathHashes[i]);
		doMatchSkeleton = (skeletonIndex != -1);
		outIndices[i] = (UInt16)skeletonIndex;
	}

	if (!doMatchSkeleton)
	{
		const Avatar* avatar = animator.GetAvatar();
		Assert(avatar);
		ErrorStringObject(Format("The input bones do not match the skeleton of the Avatar(%s).\n"
			"Please check if the Avatar is generated in optimized mode, or if the Avatar is valid for the attached SkinnedMeshRenderer.", 
			avatar->GetName()).c_str(),
			avatar);
	}

	return doMatchSkeleton;
}