Merge changes I776588c1,I7292a2fb into 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    */
155   void UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager);
156
157   /**
158    * @brief Sets the blend shape data for this model primitive.
159    *
160    * @param[in] data The blend shape data to set.
161    */
162   void SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data);
163
164   /**
165    * @brief Sets the blend shape geometry for this model primitive.
166    *
167    * @param[in] blendShapeGeometry The blend shape geometry to set.
168    */
169   void SetBlendShapeGeometry(Dali::Texture blendShapeGeometry);
170
171   /**
172    * @brief Sets the blend shape options for this model primitive.
173    *
174    * @param[in] hasPositions Whether or not this model primitive has positions for blend shapes.
175    * @param[in] hasNormals Whether or not this model primitive has normals for blend shapes.
176    * @param[in] hasTangents Whether or not this model primitive has tangents for blend shapes.
177    * @param[in] version blendShape version.
178    */
179   void SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents, Scene3D::Loader::BlendShapes::Version version);
180
181   /**
182    * @brief Sets whether or not this model primitive is skinned.
183    *
184    * @param[in] isSkinned Whether or not this model primitive is skinned.
185    */
186   void SetSkinned(bool isSkinned);
187
188 private: // From MaterialModifyObserver
189   /**
190    * @copydoc Dali::Scene3D::Internal::Material::MaterialModifyObserver::OnMaterialModified()
191    */
192   void OnMaterialModified(Dali::Scene3D::Material material, MaterialModifyObserver::ModifyFlag flag) override;
193
194 private:
195   /**
196    * @brief Apply materials data into renderer.
197    */
198   void ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag flag = MaterialModifyObserver::ModifyFlag::NONE);
199
200   /**
201    * @brief Updates the uniform of renderer.
202    */
203   void UpdateRendererUniform();
204
205   /**
206    * @brief Creates a renderer.
207    */
208   void CreateRenderer();
209
210   void UpdateShadowMapTexture();
211
212   /**
213    * @brief Updates the image-based lighting texture.
214    */
215   void UpdateImageBasedLightTexture();
216
217 private:
218   // Delete copy & move operator
219   ModelPrimitive(const ModelPrimitive&)                    = delete;
220   ModelPrimitive(ModelPrimitive&&)                         = delete;
221   ModelPrimitive& operator=(const ModelPrimitive& rhs)     = delete;
222   ModelPrimitive& operator=(ModelPrimitive&& rhs) noexcept = delete;
223
224 private:
225   ModelPrimitiveModifyObserverContainer mObservers{};
226
227   // For Renderer
228   Dali::Renderer          mRenderer;
229   Dali::Geometry          mGeometry;
230   Dali::Shader            mShader;
231   Dali::TextureSet        mTextureSet;
232   Dali::Scene3D::Material mMaterial;
233
234   Scene3D::Loader::ShaderManagerPtr mShaderManager;
235
236   // For Shadow
237   Dali::Texture mShadowMapTexture;
238
239   // For IBL
240   Dali::Texture mSpecularTexture;
241   Dali::Texture mDiffuseTexture;
242   float         mIblScaleFactor{1.0f};
243   uint32_t      mSpecularMipmapLevels{1u};
244
245   // For blend shape
246   Scene3D::Loader::BlendShapes::BlendShapeData mBlendShapeData;
247   Dali::Texture                                mBlendShapeGeometry;
248   bool                                         mHasSkinning       = false;
249   bool                                         mHasPositions      = false;
250   bool                                         mHasNormals        = false;
251   bool                                         mHasTangents       = false;
252   Scene3D::Loader::BlendShapes::Version        mBlendShapeVersion = Scene3D::Loader::BlendShapes::Version::INVALID;
253
254   bool mIsMaterialChanged        = false;
255   bool mNeedToSetRendererUniform = false;
256 };
257
258 } // namespace Internal
259
260 // Helpers for public-api forwarding methods
261
262 inline Internal::ModelPrimitive& GetImplementation(Dali::Scene3D::ModelPrimitive& modelPrimitive)
263 {
264   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
265
266   BaseObject& handle = modelPrimitive.GetBaseObject();
267
268   return static_cast<Internal::ModelPrimitive&>(handle);
269 }
270
271 inline const Internal::ModelPrimitive& GetImplementation(const Dali::Scene3D::ModelPrimitive& modelPrimitive)
272 {
273   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
274
275   const BaseObject& handle = modelPrimitive.GetBaseObject();
276
277   return static_cast<const Internal::ModelPrimitive&>(handle);
278 }
279
280 } // namespace Scene3D
281
282 } // namespace Dali
283
284 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_H