1 /*
2  * Copyright (C) 2023 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 OHOS_RENDER_3D_LUME_COMMON_H
17 #define OHOS_RENDER_3D_LUME_COMMON_H
18 
19 #include <3d/ecs/components/camera_component.h>
20 #include <3d/ecs/components/environment_component.h>
21 #include <3d/ecs/components/light_component.h>
22 #include <3d/ecs/components/material_component.h>
23 #include <3d/ecs/components/name_component.h>
24 #include <3d/ecs/components/node_component.h>
25 #include <3d/ecs/components/post_process_component.h>
26 #include <3d/ecs/components/render_configuration_component.h>
27 #include <3d/ecs/components/render_handle_component.h>
28 #include <3d/ecs/components/render_mesh_component.h>
29 #include <3d/ecs/components/transform_component.h>
30 #include <3d/ecs/components/uri_component.h>
31 #include <3d/ecs/systems/intf_animation_system.h>
32 #include <3d/ecs/systems/intf_morphing_system.h>
33 #include <3d/ecs/systems/intf_node_system.h>
34 #include <3d/ecs/systems/intf_render_system.h>
35 
36 #include <3d/implementation_uids.h>
37 #include <3d/gltf/gltf.h>
38 #include <3d/intf_graphics_context.h>
39 
40 #include <3d/util/intf_mesh_util.h>
41 #include <3d/util/intf_picking.h>
42 #include <3d/util/intf_scene_util.h>
43 
44 #include <base/containers/string_view.h>
45 #include <base/math/mathf.h>
46 #include <base/math/matrix_util.h>
47 #include <base/math/quaternion.h>
48 #include <base/math/quaternion_util.h>
49 #include <base/math/vector.h>
50 #include <base/math/vector_util.h>
51 
52 #include <core/ecs/intf_entity_manager.h>
53 #include <core/engine_info.h>
54 #include <core/intf_engine.h>
55 #include <core/namespace.h>
56 
57 #include <render/intf_plugin.h>
58 #include <render/intf_render_context.h>
59 #include <render/device/intf_device.h>
60 
61 #include "custom/lume_custom_render.h"
62 #include "i_engine.h"
63 
64 namespace OHOS::Render3D {
65 struct GltfImportInfo {
66     enum AnimationTarget { AnimateMainScene, AnimateImportedScene };
67     const char* fileName_;
68     AnimationTarget target_;
69     CORE3D_NS::GltfResourceImportFlags resourceImportFlags_;
70     CORE3D_NS::GltfSceneImportFlags sceneImportFlags_;
71 };
72 
73 struct LightInfo {
74     int type_;
75     float intensity_;
76     bool shadow_;
77     BASE_NS::Math::Vec3 color_;
78     BASE_NS::Math::Vec3 position_;
79     BASE_NS::Math::Quat rotation_;
80 };
81 
82 class OrbitCameraHelper final {
83 public:
84     OrbitCameraHelper();
85     ~OrbitCameraHelper() = default;
86 
87     OrbitCameraHelper(const OrbitCameraHelper&) = delete;
88     OrbitCameraHelper& operator=(const OrbitCameraHelper&) = delete;
89 
90     void SetOrbitFromEye(const BASE_NS::Math::Vec3& eyePosition, const BASE_NS::Math::Quat& rotation,
91         float orbitDistance);
92 
93     void SetOrbitFromTarget(const BASE_NS::Math::Vec3& targetPosition, const BASE_NS::Math::Quat& rotation,
94         float orbitDistance);
95 
96     BASE_NS::Math::Vec3 GetCameraPosition();
97     BASE_NS::Math::Quat GetCameraRotation();
98     void Update(uint64_t /* delta */);
99     void ResetPointerEvents();
100     void HandlePointerEvent(const PointerEvent& event);
101 
102 private:
103     void OnPress(const PointerEvent& event);
104     void OnRelease(const PointerEvent& event);
105     void OnMove(const PointerEvent& event);
106     void UpdateCameraRotation(float dx, float dy);
107     unsigned int pressedButtonsBits_;
108     // Just a very simple and stupid touch gesture system.
109     int touchPointerCount_;
110     PointerEvent touchPointers_[2];
111     // Double touch handling
112     PointerEvent midPoint_;
113 
114     float orbitDistance_;
115     BASE_NS::Math::Vec3 cameraTargetPosition_;
116     BASE_NS::Math::Quat cameraRotation_;
117 };
118 
119 class LumeCommon : public IEngine {
120 public:
121     LumeCommon() = default;
122     ~LumeCommon() override;
123     void Clone(IEngine* proto) override;
124     void UnloadEngineLib() override;
125     bool LoadEngineLib() override;
126     bool InitEngine(EGLContext eglContext, const PlatformData& data) override;
127     void DeInitEngine() override;
128 
129     void InitializeScene(uint32_t key) override;
130 
131     void LoadEnvModel(const std::string& modelPath, BackgroundType type) override;
132     void LoadSceneModel(const std::string& modelPath) override;
133 
134     void UpdateGeometries(const std::vector<std::shared_ptr<Geometry>>& shapes) override;
135     void UpdateGLTFAnimations(const std::vector<std::shared_ptr<GLTFAnimation>>& animations) override;
136     void UpdateLights(const std::vector<std::shared_ptr<OHOS::Render3D::Light>>& lights) override;
137 
138     void UpdateCustomRender(const std::shared_ptr<CustomRenderDescriptor>& customRender) override;
139     void UpdateShaderPath(const std::string& shaderPath) override;
140     void UpdateImageTexturePaths(const std::vector<std::string>& imageTextures) override;
141     void UpdateShaderInputBuffer(const std::shared_ptr<OHOS::Render3D::ShaderInputBuffer>& shaderInputBuffer) override;
142 
143     void SetupCameraViewPort(uint32_t width, uint32_t height) override;
144     void SetupCameraTransform(const OHOS::Render3D::Position& position, const OHOS::Render3D::Vec3& lookAt,
145         const OHOS::Render3D::Vec3& up, const OHOS::Render3D::Quaternion& rotation) override;
146     void SetupCameraViewProjection(float zNear, float zFar, float fovDegrees) override;
147 
148     void UnloadSceneModel() override;
149     void UnloadEnvModel() override;
150     void DrawFrame() override;
151 
152     void OnTouchEvent(const PointerEvent& event) override;
153     void OnWindowChange(const TextureInfo& textureInfo) override;
154 
155 #if defined(MULTI_ECS_UPDATE_AT_ONCE) && (MULTI_ECS_UPDATE_AT_ONCE == 1)
156     void DeferDraw() override;
157     void DrawMultiEcs(const std::unordered_map<void*, void*>& ecss) override;
158 #endif
159     bool NeedsRepaint() override;
160 
161 protected:
162     virtual CORE_NS::PlatformCreateInfo ToEnginePlatformData(const PlatformData& data) const = 0;
163     virtual void RegisterAssertPath() = 0;
164     void LoadSystemGraph(BASE_NS::string sysGraph);
165     void CreateEcs(uint32_t key);
166     void CreateScene();
167     void DestroyScene();
168     void CreateEnvScene(CORE3D_NS::EnvironmentComponent::Background type);
169     void DestroyEnvScene();
170     void DestroySceneNodeAndRes(CORE_NS::Entity& importedEntity, BASE_NS::vector<CORE3D_NS::GLTFResourceData>& res);
171     void CreateCamera();
172     void LoadCustGeometry(const std::vector<std::shared_ptr<Geometry>>& shapes);
173     void SetupPostprocess();
174     void AddTextureMemoryBarrrier();
175     void SetupCustomRenderTarget(const TextureInfo &info);
176     void CreateLight();
177     void ProcessGLTFAnimations();
178     int FindGLTFAnimationIndex(const std::string& name);
179     void UpdateSingleGLTFAnimation(int index, const std::shared_ptr<GLTFAnimation>& gltfAnimation);
180     bool LoadAndImport(const GltfImportInfo& info, CORE_NS::Entity& importedEntity,
181         BASE_NS::vector<CORE3D_NS::GLTFResourceData>& res);
182 
183     bool CreateSwapchain(void* nativeWindow);
184     bool DestroySwapchain();
185     void DestroyResource();
186     void Tick(const uint64_t deltaTime);
187 
188     CORE_NS::IEngine::Ptr CreateCoreEngine(const Core::PlatformCreateInfo &info);
189     CORE_NS::IEngine::Ptr GetCoreEngine();
190 
191     RENDER_NS::RenderHandleReference SetupGpuImageTarget();
192     RENDER_NS::RenderHandleReference SetupGpuDepthTarget();
193     RENDER_NS::GpuImageDesc GetImageDesc();
194     RENDER_NS::IRenderContext::Ptr CreateRenderContext(EGLContext gfxContext);
195     RENDER_NS::IDevice* GetDevice();
196     RENDER_NS::IRenderContext::Ptr GetRenderContext();
197 
198     CORE3D_NS::IGraphicsContext::Ptr CreateGfx3DContext();
199     CORE3D_NS::IGraphicsContext::Ptr GetGraphicsContext();
200 
201     bool IsValidQuaternion(const OHOS::Render3D::Quaternion& quat);
202     void CollectRenderHandles();
203     void GetLightPositionAndRotation(const std::shared_ptr<OHOS::Render3D::Light>& light,
204         BASE_NS::Math::Vec3& position, BASE_NS::Math::Quat& rotation);
205     std::shared_ptr<LumeCustomRender> CustomRenderFactory(const std::string& renderNodeGraph, bool needsFrameCallback);
206     CORE_NS::IEngine::Ptr engine_;
207     CORE_NS::IEcs::Ptr ecs_;
208     CORE_NS::Entity cameraEntity_;
209     CORE_NS::Entity sceneEntity_;
210     CORE_NS::Entity postprocessEntity_;
211     std::vector<CORE_NS::Entity> lightEntities_;
212 
213     CORE_NS::Entity importedSceneEntity_;
214     BASE_NS::vector<CORE3D_NS::GLTFResourceData> importedSceneResources_;
215 
216     CORE_NS::Entity importedEnvEntity_;
217     BASE_NS::vector<CORE3D_NS::GLTFResourceData> importedEnvResources_;
218 
219     BASE_NS::vector<CORE3D_NS::IAnimationPlayback*> animations_;
220     BASE_NS::Math::Vec3 cameraPosition_{ 0.0f, 0.0f, 4.0f };
221     BASE_NS::Math::Quat cameraRotation_{ 0.0f, 0.0f, 0.0f, 1.0f };
222 
223     CORE3D_NS::IGraphicsContext::Ptr graphicsContext_;
224     CORE3D_NS::ITransformComponentManager* transformManager_;
225     CORE3D_NS::ICameraComponentManager* cameraManager_;
226     CORE3D_NS::IRenderConfigurationComponentManager* sceneManager_;
227     CORE3D_NS::ILightComponentManager* lightManager_;
228     CORE3D_NS::IPostProcessComponentManager* postprocessManager_;
229 
230     RENDER_NS::IRenderContext::Ptr renderContext_;
231     RENDER_NS::RenderHandleReference gpuResourceImgHandle_;
232     RENDER_NS::RenderHandleReference gpuDepthTargetHandle_;
233     RENDER_NS::IDevice *device_ = nullptr;
234     RENDER_NS::RenderHandleReference swapchainHandle_;
235 
236     OrbitCameraHelper orbitCamera_;
237     std::vector<std::shared_ptr<GLTFAnimation>> gltfAnimations_;
238     std::vector<std::shared_ptr<Geometry>> shapes_;
239     std::unordered_map<std::string, std::shared_ptr<Geometry>> shapesMap_;
240 
241     CORE3D_NS::IMaterialComponentManager* materialManager_ { nullptr };
242     CORE3D_NS::IMeshComponentManager* meshManager_ { nullptr };
243     CORE3D_NS::INameComponentManager* nameManager_ { nullptr };
244     CORE3D_NS::IUriComponentManager* uriManager_ { nullptr };
245     CORE3D_NS::IRenderHandleComponentManager* gpuHandleManager_ { nullptr };
246     CORE3D_NS::INodeSystem* nodeSystem_ { nullptr };
247     CORE3D_NS::IRenderMeshComponentManager* renderMeshManager_ { nullptr };
248 
249     // Shader
250     std::shared_ptr<LumeCustomRender> customRender_;
251     BASE_NS::vector<RENDER_NS::RenderHandleReference> renderHandles_;
252 
253     bool autoAspect_ = true;
254     float originalYfov_ = BASE_NS::Math::DEG2RAD * 60.0f;
255     float orthoScale_ = 3.0f;
256     bool enablePostprocess_ = true;
257     void *libHandle_ = nullptr;
258     uint32_t key_;
259     float zNear_ = 0.5f;
260     float zFar_ = 200.0f;
261     float fovDegrees_ = 60.0f;
262     bool animProgress_ = false;
263     bool cameraUpdated_ = true;
264     bool needsRedraw_ = false;
265     bool needsFrameCallback_ = false;
266     void* nativeWindow_ = nullptr;
267     bool activateWeatherPhys_ = false;
268 
269     EGLSurface eglSurface_ = EGL_NO_SURFACE;
270     TextureInfo textureInfo_;
271 };
272 } // namespace OHOS::Render3D
273 #endif // OHOS_RENDER_3D_LUME_COMMON_H
274