Adding chipmunk implementation for physics adaptor
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / model-components / material-impl.h
1 #ifndef DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H
2 #define DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_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-toolkit/public-api/image-loader/async-image-loader.h>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/public-api/common/intrusive-ptr.h>
25 #include <dali/public-api/common/vector-wrapper.h>
26 #include <dali/public-api/object/base-object.h>
27 #include <dali/public-api/object/property-value.h>
28 #include <dali/public-api/object/property.h>
29 #include <dali/public-api/rendering/texture.h>
30 #include <set>
31 #include <utility>
32
33 // INTERNAL INCLUDES
34 #include <dali-scene3d/internal/model-components/material-modify-observer.h>
35 #include <dali-scene3d/public-api/loader/material-definition.h>
36 #include <dali-scene3d/public-api/loader/shader-definition.h>
37 #include <dali-scene3d/public-api/loader/shader-option.h>
38 #include <dali-scene3d/public-api/model-components/material.h>
39
40 namespace Dali
41 {
42 namespace Scene3D
43 {
44 namespace Internal
45 {
46 using MaterialPtr = IntrusivePtr<Material>;
47
48 /**
49  * @brief This is the internal base class for Material of model.
50  *
51  * @SINCE_2_2.99
52  */
53 class Material : public BaseObject, public ConnectionTracker
54 {
55 private:
56   using ObserverContainer = std::vector<std::pair<MaterialModifyObserver*, bool>>;
57
58 public:
59   /**
60    * @brief Pair of texture handle and it's own scale factor. Texture handle can be empty
61    */
62   struct TextureInformation
63   {
64     bool IsReady()
65     {
66       return mLoadingTaskId == 0u;
67     }
68
69     std::string                         mUrl;
70     Dali::Texture                       mTexture;
71     Vector4                             mFactor{Vector4::ONE};
72     Dali::Sampler                       mSampler;
73     uint32_t                            mLoadingTaskId{0u};
74     uint32_t                            mSemantic;
75     Scene3D::Loader::ShaderOption::Type mShaderOptionType;
76   };
77
78   using TextureInformationContainer = std::vector<TextureInformation>;
79
80 public:
81   // Creation & Destruction
82   /**
83    * @brief Create a new Material object.
84    * @return A smart-pointer to the newly allocated Material.
85    */
86   static MaterialPtr New();
87
88 protected:
89   /**
90    * @brief Construct a new Material.
91    */
92   Material();
93
94   /**
95    * @brief Second-phase constructor.
96    */
97   void Initialize();
98
99   /**
100    * @brief Virtual destructor.
101    */
102   virtual ~Material();
103
104 public:
105   /**
106    * @copydoc Dali::Scene3D::Material::SetProperty()
107    */
108   void SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue);
109
110   /**
111    * @copydoc Dali::Scene3D::Material::GetProperty()
112    */
113   Dali::Property::Value GetProperty(Dali::Property::Index index) const;
114
115   /**
116    * @brief Sets a texture information for the material.
117    *
118    * @param[in] index The index of the texture to set.
119    * @param[in] textureInformation The texture information to set.
120    *
121    * @note This function moves the value of textureInformation.
122    */
123   void SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation);
124
125   /**
126    * @brief Sets a texture for the material.
127    *
128    * @param[in] index The index of the texture to set.
129    * @param[in] texture The texture to set.
130    */
131   void SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture);
132
133   /**
134    * @brief Retrieves texture for the material.
135    *
136    * @param[in] index The index of the texture to get.
137    *
138    * @return The texture at the given index.
139    */
140   Dali::Texture GetTexture(Scene3D::Material::TextureType index);
141
142   /**
143    * @brief Retrieves the texture set for this material.
144    *
145    * @return The texture set for this material.
146    */
147   TextureSet GetTextureSet();
148
149   /**
150    * @brief Sets a sampler for the material.
151    *
152    * @param[in] index The index of the sampler to set.
153    * @param[in] sampler The sampler to set.
154    */
155   void SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler);
156
157   /**
158    * @brief Retrieves a sampler for the material.
159    *
160    * @param[in] index The index of the sampler to get.
161    * @return The sampler at the given index.
162    */
163   Dali::Sampler GetSampler(Scene3D::Material::TextureType index);
164
165   /**
166    * @brief Retrieves Shader Option of this Material.
167    *
168    * @return Shader Option of this Material.
169    */
170   Scene3D::Loader::ShaderOption GetShaderOption() const;
171
172 public:
173   /**
174    * @brief Adds observer to this material.
175    *
176    * @param[in] observer Pointer of observer.
177    */
178   void AddObserver(MaterialModifyObserver* observer);
179
180   /**
181    * @brief Removes observer from this material.
182    *
183    * @param[in] observer Pointer of observer.
184    */
185   void RemoveObserver(MaterialModifyObserver* observer);
186
187   /**
188    * @brief Updates material data.
189    */
190   void UpdateMaterialData();
191
192   /**
193    * @brief Sets uniform value to the Renderer.
194    *
195    * @param[in] renderer Renderer object.
196    */
197   void SetRendererUniform(Dali::Renderer renderer);
198
199   /**
200    * @brief Retrieves specular image based light texture offset.
201    *
202    * @return Specular image based light texture offset.
203    */
204   uint32_t GetSpecularImageBasedLightTextureOffset();
205
206   /**
207    * @brief Retrieves diffuse image based light texture offset.
208    *
209    * @return Diffuse image based light texture offset.
210    */
211   uint32_t GetDiffuseImageBasedLightTextureOffset();
212
213   /**
214    * @brief Retrieves image based light scale factor name.
215    *
216    * @return Image based light scale factor name.
217    */
218   std::string_view GetImageBasedLightScaleFactorName();
219
220   /**
221    * @brief Retrieves image based light max lod uniform name.
222    *
223    * @return Image based light max lod uniform name.
224    */
225   std::string_view GetImageBasedLightMaxLodUniformName();
226
227   /**
228    * @brief Checks if resource is ready.
229    *
230    * @return True if resource is ready, false otherwise.
231    */
232   bool IsResourceReady();
233
234   /**
235    * @brief Resets dirty flag of this material.
236    */
237   void ResetFlag();
238
239 private:
240   /**
241    * @brief Checks modify flag and send observers the material changeness.
242    * It will clean up modify flag
243    */
244   void NotifyObserver();
245
246   /**
247    * @brief Requests loading an image from a URL and store it in TextureInformation.
248    *
249    * @param[in] textureInformation TextureInformation object to store loaded texture information.
250    * @param[in] url URL of the image to load.
251    */
252   void RequestTextureLoad(TextureInformation& textureInformation, const std::string& url);
253
254   /**
255    * @brief Called when loading requested by RequestTextureLoad is complete.
256    *
257    * @param[in] loadedTaskId ID of the loaded texture.
258    * @param[in] pixelData PixelData of the loaded texture.
259    */
260   void TextureLoadComplete(uint32_t loadedTaskId, PixelData pixelData);
261
262   /**
263    * @brief Called when all requested textures are loaded.
264    */
265   void ResourcesLoadComplete();
266
267   /**
268    * @brief Updates the material using each attribute of this material and send a notification to the ModelPrimitive class.
269    */
270   void Apply();
271
272 private:
273   // Delete copy & move operator
274   Material(const Material&)                = delete;
275   Material(Material&&)                     = delete;
276   Material& operator=(const Material& rhs) = delete;
277   Material& operator=(Material&& rhs)      = delete;
278
279 private:
280   ObserverContainer mObservers{}; ///< List of observers who need to be notified after some properties are changed.
281
282   TextureInformationContainer     mTextureInformations;
283   Dali::Toolkit::AsyncImageLoader mAsyncImageLoader;
284
285   std::string                            mName;                                                   ///< Material name
286   Dali::Scene3D::Material::AlphaModeType mAlphaMode   = Scene3D::Material::AlphaModeType::OPAQUE; ///< Alpha mode
287   float                                  mAlphaCutoff = 0.5f;                                     ///< Alpha cutoff value
288   bool                                   mDoubleSided = false;                                    ///< Whether to render both sides
289   float                                  mIor         = -1.0f;                                    ///< Index of refraction (TODO: Magic number)
290   MaterialModifyObserver::ModifyFlag     mModifyFlag  = MaterialModifyObserver::ModifyFlag::NONE; ///< Modified dirty flags
291
292   Scene3D::Loader::ShaderOption        mShaderOption;
293   uint32_t                             mMaterialFlag  = std::numeric_limits<uint32_t>::max();
294   Scene3D::Loader::RendererState::Type mRendererState = Scene3D::Loader::RendererState::NONE;
295
296   bool mIsOpaque = true;
297   bool mIsMask   = false;
298   bool mObserverNotifying; ///< True if observe is notify now. If then, we should not change the mObservers.
299 };
300
301 } // namespace Internal
302
303 // Helpers for public-api forwarding methods
304
305 inline Internal::Material& GetImplementation(Dali::Scene3D::Material& material)
306 {
307   DALI_ASSERT_ALWAYS(material && "Material handle is empty");
308
309   BaseObject& handle = material.GetBaseObject();
310
311   return static_cast<Internal::Material&>(handle);
312 }
313
314 inline const Internal::Material& GetImplementation(const Dali::Scene3D::Material& material)
315 {
316   DALI_ASSERT_ALWAYS(material && "Material handle is empty");
317
318   const BaseObject& handle = material.GetBaseObject();
319
320   return static_cast<const Internal::Material&>(handle);
321 }
322
323 } // namespace Scene3D
324
325 } // namespace Dali
326
327 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H