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 "local_matrix_system.h"
17
18 #include <ComponentTools/component_query.h>
19 #include <PropertyTools/property_api_impl.inl>
20
21 #include <3d/ecs/components/local_matrix_component.h>
22 #include <3d/ecs/components/transform_component.h>
23 #include <base/math/matrix_util.h>
24 #include <core/ecs/intf_ecs.h>
25 #include <core/namespace.h>
26
27 #include "property/property_handle.h"
28
29 CORE3D_BEGIN_NAMESPACE()
30 using namespace BASE_NS;
31 using namespace CORE_NS;
32
SetActive(bool state)33 void LocalMatrixSystem::SetActive(bool state)
34 {
35 active_ = state;
36 }
37
IsActive() const38 bool LocalMatrixSystem::IsActive() const
39 {
40 return active_;
41 }
42
LocalMatrixSystem(IEcs & ecs)43 LocalMatrixSystem::LocalMatrixSystem(IEcs& ecs) : active_(true), ecs_(ecs)
44 {
45 localMatrixManager_ = GetManager<ILocalMatrixComponentManager>(ecs);
46 transformManager_ = GetManager<ITransformComponentManager>(ecs);
47 }
48
GetName() const49 string_view LocalMatrixSystem::GetName() const
50 {
51 return CORE3D_NS::GetName(this);
52 }
53
GetUid() const54 Uid LocalMatrixSystem::GetUid() const
55 {
56 return UID;
57 }
58
GetProperties() const59 const IPropertyHandle* LocalMatrixSystem::GetProperties() const
60 {
61 return nullptr;
62 }
63
GetProperties()64 IPropertyHandle* LocalMatrixSystem::GetProperties()
65 {
66 return nullptr;
67 }
68
SetProperties(const IPropertyHandle &)69 void LocalMatrixSystem::SetProperties(const IPropertyHandle&) {}
70
GetECS() const71 const IEcs& LocalMatrixSystem::GetECS() const
72 {
73 return ecs_;
74 }
75
Initialize()76 void LocalMatrixSystem::Initialize()
77 {
78 const ComponentQuery::Operation operations[] = {
79 { *localMatrixManager_, ComponentQuery::Operation::REQUIRE },
80 };
81 componentQuery_.SetEcsListenersEnabled(true);
82 componentQuery_.SetupQuery(*transformManager_, operations);
83 }
84
Update(bool frameRenderingQueued,uint64_t,uint64_t)85 bool LocalMatrixSystem::Update(bool frameRenderingQueued, uint64_t, uint64_t)
86 {
87 if (!active_) {
88 return false;
89 }
90
91 if (transformGeneration_ == transformManager_->GetGenerationCounter()) {
92 return false;
93 }
94
95 transformGeneration_ = transformManager_->GetGenerationCounter();
96
97 bool transformComponentGenerationValid = true;
98 if (componentQuery_.Execute()) {
99 transformComponentGenerationValid = false;
100 transformComponentGenerations_.resize(transformManager_->GetComponentCount());
101 }
102
103 for (const auto& row : componentQuery_.GetResults()) {
104 const auto transformComponentId = row.components[0];
105
106 // Resolve component generation.
107 uint32_t currentComponentGenerationId = transformManager_->GetComponentGeneration(transformComponentId);
108
109 // See if we need to re-calculate the matrix.
110 bool recalculateMatrix = true;
111 if (transformComponentGenerationValid) {
112 if (currentComponentGenerationId == transformComponentGenerations_[transformComponentId]) {
113 // Generation not changed.
114 recalculateMatrix = false;
115 }
116 }
117
118 if (recalculateMatrix) {
119 const TransformComponent& tm = transformManager_->Get(transformComponentId);
120
121 LocalMatrixComponent localMatrixData;
122 localMatrixData.matrix = Math::Trs(tm.position, tm.rotation, tm.scale);
123 localMatrixManager_->Set(row.components[1], localMatrixData);
124
125 // Store generation.
126 transformComponentGenerations_[transformComponentId] = currentComponentGenerationId;
127 }
128 }
129
130 return true;
131 }
132
Uninitialize()133 void LocalMatrixSystem::Uninitialize()
134 {
135 componentQuery_.SetEcsListenersEnabled(false);
136 }
137
LocalMatrixSystemInstance(IEcs & ecs)138 ISystem* LocalMatrixSystemInstance(IEcs& ecs)
139 {
140 return new LocalMatrixSystem(ecs);
141 }
LocalMatrixSystemDestroy(ISystem * instance)142 void LocalMatrixSystemDestroy(ISystem* instance)
143 {
144 delete static_cast<LocalMatrixSystem*>(instance);
145 }
146
147 CORE3D_END_NAMESPACE()
148