Add Light for Scene3D
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / controls / model / model-impl.h
1 #ifndef DALI_SCENE3D_INTERNAL_MODEL_H
2 #define DALI_SCENE3D_INTERNAL_MODEL_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/public-api/controls/control-impl.h>
23 #include <dali/public-api/actors/camera-actor.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/animation/animation.h>
26 #include <dali/public-api/object/property-notification.h>
27 #include <dali/public-api/object/weak-handle.h>
28 #include <dali/public-api/rendering/texture.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-scene3d/internal/common/environment-map-load-task.h>
32 #include <dali-scene3d/internal/common/light-observer.h>
33 #include <dali-scene3d/internal/common/model-load-task.h>
34 #include <dali-scene3d/public-api/controls/model/model.h>
35 #include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
36 #include <dali-scene3d/public-api/light/light.h>
37 #include <dali-scene3d/public-api/loader/load-result.h>
38 #include <dali-scene3d/public-api/model-components/model-node.h>
39
40 namespace Dali
41 {
42 namespace Scene3D
43 {
44 class Model;
45
46 namespace Internal
47 {
48 /**
49  * @brief Impl class for Model.
50  */
51 class Model : public Dali::Toolkit::Internal::Control, public LightObserver
52 {
53 public:
54   using AnimationData = std::pair<std::string, Dali::Animation>;
55   using CameraData    = Loader::CameraParameters;
56
57   /**
58    * @copydoc Model::New()
59    */
60   static Dali::Scene3D::Model New(const std::string& modelUrl, const std::string& resourceDirectoryUrl);
61
62   /**
63    * @copydoc Model::GetModelRoot()
64    */
65   const Scene3D::ModelNode GetModelRoot() const;
66
67   /**
68    * @copydoc Model::AddModelNode()
69    */
70   void AddModelNode(Scene3D::ModelNode modelNode);
71
72   /**
73    * @copydoc Model::RemoveModelNode()
74    */
75   void RemoveModelNode(Scene3D::ModelNode modelNode);
76
77   /**
78    * @copydoc Model::SetChildrenSensitive()
79    */
80   void SetChildrenSensitive(bool enable);
81
82   /**
83    * @copydoc Model::GetChildrenSensitive()
84    */
85   bool GetChildrenSensitive() const;
86
87   /**
88    * @copydoc Model::SetChildrenFocusable()
89    */
90   void SetChildrenFocusable(bool enable);
91
92   /**
93    * @copydoc Model::GetChildrenFocusable()
94    */
95   bool GetChildrenFocusable() const;
96
97   /**
98    * @copydoc Model::SetImageBasedLightSource()
99    */
100   void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor);
101
102   /**
103    * @copydoc Model::SetImageBasedLightScaleFactor()
104    */
105   void SetImageBasedLightScaleFactor(float scaleFactor);
106
107   /**
108    * @copydoc Model::GetImageBasedLightScaleFactor()
109    */
110   float GetImageBasedLightScaleFactor() const;
111
112   /**
113    * @copydoc Model::GetAnimationCount()
114    */
115   uint32_t GetAnimationCount() const;
116
117   /**
118    * @copydoc Model::GetAnimation()
119    */
120   Dali::Animation GetAnimation(uint32_t index) const;
121
122   /**
123    * @copydoc Model::GetAnimation()
124    */
125   Dali::Animation GetAnimation(const std::string& name) const;
126
127   /**
128    * @copydoc Model::GetCameraCount()
129    */
130   uint32_t GetCameraCount() const;
131
132   /**
133    * @copydoc Model::GenerateCamera()
134    */
135   Dali::CameraActor GenerateCamera(uint32_t index) const;
136
137   /**
138    * @copydoc Model::ApplyCamera()
139    */
140   bool ApplyCamera(uint32_t index, Dali::CameraActor camera) const;
141
142   /**
143    * @copydoc Model::FindChildModelNodeByName()
144    */
145   Scene3D::ModelNode FindChildModelNodeByName(std::string_view nodeName);
146
147 protected:
148   /**
149    * @brief Constructs a new Model.
150    * @param[in] modelUrl model file path.(e.g., glTF, and DLI).
151    * @param[in] resourceDirectoryUrl resource file path that includes binary, image etc.
152    */
153   Model(const std::string& modelUrl, const std::string& resourceDirectoryUrl);
154
155   /**
156    * A reference counted object may only be deleted by calling Unreference()
157    */
158   virtual ~Model();
159
160 private:
161   /**
162    * @copydoc Toolkit::Control::OnInitialize
163    */
164   void OnInitialize();
165
166   /**
167    * @copydoc CustomActorImpl::OnSceneConnection()
168    */
169   void OnSceneConnection(int depth) override;
170
171   /**
172    * @copydoc CustomActorImpl::OnSceneDisconnection()
173    */
174   void OnSceneDisconnection() override;
175
176   /**
177    * @copydoc CustomActorImpl::OnSizeSet( const Vector3& size )
178    */
179   void OnSizeSet(const Vector3& size) override;
180
181   /**
182    * @copydoc Toolkit::Control::GetNaturalSize
183    */
184   Vector3 GetNaturalSize() override;
185
186   /**
187    * @copydoc Toolkit::Control::GetHeightForWidth()
188    */
189   float GetHeightForWidth(float width) override;
190
191   /**
192    * @copydoc Toolkit::Control::GetWidthForHeight()
193    */
194   float GetWidthForHeight(float height) override;
195
196   /**
197    * @copydoc Toolkit::Control::OnRelayout()
198    */
199   void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
200
201   /**
202    * @copydoc Toolkit::Control::IsResourceReady()
203    */
204   bool IsResourceReady() const override;
205
206 private:
207   /**
208    * @brief Create Model Root of this Model class.
209    */
210   void CreateModelRoot();
211
212   /**
213    * @brief Scales the model to fit the control or to return to original size.
214    */
215   void ScaleModel(bool useCurrentSize);
216
217   /**
218    * @brief Changes model anchor point to set the model at center or returns to the original model pivot.
219    */
220   void FitModelPosition();
221
222   /**
223    * @brief Changes IBL information of the input node.
224    */
225   void UpdateImageBasedLightTextureRecursively(Scene3D::ModelNode node, Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels);
226
227   /**
228    * @brief Changes IBL factor of the input node.
229    */
230   void UpdateImageBasedLightScaleFactorRecursively(Scene3D::ModelNode node, float iblScaleFactor);
231
232   /**
233    * @brief Changes IBL textures of the input node.
234    */
235   void UpdateImageBasedLightTexture();
236
237   /**
238    * @brief Changes IBL scale factor of the input node.
239    */
240   void UpdateImageBasedLightScaleFactor();
241
242   /**
243    * @brief Apply self transform into inputed camera.
244    * Inputed camera must be configured by CameraParameter. Mean, inputed camera coordinate depend on Model.
245    * After this API finished, CameraActor coordinate system converted as DALi coordinate system.
246    *
247    * @param[in,out] camera CameraActor who need to apply model itself's transform
248    */
249   void ApplyCameraTransform(Dali::CameraActor camera) const;
250
251 public: // Overrides LightObserver Methods.
252   /**
253    * @copydoc Dali::Scene3D::Internal::LightObserver::NotifyImageBasedLightTexture()
254    */
255   void NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor, uint32_t specularMipmapLevels) override;
256
257   /**
258    * @copydoc Dali::Scene3D::Internal::LightObserver::NotifyImageBasedLightScaleFactor()
259    */
260   void NotifyImageBasedLightScaleFactor(float scaleFactor) override;
261
262   /**
263    * @copydoc Dali::Scene3D::Internal::LightObserver::NotifyLightAdded()
264    */
265   void NotifyLightAdded(uint32_t lightIndex, Scene3D::Light light) override;
266
267   /**
268    * @copydoc Dali::Scene3D::Internal::LightObserver::NotifyLightRemoved()
269    */
270   void NotifyLightRemoved(uint32_t lightIndex) override;
271
272 private:
273   /**
274    * @brief Asynchronously model loading finished.
275    */
276   void OnModelLoadComplete();
277
278   /**
279    * @brief Asynchronously ibl diffusel image loading finished.
280    */
281   void OnIblDiffuseLoadComplete();
282
283   /**
284    * @brief Asynchronously ibl specular image loading finished.
285    */
286   void OnIblSpecularLoadComplete();
287
288   /**
289    * @brief Asynchronously ibl loading finished.
290    */
291   void OnIblLoadComplete();
292
293   /**
294    * @brief Update model root scale when Model size property is updated.
295    */
296   void OnSizeNotification(Dali::PropertyNotification& source);
297
298   /**
299    * @brief Reset Resource loading tasks.
300    */
301   void ResetResourceTasks();
302
303   /**
304    * @brief Reset a Resource loading task.
305    */
306   void ResetResourceTask(IntrusivePtr<AsyncTask> asyncTask);
307
308   /**
309    * @brief Notify Resource Ready signal.
310    */
311   void NotifyResourceReady();
312
313   /**
314    * @brief Create Model from loaded SceneDefinition.
315    */
316   void CreateModel();
317
318   /**
319    * @brief Create Dali::Animation from loaded AnimationDefinitions.
320    */
321   void CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene);
322
323   /**
324    * @brief Reset CameraData from loaded CameraParameters.
325    */
326   void ResetCameraParameters();
327
328 private:
329   std::string                    mModelUrl;
330   std::string                    mResourceDirectoryUrl;
331   Scene3D::ModelNode             mModelRoot;
332   std::vector<AnimationData>     mAnimations;
333   std::vector<CameraData>        mCameraParameters;
334   WeakHandle<Scene3D::SceneView> mParentSceneView;
335   Dali::PropertyNotification     mSizeNotification;
336
337   // Light
338   std::vector<Scene3D::Light> mLights;
339
340   // Asynchronous loading variable
341   ModelLoadTaskPtr          mModelLoadTask;
342   EnvironmentMapLoadTaskPtr mIblDiffuseLoadTask;
343   EnvironmentMapLoadTaskPtr mIblSpecularLoadTask;
344
345   std::string mDiffuseIblUrl;
346   std::string mSpecularIblUrl;
347
348   Dali::Texture mDefaultSpecularTexture;
349   Dali::Texture mDefaultDiffuseTexture;
350   Dali::Texture mSceneSpecularTexture;
351   Dali::Texture mSceneDiffuseTexture;
352   Dali::Texture mSpecularTexture;
353   Dali::Texture mDiffuseTexture;
354   Vector3       mNaturalSize;
355   Vector3       mModelPivot;
356   float         mSceneIblScaleFactor;
357   float         mIblScaleFactor;
358   uint32_t      mSceneSpecularMipmapLevels;
359   uint32_t      mSpecularMipmapLevels;
360   bool          mModelChildrenSensitive;
361   bool          mModelChildrenFocusable;
362   bool          mModelResourceReady;
363   bool          mIblDiffuseResourceReady;
364   bool          mIblSpecularResourceReady;
365   bool          mIblDiffuseDirty;
366   bool          mIblSpecularDirty;
367 };
368
369 } // namespace Internal
370
371 // Helpers for public-api forwarding methods
372 inline Dali::Scene3D::Internal::Model& GetImpl(Dali::Scene3D::Model& obj)
373 {
374   DALI_ASSERT_ALWAYS(obj);
375   Dali::RefObject& handle = obj.GetImplementation();
376   return static_cast<Dali::Scene3D::Internal::Model&>(handle);
377 }
378
379 inline const Dali::Scene3D::Internal::Model& GetImpl(const Dali::Scene3D::Model& obj)
380 {
381   DALI_ASSERT_ALWAYS(obj);
382   const Dali::RefObject& handle = obj.GetImplementation();
383   return static_cast<const Dali::Scene3D::Internal::Model&>(handle);
384 }
385
386 } // namespace Scene3D
387
388 } // namespace Dali
389
390 #endif // DALI_SCENE3D_INTERNAL_MODEL_H