Use ModelNode / ModelPrimitive / Material instead of Actor / Renderer
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / node-definition.h
1 #ifndef DALI_SCENE3D_LOADER_NODE_DEFINITION_H_
2 #define DALI_SCENE3D_LOADER_NODE_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 <functional>
26 #include <memory>
27 #include <string>
28
29 // INTERNAL INCLUDES
30 #include <dali-scene3d/public-api/loader/customization.h>
31 #include <dali-scene3d/public-api/loader/matrix-stack.h>
32 #include <dali-scene3d/public-api/loader/resource-bundle.h>
33 #include <dali-scene3d/public-api/model-components/model-node.h>
34
35 namespace Dali
36 {
37 namespace Scene3D
38 {
39 namespace Loader
40 {
41 class ViewProjection;
42
43 /**
44  * @brief Interface to report (const) resource ids to.
45  */
46 class DALI_SCENE3D_API IResourceReceiver
47 {
48 public:
49   virtual ~IResourceReceiver() = default;
50
51   virtual void Register(ResourceType::Value type, Index id) = 0;
52 };
53
54 /**
55  * @brief Interface to report modifiable resource ids to.
56  * @note These are supposed to be transient. Obviously, the references collected
57  *  this way must not outlive the objects that they came from.
58  */
59 class DALI_SCENE3D_API IResourceReflector
60 {
61 public:
62   virtual ~IResourceReflector() = default;
63
64   virtual void Reflect(ResourceType::Value type, Index& id) = 0;
65 };
66
67 /**
68  * @brief Intermediate representation for a constraint that shall be
69  *  set up after the Actors were created. The target of the constraint
70  *  is the node definition that carries it.
71  */
72 struct DALI_SCENE3D_API ConstraintDefinition
73 {
74   std::string mProperty;  ///< name of the property to constrain.
75   Index       mSourceIdx; ///< index of the node to serve as the source of the constraint.
76
77   bool operator<(const ConstraintDefinition& other) const
78   {
79     return mProperty < other.mProperty;
80   }
81
82   bool operator==(const ConstraintDefinition& other) const
83   {
84     return mSourceIdx == other.mSourceIdx && mProperty == other.mProperty;
85   }
86
87   bool operator!=(const ConstraintDefinition& other) const
88   {
89     return !operator==(other);
90   }
91 };
92
93 struct DALI_SCENE3D_API Transforms
94 {
95   MatrixStack           modelStack;
96   const ViewProjection& viewProjection;
97 };
98
99 /**
100  * @brief Information about a skeleton and the shader that needs to be configured with it.
101  * @note Multiple skeletons shalt not share the same shader.
102  */
103 struct DALI_SCENE3D_API SkinningShaderConfigurationRequest
104 {
105   Index          mSkeletonIdx;
106   Shader         mShader;
107   ModelPrimitive mPrimitive;
108
109   bool operator<(const SkinningShaderConfigurationRequest& other) const
110   {
111     return mShader < other.mShader;
112   }
113 };
114
115 /**
116  * @brief Needed to configure blend shape properties.
117  */
118 struct DALI_SCENE3D_API BlendshapeShaderConfigurationRequest
119 {
120   std::string    mNodeName;
121   Index          mMeshIdx;
122   Shader         mShader;
123   ModelPrimitive mPrimitive;
124
125   bool operator<(const BlendshapeShaderConfigurationRequest& other) const
126   {
127     return mShader < other.mShader;
128   }
129 };
130
131 /**
132  * @brief Request for creating a constraint, output from NodeDefinition::OnCreate.
133  */
134 struct DALI_SCENE3D_API ConstraintRequest
135 {
136   const ConstraintDefinition* const mConstraint; ///< Definition of the constraint to create.
137   Actor                             mTarget;     ///< Target of the constraint.
138 };
139
140 /**
141  * @brief Defines a node, consisting of a name, a transform, a size, a list of child nodes,
142  *  and slots for customization and rendering logic, which are mutually exclusive in the
143  *  current implementation.
144  */
145 struct DALI_SCENE3D_API NodeDefinition
146 {
147 public: // TYPES
148   using Vector = std::vector<NodeDefinition>;
149
150   struct CreateParams
151   {
152   public: // input
153     ResourceBundle& mResources;
154     Transforms&     mXforms;
155
156   public: // output
157     std::vector<ConstraintRequest>                    mConstrainables;
158     std::vector<SkinningShaderConfigurationRequest>   mSkinnables;
159     std::vector<BlendshapeShaderConfigurationRequest> mBlendshapeRequests;
160   };
161
162   class DALI_SCENE3D_API Renderable
163   {
164   public: // DATA
165     Index mShaderIdx = INVALID_INDEX;
166
167   public: // METHODS
168     virtual ~Renderable() = default;
169
170     virtual bool GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const;
171     virtual void RegisterResources(IResourceReceiver& receiver) const;
172     virtual void ReflectResources(IResourceReflector& reflector);
173     virtual void OnCreate(const NodeDefinition& nodeDefinition, CreateParams& params, ModelNode& node) const;
174   };
175
176   struct CustomizationDefinition
177   {
178     std::string mTag;
179
180     Index GetChildId(const Customization::Choices& choices, const NodeDefinition& node)
181     {
182       auto choice = choices.Get(mTag);
183       return std::min(choice != Customization::NONE ? choice : 0,
184                       static_cast<Index>(node.mChildren.size() - 1));
185     }
186   };
187
188   class IVisitor
189   {
190   public:
191     virtual void Start(NodeDefinition& n)  = 0;
192     virtual void Finish(NodeDefinition& n) = 0;
193
194   protected:
195     ~IVisitor() = default; // deliberately non-virtual these are transient objects and we don't want to pay for the vtable.
196   };
197
198   class IConstVisitor
199   {
200   public:
201     virtual void Start(const NodeDefinition& n)  = 0;
202     virtual void Finish(const NodeDefinition& n) = 0;
203
204   protected:
205     ~IConstVisitor() = default; // deliberately non-virtual these are transient objects and we don't want to pay for the vtable.
206   };
207
208   struct Extra
209   {
210     std::string     mKey;
211     Property::Value mValue;
212
213     bool operator<(const Extra& other) const
214     {
215       return mKey < other.mKey;
216     }
217   };
218
219 public: // METHODS
220   /**
221    * @brief Creates a ModelNode from this definition only.
222    * @note Not recursive.
223    */
224   ModelNode CreateModelNode(CreateParams& params);
225
226   /**
227    * @brief Gets local space matrix of this node
228    * @return Matrix of local space.
229    */
230   Matrix GetLocalSpace() const;
231
232   /**
233    * @brief Retrieves minimum and maximum position of this node in local space.
234    * @param[in] resources ResourceBundle that contains mesh information of this node.
235    * @param[out] min Minimum position of the mesh of this node.
236    * @param[out] max Maximum position of the mesh of this node.
237    * @return true If the node has mesh.
238    */
239   bool GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const;
240
241   /**
242    * @brief Retrieves Scale Factor uniform name.
243    * This uniform name can be used to change scale factor for ibl.
244    * @return std::string_view of the scale factor uniform name.
245    */
246   static std::string_view GetIblScaleFactorUniformName();
247
248   /**
249    * @brief Retrieves ibl Ydirection uniform name.
250    * This uniform name can be used to flip y direction of ibl in shader.
251    * @return std::string_view of the YDirection uniform name.
252    */
253   static std::string_view GetIblYDirectionUniformName();
254
255   /**
256    * @brief Retrieves ibl MaxLod uniform name.
257    * This uniform name can be used to set max lod of ibl in shader.
258    * @return std::string_view of the Max Lod uniform name.
259    */
260   static std::string_view GetIblMaxLodUniformName();
261
262 public: // DATA
263   static const char* ORIGINAL_MATRIX_PROPERTY_NAME;
264
265   std::string mName;
266   uint32_t    mNodeId = INVALID_INDEX;
267
268   Vector3    mPosition    = Vector3::ZERO;
269   Quaternion mOrientation = Quaternion::IDENTITY;
270   Vector3    mScale       = Vector3::ONE;
271   Vector3    mSize        = Vector3::ONE;
272
273   bool mIsVisible = true;
274
275   std::vector<std::unique_ptr<Renderable>> mRenderables;
276   std::unique_ptr<CustomizationDefinition> mCustomization;
277   std::vector<Extra>                       mExtras;
278   std::vector<ConstraintDefinition>        mConstraints;
279
280   std::vector<Index> mChildren;
281   Index              mParentIdx = INVALID_INDEX;
282 };
283
284 class DALI_SCENE3D_API ModelRenderable : public NodeDefinition::Renderable
285 {
286 public: // DATA
287   Vector4 mColor       = Color::WHITE;
288   Index   mMeshIdx     = INVALID_INDEX;
289   Index   mMaterialIdx = INVALID_INDEX;
290
291 public: // METHODS
292   bool GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const override;
293   void RegisterResources(IResourceReceiver& receiver) const override;
294   void ReflectResources(IResourceReflector& reflector) override;
295   void OnCreate(const NodeDefinition& nodeDefinition, NodeDefinition::CreateParams& params, ModelNode& node) const override;
296 };
297
298 /**
299  * @brief Parameters for an Arc node.
300  */
301 class DALI_SCENE3D_API ArcRenderable : public ModelRenderable
302 {
303 public: // DATA
304   bool  mAntiAliasing      = true;
305   int   mArcCaps           = 0;
306   float mStartAngleDegrees = .0f;
307   float mEndAngleDegrees   = .0f;
308   float mRadius            = .0f;
309
310 public: // METHODS
311   static void GetEndVectorWithDiffAngle(float startAngle, float endAngle, Vector2& endVector);
312
313   void OnCreate(const NodeDefinition& nodeDefinition, NodeDefinition::CreateParams& params, ModelNode& node) const override;
314 };
315
316 } // namespace Loader
317 } // namespace Scene3D
318 } // namespace Dali
319
320 #endif // DALI_SCENE3D_LOADER_NODE_DEFINITION_H_