[NUI.Scene3D] Create and Register Scene3D.Camera
[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 UseFramebuffer.
111         /// If this property is true, rendering result of SceneView is drawn on FBO and it is mapping on this SceneView plane.
112         /// If this property is false, each item in SceneView is rendered on window directly.
113         /// Default is false.
114         /// </summary>
115         /// <remarks>
116         /// If useFramebuffer is true, it could decrease performance but entire rendering order is satisfied.
117         /// If useFramebuffer is false, the performance becomes better but SceneView is rendered on the top of the other 2D components regardless tree order.
118         /// </remarks>
119         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
120         [EditorBrowsable(EditorBrowsableState.Never)]
121         public bool UseFramebuffer
122         {
123             set
124             {
125                 SetUseFramebuffer(value);
126             }
127             get
128             {
129                 return IsUsingFramebuffer();
130             }
131         }
132
133         /// <summary>
134         /// Adds a Camera to the SceneView
135         /// The Camera can be used as a selected camera to render the scene by using <see cref="SelectCamera(uint)"/> or <see cref="SelectCamera(string)"/>
136         /// </summary>
137         /// <param name="camera">Camera added on this SceneView.</param>
138         /// <remarks>
139         /// Some properties of the Camera will be change depending on the Size of this SceneView.
140         /// Those properties are as follows:
141         /// aspectRatio, nearPlaneDistance, farPlaneDistance, leftPlaneDistance, rightPlaneDistance, topPlaneDistance, and bottomPlaneDistance.
142         ///
143         /// The FieldOfView of Camera is for vertical fov.
144         /// When the size of the SceneView is changed, the vertical fov is maintained
145         /// and the horizontal fov is automatically calculated according to the SceneView's aspect ratio.
146         /// </remarks>
147         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
148         [EditorBrowsable(EditorBrowsableState.Never)]
149         public void AddCamera(Camera camera)
150         {
151             if(camera != null)
152             {
153                 Interop.SceneView.AddCamera(SwigCPtr, camera.SwigCPtr);
154                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
155             }
156         }
157
158         /// <summary>
159         /// Removes a Camera from this SceneView.
160         /// If removed Camera is selected Camera,
161         /// first camera in the list is set to selected Camera.
162         /// </summary>
163         /// <param name="camera"> camera Camera to be removed from this Camera.</param>
164         /// <remarks>
165         /// Camera.Dispose() don't automatically release memory. We should call this API if we want to release memory.
166         /// We cannot remove default camera. If we try to remove default camera, ignored.
167         /// </remarks>
168         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
169         [EditorBrowsable(EditorBrowsableState.Never)]
170         public void RemoveCamera(Camera camera)
171         {
172             if(camera != null)
173             {
174                 Interop.SceneView.RemoveCamera(SwigCPtr, camera.SwigCPtr);
175                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
176             }
177         }
178
179         /// <summary>
180         /// Retrieves the number of cameras.
181         /// </summary>
182         /// <returns>The number of Cameras.</returns>
183         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
184         [EditorBrowsable(EditorBrowsableState.Never)]
185         public uint GetCameraCount()
186         {
187             uint count = Interop.SceneView.GetCameraCount(SwigCPtr);
188             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
189             return count;
190         }
191
192         /// <summary>
193         /// Retrieves a Camera of the index.
194         /// </summary>
195         /// <param name="index"> Index of Camera to be retrieved.</param>
196         /// <returns>Camera of the index.</returns>
197         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
198         [EditorBrowsable(EditorBrowsableState.Never)]
199         public Camera GetCamera(uint index)
200         {
201             global::System.IntPtr cPtr = Interop.SceneView.GetCamera(SwigCPtr, index);
202             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
203             if(camera == null)
204             {
205                 // Register new camera into Registry.
206                 camera = new Camera(cPtr, true);
207             }
208             else
209             {
210                 // We found matched NUI camera. Reduce cPtr reference count.
211                 HandleRef handle = new HandleRef(this, cPtr);
212                 Interop.Camera.DeleteCameraProperty(handle);
213                 handle = new HandleRef(null, IntPtr.Zero);
214             }
215             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
216             return camera;
217         }
218
219         /// <summary>
220         /// Retrieves a Camera of the index.
221         /// </summary>
222         /// <param name="name"> string keyword of Camera to be retrieved.</param>
223         /// <returns>Camera that has the name as a View.Name property</returns>
224         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
225         [EditorBrowsable(EditorBrowsableState.Never)]
226         public Camera GetCamera(string name)
227         {
228             global::System.IntPtr cPtr = Interop.SceneView.GetCamera(SwigCPtr, name);
229             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
230             if(camera == null)
231             {
232                 // Register new camera into Registry.
233                 camera = new Camera(cPtr, true);
234             }
235             else
236             {
237                 // We found matched NUI camera. Reduce cPtr reference count.
238                 HandleRef handle = new HandleRef(this, cPtr);
239                 Interop.Camera.DeleteCameraProperty(handle);
240                 handle = new HandleRef(null, IntPtr.Zero);
241             }
242             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
243             return camera;
244         }
245
246         /// <summary>
247         /// Makes SceneView use a Camera of index as a selected camera.
248         /// </summary>
249         /// <param name="index"> Index of Camera to be used as a selected camera.</param>
250         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
251         [EditorBrowsable(EditorBrowsableState.Never)]
252         public void SelectCamera(uint index)
253         {
254             Interop.SceneView.SelectCamera(SwigCPtr, index);
255             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
256         }
257
258         /// <summary>
259         /// Makes SceneView use a Camera of a name as a selected camera.
260         /// </summary>
261         /// <param name="name"> string keyword of Camera to be used as a selected camera.</param>
262         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
263         [EditorBrowsable(EditorBrowsableState.Never)]
264         public void SelectCamera(string name)
265         {
266             Interop.SceneView.SelectCamera(SwigCPtr, name);
267             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
268         }
269
270         /// <summary>
271         /// Retrieves selected Camera.
272         /// </summary>
273         /// <returns> Camera currently used in SceneView as a selected Camera.</returns>
274         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
275         [EditorBrowsable(EditorBrowsableState.Never)]
276         public Camera GetSelectedCamera()
277         {
278             global::System.IntPtr cPtr = Interop.SceneView.GetSelectedCamera(SwigCPtr);
279             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
280             if(camera == null)
281             {
282                 // Register new camera into Registry.
283                 camera = new Camera(cPtr, true);
284             }
285             else
286             {
287                 // We found matched NUI camera. Reduce cPtr reference count.
288                 HandleRef handle = new HandleRef(this, cPtr);
289                 Interop.Camera.DeleteCameraProperty(handle);
290                 handle = new HandleRef(null, IntPtr.Zero);
291             }
292             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
293             return camera;
294         }
295
296         /// <summary>
297         /// Changes Image Based Light as the input textures.
298         /// </summary>
299         /// <param name="diffuseUrl">The path of Cube map image that can be used as a diffuse IBL source.</param>
300         /// <param name="specularUrl">The path of Cube map image that can be used as a specular IBL source.</param>
301         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.</param>
302         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
303         [EditorBrowsable(EditorBrowsableState.Never)]
304         public void SetImageBasedLightSource(string diffuseUrl, string specularUrl, float scaleFactor = 1.0f)
305         {
306             Interop.SceneView.SetImageBasedLightSource(SwigCPtr, diffuseUrl, specularUrl, scaleFactor);
307             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
308         }
309
310         internal void SetUseFramebuffer(bool useFramebuffer)
311         {
312             Interop.SceneView.UseFramebuffer(SwigCPtr, useFramebuffer);
313             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
314         }
315
316         internal bool IsUsingFramebuffer()
317         {
318             bool result = Interop.SceneView.IsUsingFramebuffer(SwigCPtr);
319             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
320             return result;
321         }
322
323         /// <summary>
324         /// Release swigCPtr.
325         /// </summary>
326         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
327         [EditorBrowsable(EditorBrowsableState.Never)]
328         protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
329         {
330             Interop.SceneView.DeleteScene(swigCPtr);
331         }
332     }
333 }