[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / model-components / model-primitive-impl.h
1 #ifndef DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_H
2 #define DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_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/public-api/common/dali-common.h>
23 #include <dali/public-api/common/intrusive-ptr.h>
24 #include <dali/public-api/object/base-object.h>
25 #include <dali/public-api/object/property-value.h>
26 #include <dali/public-api/object/property.h>
27 #include <set>
28
29 // INTERNAL INCLUDES
30 #include <dali-scene3d/internal/model-components/material-modify-observer.h>
31 #include <dali-scene3d/internal/model-components/model-primitive-modify-observer.h>
32 #include <dali-scene3d/public-api/light/light.h>
33 #include <dali-scene3d/public-api/loader/blend-shape-details.h>
34 #include <dali-scene3d/public-api/loader/mesh-definition.h>
35 #include <dali-scene3d/public-api/loader/shader-manager.h>
36 #include <dali-scene3d/public-api/model-components/material.h>
37 #include <dali-scene3d/public-api/model-components/model-primitive.h>
38
39 namespace Dali
40 {
41 namespace Scene3D
42 {
43 namespace Internal
44 {
45 using ModelPrimitivePtr = IntrusivePtr<ModelPrimitive>;
46
47 /**
48  * @brief TODO : Explain me.
49  * Use Vector4 Tangent data
50  * Same ModelPrimitive all shares IBL
51  */
52 class ModelPrimitive : public BaseObject, public MaterialModifyObserver
53 {
54 private:
55   using ModelPrimitiveModifyObserverContainer = std::set<ModelPrimitiveModifyObserver*>;
56
57 public:
58   // Creation & Destruction
59   /**
60    * @brief Create a new ModelPrimitive object.
61    * @return A smart-pointer to the newly allocated ModelPrimitive.
62    */
63   static ModelPrimitivePtr New();
64
65 protected:
66   /**
67    * @brief Construct a new ModelPrimitive.
68    */
69   ModelPrimitive();
70
71   /**
72    * @brief Second-phase constructor.
73    */
74   void Initialize();
75
76   /**
77    * @brief Virtual destructor.
78    */
79   virtual ~ModelPrimitive();
80
81 public:
82   /**
83    * @brief Set Renderer that is created by Scene3D::Loader internally.
84    */
85   void SetRenderer(Dali::Renderer renderer);
86
87   /**
88    * @copydoc Dali::Scene3D::ModelPrimitive::GetRenderer()
89    */
90   Dali::Renderer GetRenderer() const;
91
92   /**
93    * @copydoc Dali::Scene3D::ModelPrimitive::SetGeometry()
94    */
95   void SetGeometry(Dali::Geometry geometry);
96
97   /**
98    * @copydoc Dali::Scene3D::ModelPrimitive::GetGeometry()
99    */
100   Dali::Geometry GetGeometry() const;
101
102   /**
103    * @copydoc Dali::Scene3D::ModelPrimitive::SetMaterial()
104    */
105   void SetMaterial(Dali::Scene3D::Material material, bool updateRenderer = true);
106
107   /**
108    * @copydoc Dali::Scene3D::ModelPrimitive::GetMaterial()
109    */
110   Dali::Scene3D::Material GetMaterial() const;
111
112   /**
113    * @brief Adds a primitive observer to this model primitive.
114    *
115    * @param[in] observer The observer to add.
116    */
117   void AddPrimitiveObserver(ModelPrimitiveModifyObserver* observer);
118
119   /**
120    * @brief Removes a primitive observer from this model primitive.
121    *
122    * @param[in] observer The observer to remove.
123    */
124   void RemovePrimitiveObserver(ModelPrimitiveModifyObserver* observer);
125
126   /**
127    * @brief Sets shadow map texture for this model primitive.
128    *
129    * @param[in] shadowMapTexture The shadow map texture.
130    */
131   void SetShadowMapTexture(Dali::Texture shadowMapTexture);
132
133   /**
134    * @brief Sets the image-based lighting texture for this model primitive.
135    *
136    * @param[in] diffuseTexture The diffuse texture.
137    * @param[in] specularTexture The specular texture.
138    * @param[in] iblScaleFactor The scale factor to set for image-based lighting.
139    * @param[in] specularMipmapLevels The number of mipmap levels of specular texture.
140    */
141   void SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels);
142
143   /**
144    * @brief Sets the scale factor for image-based lighting for this model primitive.
145    *
146    * @param[in] iblScaleFactor The scale factor to set for image-based lighting.
147    */
148   void SetImageBasedLightScaleFactor(float iblScaleFactor);
149
150   /**
151    * @brief Updates shaders by using current material
152    *
153    * @param[in] shaderManager Shader manager to create shader.
154    * @param[in] hash of old shader option
155    */
156   void UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager, Loader::ShaderOption::HashType hash);
157
158   /**
159    * @brief Sets the blend shape data for this model primitive.
160    *
161    * @param[in] data The blend shape data to set.
162    */
163   void SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data);
164
165   /**
166    * @brief Sets the blend shape geometry for this model primitive.
167    *
168    * @param[in] blendShapeGeometry The blend shape geometry to set.
169    */
170   void SetBlendShapeGeometry(Dali::Texture blendShapeGeometry);
171
172   /**
173    * @brief Sets the blend shape options for this model primitive.
174    *
175    * @param[in] hasPositions Whether or not this model primitive has positions for blend shapes.
176    * @param[in] hasNormals Whether or not this model primitive has normals for blend shapes.
177    * @param[in] hasTangents Whether or not this model primitive has tangents for blend shapes.
178    * @param[in] version blendShape version.
179    */
180   void SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents, Scene3D::Loader::BlendShapes::Version version);
181
182   /**
183    * @brief Sets whether or not this model primitive is skinned.
184    *
185    * @param[in] isSkinned Whether or not this model primitive is skinned.
186    * @param[in] numberOfJointSets How many joint sets the mesh expects in the shader
187    */
188   void SetSkinned(bool isSkinned, uint32_t numberOfJointSets);
189
190   /**
191    * @brief Set whether this model primitve has vertex color attributes
192    *
193    * @param[in] hasVertexColor Whether or not this model primitive has vertex color attributes
194    */
195   void SetVertexColor(bool hasVertexColor);
196
197 private: // From MaterialModifyObserver
198   /**
199    * @copydoc Dali::Scene3D::Internal::Material::MaterialModifyObserver::OnMaterialModified()
200    */
201   void OnMaterialModified(Dali::Scene3D::Material material, MaterialModifyObserver::ModifyFlag flag) override;
202
203 private:
204   /**
205    * @brief Apply materials data into renderer.
206    */
207   void ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag flag    = MaterialModifyObserver::ModifyFlag::NONE,
208                                Loader::ShaderOption::HashType     oldHash = 0u);
209
210   /**
211    * @brief Updates the uniform of renderer.
212    */
213   void UpdateRendererUniform();
214
215   /**
216    * @brief Updates the property of renderer.
217    */
218   void UpdateRendererProperty();
219
220   /**
221    * @brief Creates a renderer.
222    */
223   void CreateRenderer();
224
225   void UpdateShadowMapTexture();
226
227   /**
228    * @brief Updates the image-based lighting texture.
229    */
230   void UpdateImageBasedLightTexture();
231
232 private:
233   // Delete copy & move operator
234   ModelPrimitive(const ModelPrimitive&) = delete;
235   ModelPrimitive(ModelPrimitive&&)      = delete;
236   ModelPrimitive& operator=(const ModelPrimitive& rhs) = delete;
237   ModelPrimitive& operator=(ModelPrimitive&& rhs) noexcept = delete;
238
239 private:
240   ModelPrimitiveModifyObserverContainer mObservers{};
241
242   // For Renderer
243   Dali::Renderer          mRenderer;
244   Dali::Geometry          mGeometry;
245   Dali::Shader            mShader;
246   Dali::TextureSet        mTextureSet;
247   Dali::Scene3D::Material mMaterial;
248
249   Scene3D::Loader::ShaderManagerPtr mShaderManager;
250
251   // For Shadow
252   Dali::Texture mShadowMapTexture;
253
254   // For IBL
255   Dali::Texture mSpecularTexture;
256   Dali::Texture mDiffuseTexture;
257   float         mIblScaleFactor{1.0f};
258   uint32_t      mSpecularMipmapLevels{1u};
259
260   // For skinning
261   uint32_t mNumberOfJointSets{0};
262
263   // For blend shape
264   Scene3D::Loader::BlendShapes::BlendShapeData mBlendShapeData;
265   Dali::Texture                                mBlendShapeGeometry;
266   bool                                         mHasSkinning       = false;
267   bool                                         mHasVertexColor    = false;
268   bool                                         mHasPositions      = false;
269   bool                                         mHasNormals        = false;
270   bool                                         mHasTangents       = false;
271   Scene3D::Loader::BlendShapes::Version        mBlendShapeVersion = Scene3D::Loader::BlendShapes::Version::INVALID;
272
273   bool mIsMaterialChanged        = false;
274 };
275
276 } // namespace Internal
277
278 // Helpers for public-api forwarding methods
279
280 inline Internal::ModelPrimitive& GetImplementation(Dali::Scene3D::ModelPrimitive& modelPrimitive)
281 {
282   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
283
284   BaseObject& handle = modelPrimitive.GetBaseObject();
285
286   return static_cast<Internal::ModelPrimitive&>(handle);
287 }
288
289 inline const Internal::ModelPrimitive& GetImplementation(const Dali::Scene3D::ModelPrimitive& modelPrimitive)
290 {
291   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
292
293   const BaseObject& handle = modelPrimitive.GetBaseObject();
294
295   return static_cast<const Internal::ModelPrimitive&>(handle);
296 }
297
298 } // namespace Scene3D
299
300 } // namespace Dali
301
302 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_H