1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "animation_playback.h"
17 
18 #include <3d/ecs/components/animation_component.h>
19 #include <3d/ecs/components/animation_input_component.h>
20 #include <3d/ecs/components/animation_state_component.h>
21 #include <3d/ecs/components/animation_track_component.h>
22 #include <3d/ecs/components/name_component.h>
23 #include <base/containers/fixed_string.h>
24 #include <base/math/mathf.h>
25 #include <base/math/quaternion_util.h>
26 #include <base/math/spline.h>
27 #include <base/math/vector_util.h>
28 #include <base/util/uid_util.h>
29 #include <core/ecs/intf_ecs.h>
30 #include <core/implementation_uids.h>
31 #include <core/namespace.h>
32 
33 CORE3D_BEGIN_NAMESPACE()
34 using namespace BASE_NS;
35 using namespace CORE_NS;
36 
AnimationPlayback(const Entity animationEntity,const array_view<const Entity> targetEntities,IEcs & ecs)37 AnimationPlayback::AnimationPlayback(
38     const Entity animationEntity, const array_view<const Entity> targetEntities, IEcs& ecs)
39     : animation_(animationEntity), ecs_(ecs), animationManager_(GetManager<IAnimationComponentManager>(ecs)),
40       animationStateManager_(GetManager<IAnimationStateComponentManager>(ecs)),
41       nameManager_(GetManager<INameComponentManager>(ecs))
42 {}
43 
~AnimationPlayback()44 AnimationPlayback::~AnimationPlayback()
45 {
46     if (auto animMgr = GetManager<IAnimationComponentManager>(ecs_); animMgr) {
47         if (auto animHandle = animMgr->Write(animation_); animHandle) {
48             animHandle->state = AnimationComponent::PlaybackState::STOP;
49         }
50     }
51 }
52 
GetName() const53 string_view AnimationPlayback::GetName() const
54 {
55     string_view name;
56     if (const auto nameData = nameManager_->Read(animation_); nameData) {
57         name = nameData->name;
58     }
59     return name;
60 }
61 
SetPlaybackState(AnimationComponent::PlaybackState state)62 void AnimationPlayback::SetPlaybackState(AnimationComponent::PlaybackState state)
63 {
64     if (auto handle = animationManager_->Write(animation_); handle) {
65         handle->state = state;
66     }
67 }
68 
GetPlaybackState() const69 AnimationComponent::PlaybackState AnimationPlayback::GetPlaybackState() const
70 {
71     if (auto handle = animationManager_->Read(animation_); handle) {
72         return handle->state;
73     }
74     return AnimationComponent::PlaybackState::STOP;
75 }
76 
SetRepeatCount(uint32_t repeatCount)77 void AnimationPlayback::SetRepeatCount(uint32_t repeatCount)
78 {
79     if (auto handle = animationManager_->Write(animation_); handle) {
80         handle->repeatCount = repeatCount;
81     }
82 }
83 
GetRepeatCount() const84 uint32_t AnimationPlayback::GetRepeatCount() const
85 {
86     if (auto handle = animationManager_->Read(animation_); handle) {
87         return handle->repeatCount;
88     }
89     return 0U;
90 }
91 
SetWeight(float weight)92 void AnimationPlayback::SetWeight(float weight)
93 {
94     if (auto handle = animationManager_->Write(animation_); handle) {
95         handle->weight = weight;
96     }
97 }
98 
GetWeight() const99 float AnimationPlayback::GetWeight() const
100 {
101     if (auto handle = animationManager_->Read(animation_); handle) {
102         return handle->weight;
103     }
104     return 0.f;
105 }
106 
GetTimePosition() const107 float AnimationPlayback::GetTimePosition() const
108 {
109     if (auto handle = animationStateManager_->Read(animation_); handle) {
110         return handle->time;
111     }
112     return 0.f;
113 }
114 
SetTimePosition(float timePosition)115 void AnimationPlayback::SetTimePosition(float timePosition)
116 {
117     if (auto handle = animationStateManager_->Write(animation_); handle) {
118         handle->time = timePosition;
119     }
120 }
121 
GetAnimationLength() const122 float AnimationPlayback::GetAnimationLength() const
123 {
124     float maxLength = 0.f;
125     if (auto handle = animationManager_->Read(animation_); handle) {
126         auto trackManager = GetManager<IAnimationTrackComponentManager>(animationManager_->GetEcs());
127         auto inputManager = GetManager<IAnimationInputComponentManager>(animationManager_->GetEcs());
128         for (const auto& trackEntity : handle->tracks) {
129             if (auto track = trackManager->Read(trackEntity); track) {
130                 if (auto inputData = inputManager->Read(track->timestamps); inputData) {
131                     if (!inputData->timestamps.empty()) {
132                         maxLength = Math::max(maxLength, inputData->timestamps.back());
133                     }
134                 }
135             }
136         }
137     }
138     return maxLength;
139 }
140 
SetStartOffset(float startOffset)141 void AnimationPlayback::SetStartOffset(float startOffset)
142 {
143     if (auto handle = animationManager_->Write(animation_); handle) {
144         handle->startOffset = startOffset;
145     }
146 }
147 
GetStartOffset() const148 float AnimationPlayback::GetStartOffset() const
149 {
150     if (auto handle = animationManager_->Read(animation_); handle) {
151         return handle->startOffset;
152     }
153     return 0.f;
154 }
155 
SetDuration(float duration)156 void AnimationPlayback::SetDuration(float duration)
157 {
158     if (auto handle = animationManager_->Write(animation_); handle) {
159         handle->duration = duration;
160     }
161 }
162 
GetDuration() const163 float AnimationPlayback::GetDuration() const
164 {
165     if (auto handle = animationManager_->Read(animation_); handle) {
166         return handle->duration;
167     }
168     return 0.f;
169 }
170 
IsCompleted() const171 bool AnimationPlayback::IsCompleted() const
172 {
173     if (auto handle = animationStateManager_->Read(animation_); handle) {
174         return handle->completed;
175     }
176     return true;
177 }
178 
SetSpeed(float speed)179 void AnimationPlayback::SetSpeed(float speed)
180 {
181     if (auto handle = animationManager_->Write(animation_); handle) {
182         handle->speed = speed;
183     }
184 }
185 
GetSpeed() const186 float AnimationPlayback::GetSpeed() const
187 {
188     if (auto handle = animationManager_->Read(animation_); handle) {
189         return handle->speed;
190     }
191     return 0.f;
192 }
193 
GetEntity() const194 Entity AnimationPlayback::GetEntity() const
195 {
196     return animation_;
197 }
198 CORE3D_END_NAMESPACE()
199