[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / light / light-impl.cpp
1 /*
2  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-scene3d/internal/light/light-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/devel-api/controls/control-devel.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/public-api/object/type-registry-helper.h>
25 #include <dali/public-api/object/type-registry.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
29
30 namespace Dali
31 {
32 namespace Scene3D
33 {
34 namespace Internal
35 {
36 namespace
37 {
38 static constexpr uint32_t         MAX_NUMBER_OF_LIGHT = 5;
39 static constexpr std::string_view LIGHT_COUNT_STRING("uLightCount");
40 static constexpr std::string_view LIGHT_DIRECTION_STRING("uLightDirection");
41 static constexpr std::string_view LIGHT_COLOR_STRING("uLightColor");
42 static constexpr std::string_view SHADOW_ENABLED_STRING("uIsShadowEnabled");
43 static constexpr std::string_view SHADOW_VIEW_PROJECTION_MATRIX_STRING("uShadowLightViewProjectionMatrix");
44
45 /**
46  * Creates control through type registry
47  */
48 BaseHandle Create()
49 {
50   return Scene3D::Light::New();
51 }
52
53 // Setup properties, signals and actions using the type-registry.
54 DALI_TYPE_REGISTRATION_BEGIN(Scene3D::Light, Dali::CustomActor, Create);
55 DALI_TYPE_REGISTRATION_END()
56 } // unnamed namespace
57
58 Dali::Scene3D::Light Light::New()
59 {
60   // Create the implementation, temporarily owned on stack
61   IntrusivePtr<Light> nodeImpl = new Light();
62
63   // Pass ownership to handle
64   Scene3D::Light handle(*nodeImpl);
65
66   // Second-phase init of the implementation
67   // This can only be done after the CustomActor connection has been made...
68   nodeImpl->Initialize();
69
70   return handle;
71 }
72
73 Light::Light()
74 : Control(static_cast<ControlBehaviour>(ControlBehaviour::DISABLE_STYLE_CHANGE_SIGNALS | ActorFlags::DISABLE_SIZE_NEGOTIATION))
75 {
76 }
77
78 Light::~Light()
79 {
80 }
81
82 // From Internal::Control.
83
84 void Light::OnInitialize()
85 {
86   Actor self = Self();
87
88   // TODO : We need to check this is enough.
89   Toolkit::DevelControl::EnableCreateAccessible(Toolkit::Control::DownCast(self), false);
90
91   self.SetProperty(Dali::Actor::Property::COLOR, Color::WHITE);
92
93   // Directional Light setting
94   mLightSourceActor = Dali::CameraActor::New();
95   mLightSourceActor.SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
96   mLightSourceActor.SetProperty(Dali::Actor::Property::POSITION, Vector3::ZERO);
97   mLightSourceActor.SetProperty(Dali::Actor::Property::ORIENTATION, Quaternion());
98   self.Add(mLightSourceActor);
99 }
100
101 // From CustomActorImpl.
102
103 void Light::OnSceneConnection(int depth)
104 {
105   Actor parent = Self().GetParent();
106   while(parent)
107   {
108     Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent);
109     if(sceneView)
110     {
111       mParentSceneView = sceneView;
112       if(mIsEnabled)
113       {
114         GetImpl(sceneView).AddLight(Scene3D::Light::DownCast(Self()));
115       }
116       if(mIsShadowEnabled)
117       {
118         GetImpl(sceneView).SetShadow(Scene3D::Light::DownCast(Self()));
119       }
120       break;
121     }
122     parent = parent.GetParent();
123   }
124 }
125
126 void Light::OnSceneDisconnection()
127 {
128   Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
129   if(sceneView)
130   {
131     mParentSceneView.Reset();
132     GetImpl(sceneView).RemoveLight(Scene3D::Light::DownCast(Self()));
133   }
134 }
135
136 void Light::OnChildAdd(Actor& child)
137 {
138 }
139
140 void Light::OnChildRemove(Actor& child)
141 {
142 }
143
144 void Light::OnSizeSet(const Vector3& targetSize)
145 {
146 }
147
148 void Light::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
149 {
150   // @todo size negotiate background to new size, animate as well?
151 }
152
153 void Light::OnRelayout(const Vector2& size, RelayoutContainer& container)
154 {
155 }
156
157 void Light::OnSetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
158 {
159 }
160
161 Vector3 Light::GetNaturalSize()
162 {
163   return Vector3::ZERO;
164 }
165
166 float Light::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
167 {
168   return 0.0f;
169 }
170
171 float Light::GetHeightForWidth(float width)
172 {
173   return 0.0f;
174 }
175
176 float Light::GetWidthForHeight(float height)
177 {
178   return 0.0f;
179 }
180
181 bool Light::RelayoutDependentOnChildren(Dimension::Type dimension)
182 {
183   return false;
184 }
185
186 void Light::OnCalculateRelayoutSize(Dimension::Type dimension)
187 {
188 }
189
190 void Light::OnLayoutNegotiated(float size, Dimension::Type dimension)
191 {
192 }
193
194 Light& GetImplementation(Dali::Scene3D::Light& handle)
195 {
196   CustomActorImpl& customInterface = handle.GetImplementation();
197   Light&           impl            = dynamic_cast<Internal::Light&>(customInterface);
198   return impl;
199 }
200
201 const Light& GetImplementation(const Dali::Scene3D::Light& handle)
202 {
203   const CustomActorImpl& customInterface = handle.GetImplementation();
204   // downcast to control
205   const Light& impl = dynamic_cast<const Internal::Light&>(customInterface);
206   return impl;
207 }
208
209 // Public Method
210
211 void Light::Enable(bool enable)
212 {
213   if(enable == mIsEnabled)
214   {
215     return;
216   }
217   mIsEnabled = enable;
218
219   Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
220   if(!sceneView)
221   {
222     return;
223   }
224
225   if(mIsEnabled)
226   {
227     GetImpl(sceneView).AddLight(Scene3D::Light::DownCast(Self()));
228   }
229   else
230   {
231     GetImpl(sceneView).RemoveLight(Scene3D::Light::DownCast(Self()));
232   }
233 }
234
235 bool Light::IsEnabled() const
236 {
237   return mIsEnabled;
238 }
239
240 void Light::EnableShadow(bool enable)
241 {
242   if(enable == mIsShadowEnabled)
243   {
244     return;
245   }
246   mIsShadowEnabled = enable;
247
248   Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
249   if(!sceneView)
250   {
251     return;
252   }
253
254   if(mIsShadowEnabled)
255   {
256     GetImpl(sceneView).SetShadow(Scene3D::Light::DownCast(Self()));
257   }
258   else
259   {
260     GetImpl(sceneView).RemoveShadow(Scene3D::Light::DownCast(Self()));
261   }
262 }
263
264 bool Light::IsShadowEnabled() const
265 {
266   return mIsShadowEnabled;
267 }
268
269 CameraActor Light::GetCamera() const
270 {
271   return mLightSourceActor;
272 }
273
274 void Light::EnableShadowSoftFiltering(bool useSoftFiltering)
275 {
276   mUseSoftFiltering = useSoftFiltering;
277   UpdateShadowUniforms();
278 }
279
280 bool Light::IsShadowSoftFilteringEnabled() const
281 {
282   return mUseSoftFiltering;
283 }
284
285 void Light::SetShadowIntensity(float shadowIntensity)
286 {
287   mShadowIntensity = shadowIntensity;
288   UpdateShadowUniforms();
289 }
290
291 float Light::GetShadowIntensity() const
292 {
293   return mShadowIntensity;
294 }
295
296 void Light::SetShadowBias(float shadowBias)
297 {
298   mShadowBias = shadowBias;
299   UpdateShadowUniforms();
300 }
301
302 float Light::GetShadowBias() const
303 {
304   return mShadowBias;
305 }
306
307 // Public Static Method
308
309 uint32_t Light::GetMaximumEnabledLightCount()
310 {
311   return MAX_NUMBER_OF_LIGHT;
312 }
313
314 std::string_view Light::GetLightCountUniformName()
315 {
316   return LIGHT_COUNT_STRING;
317 }
318
319 std::string_view Light::GetLightDirectionUniformName()
320 {
321   return LIGHT_DIRECTION_STRING;
322 }
323
324 std::string_view Light::GetLightColorUniformName()
325 {
326   return LIGHT_COLOR_STRING;
327 }
328
329 std::string_view Light::GetShadowEnabledUniformName()
330 {
331   return SHADOW_ENABLED_STRING;
332 }
333
334 std::string_view Light::GetShadowViewProjectionMatrixUniformName()
335 {
336   return SHADOW_VIEW_PROJECTION_MATRIX_STRING;
337 }
338
339 // Private Method
340
341 void Light::UpdateShadowUniforms()
342 {
343   Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
344   if(!sceneView)
345   {
346     return;
347   }
348
349   if(mIsShadowEnabled)
350   {
351     GetImpl(sceneView).UpdateShadowUniform(Scene3D::Light::DownCast(Self()));
352   }
353 }
354
355 } // namespace Internal
356
357 } // namespace Scene3D
358
359 } // namespace Dali