[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / scene-definition.h
1 #ifndef DALI_SCENE3D_LOADER_SCENE_DEFINITION_H_
2 #define DALI_SCENE3D_LOADER_SCENE_DEFINITION_H_
3 /*
4  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 // EXTERNAL INCLUDES
21 #include <dali/public-api/actors/actor.h>
22 #include <dali/public-api/math/matrix.h>
23 #include <dali/public-api/math/quaternion.h>
24 #include <dali/public-api/math/vector4.h>
25 #include <memory>
26 #include <string>
27
28 // INTERNAL INCLUDES
29 #include <dali-scene3d/public-api/loader/customization.h>
30 #include <dali-scene3d/public-api/loader/node-definition.h>
31 #include <dali-scene3d/public-api/loader/string-callback.h>
32 #include <dali-scene3d/public-api/loader/utils.h>
33
34 namespace Dali::Scene3D::Loader
35 {
36 class MatrixStack;
37
38 /**
39  * @brief Intermediate representation of a scene with functionality required to
40  * create DALi objects (Actors, Renderers) from it.
41  * @SINCE_2_0.7
42  */
43 class DALI_SCENE3D_API SceneDefinition
44 {
45 public: // TYPES
46   using NodePredicate     = std::function<bool(const NodeDefinition&)>;
47   using NodeConsumer      = std::function<void(NodeDefinition&)>;
48   using ConstNodeConsumer = std::function<void(const NodeDefinition&)>;
49
50 public: // METHODS
51   SceneDefinition();
52   SceneDefinition(SceneDefinition&& other);
53   ~SceneDefinition();
54
55   /**
56    * @brief Registers a scene root node.
57    * @SINCE_2_0.7
58    * @return The index of the scene root node *registration*.
59    */
60   Index AddRootNode(Index iNode);
61
62   /**
63    * @brief Retrieves a list of scene root node IDs in the order of loading.
64    * @SINCE_2_0.7
65    * @return List of scene root node IDs in the order of loading
66    */
67   const std::vector<Index>& GetRoots() const;
68
69   /**
70    * @brief Removes scene root registration at the given index @a iRoot.
71    * @SINCE_2_0.7
72    * @note @a iRoot is the index of the registration (i.e. into the vector returned by GetRoots()), not of the node.
73    */
74   void RemoveRootNode(Index iRoot);
75
76   /**
77    * @brief Retrieve the number of node(definition)s in the scene.
78    * @SINCE_2_0.7
79    * @return The number of node(definition)s in the scene
80    */
81   uint32_t GetNodeCount() const;
82
83   /**
84    * @brief Retrieve a const pointer to the node (definition) at the given index.
85    * @SINCE_2_0.7
86    * @return Const pointer to the node (definition).
87    */
88   const NodeDefinition* GetNode(Index iNode) const;
89
90   /**
91    * @brief Retrive a pointer to the node (definition) at the given index.
92    * @SINCE_2_0.7
93    * @return Pointer to the node (definition).
94    */
95   NodeDefinition* GetNode(Index iNode);
96
97   /**
98    * @brief Traverses the scene starting from the node at the given index into nodes,
99    * using the given customization @a choices and the visitor @a v.
100    * @SINCE_2_0.7
101    */
102   void Visit(Index iNode, const Customization::Choices& choices, NodeDefinition::IVisitor& v);
103
104   /**
105    * @brief Traverses the scene starting from the node at the given index into nodes,
106    * using the given customization @a choices and the visitor @a v.
107    * @SINCE_2_0.7
108    */
109   void Visit(Index iNode, const Customization::Choices& choices, NodeDefinition::IConstVisitor& v) const;
110
111   /**
112    * @brief Counts the references to meshes, shaders, materials that nodes in the scene are holding,
113    * writing the results into @a refCounts.
114    * @SINCE_2_0.7
115    * @note @a refCounts' entries must have the correct size. Use ResourceBundle::GetRefCounter().
116    */
117   void CountResourceRefs(Index iNode, const Customization::Choices& choices, ResourceRefCounts& refCounts) const;
118
119   /**
120    * @brief Given a bundle of @a resources that are loaded, and customization @a choices,
121    * this method traverses the scene, creating the ModelNodes and renderers from node definitions.
122    * @SINCE_2_0.7
123    * @return Handle to the root node.
124    */
125   ModelNode CreateNodes(Index iNode, const Customization::Choices& choices, NodeDefinition::CreateParams& params);
126
127   /**
128    * @brief Creates / update a registry of mappings from customization tags to a lists of names of
129    * customizable nodes under each tag, and the number of options.
130    *
131    * If @a outMissingChoices was specified, each tag that it encounters in the scene but not in @a choices,
132    * will be registered on it with the default choice of 0.
133    * @SINCE_2_0.7
134    */
135   void GetCustomizationOptions(const Customization::Choices& choices,
136                                Customization::Map&           outCustomizationOptions,
137                                Customization::Choices*       outMissingChoices) const;
138
139   /**
140    * @brief Attempts to add @a nodeDef to the end of nodes, and its index to the end of its parent's
141    * list of children (if iParent != NodeDefinition::INVALID_PARENT).
142    * @SINCE_2_0.7
143    * @return If the operation was successful - which requires nodeDef->name to be unique -
144    *  a pointer to the stored node definition; nullptr otherwise.
145    */
146   NodeDefinition* AddNode(std::unique_ptr<NodeDefinition>&& nodeDef);
147
148   /**
149    * @brief Moves the node to some other parent and / or to a different index.
150    * @SINCE_2_0.7
151    * @return Whether the operation was successful.
152    * @note This is currently breaking an assumption of never having a child of a node at a lower
153    *  index as that of the node itself, due to the fact that we're only changing parent ids (and
154    *  entries into the vector of children of node definitions), to save the complication of having
155    *  to move about, and offset indices to, everything past the reparented node. This should be
156    *  sufficient AT LEAST AS LONG AS we recreate the SceneDefinition when loading the scene; if
157    *  we ever needed to serialize it, we should ensure correct ordering of nodes.
158    */
159   bool ReparentNode(const std::string& name, const std::string& newParentName, Index siblingOrder);
160
161   /**
162    * @brief Removes a node with the given name, including all of its children, and updating
163    *  the indices on all remaining node definitions.
164    * @SINCE_2_0.7
165    * @return Whether the operation was successful.
166    */
167   bool RemoveNode(const std::string& name);
168
169   /**
170    * @brief Builds the model matrix stack for the node at the given @a index.
171    * @SINCE_2_0.7
172    * @note It only pushes new matrices; does not require the stack to be empty (or cares if it was not).
173    */
174   void GetNodeModelStack(Index index, MatrixStack& model) const;
175
176   /**
177    * @brief Attempts to find the definition of a node with the given @a name. Only upon
178    *  success, and if @a outIndex is non-null, the index of the node is written to it.
179    * @SINCE_2_0.7
180    * @return Pointer to the node definition; nullptr if not found.
181    * @note No ownership transfer.
182    */
183   NodeDefinition* FindNode(const std::string& name, Index* outIndex = nullptr);
184
185   /**
186    * @brief Attempts to find the definition of a node with the given @a name. Only upon
187    *  success, and if @a outIndex is non-null, the index of the node is written to it.
188    * @SINCE_2_0.7
189    * @return Pointer to the node definition; nullptr if not found.
190    * @note No ownership transfer.
191    */
192   const NodeDefinition* FindNode(const std::string& name, Index* outIndex = nullptr) const;
193
194   /**
195    * @brief The index of the given NodeDefinition @a node, or -1 if the node definition was not found.
196    * @SINCE_2_0.7
197    * @return The index of the given NodeDefinition @a node, or -1 if the node definition was not found
198    */
199   Index FindNodeIndex(const NodeDefinition& node) const;
200
201   /**
202    * @brief Calls @a consumer with up to @a limit NodeDefinitions that evaluate to true
203    *  with @a predicate.
204    * @SINCE_2_0.7
205    * @note A @a limit value of 0 means no limit.
206    */
207   void FindNodes(NodePredicate predicate, NodeConsumer consumer, unsigned int limit = 0);
208
209   /**
210    * @brief Calls @a consumer with up to @a limit NodeDefinitions that evaluate to true with @a predicate.
211    * @SINCE_2_0.7
212    * @note A @a limit value of 0 means no limit.
213    */
214   void FindNodes(NodePredicate predicate, ConstNodeConsumer consumer, unsigned int limit = 0) const;
215
216   /**
217    * @brief Applies constraints from the given requests.
218    * @SINCE_2_0.7
219    */
220   void ApplyConstraints(Actor&                           root,
221                         std::vector<ConstraintRequest>&& constrainables,
222                         StringCallback                   onError = DefaultErrorCallback) const;
223
224   /**
225    * @brief Ensures that there is no overlap between shaders used by nodes that have meshes skinned to different skeletons.
226    * @SINCE_2_0.7
227    */
228   void EnsureUniqueSkinningShaderInstances(ResourceBundle& resources) const;
229
230   /**
231    * @brief Performs the configuration of the given skinning shaders with the given skeleton.
232    *
233    * This means that the absolute transforms of the joints are calculated and set as one of
234    * the uniforms in the mat4 @b uBone array (in depth first traversal). Further, the following
235    * are created:<br />
236    *  - a @b jointMatrix property on each joint Actor;<br />
237    *  - constraint from the Actor's local position and rotation (and if it has a @e joint
238    *    parent, the jointMatrix of the parent) to its @b jointMatrix property;<br />
239    *  - a constraint from the the Actor's @b jointMatrix property to the related entry in
240    *    the shader's @b uBone property;<br />
241    * This ensures the automatic update of the skeletal animation, should any of the joints' transform changes,
242    * by whatever means.
243    * @SINCE_2_0.7
244    * @note Error messages will be posted to the optional @a onError callback.
245    * @note A maximum of SkinningDetails::MAX_JOINTS joints per skeleton are supported at the moment.
246    * @note Even if multiple skinned meshes use the same skinning shader, the correct number
247    *   of separate instances need to be declared in the .dli to avoid clashing uniform
248    *   definitions and constraints.
249    */
250   void ConfigureSkinningShaders(const ResourceBundle&                             resources,
251                                 Actor                                             root,
252                                 std::vector<SkinningShaderConfigurationRequest>&& requests) const;
253
254   /**
255    * @brief Ensures there is no two meshes with blend shapes sharing the same shader.
256    * @SINCE_2_0.7
257    */
258   void EnsureUniqueBlendShapeShaderInstances(ResourceBundle& resources) const;
259
260   /**
261    * @brief Performs the configuration of the given blend shapes.
262    *
263    * For each node with blend shapes it registers into the actor the weights properties for each morph target
264    * and some needed uniforms into the shader.
265    *
266    * @SINCE_2_0.7
267    * @param[in] root The root actor.
268    * @param[in] requests The requests to configure blend shapes.
269    * @param[in] resources The resources bundle. Meshes need to be accessed to configure the blend shapes.
270    * @param[in] onError The error callback.
271    */
272   bool ConfigureBlendshapeShaders(const ResourceBundle&                               resources,
273                                   Actor                                               root,
274                                   std::vector<BlendshapeShaderConfigurationRequest>&& requests,
275                                   StringCallback                                      onError = DefaultErrorCallback) const;
276
277   SceneDefinition& operator=(SceneDefinition&& other);
278
279 private: // METHODS
280   bool FindNode(const std::string& name, std::unique_ptr<NodeDefinition>** result);
281
282 private:                                               // DATA
283   std::vector<std::unique_ptr<NodeDefinition>> mNodes; // size unknown up front (may discard nodes).
284   std::vector<Index>                           mRootNodeIds;
285 };
286
287 } // namespace Dali::Scene3D::Loader
288
289 #endif //DALI_SCENE3D_LOADER_SCENE_DEFINITION_H_