[NUI] Add Set/Get IBL Scale Factor for SceneView and Model
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Scene3D / src / public / Controls / SceneView.cs
1 /*
2  * Copyright(c) 2022 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 using System;
19 using System.Runtime.InteropServices;
20 using System.ComponentModel;
21 using Tizen.NUI;
22 using Tizen.NUI.Binding;
23 using Tizen.NUI.BaseComponents;
24
25 namespace Tizen.NUI.Scene3D
26 {
27     /// <summary>
28     /// SceneView is a Class to show multiple 3D objects in a single 2D sreen.
29     /// Each SceneView has its own 3D space, and 3D objects added to SceneView are positioned in the space.
30     /// SceneView uses left-handed coordinate system same as NUI. X as right, Y as down, and Z as forward.
31     ///
32     /// SceneView has internal root container to control inner rendering process like depth test.
33     /// When a View is added to the SceneView with <see cref="View.Add(View)"/> method, it is actually added on the root container.
34     /// Therefore, the added Views exist in the sub tree of SceneView, but are not direct children.
35     /// The sub tree of Views will be rendered with the SceneView's own Camera.
36     ///
37     /// SceneView has one built-in camera by default.
38     /// The default Camera is not removed by using <see cref="RemoveCamera(Camera)"/> method.
39     /// <see cref="GetCamera(uint)"/> method with index "0" returns the default camera,
40     /// and the minimum value returned by <see cref="GetCameraCount()"/> method is 1.
41     ///
42     /// SceneView also provides multiple Camera and one of them can be used to render the multiple objects.
43     /// <see cref="AddCamera(Camera)"/>, <see cref="RemoveCamera(Camera)"/>, <see cref="GetCamera(uint)"/>,
44     /// and <see cref="SelectCamera(uint)"/> are methods to manage Cameras of the SceneView.
45     /// User can place multiple cameras in a scene to display the entire scene or to display individual objects.
46     /// User can use the <see cref="SelectCamera(uint)"/> method to select the currently required camera.
47     ///
48     /// When the SceneView's size changes, some camera properties that depend on its size may also change.
49     /// The changing properties are as follows: ProjectionMode, AspectRatio, LeftPlaneDistance, RightPlaneDistance, TopPlaneDistance, and BottomPlaneDistance.
50     /// Position, Near/FarPlaneDistance, and FieldOfView are maintained even if the size of the SceneView is changed.
51     /// The Camera's FieldOfView is vertical fov. The horizontal fov is updated internally according to the SceneView size.
52     ///
53     /// The <see cref="SetImageBasedLightSource(string, string, float)"/> method sets the same IBL to all Model objects added to the SceneView.
54     /// If a model already has an IBL, it is batch overridden with the IBL of the SceneView.
55     /// If the SceneView has IBL, the IBL of newly added models is also overridden.
56     ///
57     /// SceneView provides an option to use FBO for rendering result with <see cref="UseFramebuffer"/> property.
58     /// If it is false, SceneView is always drawn in the form of a rectangle on the default window surface directly.
59     /// It improves performance, but the SceneView is always drawn on top of other 2D objects regardless of rendering order.
60     ///
61     /// If FBO is used, the rendering result of SceneView is drawn on the FBO and it is mapped on the plane of the SceneView.
62     /// It could decreases performance slightly, but it is useful to show SceneView according to the rendering order with other Views.
63     ///
64     /// And since SceneView is a View, it can be placed together with other 2D UI components in the NUI window.
65     /// </summary>
66     /// <code>
67     /// </code>
68     // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
69     [EditorBrowsable(EditorBrowsableState.Never)]
70     public class SceneView : View
71     {
72         internal SceneView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
73         {
74         }
75
76         /// <summary>
77         /// Create an initialized SceneView.
78         /// </summary>
79         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
80         [EditorBrowsable(EditorBrowsableState.Never)]
81         public SceneView() : this(Interop.SceneView.SceneNew(), true)
82         {
83             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
84         }
85
86         /// <summary>
87         /// Copy constructor.
88         /// </summary>
89         /// <param name="sceneView">Handle to an object.</param>
90         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
91         [EditorBrowsable(EditorBrowsableState.Never)]
92         public SceneView(SceneView sceneView) : this(Interop.SceneView.NewScene(SceneView.getCPtr(sceneView)), true)
93         {
94             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
95         }
96
97         /// <summary>
98         /// Assignment operator.
99         /// </summary>
100         /// <param name="sceneView">Handle to an object.</param>
101         /// <returns>Reference to this.</returns>
102         internal SceneView Assign(SceneView sceneView)
103         {
104             SceneView ret = new SceneView(Interop.SceneView.SceneAssign(SwigCPtr, SceneView.getCPtr(sceneView)), false);
105             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
106             return ret;
107         }
108
109         /// <summary>
110         /// Set/Get the ImageBasedLight ScaleFactor.
111         /// Scale factor controls light source intensity in [0.0f, 1.0f]
112         /// </summary>
113         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
114         [EditorBrowsable(EditorBrowsableState.Never)]
115         public float ImageBasedLightScaleFactor
116         {
117             set
118             {
119                 SetImageBasedLightScaleFactor(value);
120             }
121             get
122             {
123                 return GetImageBasedLightScaleFactor();
124             }
125         }
126
127         /// <summary>
128         /// Set/Get the UseFramebuffer.
129         /// If this property is true, rendering result of SceneView is drawn on FBO and it is mapping on this SceneView plane.
130         /// If this property is false, each item in SceneView is rendered on window directly.
131         /// Default is false.
132         /// </summary>
133         /// <remarks>
134         /// If useFramebuffer is true, it could decrease performance but entire rendering order is satisfied.
135         /// If useFramebuffer is false, the performance becomes better but SceneView is rendered on the top of the other 2D components regardless tree order.
136         /// </remarks>
137         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
138         [EditorBrowsable(EditorBrowsableState.Never)]
139         public bool UseFramebuffer
140         {
141             set
142             {
143                 SetUseFramebuffer(value);
144             }
145             get
146             {
147                 return IsUsingFramebuffer();
148             }
149         }
150
151         /// <summary>
152         /// Adds a Camera to the SceneView
153         /// The Camera can be used as a selected camera to render the scene by using <see cref="SelectCamera(uint)"/> or <see cref="SelectCamera(string)"/>
154         /// </summary>
155         /// <param name="camera">Camera added on this SceneView.</param>
156         /// <remarks>
157         /// Some properties of the Camera will be change depending on the Size of this SceneView.
158         /// Those properties are as follows:
159         /// aspectRatio, nearPlaneDistance, farPlaneDistance, leftPlaneDistance, rightPlaneDistance, topPlaneDistance, and bottomPlaneDistance.
160         ///
161         /// The FieldOfView of Camera is for vertical fov.
162         /// When the size of the SceneView is changed, the vertical fov is maintained
163         /// and the horizontal fov is automatically calculated according to the SceneView's aspect ratio.
164         /// </remarks>
165         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
166         [EditorBrowsable(EditorBrowsableState.Never)]
167         public void AddCamera(Camera camera)
168         {
169             if(camera != null)
170             {
171                 Interop.SceneView.AddCamera(SwigCPtr, camera.SwigCPtr);
172                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
173             }
174         }
175
176         /// <summary>
177         /// Removes a Camera from this SceneView.
178         /// If removed Camera is selected Camera,
179         /// first camera in the list is set to selected Camera.
180         /// </summary>
181         /// <param name="camera"> camera Camera to be removed from this Camera.</param>
182         /// <remarks>
183         /// Camera.Dispose() don't automatically release memory. We should call this API if we want to release memory.
184         /// We cannot remove default camera. If we try to remove default camera, ignored.
185         /// </remarks>
186         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
187         [EditorBrowsable(EditorBrowsableState.Never)]
188         public void RemoveCamera(Camera camera)
189         {
190             if(camera != null)
191             {
192                 Interop.SceneView.RemoveCamera(SwigCPtr, camera.SwigCPtr);
193                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
194             }
195         }
196
197         /// <summary>
198         /// Retrieves the number of cameras.
199         /// </summary>
200         /// <returns>The number of Cameras.</returns>
201         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
202         [EditorBrowsable(EditorBrowsableState.Never)]
203         public uint GetCameraCount()
204         {
205             uint count = Interop.SceneView.GetCameraCount(SwigCPtr);
206             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
207             return count;
208         }
209
210         /// <summary>
211         /// Retrieves a Camera of the index.
212         /// </summary>
213         /// <param name="index"> Index of Camera to be retrieved.</param>
214         /// <returns>Camera of the index.</returns>
215         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
216         [EditorBrowsable(EditorBrowsableState.Never)]
217         public Camera GetCamera(uint index)
218         {
219             global::System.IntPtr cPtr = Interop.SceneView.GetCamera(SwigCPtr, index);
220             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
221             if(camera == null)
222             {
223                 // Register new camera into Registry.
224                 camera = new Camera(cPtr, true);
225             }
226             else
227             {
228                 // We found matched NUI camera. Reduce cPtr reference count.
229                 HandleRef handle = new HandleRef(this, cPtr);
230                 Interop.Camera.DeleteCameraProperty(handle);
231                 handle = new HandleRef(null, IntPtr.Zero);
232             }
233             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
234             return camera;
235         }
236
237         /// <summary>
238         /// Retrieves a Camera of the index.
239         /// </summary>
240         /// <param name="name"> string keyword of Camera to be retrieved.</param>
241         /// <returns>Camera that has the name as a View.Name property</returns>
242         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
243         [EditorBrowsable(EditorBrowsableState.Never)]
244         public Camera GetCamera(string name)
245         {
246             global::System.IntPtr cPtr = Interop.SceneView.GetCamera(SwigCPtr, name);
247             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
248             if(camera == null)
249             {
250                 // Register new camera into Registry.
251                 camera = new Camera(cPtr, true);
252             }
253             else
254             {
255                 // We found matched NUI camera. Reduce cPtr reference count.
256                 HandleRef handle = new HandleRef(this, cPtr);
257                 Interop.Camera.DeleteCameraProperty(handle);
258                 handle = new HandleRef(null, IntPtr.Zero);
259             }
260             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
261             return camera;
262         }
263
264         /// <summary>
265         /// Makes SceneView use a Camera of index as a selected camera.
266         /// </summary>
267         /// <param name="index"> Index of Camera to be used as a selected camera.</param>
268         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
269         [EditorBrowsable(EditorBrowsableState.Never)]
270         public void SelectCamera(uint index)
271         {
272             Interop.SceneView.SelectCamera(SwigCPtr, index);
273             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
274         }
275
276         /// <summary>
277         /// Makes SceneView use a Camera of a name as a selected camera.
278         /// </summary>
279         /// <param name="name"> string keyword of Camera to be used as a selected camera.</param>
280         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
281         [EditorBrowsable(EditorBrowsableState.Never)]
282         public void SelectCamera(string name)
283         {
284             Interop.SceneView.SelectCamera(SwigCPtr, name);
285             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
286         }
287
288         /// <summary>
289         /// Retrieves selected Camera.
290         /// </summary>
291         /// <returns> Camera currently used in SceneView as a selected Camera.</returns>
292         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
293         [EditorBrowsable(EditorBrowsableState.Never)]
294         public Camera GetSelectedCamera()
295         {
296             global::System.IntPtr cPtr = Interop.SceneView.GetSelectedCamera(SwigCPtr);
297             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
298             if(camera == null)
299             {
300                 // Register new camera into Registry.
301                 camera = new Camera(cPtr, true);
302             }
303             else
304             {
305                 // We found matched NUI camera. Reduce cPtr reference count.
306                 HandleRef handle = new HandleRef(this, cPtr);
307                 Interop.Camera.DeleteCameraProperty(handle);
308                 handle = new HandleRef(null, IntPtr.Zero);
309             }
310             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
311             return camera;
312         }
313
314         /// <summary>
315         /// Changes Image Based Light as the input textures.
316         /// </summary>
317         /// <param name="diffuseUrl">The path of Cube map image that can be used as a diffuse IBL source.</param>
318         /// <param name="specularUrl">The path of Cube map image that can be used as a specular IBL source.</param>
319         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.</param>
320         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
321         [EditorBrowsable(EditorBrowsableState.Never)]
322         public void SetImageBasedLightSource(string diffuseUrl, string specularUrl, float scaleFactor = 1.0f)
323         {
324             Interop.SceneView.SetImageBasedLightSource(SwigCPtr, diffuseUrl, specularUrl, scaleFactor);
325             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
326         }
327
328         internal void SetUseFramebuffer(bool useFramebuffer)
329         {
330             Interop.SceneView.UseFramebuffer(SwigCPtr, useFramebuffer);
331             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
332         }
333
334         internal bool IsUsingFramebuffer()
335         {
336             bool result = Interop.SceneView.IsUsingFramebuffer(SwigCPtr);
337             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
338             return result;
339         }
340
341         /// <summary>
342         /// Set the ImageBasedLight ScaleFactor.
343         /// </summary>
344         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f].</param>
345         private void SetImageBasedLightScaleFactor(float scaleFactor)
346         {
347             Interop.SceneView.SetImageBasedLightScaleFactor(SwigCPtr, scaleFactor);
348             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
349         }
350
351         /// <summary>
352         /// Get the ImageBasedLight ScaleFactor.
353         /// </summary>
354         /// <returns>ImageBasedLightScaleFactor that controls light source intensity.</returns>
355         private float GetImageBasedLightScaleFactor()
356         {
357             float scaleFactor = Interop.SceneView.GetImageBasedLightScaleFactor(SwigCPtr);
358             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
359             return scaleFactor;
360         }
361
362         /// <summary>
363         /// Release swigCPtr.
364         /// </summary>
365         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
366         [EditorBrowsable(EditorBrowsableState.Never)]
367         protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
368         {
369             Interop.SceneView.DeleteScene(swigCPtr);
370         }
371     }
372 }