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