Use ModelNode / ModelPrimitive / Material instead of Actor / Renderer
[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/loader/blend-shape-details.h>
33 #include <dali-scene3d/public-api/loader/mesh-definition.h>
34 #include <dali-scene3d/public-api/model-components/material.h>
35 #include <dali-scene3d/public-api/model-components/model-primitive.h>
36
37 namespace Dali
38 {
39 namespace Scene3D
40 {
41 namespace Internal
42 {
43 using ModelPrimitivePtr = IntrusivePtr<ModelPrimitive>;
44
45 /**
46  * @brief TODO : Explain me.
47  * Use Vector4 Tangent data
48  * Same ModelPrimitive all shares IBL
49  */
50 class ModelPrimitive : public BaseObject, public MaterialModifyObserver
51 {
52 private:
53   using ModelPrimitiveModifyObserverContainer = std::set<ModelPrimitiveModifyObserver*>;
54
55 public:
56   // Creation & Destruction
57   /**
58    * @brief Create a new ModelPrimitive object.
59    * @return A smart-pointer to the newly allocated ModelPrimitive.
60    */
61   static ModelPrimitivePtr New();
62
63 protected:
64   /**
65    * @brief Construct a new ModelPrimitive.
66    */
67   ModelPrimitive();
68
69   /**
70    * @brief Second-phase constructor.
71    */
72   void Initialize();
73
74   /**
75    * @brief Virtual destructor.
76    */
77   virtual ~ModelPrimitive();
78
79 public:
80   /**
81    * @brief Set Renderer that is created by Scene3D::Loader internally.
82    */
83   void SetRenderer(Dali::Renderer renderer);
84
85   /**
86    * @copydoc Dali::Scene3D::ModelPrimitive::GetRenderer()
87    */
88   Dali::Renderer GetRenderer() const;
89
90   /**
91    * @copydoc Dali::Scene3D::ModelPrimitive::SetGeometry()
92    */
93   void SetGeometry(Dali::Geometry geometry);
94
95   /**
96    * @copydoc Dali::Scene3D::ModelPrimitive::GetGeometry()
97    */
98   Dali::Geometry GetGeometry() const;
99
100   /**
101    * @copydoc Dali::Scene3D::ModelPrimitive::SetMaterial()
102    */
103   void SetMaterial(Dali::Scene3D::Material material, bool updateRenderer = true);
104
105   /**
106    * @copydoc Dali::Scene3D::ModelPrimitive::GetMaterial()
107    */
108   Dali::Scene3D::Material GetMaterial() const;
109
110   /**
111    * @brief Adds a primitive observer to this model primitive.
112    *
113    * @param[in] observer The observer to add.
114    */
115   void AddPrimitiveObserver(ModelPrimitiveModifyObserver* observer);
116
117   /**
118    * @brief Removes a primitive observer from this model primitive.
119    *
120    * @param[in] observer The observer to remove.
121    */
122   void RemovePrimitiveObserver(ModelPrimitiveModifyObserver* observer);
123
124   /**
125    * @brief Sets the image-based lighting texture for this model primitive.
126    *
127    * @param[in] diffuseTexture The diffuse texture.
128    * @param[in] specularTexture The specular texture.
129    * @param[in] iblScaleFactor The scale factor to set for image-based lighting.
130    * @param[in] specularMipmapLevels The number of mipmap levels of specular texture.
131    */
132   void SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels);
133
134   /**
135    * @brief Sets the scale factor for image-based lighting for this model primitive.
136    *
137    * @param[in] iblScaleFactor The scale factor to set for image-based lighting.
138    */
139   void SetImageBasedLightScaleFactor(float iblScaleFactor);
140
141   /**
142    * @brief Sets the blend shape data for this model primitive.
143    *
144    * @param[in] data The blend shape data to set.
145    */
146   void SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data);
147
148   /**
149    * @brief Sets the blend shape geometry for this model primitive.
150    *
151    * @param[in] blendShapeGeometry The blend shape geometry to set.
152    */
153   void SetBlendShapeGeometry(Dali::Texture blendShapeGeometry);
154
155   /**
156    * @brief Sets the blend shape options for this model primitive.
157    *
158    * @param[in] hasPositions Whether or not this model primitive has positions for blend shapes.
159    * @param[in] hasNormals Whether or not this model primitive has normals for blend shapes.
160    * @param[in] hasTangents Whether or not this model primitive has tangents for blend shapes.
161    */
162   void SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents);
163
164   /**
165    * @brief Sets whether or not this model primitive is skinned.
166    *
167    * @param[in] isSkinned Whether or not this model primitive is skinned.
168    */
169   void SetSkinned(bool isSkinned);
170
171 private: // From MaterialModifyObserver
172   /**
173    * @copydoc Dali::Scene3D::Internal::Material::MaterialModifyObserver::OnMaterialModified()
174    */
175   void OnMaterialModified(Dali::Scene3D::Material material, MaterialModifyObserver::ModifyFlag flag) override;
176
177 private:
178   /**
179    * @brief Apply materials data into renderer.
180    */
181   void ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag flag = MaterialModifyObserver::ModifyFlag::NONE);
182
183   /**
184    * @brief Updates the uniform of renderer.
185    */
186   void UpdateRendererUniform();
187
188   /**
189    * @brief Creates a renderer.
190    */
191   void CreateRenderer();
192
193   /**
194    * @brief Updates the image-based lighting texture.
195    */
196   void UpdateImageBasedLightTexture();
197
198 private:
199   // Delete copy & move operator
200   ModelPrimitive(const ModelPrimitive&)                = delete;
201   ModelPrimitive(ModelPrimitive&&)                     = delete;
202   ModelPrimitive& operator=(const ModelPrimitive& rhs) = delete;
203   ModelPrimitive& operator=(ModelPrimitive&& rhs) noexcept = delete;
204
205 private:
206   ModelPrimitiveModifyObserverContainer mObservers{};
207
208   // For Renderer
209   Dali::Renderer          mRenderer;
210   Dali::Geometry          mGeometry;
211   Dali::Shader            mShader;
212   Dali::TextureSet        mTextureSet;
213   Dali::Scene3D::Material mMaterial;
214
215   // For IBL
216   Dali::Texture mSpecularTexture;
217   Dali::Texture mDiffuseTexture;
218   float         mIblScaleFactor{1.0f};
219   uint32_t      mSpecularMipmapLevels{1u};
220
221   // For blend shape
222   Scene3D::Loader::BlendShapes::BlendShapeData mBlendShapeData;
223   Dali::Texture                                mBlendShapeGeometry;
224   bool                                         mHasSkinning  = false;
225   bool                                         mHasPositions = false;
226   bool                                         mHasNormals   = false;
227   bool                                         mHasTangents  = false;
228
229   bool mIsMaterialChanged        = false;
230   bool mNeedToSetRendererUniform = false;
231 };
232
233 } // namespace Internal
234
235 // Helpers for public-api forwarding methods
236
237 inline Internal::ModelPrimitive& GetImplementation(Dali::Scene3D::ModelPrimitive& modelPrimitive)
238 {
239   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
240
241   BaseObject& handle = modelPrimitive.GetBaseObject();
242
243   return static_cast<Internal::ModelPrimitive&>(handle);
244 }
245
246 inline const Internal::ModelPrimitive& GetImplementation(const Dali::Scene3D::ModelPrimitive& modelPrimitive)
247 {
248   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
249
250   const BaseObject& handle = modelPrimitive.GetBaseObject();
251
252   return static_cast<const Internal::ModelPrimitive&>(handle);
253 }
254
255 } // namespace Scene3D
256
257 } // namespace Dali
258
259 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_H