• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 #include <3d/ecs/systems/intf_animation_system.h>
22 #include <3d/namespace.h>
23 #include <base/containers/unique_ptr.h>
24 #include <base/containers/vector.h>
25 #include <core/ecs/entity.h>
26 #include <core/namespace.h>
27 #include <core/property_tools/property_api_impl.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     enum class TrackState : uint8_t {
108         PLAYING,
109         PAUSED,
110         STOPPING,
111         STOPPED,
112     };
113     struct TrackValues {
114         InitialTransformComponent initial;
115         InitialTransformComponent result;
116         float timePosition { 0.f };
117         float weight { 0.f };
118         TrackState state { TrackState::STOPPED };
119         bool forward { true };
120         bool updated { false };
121     };
122 
123     class InitTask;
124     class FrameIndexTask;
125     class AnimateTask;
126 
127     // IEcs::ComponentListener
128     void OnComponentEvent(EventType type, const CORE_NS::IComponentManager& componentManager,
129         BASE_NS::array_view<const CORE_NS::Entity> entities) override;
130     void OnAnimationComponentsCreated(BASE_NS::array_view<const CORE_NS::Entity> entities);
131     void OnAnimationComponentsUpdated(BASE_NS::array_view<const CORE_NS::Entity> entities);
132     void OnAnimationTrackComponentsUpdated(BASE_NS::array_view<const CORE_NS::Entity> entities);
133 
134     void UpdateAnimationStates(uint64_t delta);
135     void UpdateAnimation(AnimationStateComponent& state, const AnimationComponent& animation,
136         const CORE_NS::ComponentQuery& trackQuery, float delta);
137     void InitializeTrackValues();
138     void AnimateTrackValues();
139     void ResetToInitialTrackValues();
140     void WriteUpdatedTrackValues();
141 
142     void InitializeTrackValues(BASE_NS::array_view<const uint32_t> resultIndices);
143     void ResetTargetProperties(BASE_NS::array_view<const uint32_t> resultIndices);
144     void CalculateFrameIndices(BASE_NS::array_view<const uint32_t> resultIndices);
145     void AnimateTracks(BASE_NS::array_view<const uint32_t> resultIndices);
146     void ApplyResults(BASE_NS::array_view<const uint32_t> resultIndices);
147 
148     const PropertyEntry& GetEntry(const AnimationTrackComponent& track);
149     void InitializeInitialDataComponent(CORE_NS::Entity trackEntity, const AnimationTrackComponent& animationTrack);
150 
151     CORE_NS::IEcs& ecs_;
152     bool active_ = true;
153     Properties systemProperties_ { 128U };
154     CORE_NS::PropertyApiImpl<Properties> systemPropertyApi_;
155 
156     BASE_NS::vector<BASE_NS::unique_ptr<AnimationPlayback>> animations_;
157 
158     IInitialTransformComponentManager& initialTransformManager_;
159     IAnimationComponentManager& animationManager_;
160     IAnimationInputComponentManager& inputManager_;
161     IAnimationOutputComponentManager& outputManager_;
162     IAnimationStateComponentManager& stateManager_;
163     IAnimationTrackComponentManager& animationTrackManager_;
164     INameComponentManager& nameManager_;
165 
166     CORE_NS::ComponentQuery trackQuery_;
167     CORE_NS::ComponentQuery animationQuery_;
168     uint32_t stateGeneration_ {};
169     uint32_t animationGeneration_ {};
170 
171     BASE_NS::vector<uint32_t> animationOrder_;
172     BASE_NS::vector<uint32_t> trackOrder_;
173     BASE_NS::vector<PropertyEntry> propertyCache_;
174 
175     CORE_NS::IThreadPool::Ptr threadPool_;
176 
177     size_t taskSize_ { 0U };
178     size_t tasks_ { 0U };
179     size_t remaining_ { 0U };
180 
181     uint64_t taskId_ { 0U };
182 
183     BASE_NS::vector<CORE_NS::IThreadPool::IResult::Ptr> taskResults_;
184 
185     BASE_NS::vector<InitTask> initTasks_;
186     uint64_t initTaskStart_ { 0U };
187 
188     BASE_NS::vector<FrameIndexTask> frameIndexTasks_;
189 
190     BASE_NS::vector<AnimateTask> animTasks_;
191     uint64_t animTaskStart_ { 0U };
192 
193     BASE_NS::vector<TrackValues> trackValues_;
194     BASE_NS::vector<FrameData> frameIndices_;
195 };
196 
197 /** @ingroup group_ecs_systems_ianimation */
198 /** Return name of this system
199  */
GetName(const IAnimationSystem *)200 inline constexpr BASE_NS::string_view GetName(const IAnimationSystem*)
201 {
202     return "AnimationSystem";
203 }
204 CORE3D_END_NAMESPACE()
205 
206 #endif // CORE_ECS_ANIMATIONSYSTEM_H
207