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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include "UnityPrefix.h"
#include "AnimatorManager.h"
#include "Animator.h"
#include "Runtime/Input/TimeManager.h"
#include "Runtime/Core/Callbacks/PlayerLoopCallbacks.h"
static AnimatorManager* gAnimatorManager = NULL;
void AnimatorManager::FixedUpdateFKMove()
{
if(m_FixedUpdateAvatars.size() > 0 && GetTimeManager().GetFixedDeltaTime())
{
Animator::UpdateAvatars(m_FixedUpdateAvatars.begin(), m_FixedUpdateAvatars.size(), GetTimeManager().GetFixedDeltaTime(),true,false);
}
}
void AnimatorManager::FixedUpdateRetargetIKWrite()
{
//@TODO: Why do we do FixedUpdateRetargetIKWrite?
// This visually wrong when you use physics interpolation to get smooth root motion, but then the animation of the characters limbs only updates at a very low physics framerate.
// It would be better to run UpdateRetargetWrite in the dynamic framerate.
if(m_FixedUpdateAvatars.size() > 0 && GetTimeManager().GetFixedDeltaTime())
{
Animator::UpdateAvatars(m_FixedUpdateAvatars.begin(), m_FixedUpdateAvatars.size(), GetTimeManager().GetFixedDeltaTime(),false,true);
}
}
void AnimatorManager::UpdateFKMove ()
{
if(m_UpdateAvatars.size() > 0 && GetTimeManager().GetDeltaTime())
{
Animator::UpdateAvatars(m_UpdateAvatars.begin(), m_UpdateAvatars.size(), GetDeltaTime(),true,false);
}
}
void AnimatorManager::UpdateRetargetIKWrite ()
{
if(m_UpdateAvatars.size() > 0 && GetTimeManager().GetDeltaTime())
{
Animator::UpdateAvatars(m_UpdateAvatars.begin(), m_UpdateAvatars.size(), GetDeltaTime(),false,true);
}
}
void AnimatorManager::AddAnimator (Animator& animator)
{
if (animator.GetEnabled() && animator.IsActive() && animator.IsValid())
{
if(animator.GetAnimatePhysics())
{
animator.SetFixedBehaviourIndex(m_FixedUpdateAvatars.size());
m_FixedUpdateAvatars.push_back(&animator);
}
else
{
animator.SetBehaviourIndex(m_UpdateAvatars.size());
m_UpdateAvatars.push_back(&animator);
}
}
}
void AnimatorManager::RemoveAnimator (Animator& animator)
{
int index = animator.GetBehaviourIndex();
if(index != -1)
{
Animator* backBehaviour = m_UpdateAvatars.back();
m_UpdateAvatars[index] = backBehaviour;
backBehaviour->SetBehaviourIndex(index);
animator.SetBehaviourIndex(-1);
m_UpdateAvatars.pop_back();
}
int fixedIndex = animator.GetFixedBehaviourIndex();
if(fixedIndex != -1)
{
Animator* backBehaviour = m_FixedUpdateAvatars.back();
m_FixedUpdateAvatars[fixedIndex] = backBehaviour;
backBehaviour->SetFixedBehaviourIndex(fixedIndex);
animator.SetFixedBehaviourIndex(-1);
m_FixedUpdateAvatars.pop_back();
}
}
void AnimatorManager::InitializeClass ()
{
Assert(gAnimatorManager == NULL);
gAnimatorManager = UNITY_NEW_AS_ROOT (AnimatorManager, kMemAnimation, "AnimatorManager", "");
REGISTER_PLAYERLOOP_CALL (AnimatorFixedUpdateRetargetIKWrite, GetAnimatorManager().FixedUpdateRetargetIKWrite());
REGISTER_PLAYERLOOP_CALL (AnimatorUpdateRetargetIKWrite, GetAnimatorManager().UpdateRetargetIKWrite ());
REGISTER_PLAYERLOOP_CALL (AnimatorUpdateFKMove, GetAnimatorManager().UpdateFKMove ());
REGISTER_PLAYERLOOP_CALL (AnimatorFixedUpdateFKMove, GetAnimatorManager().FixedUpdateFKMove ());
}
void AnimatorManager::CleanupClass ()
{
UNITY_DELETE (gAnimatorManager, kMemAnimation);
gAnimatorManager = NULL;
}
AnimatorManager& GetAnimatorManager ()
{
Assert(gAnimatorManager != NULL);
return *gAnimatorManager;
}
|