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