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 CORE3D_ECS_RENDER_PREPROCESSOR_SYSTEM_H
17 #define CORE3D_ECS_RENDER_PREPROCESSOR_SYSTEM_H
18 
19 #include <ComponentTools/component_query.h>
20 #include <PropertyTools/property_api_impl.h>
21 #include <limits>
22 
23 #include <3d/ecs/systems/intf_render_preprocessor_system.h>
24 #include <3d/intf_graphics_context.h>
25 #include <base/math/vector.h>
26 #include <render/datastore/intf_render_data_store_manager.h>
27 #include <render/intf_render_context.h>
28 
29 #include "property/property_handle.h"
30 
31 RENDER_BEGIN_NAMESPACE()
32 class IRenderContext;
33 class IRenderDataStoreManager;
34 RENDER_END_NAMESPACE()
35 
36 CORE3D_BEGIN_NAMESPACE()
37 class IRenderDataStoreDefaultCamera;
38 class IRenderDataStoreDefaultLight;
39 class IRenderDataStoreDefaultMaterial;
40 class IRenderDataStoreDefaultScene;
41 class IRenderDataStoreMorph;
42 class IJointMatricesComponentManager;
43 class ILayerComponentManager;
44 class IMaterialComponentManager;
45 class IMeshComponentManager;
46 class INodeComponentManager;
47 class IRenderMeshComponentManager;
48 class ISkinComponentManager;
49 class IWorldMatrixComponentManager;
50 class IPicking;
51 
52 class RenderPreprocessorSystem final : public IRenderPreprocessorSystem {
53 public:
54     explicit RenderPreprocessorSystem(CORE_NS::IEcs& ecs);
55     ~RenderPreprocessorSystem() override;
56     BASE_NS::string_view GetName() const override;
57     BASE_NS::Uid GetUid() const override;
58     CORE_NS::IPropertyHandle* GetProperties() override;
59     const CORE_NS::IPropertyHandle* GetProperties() const override;
60     void SetProperties(const CORE_NS::IPropertyHandle&) override;
61     bool IsActive() const override;
62     void SetActive(bool state) override;
63 
64     void Initialize() override;
65     void Uninitialize() override;
66     bool Update(bool frameRenderingQueued, uint64_t totalTime, uint64_t deltaTime) override;
67 
68     const CORE_NS::IEcs& GetECS() const override;
69 
70     BASE_NS::array_view<const CORE_NS::Entity> GetRenderBatchMeshEntities() const;
71     BASE_NS::array_view<const CORE_NS::Entity> GetInstancingAllowedEntities() const;
72     BASE_NS::array_view<const CORE_NS::Entity> GetInstancingDisabledEntities() const;
73 
74     struct Aabb {
75         BASE_NS::Math::Vec3 min { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(),
76             std::numeric_limits<float>::max() };
77         BASE_NS::Math::Vec3 max { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(),
78             -std::numeric_limits<float>::max() };
79     };
80 
81     // whole mesh
82     Aabb GetRenderMeshAabb(CORE_NS::Entity renderMesh) const;
83     // one for each submesh
84     BASE_NS::array_view<const Aabb> GetRenderMeshAabbs(CORE_NS::Entity renderMesh) const;
85 
86     struct Sphere {
87         BASE_NS::Math::Vec3 center;
88         float radius {};
89     };
90     Sphere GetBoundingSphere() const;
91 
92     struct SortData {
93         CORE_NS::IComponentManager::ComponentId renderMeshId;
94         CORE_NS::Entity mesh;
95         CORE_NS::Entity batch;
96         CORE_NS::Entity skin;
97         bool allowInstancing;
98     };
99 
100     struct MaterialProperties {
101         CORE_NS::Entity material;
102         bool disabled;
103         bool allowInstancing;
104         bool shadowCaster;
105     };
106 
107 private:
108     void SetDataStorePointers(RENDER_NS::IRenderDataStoreManager& manager);
109     void CalculateSceneBounds();
110     void GatherSortData();
111 
112     CORE_NS::IEcs& ecs_;
113     IGraphicsContext* graphicsContext_ { nullptr };
114     RENDER_NS::IRenderContext* renderContext_ { nullptr };
115     IJointMatricesComponentManager* jointMatricesManager_ { nullptr };
116     ILayerComponentManager* layerManager_ { nullptr };
117     IMaterialComponentManager* materialManager_ { nullptr };
118     IMeshComponentManager* meshManager_ { nullptr };
119     INodeComponentManager* nodeManager_ { nullptr };
120     IRenderMeshComponentManager* renderMeshManager_ { nullptr };
121     ISkinComponentManager* skinManager_ { nullptr };
122     IWorldMatrixComponentManager* worldMatrixManager_ { nullptr };
123     bool active_ { true };
124 
125     IRenderPreprocessorSystem::Properties properties_ {
126         "RenderDataStoreDefaultScene",
127         "RenderDataStoreDefaultCamera",
128         "RenderDataStoreDefaultLight",
129         "RenderDataStoreDefaultMaterial",
130         "RenderDataStoreMorph",
131         "",
132     };
133     CORE_NS::PropertyApiImpl<IRenderPreprocessorSystem::Properties> RENDER_PREPROCESSOR_SYSTEM_PROPERTIES;
134 
135     IRenderDataStoreDefaultCamera* dsCamera_ { nullptr };
136     IRenderDataStoreDefaultLight* dsLight_ { nullptr };
137     IRenderDataStoreDefaultMaterial* dsMaterial_ { nullptr };
138     IRenderDataStoreDefaultScene* dsScene_ { nullptr };
139     IRenderDataStoreMorph* dsMorph_ { nullptr };
140 
141     IPicking* picking_ = nullptr;
142 
143     CORE_NS::ComponentQuery renderableQuery_;
144     uint32_t layerGeneration_ { 0U };
145     uint32_t materialGeneration_ { 0U };
146     uint32_t meshGeneration_ { 0U };
147     uint32_t nodeGeneration_ { 0U };
148     uint32_t renderMeshGeneration_ { 0U };
149     uint32_t worldMatrixGeneration_ { 0U };
150     BASE_NS::vector<MaterialProperties> materialProperties_;
151     BASE_NS::vector<SortData> meshComponents_;
152 
153     BASE_NS::vector<CORE_NS::Entity> renderMeshComponents_;
154     BASE_NS::array_view<const CORE_NS::Entity> renderBatchComponents_;
155     BASE_NS::array_view<const CORE_NS::Entity> instancingAllowed_;
156     BASE_NS::array_view<const CORE_NS::Entity> rest_;
157     struct RenderMeshAaabb {
158         Aabb meshAabb;
159         BASE_NS::vector<Aabb> submeshAabbs;
160     };
161     BASE_NS::unordered_map<CORE_NS::Entity, RenderMeshAaabb> renderMeshAabbs_;
162     Sphere boundingSphere_;
163 };
164 CORE3D_END_NAMESPACE()
165 
166 #endif // CORE3D_ECS_RENDER_PREPROCESSOR_SYSTEM_H
167