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