[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / controls / model / model.h
1 #ifndef DALI_SCENE3D_MODEL_H
2 #define DALI_SCENE3D_MODEL_H
3
4 /*
5  * Copyright (c) 2024 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 <memory>
23
24 #include <dali-toolkit/public-api/controls/control.h>
25 #include <dali/public-api/actors/camera-actor.h>
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/rendering/texture.h>
28
29 // INTERNAL INCLUDES
30 #include <dali-scene3d/public-api/algorithm/navigation-mesh.h>
31 #include <dali-scene3d/public-api/api.h>
32 #include <dali-scene3d/public-api/model-components/model-node.h>
33 #include <dali-scene3d/public-api/model-motion/motion-data.h>
34
35 namespace Dali
36 {
37 namespace Scene3D
38 {
39 namespace Internal DALI_INTERNAL
40 {
41 class Model;
42 }
43
44 /**
45  * @addtogroup dali_toolkit_controls_model
46  * @{
47  */
48
49 /**
50  * @brief Model is a control to show 3D model objects.
51  * Model supports to load glTF 2.0 and DLI models for the input format
52  * and also supports Physically Based Rendering with Image Based Lighting.
53  *
54  * The Animations defined in the glTF or DLI models are also loaded and can be retrieved by using GetAnimation() method.
55  * The number of animation is also retrieved by GetAnimationCount() method.
56  *
57  * By default, The loaded model has its own position and size which are defined in vertex buffer regardless of the Control size.
58  *
59  * @note We support to render model well only if glsl version is higher than 300.
60  *
61  * @SINCE_2_1.41
62  * @code
63  *
64  * Model model = Model::New(modelUrl);
65  * model.SetProperty(Dali::Actor::Property::SIZE, Vector2(width, height));
66  * model.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
67  * model.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
68  * model.SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
69  * window.Add(model);
70  * uint32_t animationCount = model.GetAnimationCount();
71  * Dali::Animation animation = model.GetAnimation(0);
72  * animation.Play();
73  *
74  * @endcode
75  */
76 class DALI_SCENE3D_API Model : public Dali::Toolkit::Control
77 {
78 public:
79   // Typedefs
80   using MeshHitSignalType = Signal<bool(Model, Scene3D::ModelNode)>; ///< Mesh hit signal type @SINCE_2_2.53
81   using ColliderMeshPtr   = std::unique_ptr<Algorithm::NavigationMesh>;
82
83   /**
84    * @brief Create an initialized Model.
85    *
86    * @SINCE_2_1.41
87    * @param[in] modelUrl model file path.(e.g., glTF, and DLI).
88    * @param[in] resourceDirectoryUrl resource file path that includes binary, image etc.
89    * @note If modelUrl is empty, it will not load resouces. Only ModelRoot will be created.
90    * @note If resourceDirectoryUrl is empty, the parent directory path of modelUrl is used for resource path.
91    * @return A handle to a newly allocated Dali resource
92    */
93   static Model New(const std::string& modelUrl = std::string(), const std::string& resourceDirectoryUrl = std::string());
94
95   /**
96    * @brief Creates an uninitialized Model.
97    *
98    * Only derived versions can be instantiated. Calling member
99    * functions with an uninitialized Dali::Object is not allowed.
100    *
101    * @SINCE_2_1.41
102    */
103   Model();
104
105   /**
106    * @brief Destructor.
107    *
108    * This is non-virtual since derived Handle types must not contain data or virtual methods.
109    *
110    * @SINCE_2_1.41
111    */
112   ~Model();
113
114   /**
115    * @brief Copy constructor.
116    *
117    * @SINCE_2_1.41
118    * @param[in] model Handle to an object
119    */
120   Model(const Model& model);
121
122   /**
123    * @brief Move constructor
124    *
125    * @SINCE_2_1.41
126    * @param[in] rhs A reference to the moved handle
127    */
128   Model(Model&& rhs) noexcept;
129
130   /**
131    * @brief Assignment operator.
132    *
133    * @SINCE_2_1.41
134    * @param[in] model Handle to an object
135    * @return reference to this
136    */
137   Model& operator=(const Model& model);
138
139   /**
140    * @brief Move assignment
141    *
142    * @SINCE_2_1.41
143    * @param[in] rhs A reference to the moved handle
144    * @return A reference to this
145    */
146   Model& operator=(Model&& rhs) noexcept;
147
148   /**
149    * @brief Downcasts an Object handle to Model.
150    *
151    * If handle points to a Model, the downcast produces valid handle.
152    * If not, the returned handle is left uninitialized.
153    *
154    * @SINCE_2_1.41
155    * @param[in] handle Handle to an object
156    * @return Handle to a Model or an uninitialized handle
157    */
158   static Model DownCast(BaseHandle handle);
159
160   /**
161    * @brief Retrieves model root Node.
162    *
163    * @SINCE_2_1.41
164    * @return Root Node of the model.
165    */
166   const ModelNode GetModelRoot() const;
167
168   /**
169    * @brief Add new ModelNode to this Model.
170    * This modelNode will become child of ModelRoot.
171    *
172    * @SINCE_2_2.22
173    * @param[in] modelNode the root of ModelNode tree to be added.
174    */
175   void AddModelNode(ModelNode modelNode);
176
177   /**
178    * @brief Remove ModelNode from this Model.
179    *
180    * @SINCE_2_2.22
181    * @param[in] modelNode the root of ModelNode tree to be removed.
182    */
183   void RemoveModelNode(ModelNode modelNode);
184
185   /**
186    * @brief Whether allow this model's children actor to use events.
187    *
188    * Usually, 3D Model might have a lot of actors. And most of them don't need to check events.
189    * To optimize traversal, we need to setup some flag that this model don't allow (or allow) to traversal
190    * children so that child can use events.
191    *
192    * @SINCE_2_1.43
193    * @note Even if we set children sensitive as false, model itself's sensitive
194    * is depend on it's property.
195    * @note If we don't call this API, default is false. (Don't allow to traversal model's children during hit-test)
196    *
197    * @param[in] enable True to enable model's children can use events.
198    */
199   void SetChildrenSensitive(bool enable);
200
201   /**
202    * @brief Gets whether this Model allow model's children actor to use events or not.
203    *
204    * @SINCE_2_1.43
205    * @return bool True if this Model allow model children sensitive.
206    */
207   bool GetChildrenSensitive() const;
208
209   /**
210    * @brief Whether allow this model's children actor to be keyboard focusable.
211    *
212    * Usually, 3D Model might have a lot of actors. And most of them don't need to check focusable.
213    * To optimize traversal, we need to setup some flag that this model don't allow (or allow) to traversal
214    * children so that child can be keyboard focusable.
215    *
216    * @SINCE_2_2.2
217    * @note Even if we set children focusable as false, model itself's focusable
218    * is depend on it's property.
219    * @note If we don't call this API, default is false. (Don't allow to traversal model's children during focusable test)
220    *
221    * @param[in] enable True to enable model's children can be focusable.
222    */
223   void SetChildrenFocusable(bool enable);
224
225   /**
226    * @brief Gets whether this Model allow model's children actor to be keyboard focusable or not.
227    *
228    * @SINCE_2_2.2
229    * @return bool True if this Model allow model children are focusable.
230    */
231   bool GetChildrenFocusable() const;
232
233   /**
234    * @brief Changes Image Based Light as the input textures.
235    *
236    * @SINCE_2_1.41
237    * @param[in] diffuseUrl cube map that can be used as a diffuse IBL source.
238    * @param[in] specularUrl cube map that can be used as a specular IBL source.
239    * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
240    */
241   void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor = 1.0f);
242
243   /**
244    * @brief Sets Scale Factor of Image Based Light Source.
245    *
246    * @SINCE_2_1.41
247    * @note If SetImageBasedLightSource() method is called after this method, scaleFactor is overrided.
248    *
249    * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f].
250    */
251   void SetImageBasedLightScaleFactor(float scaleFactor);
252
253   /**
254    * @brief Gets Scale Factor of Image Based Light Source.
255    * Default value is 1.0f.
256    *
257    * @SINCE_2_1.41
258    * @return scale factor that controls light source intensity.
259    */
260   float GetImageBasedLightScaleFactor() const;
261
262   /**
263    * @brief Gets number of animations those loaded from model file.
264    *
265    * @SINCE_2_1.41
266    * @return The number of loaded animations.
267    * @note This method should be called after Model load finished.
268    */
269   uint32_t GetAnimationCount() const;
270
271   /**
272    * @brief Gets animation at the index.
273    *
274    * @SINCE_2_1.41
275    * @param[in] index Index of animation to be retrieved.
276    * @return Animation at the index.
277    * @note This method should be called after Model load finished.
278    */
279   Dali::Animation GetAnimation(uint32_t index) const;
280
281   /**
282    * @brief Retrieves animation with the given name.
283    *
284    * @SINCE_2_1.41
285    * @param[in] name string name of animation to be retrieved.
286    * @return Animation that has the given name.
287    * @note This method should be called after Model load finished.
288    */
289   Dali::Animation GetAnimation(const std::string& name) const;
290
291   /**
292    * @brief Gets number of camera parameters those loaded from model file.
293    *
294    * @SINCE_2_2.15
295    * @return The number of loaded camera parameters.
296    * @note This method should be called after Model load finished.
297    */
298   uint32_t GetCameraCount() const;
299
300   /**
301    * @brief Generate camera actor using camera parameters at the index.
302    * If camera parameter is valid, create new CameraActor.
303    * Camera parameter decide at initialized time and
304    * didn't apply model node's current position (like Animation).
305    *
306    * @SINCE_2_2.15
307    * @param[in] index Index of camera to be used for generation camera.
308    * @return Generated CameraActor by the index, or empty Handle if generation failed.
309    * @note This method should be called after Model load finished.
310    */
311   Dali::CameraActor GenerateCamera(uint32_t index) const;
312
313   /**
314    * @brief Apply camera parameters at the index to inputed camera actor.
315    * If camera parameter is valid and camera actor is not empty, apply parameters.
316    * It will change camera's transform and near / far / fov or orthographic size / aspect ratio (if defined)
317    * Camera parameter decide at initialized time and
318    * didn't apply model node's current position (like Animation).
319    *
320    * @SINCE_2_2.15
321    * @param[in] index Index of camera to be used for generation camera.
322    * @param[in,out] camera Index of camera to be used for generation camera.
323    * @return True if apply successed. False otherwise.
324    * @note This method should be called after Model load finished.
325    */
326   bool ApplyCamera(uint32_t index, Dali::CameraActor camera) const;
327
328   /**
329    * @brief Returns a child ModelNode object with a name that matches nodeName.
330    *
331    * @SINCE_2_2.34
332    * @param[in] nodeName The name of the child ModelNode object you want to find.
333    * @return Returns a child ModelNode object with a name that matches nodeName. If there is no corresponding child ModelNode object, it returns an empty ModelNode object.
334    */
335   ModelNode FindChildModelNodeByName(std::string_view nodeName);
336
337   /**
338    * @brief Retrieves the list of blendshape name that current Model hold.
339    * The name will be appended end of input list.
340    *
341    * @SINCE_2_2.34
342    * @param[in, out] blendShapeNames The name of blendShape list collected.
343    * @note This method should be called after Model load finished.
344    */
345   void RetrieveBlendShapeNames(std::vector<std::string>& blendShapeNames) const;
346
347   /**
348    * @brief Retrieves the list of ModelNode that contains given blend shape name.
349    * The ModelNode will be appended end of input list.
350    *
351    * @SINCE_2_2.34
352    * @param[in] blendShapeName The name of blendShape that want to collect.
353    * @param[in, out] modelNodes The ModelNode list collected.
354    * @note This method should be called after Model load finished.
355    */
356   void RetrieveModelNodesByBlendShapeName(std::string_view blendShapeName, std::vector<ModelNode>& modelNodes) const;
357
358   /**
359    * @brief Generates specific animation of this Model by inputed MotionData.
360    *
361    * @SINCE_2_2.34
362    * @param[in] motionData the data of motion animation.
363    * @return Animation that be generated by MotionData. Or empty handle if there is no valid animation generated.
364    * @note This method should be called after Model load finished.
365    */
366   Dali::Animation GenerateMotionDataAnimation(MotionData motionData);
367
368   /**
369    * @brief Sets specific values of this Model by inputed MotionData.
370    * @note If MotionValue's ValueType is ValueType::KEY_FRAMES, the last value will be set.
371    *
372    * @SINCE_2_2.34
373    * @param[in] motionData the data of motion to be set.
374    * @note This method should be called after Model load finished.
375    */
376   void SetMotionData(Scene3D::MotionData motionData);
377
378   /**
379    * @brief Sets whether this Model casts shadow or not.
380    * If it is true, this model is drawn on Shadow Map.
381    *
382    * @SINCE_2_3.99
383    * @param[in] castShadow Whether this Model casts shadow or not.
384    * @note This method affects all of the child ModelNode.
385    * However, same property of each child ModelNode can be changed respectively and it not changes parent's property.
386    */
387   void CastShadow(bool castShadow);
388
389   /**
390    * @brief Retrieves whether the Model casts shadow or not for Light.
391    *
392    * @SINCE_2_3.99
393    * @return True if this model casts shadow.
394    * @note IBL does not cast any shadow.
395    */
396   bool IsShadowCasting() const;
397
398   /**
399    * @brief Sets whether this Model receives shadow or not.
400    * If it is true, shadows are drawn on this model.
401    *
402    * @SINCE_2_3.99
403    * @param[in] receiveShadow Whether this Model receives shadow or not.
404    * @note This method affects all of the child ModelNode.
405    * However, same property of each child ModelNode can be changed respectively and it not changes parent's property.
406    */
407   void ReceiveShadow(bool receiveShadow);
408
409   /**
410    * @brief Retrieves whether the Model receives shadow or not for Light.
411    *
412    * @SINCE_2_3.99
413    * @return True if this model receives shadow.
414    */
415   bool IsShadowReceiving() const;
416
417   /**
418    * @brief This signal is emitted when the collider mesh is touched/hit.
419    *
420    * A callback of the following type may be connected:
421    * @code
422    *   bool YourCallbackName(Model model, ModelNode modelNode);
423    * @endcode
424    * Here the model is the model that is hit and the ModelNode containing the collider mesh
425    * was applied to.
426    * The return value of True, indicates that the hover event should be consumed.
427    * Otherwise the signal will be emitted on the next sensitive parent of the actor.
428    *
429    * @SINCE_2_2.53
430    * @return The signal to connect to
431    */
432   MeshHitSignalType& MeshHitSignal();
433
434 public: // Not intended for application developers
435   /// @cond internal
436   /**
437    * @brief Creates a handle using the Toolkit::Internal implementation.
438    *
439    * @param[in] implementation The Control implementation
440    */
441   DALI_INTERNAL Model(Internal::Model& implementation);
442
443   /**
444    * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
445    *
446    * @param[in] internal A pointer to the internal CustomActor
447    */
448   DALI_INTERNAL Model(Dali::Internal::CustomActor* internal);
449   /// @endcond
450 };
451
452 /**
453  * @}
454  */
455 } // namespace Scene3D
456
457 } // namespace Dali
458
459 #endif // DALI_SCENE3D_MODEL_H