CSEngine
Loading...
Searching...
No Matches
AnimatorComponent.cpp
1#include "AnimatorComponent.h"
2#include "../../Object/SGameObjectFromSPrefab.h"
3
4using namespace CSE;
5
6COMPONENT_CONSTRUCTOR(AnimatorComponent) {
7
8}
9
10
11AnimatorComponent::~AnimatorComponent() = default;
12
13void AnimatorComponent::Init() {
14}
15
16
17void AnimatorComponent::Tick(float elapsedTime) {
18 if (m_currentAnimation == nullptr) return;
19
20 if (m_startTime == 0) {
21 m_startTime = elapsedTime;
22 }
23 UpdateAnimationTime(elapsedTime);
24
25 std::vector<mat4> currentPose = calculateCurrentAnimationPose();
26 applyPoseToJoints(currentPose, m_rootJoint, mat4::Identity());
27
28}
29
30
31void AnimatorComponent::Exterminate() {
32}
33
34void AnimatorComponent::SetRootJoint(JointComponent* mesh) {
35 m_rootJoint = mesh;
36}
37
38// void AnimatorComponent::SetAnimation(Animation* animation) {
39// m_animation = animation;
40// }
41
42void AnimatorComponent::PlayAnimation(Animation* animation) {
43 m_currentAnimation = animation;
44 m_animationTime = m_startTime = 0;
45}
46
47void AnimatorComponent::UpdateAnimationTime(float elapsedTime) {
48 m_animationTime += (elapsedTime - m_startTime) / 1000.f;
49 float length = m_currentAnimation->GetLength();
50
51 if (m_animationTime > length) {
52 m_animationTime -= (m_animationTime / length) * length;
53 }
54
55 m_startTime = elapsedTime;
56}
57
58
59std::vector<mat4> AnimatorComponent::calculateCurrentAnimationPose() const {
60 std::vector<KeyFrame*> frames = getPreviousAndNextFrames();
61 const float progression = CalculateProgression(frames[0], frames[1]);
62 return InterpolatePoses(frames[0], frames[1], progression);
63}
64
65void AnimatorComponent::applyPoseToJoints(std::vector<mat4>& currentPose, JointComponent* joint,
66 const mat4& parentTransform) {
67 const auto& object = joint->GetGameObject();
68 const int jointId = joint->GetAnimationJointId();
69 const mat4& currentLocalTransform = currentPose[jointId];
70 mat4&& currentTransform = currentLocalTransform * parentTransform;
71 auto children = object->GetChildren();
72 for (const auto& child : children) {
73 const auto& joint_component = child->GetComponent<JointComponent>();
74 if (joint_component != nullptr)
75 applyPoseToJoints(currentPose, joint_component, currentTransform);
76 }
77 currentTransform = joint->GetInverseTransformMatrix() * currentTransform;
78 joint->SetAnimationMatrix(std::move(currentTransform));
79}
80
81std::vector<KeyFrame*> AnimatorComponent::getPreviousAndNextFrames() const {
82 auto allFrames = m_currentAnimation->GetKeyFrames();
83 KeyFrame* previousFrame = allFrames.front();
84 KeyFrame* nextFrame = allFrames.front();
85
86 // 첫 번째 키 프레임을 제외한 나머지 키 프레임만을 순회합니다.
87 for (auto it = std::next(allFrames.begin()); it != allFrames.end(); ++it) {
88 nextFrame = *it;
89 if (nextFrame->GetTimeStamp() > m_animationTime) {
90 break;
91 }
92 previousFrame = nextFrame;
93 }
94
95 std::vector<KeyFrame*> result;
96 result.reserve(2);
97 result.push_back(previousFrame);
98 result.push_back(nextFrame);
99 return result;
100}
101
102float AnimatorComponent::CalculateProgression(KeyFrame* previous, KeyFrame* next) const {
103 float totalTime = next->GetTimeStamp() - previous->GetTimeStamp();
104 float currentTime = m_animationTime - previous->GetTimeStamp();
105 return currentTime / totalTime;
106}
107
108std::vector<mat4> AnimatorComponent::InterpolatePoses(KeyFrame* previousFrame, KeyFrame* nextFrame, float t) {
109 const auto& jointKeyFrames_prev = previousFrame->GetJointKeyFrames();
110 const auto& jointKeyFrames_next = nextFrame->GetJointKeyFrames();
111 const auto jointSize = jointKeyFrames_prev.size();
112 std::vector<mat4> currentPose;
113 currentPose.reserve(jointSize);
114
115 for (unsigned short i = 0; i < jointSize; ++i) {
116 const auto& prevTransform = jointKeyFrames_prev[i];
117 const auto& nextTransform = jointKeyFrames_next[i];
118 JointTransform&& currentTransform = JointTransform::Interpolate(t, *prevTransform, *nextTransform);
119 currentPose.emplace_back(std::move(currentTransform).GetLocalMatrix());
120 }
121 return currentPose;
122}
123
124SComponent* AnimatorComponent::Clone(SGameObject* object) {
125 INIT_COMPONENT_CLONE(AnimatorComponent, clone);
126
127 clone->m_animationTime = m_animationTime;
128 clone->m_startTime = m_startTime;
129 clone->m_currentAnimation = m_currentAnimation;
130
131 return clone;
132}
133
134void AnimatorComponent::CopyReference(SComponent* src, std::map<SGameObject*, SGameObject*> lists_obj,
135 std::map<SComponent*, SComponent*> lists_comp) {
136 if (src == nullptr) return;
137 auto convert = static_cast<AnimatorComponent*>(src);
138
139 //Copy Components
140 FIND_COMP_REFERENCE(m_rootJoint, convert, JointComponent);
141
142}
143
144void AnimatorComponent::SetValue(std::string name_str, Arguments value) {
145 if (name_str == "m_animationTime") {
146 m_animationTime = std::stof(value[0]);
147 } else if (name_str == "m_startTime") {
148 m_startTime = std::stof(value[0]);
149 } else if (name_str == "m_currentAnimation") {
150 m_currentAnimation = SResource::Create<Animation>(value[0]);
151 } else if (name_str == "m_rootJoint") {
152 SET_SPREFAB_REF(m_rootJoint, JointComponent);
153 }
154}
155
156std::string AnimatorComponent::PrintValue() const {
157
158 PRINT_START("component");
159
160 PRINT_VALUE(m_animationTime, m_animationTime);
161 PRINT_VALUE(m_startTime, m_startTime);
162 PRINT_VALUE(m_currentAnimation, ConvertSpaceStr(m_currentAnimation->GetHash()));
163 PRINT_VALUE_SPREFAB_REF(m_rootJoint);
164
165
166 PRINT_END("component");
167}
168