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 #ifndef CORE_ECS_ANIMATIONSYSTEM_H
17 #define CORE_ECS_ANIMATIONSYSTEM_H
18
19 #include <ComponentTools/component_query.h>
20 #include <PropertyTools/property_api_impl.h>
21
22 #include <3d/ecs/systems/intf_animation_system.h>
23 #include <3d/namespace.h>
24 #include <base/containers/unique_ptr.h>
25 #include <base/containers/vector.h>
26 #include <core/ecs/entity.h>
27 #include <core/namespace.h>
28 #include <core/threading/intf_thread_pool.h>
29
30 #include "ecs/components/initial_transform_component.h"
31
32 CORE_BEGIN_NAMESPACE()
33 class IEcs;
34 class IPropertyApi;
35 class IPropertyHandle;
36 struct PropertyTypeDecl;
37 CORE_END_NAMESPACE()
38
39 CORE3D_BEGIN_NAMESPACE()
40 class IAnimationPlayback;
41 class INameComponentManager;
42 class ISceneNode;
43 class IAnimationComponentManager;
44 class IAnimationInputComponentManager;
45 class IAnimationOutputComponentManager;
46 class IAnimationStateComponentManager;
47 class IAnimationTrackComponentManager;
48 class IInitialTransformComponentManager;
49 class AnimationPlayback;
50 struct AnimationTrackComponent;
51 struct AnimationOutputComponent;
52 struct AnimationStateComponent;
53
54 class AnimationSystem final : public IAnimationSystem, CORE_NS::IEcs::ComponentListener {
55 public:
56 explicit AnimationSystem(CORE_NS::IEcs& ecs);
57 ~AnimationSystem() override = default;
58
59 BASE_NS::string_view GetName() const override;
60 BASE_NS::Uid GetUid() const override;
61
62 CORE_NS::IPropertyHandle* GetProperties() override;
63 const CORE_NS::IPropertyHandle* GetProperties() const override;
64 void SetProperties(const CORE_NS::IPropertyHandle&) override;
65
66 bool IsActive() const override;
67 void SetActive(bool state) override;
68
69 void Initialize() override;
70 bool Update(bool frameRenderingQueued, uint64_t time, uint64_t delta) override;
71 void Uninitialize() override;
72
73 const CORE_NS::IEcs& GetECS() const override;
74
75 // IAnimationSystem.
76 IAnimationPlayback* CreatePlayback(CORE_NS::Entity const& animationEntity, ISceneNode const& node) override;
77 IAnimationPlayback* CreatePlayback(const CORE_NS::Entity animationEntity,
78 const BASE_NS::array_view<const CORE_NS::Entity> targetEntities) override;
79 void DestroyPlayback(IAnimationPlayback* playback) override;
80
81 size_t GetPlaybackCount() const override;
82 IAnimationPlayback* GetPlayback(size_t index) const override;
83
84 struct Properties {
85 size_t minTaskSize;
86 };
87
88 struct PropertyEntry;
89 struct InterpolationData;
90
91 private:
92 struct Data {
93 // for checking the type of the data
94 const CORE_NS::PropertyTypeDecl* property;
95 // for accessing the data. data() include offset and size() equals sizeof(type)
96 BASE_NS::array_view<uint8_t> data;
97 // for calling WUnlock automatically when data is not needed
98 CORE_NS::ScopedHandle<uint8_t> handle;
99 };
100
101 struct FrameData {
102 float currentOffset;
103 size_t currentFrameIndex;
104 size_t nextFrameIndex;
105 };
106
107 struct TrackValues {
108 InitialTransformComponent initial;
109 InitialTransformComponent result;
110 float timePosition { 0.f };
111 float weight { 0.f };
112 bool stopped { true };
113 bool forward { true };
114 bool updated { false };
115 };
116
117 class InitTask;
118 class AnimateTask;
119
120 // IEcs::ComponentListener
121 void OnComponentEvent(EventType type, const CORE_NS::IComponentManager& componentManager,
122 BASE_NS::array_view<const CORE_NS::Entity> entities) override;
123 void OnAnimationComponentsCreated(BASE_NS::array_view<const CORE_NS::Entity> entities);
124 void OnAnimationComponentsUpdated(BASE_NS::array_view<const CORE_NS::Entity> entities);
125 void OnAnimationTrackComponentsUpdated(BASE_NS::array_view<const CORE_NS::Entity> entities);
126
127 void UpdateAnimation(AnimationStateComponent& state, const AnimationComponent& animation,
128 const CORE_NS::ComponentQuery& trackQuery, float delta);
129 void InitializeTrackValues();
130 void ResetToInitialTrackValues();
131 void WriteUpdatedTrackValues();
132
133 void InitializeTrackValues(BASE_NS::array_view<const uint32_t> resultIndices);
134 void ResetTargetProperties(BASE_NS::array_view<const uint32_t> resultIndices);
135 void Calculate(BASE_NS::array_view<const uint32_t> resultIndices);
136 void AnimateTracks(BASE_NS::array_view<const uint32_t> resultIndices);
137 void ApplyResults(BASE_NS::array_view<const uint32_t> resultIndices);
138
139 const PropertyEntry& GetEntry(const AnimationTrackComponent& track);
140 void InitializeInitialDataComponent(CORE_NS::Entity trackEntity, const AnimationTrackComponent& animationTrack);
141
142 CORE_NS::IEcs& ecs_;
143 bool active_ = true;
144 Properties systemProperties_ { 128U };
145 CORE_NS::PropertyApiImpl<Properties> systemPropertyApi_;
146
147 BASE_NS::vector<BASE_NS::unique_ptr<AnimationPlayback>> animations_;
148
149 IInitialTransformComponentManager& initialTransformManager_;
150 IAnimationComponentManager& animationManager_;
151 IAnimationInputComponentManager& inputManager_;
152 IAnimationOutputComponentManager& outputManager_;
153 IAnimationStateComponentManager& stateManager_;
154 IAnimationTrackComponentManager& animationTrackManager_;
155 INameComponentManager& nameManager_;
156
157 CORE_NS::ComponentQuery trackQuery_;
158 CORE_NS::ComponentQuery animationQuery_;
159 uint32_t stateGeneration_ {};
160 uint32_t animationGeneration_ {};
161
162 BASE_NS::vector<uint32_t> animationOrder_;
163 BASE_NS::vector<uint32_t> trackOrder_;
164 BASE_NS::vector<PropertyEntry> propertyCache_;
165
166 CORE_NS::IThreadPool::Ptr threadPool_;
167
168 size_t taskSize_ { 0U };
169 size_t tasks_ { 0U };
170 size_t remaining_ { 0U };
171
172 uint64_t taskId_ { 0U };
173
174 BASE_NS::vector<CORE_NS::IThreadPool::IResult::Ptr> taskResults_;
175
176 BASE_NS::vector<InitTask> initTasks_;
177 uint64_t initTaskStart_ { 0U };
178 uint64_t initTaskCount_ { 0U };
179
180 BASE_NS::vector<AnimateTask> animTasks_;
181 uint64_t animTaskStart_ { 0U };
182 uint64_t animTaskCount_ { 0U };
183
184 BASE_NS::vector<TrackValues> trackValues_;
185 BASE_NS::vector<FrameData> frameIndices_;
186 };
187
188 /** @ingroup group_ecs_systems_ianimation */
189 /** Return name of this system
190 */
GetName(const IAnimationSystem *)191 inline constexpr BASE_NS::string_view GetName(const IAnimationSystem*)
192 {
193 return "AnimationSystem";
194 }
195 CORE3D_END_NAMESPACE()
196
197 #endif // CORE_ECS_ANIMATIONSYSTEM_H
198