c0db71a25bc0a5f4068458daba97cf7184fc2ed4
[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 System.Diagnostics.CodeAnalysis;
22 using Tizen.NUI;
23 using Tizen.NUI.Binding;
24 using Tizen.NUI.BaseComponents;
25
26 namespace Tizen.NUI.Scene3D
27 {
28     /// <summary>
29     /// SceneView is a Class to show multiple 3D objects in a single 2D screen.
30     /// Each SceneView has its own 3D space, and 3D objects added to SceneView are positioned in the space.
31     /// SceneView uses left-handed coordinate system same as NUI. X as right, Y as down, and Z as forward.
32     ///
33     /// SceneView has internal root container to control inner rendering process like depth test.
34     /// When a View is added to the SceneView with <see cref="View.Add(View)"/> method, it is actually added on the root container.
35     /// Therefore, the added Views exist in the sub tree of SceneView, but are not direct children.
36     /// The sub tree of Views will be rendered with the SceneView's own Camera.
37     ///
38     /// SceneView has one built-in camera by default.
39     /// The default Camera is not removed by using <see cref="RemoveCamera(Camera)"/> method.
40     /// <see cref="GetCamera(uint)"/> method with index "0" returns the default camera,
41     /// and the minimum value returned by <see cref="GetCameraCount()"/> method is 1.
42     ///
43     /// SceneView also provides multiple Camera and one of them can be used to render multiple objects.
44     /// <see cref="AddCamera(Camera)"/>, <see cref="RemoveCamera(Camera)"/>, <see cref="GetCamera(uint)"/>,
45     /// and <see cref="SelectCamera(uint)"/> are methods to manage Cameras of the SceneView.
46     /// User can place multiple cameras in a scene to display the entire scene or to display individual objects.
47     /// User can use the <see cref="SelectCamera(uint)"/> method to select the currently required camera.
48     ///
49     /// When the SceneView's size changes, some camera properties that depend on its size may also change.
50     /// The changing properties are as follows: AspectRatio, LeftPlaneDistance, RightPlaneDistance, TopPlaneDistance, and BottomPlaneDistance.
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     /// For the IBL, two cube map textures(diffuse and specular) are required.
55     /// SceneView supports 4 types layout for Cube Map: Vertical/Horizontal Cross layouts, and Vertical/Horizontal Array layouts.
56     /// And also, ktx format with cube map is supported.
57     /// If a model already has an IBL, it is batch overridden with the IBL of the SceneView.
58     /// If the SceneView has IBL, the IBL of newly added models is also overridden.
59     ///
60     /// The IBL textures start to be loaded asynchronously when <see cref="SetImageBasedLightSource(string, string, float)"/> method is called.
61     /// ResourcesLoaded signal notifies that the loading of the IBL resources have been completed.
62     ///
63     /// If FBO is used, the rendering result of SceneView is drawn on the FBO and it is mapped on the plane of the SceneView.
64     /// It could decreases performance slightly, but it is useful to show SceneView according to the rendering order with other Views.
65     ///
66     /// And since SceneView is a View, it can be placed together with other 2D UI components in the NUI window.
67     /// </summary>
68     /// <since_tizen> 10 </since_tizen>
69     public class SceneView : View
70     {
71         private bool inCameraTransition = false;
72         private Animation cameraTransition;
73         private string skyboxUrl;
74
75         internal SceneView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
76         {
77         }
78
79         /// <summary>
80         /// Create an initialized SceneView.
81         /// </summary>
82         /// <since_tizen> 10 </since_tizen>
83         public SceneView() : this(Interop.SceneView.SceneNew(), true)
84         {
85             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
86         }
87
88         /// <summary>
89         /// Copy constructor.
90         /// </summary>
91         /// <param name="sceneView">The source object.</param>
92         /// <since_tizen> 10 </since_tizen>
93         public SceneView(SceneView sceneView) : this(Interop.SceneView.NewScene(SceneView.getCPtr(sceneView)), true)
94         {
95             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
96         }
97
98         /// <summary>
99         /// Assignment operator.
100         /// </summary>
101         /// <param name="sceneView">Handle to an object.</param>
102         /// <returns>Reference to this.</returns>
103         internal SceneView Assign(SceneView sceneView)
104         {
105             SceneView ret = new SceneView(Interop.SceneView.SceneAssign(SwigCPtr, SceneView.getCPtr(sceneView)), false);
106             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
107             return ret;
108         }
109
110         /// <summary>
111         /// An event emitted when Camera Transition is finished.
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 event EventHandler CameraTransitionFinished;
116
117         /// <summary>
118         /// Set/Get the ImageBasedLight ScaleFactor.
119         /// Scale factor controls light source intensity in [0.0f, 1.0f]
120         /// </summary>
121         /// <since_tizen> 10 </since_tizen>
122         public float ImageBasedLightScaleFactor
123         {
124             set
125             {
126                 SetImageBasedLightScaleFactor(value);
127             }
128             get
129             {
130                 return GetImageBasedLightScaleFactor();
131             }
132         }
133
134         /// <summary>
135         /// Set/Get the UseFramebuffer.
136         /// If this property is true, rendering result of SceneView is drawn on FBO and it is mapping on this SceneView plane.
137         /// If this property is false, each item in SceneView is rendered on window directly.
138         /// Default is false.
139         /// </summary>
140         /// <remarks>
141         /// If UseFramebuffer is true, it could decrease performance but entire rendering order is satisfied.
142         /// If UseFramebuffer is false, the performance becomes better but SceneView is rendered on the top of the other 2D components regardless tree order.
143         /// </remarks>
144         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
145         [EditorBrowsable(EditorBrowsableState.Never)]
146         public bool UseFramebuffer
147         {
148             set
149             {
150                 SetUseFramebuffer(value);
151             }
152             get
153             {
154                 return IsUsingFramebuffer();
155             }
156         }
157
158         /// <summary>
159         /// Set/Get the Framebuffer's MultiSamplingLevel.
160         /// Only has effects if UseFramebuffer is true, and Framebuffer MultiSampling is supported.
161         /// Default is 0.
162         /// </summary>
163         /// <remarks>
164         /// Getter didn't consider Framebuffer MultiSampling is supported or not.
165         /// </remarks>
166         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
167         [EditorBrowsable(EditorBrowsableState.Never)]
168         public uint FramebufferMultiSamplingLevel
169         {
170             set
171             {
172                 SetFramebufferMultiSamplingLevel(value);
173             }
174             get
175             {
176                 return GetFramebufferMultiSamplingLevel();
177             }
178         }
179
180         /// <summary>
181         /// Set/Get SkyboxUrl.
182         /// If SkyboxUrl is set, the cube map image is loaded and skybox is attached on scene.
183         /// Skybox texture is asynchronously loaded. When loading is finished, ResourcesLoaded is emitted.
184         /// </summary>
185         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
186         [EditorBrowsable(EditorBrowsableState.Never)]
187         public string SkyboxUrl
188         {
189             set
190             {
191                 SetSkybox(value);
192             }
193             get
194             {
195                 return skyboxUrl;
196             }
197         }
198
199         /// <summary>
200         /// Set/Get Skybox intensity.
201         /// The skybox intensity is multiplied to the color of skybox texture.
202         /// Default value is 1.0f.
203         /// </summary>
204         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
205         [EditorBrowsable(EditorBrowsableState.Never)]
206         public float SkyboxIntensity
207         {
208             set
209             {
210                 SetSkyboxIntensity(value);
211             }
212             get
213             {
214                 return GetSkyboxIntensity();
215             }
216         }
217
218         /// <summary>
219         /// Set/Get angle of orientation of the skybox.
220         /// If orientation is set, the skybox will be rotate by the Radian orientation along YAxis.
221         /// Default value is 0.0f.
222         /// </summary>
223         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
224         [EditorBrowsable(EditorBrowsableState.Never)]
225         public Rotation SkyboxOrientation
226         {
227             set
228             {
229                 SetSkyboxOrientation(value);
230             }
231             get
232             {
233                 return GetSkyboxOrientation();
234             }
235         }
236
237         /// <summary>
238         /// Adds a Camera to the SceneView at the end of the camera list of SceneView.
239         /// The Camera can be used as a selected camera to render the scene by using <see cref="SelectCamera(uint)"/> or <see cref="SelectCamera(string)"/>
240         /// </summary>
241         /// <param name="camera">Camera added on this SceneView.</param>
242         /// <remarks>
243         /// Some properties of the Camera will be change depending on the Size of this SceneView.
244         /// Those properties are as follows:
245         /// AspectRatio, LeftPlaneDistance, RightPlaneDistance, TopPlaneDistance, and BottomPlaneDistance.
246         ///
247         /// The FieldOfView of Camera is for vertical fov.
248         /// When the size of the SceneView is changed, the vertical fov is maintained
249         /// and the horizontal fov is automatically calculated according to the SceneView's AspectRatio.
250         /// </remarks>
251         /// <since_tizen> 10 </since_tizen>
252         public void AddCamera(Camera camera)
253         {
254             if (camera != null)
255             {
256                 Interop.SceneView.AddCamera(SwigCPtr, camera.SwigCPtr);
257                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
258             }
259         }
260
261         /// <summary>
262         /// Removes a Camera from this SceneView.
263         /// If removed Camera is selected Camera,
264         /// first camera in the list becomes the selected Camera.
265         /// </summary>
266         /// <param name="camera"> camera Camera to be removed from this Camera.</param>
267         /// <remarks>
268         /// When Camera.Dispose() is called, the NUI object is disposed, but camera information is maintained internally.
269         /// Therefore, even if Camera.Dispose() is called, RemoveCamera() or RemoveCamera() methods can be used.
270         /// If RemoveCamera() is called too, all information is deleted together.
271         /// </remarks>
272         /// <since_tizen> 10 </since_tizen>
273         public void RemoveCamera(Camera camera)
274         {
275             if (camera != null)
276             {
277                 Interop.SceneView.RemoveCamera(SwigCPtr, camera.SwigCPtr);
278                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
279             }
280         }
281
282         /// <summary>
283         /// Retrieves the number of cameras.
284         /// </summary>
285         /// <returns>The number of Cameras.</returns>
286         /// <since_tizen> 10 </since_tizen>
287         public uint GetCameraCount()
288         {
289             uint count = Interop.SceneView.GetCameraCount(SwigCPtr);
290             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
291             return count;
292         }
293
294         /// <summary>
295         /// Retrieves a Camera of the index.
296         /// </summary>
297         /// <param name="index"> Index of Camera to be retrieved.</param>
298         /// <returns>Camera of the index.</returns>
299         /// <since_tizen> 10 </since_tizen>
300         public Camera GetCamera(uint index)
301         {
302             global::System.IntPtr cPtr = Interop.SceneView.GetCamera(SwigCPtr, index);
303             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
304             if (camera == null)
305             {
306                 // Register new camera into Registry.
307                 camera = new Camera(cPtr, true);
308             }
309             else
310             {
311                 // We found matched NUI camera. Reduce cPtr reference count.
312                 HandleRef handle = new HandleRef(this, cPtr);
313                 Interop.Camera.DeleteCameraProperty(handle);
314                 handle = new HandleRef(null, IntPtr.Zero);
315             }
316             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
317             return camera;
318         }
319
320         /// <summary>
321         /// Retrieves a Camera of the input name.
322         /// </summary>
323         /// <param name="name"> string keyword of Camera to be retrieved.</param>
324         /// <returns>Camera that has the name as a View.Name property</returns>
325         /// <since_tizen> 10 </since_tizen>
326         public Camera GetCamera(string name)
327         {
328             global::System.IntPtr cPtr = Interop.SceneView.GetCamera(SwigCPtr, name);
329             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
330             if (camera == null)
331             {
332                 // Register new camera into Registry.
333                 camera = new Camera(cPtr, true);
334             }
335             else
336             {
337                 // We found matched NUI camera. Reduce cPtr reference count.
338                 HandleRef handle = new HandleRef(this, cPtr);
339                 Interop.Camera.DeleteCameraProperty(handle);
340                 handle = new HandleRef(null, IntPtr.Zero);
341             }
342             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
343             return camera;
344         }
345
346         /// <summary>
347         /// Makes SceneView use a Camera of index as a selected camera.
348         /// </summary>
349         /// <param name="index"> Index of Camera to be used as a selected camera.</param>
350         /// <since_tizen> 10 </since_tizen>
351         public void SelectCamera(uint index)
352         {
353             if (inCameraTransition)
354             {
355                 return;
356             }
357             this.GetSelectedCamera()?.Unparent();
358             Interop.SceneView.SelectCamera(SwigCPtr, index);
359             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
360         }
361
362         /// <summary>
363         /// Makes SceneView use a Camera of a name as a selected camera.
364         /// </summary>
365         /// <param name="name"> string keyword of Camera to be used as a selected camera.</param>
366         /// <since_tizen> 10 </since_tizen>
367         public void SelectCamera(string name)
368         {
369             if (inCameraTransition)
370             {
371                 return;
372             }
373             this.GetSelectedCamera()?.Unparent();
374             Interop.SceneView.SelectCamera(SwigCPtr, name);
375             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
376         }
377
378         /// <summary>
379         /// Starts camera transition from currently selected camera to a camera of index.
380         /// Camera Position, Orientation and FieldOfView are smoothly animated.
381         /// </summary>
382         /// <remarks>
383         /// The selected camera is switched to the Camera of the index when the transition is started.
384         /// During camera transition, Selected Camera should not be changed by using SelectCamera() or CameraTransition() method.
385         /// During camera transition, Camera properties of Selected Camera should not be changed.
386         /// </remarks>
387         /// <param name="index"> Index of destination Camera of Camera transition.</param>
388         /// <param name="durationMilliSeconds">The duration in milliseconds.</param>
389         /// <param name="alphaFunction">The alpha function to apply.</param>
390         /// <since_tizen> 10 </since_tizen>
391         [SuppressMessage("Microsoft.Design", "CA2000: Dispose objects before losing scope", Justification = "The ownership of camera object is not owned by this class.")]
392         public void CameraTransition(uint index, int durationMilliSeconds, AlphaFunction alphaFunction = null)
393         {
394             if (inCameraTransition || GetSelectedCamera() == GetCamera(index))
395             {
396                 return;
397             }
398             Camera source = GetSelectedCamera();
399             SelectCamera(index);
400             Camera destination = GetSelectedCamera();
401             CameraTransition(source, destination, durationMilliSeconds, alphaFunction);
402         }
403
404         /// <summary>
405         /// Starts camera transition from currently selected camera to a camera of input name.
406         /// Camera Position, Orientation and FieldOfView are smoothly animated.
407         /// </summary>
408         /// <remarks>
409         /// The selected camera is switched to the Camera of the input name when the transition is started.
410         /// During camera transition, Selected Camera should not be changed by using SelectCamera() or CameraTransition() method.
411         /// During camera transition, Camera properties of Selected Camera should not be changed.
412         /// </remarks>
413         /// <param name="name"> string keyword of destination Camera of Camera transition.</param>
414         /// <param name="durationMilliSeconds">The duration in milliseconds.</param>
415         /// <param name="alphaFunction">The alpha function to apply.</param>
416         /// <since_tizen> 10 </since_tizen>
417         [SuppressMessage("Microsoft.Design", "CA2000: Dispose objects before losing scope", Justification = "The ownership of camera object is not owned by this class.")]
418         public void CameraTransition(string name, int durationMilliSeconds, AlphaFunction alphaFunction = null)
419         {
420             if (inCameraTransition || GetSelectedCamera() == GetCamera(name))
421             {
422                 return;
423             }
424             Camera source = GetSelectedCamera();
425             SelectCamera(name);
426             Camera destination = GetSelectedCamera();
427             CameraTransition(source, destination, durationMilliSeconds, alphaFunction);
428         }
429
430         /// <summary>
431         /// Retrieves selected Camera.
432         /// </summary>
433         /// <returns> Camera currently used in SceneView as a selected Camera.</returns>
434         /// <since_tizen> 10 </since_tizen>
435         public Camera GetSelectedCamera()
436         {
437             global::System.IntPtr cPtr = Interop.SceneView.GetSelectedCamera(SwigCPtr);
438             Camera camera = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Camera;
439             if (camera == null)
440             {
441                 // Register new camera into Registry.
442                 camera = new Camera(cPtr, true);
443             }
444             else
445             {
446                 // We found matched NUI camera. Reduce cPtr reference count.
447                 HandleRef handle = new HandleRef(this, cPtr);
448                 Interop.Camera.DeleteCameraProperty(handle);
449                 handle = new HandleRef(null, IntPtr.Zero);
450             }
451             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
452             return camera;
453         }
454
455         /// <summary>
456         /// Changes Image Based Light as the input textures.
457         /// </summary>
458         /// <param name="diffuseUrl">The path of Cube map image that can be used as a diffuse IBL source.</param>
459         /// <param name="specularUrl">The path of Cube map image that can be used as a specular IBL source.</param>
460         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.</param>
461         /// <remarks>
462         /// http://tizen.org/privilege/mediastorage for local files in media storage.
463         /// http://tizen.org/privilege/externalstorage for local files in external storage.
464         /// </remarks>
465         /// <since_tizen> 10 </since_tizen>
466         public void SetImageBasedLightSource(string diffuseUrl, string specularUrl, float scaleFactor = 1.0f)
467         {
468             Interop.SceneView.SetImageBasedLightSource(SwigCPtr, diffuseUrl, specularUrl, scaleFactor);
469             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
470         }
471
472         internal void SetUseFramebuffer(bool useFramebuffer)
473         {
474             Interop.SceneView.UseFramebuffer(SwigCPtr, useFramebuffer);
475             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
476         }
477
478         internal bool IsUsingFramebuffer()
479         {
480             bool result = Interop.SceneView.IsUsingFramebuffer(SwigCPtr);
481             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
482             return result;
483         }
484
485         internal void SetFramebufferMultiSamplingLevel(uint multiSamplingLevel)
486         {
487             Interop.SceneView.SetFramebufferMultiSamplingLevel(SwigCPtr, multiSamplingLevel);
488             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
489         }
490
491         internal uint GetFramebufferMultiSamplingLevel()
492         {
493             uint result = Interop.SceneView.GetFramebufferMultiSamplingLevel(SwigCPtr);
494             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
495             return result;
496         }
497
498         /// <summary>
499         /// Set the ImageBasedLight ScaleFactor.
500         /// </summary>
501         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f].</param>
502         private void SetImageBasedLightScaleFactor(float scaleFactor)
503         {
504             Interop.SceneView.SetImageBasedLightScaleFactor(SwigCPtr, scaleFactor);
505             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
506         }
507
508         /// <summary>
509         /// Get the ImageBasedLight ScaleFactor.
510         /// </summary>
511         /// <returns>ImageBasedLightScaleFactor that controls light source intensity.</returns>
512         private float GetImageBasedLightScaleFactor()
513         {
514             float scaleFactor = Interop.SceneView.GetImageBasedLightScaleFactor(SwigCPtr);
515             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
516             return scaleFactor;
517         }
518
519         /// <summary>
520         /// Set the Skybox from cube map image.
521         /// Skybox texture is asynchronously loaded. When loading is finished, ResourcesLoaded is emitted.
522         /// </summary>
523         /// <param name="skyboxUrl">Cube map image url for skybox.</param>
524         private void SetSkybox(string skyboxUrl)
525         {
526             this.skyboxUrl = skyboxUrl;
527             Interop.SceneView.SetSkybox(SwigCPtr, skyboxUrl);
528             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
529         }
530
531         /// <summary>
532         /// Sets Skybox intensity.
533         /// The skybox intensity is multiplied to the color of skybox texture.
534         /// Default value is 1.0f.
535         /// </summary>
536         /// <param name="intensity">Intensity value to be multiplied to the cube map color.</param>
537         private void SetSkyboxIntensity(float intensity)
538         {
539             Interop.SceneView.SetSkyboxIntensity(SwigCPtr, intensity);
540             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
541         }
542
543         /// <summary>
544         /// Gets Skybox intensity.
545         /// Default value is 1.0f.
546         /// </summary>
547         /// <returns>skybox intensity.</returns>
548         private float GetSkyboxIntensity()
549         {
550             float intensity = Interop.SceneView.GetSkyboxIntensity(SwigCPtr);
551             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
552             return intensity;
553         }
554
555         /// <summary>
556         /// Sets orientation of the skybox.
557         /// </summary>
558         /// <param name="orientation">Rotation angle of the skybox along YAxis.</param>
559         private void SetSkyboxOrientation(Rotation orientation)
560         {
561             Interop.SceneView.SetSkyboxOrientation(SwigCPtr, Rotation.getCPtr(orientation));
562             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
563         }
564
565         /// <summary>
566         /// Gets Skybox orientation.
567         /// </summary>
568         /// <returns>skybox orientation.</returns>
569         private Rotation GetSkyboxOrientation()
570         {
571             global::System.IntPtr cPtr = Interop.SceneView.GetSkyboxOrientation(SwigCPtr);
572             Rotation ret = (cPtr == global::System.IntPtr.Zero) ? null : new Rotation(cPtr, true);
573             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
574             return ret;
575         }
576
577         private void CameraTransition(Camera sourceCamera, Camera destinationCamera, int durationMilliSeconds, AlphaFunction alphaFunction)
578         {
579             inCameraTransition = true;
580
581             Position sourcePosition = sourceCamera.Position;
582             Rotation sourceOrientation = sourceCamera.Orientation;
583
584             Position destinationPosition = destinationCamera.Position;
585             Rotation destinationOrientation = destinationCamera.Orientation;
586
587             cameraTransition = new Animation(durationMilliSeconds);
588
589             KeyFrames positionKeyFrames = new KeyFrames();
590             positionKeyFrames.Add(0.0f, sourcePosition);
591             positionKeyFrames.Add(1.0f, destinationPosition);
592
593             KeyFrames orientationKeyFrames = new KeyFrames();
594             orientationKeyFrames.Add(0.0f, sourceOrientation);
595             orientationKeyFrames.Add(1.0f, destinationOrientation);
596
597             cameraTransition.AnimateBetween(destinationCamera, "Position", positionKeyFrames, Animation.Interpolation.Linear, alphaFunction);
598             cameraTransition.AnimateBetween(destinationCamera, "Orientation", orientationKeyFrames, Animation.Interpolation.Linear, alphaFunction);
599
600             if (destinationCamera.ProjectionMode == Camera.ProjectionModeType.Perspective)
601             {
602                 Radian sourceFieldOfView = sourceCamera.FieldOfView;
603                 Radian destinationFieldOfView = destinationCamera.FieldOfView;
604
605                 // If ProjectionDirection is not equal, match the value.
606                 if (sourceCamera.ProjectionDirection != destinationCamera.ProjectionDirection)
607                 {
608                     float aspect = destinationCamera.AspectRatio;
609                     if (destinationCamera.ProjectionDirection == Camera.ProjectionDirectionType.Vertical)
610                     {
611                         Camera.ConvertFovFromHorizontalToVertical(aspect, ref sourceFieldOfView);
612                     }
613                     else
614                     {
615                         Camera.ConvertFovFromVerticalToHorizontal(aspect, ref sourceFieldOfView);
616                     }
617                 }
618
619                 KeyFrames fieldOfViewKeyFrames = new KeyFrames();
620                 fieldOfViewKeyFrames.Add(0.0f, sourceFieldOfView.ConvertToFloat());
621                 fieldOfViewKeyFrames.Add(1.0f, destinationFieldOfView.ConvertToFloat());
622                 cameraTransition.AnimateBetween(destinationCamera, "FieldOfView", fieldOfViewKeyFrames, Animation.Interpolation.Linear, alphaFunction);
623
624                 sourceFieldOfView.Dispose();
625                 destinationFieldOfView.Dispose();
626                 fieldOfViewKeyFrames.Dispose();
627             }
628             else
629             {
630                 float sourceOrthographicSize = sourceCamera.OrthographicSize;
631                 float destinationOrthographicSize = destinationCamera.OrthographicSize;
632
633                 // If ProjectionDirection is not equal, match the value.
634                 if (sourceCamera.ProjectionDirection != destinationCamera.ProjectionDirection)
635                 {
636                     float aspect = destinationCamera.AspectRatio;
637                     if (destinationCamera.ProjectionDirection == Camera.ProjectionDirectionType.Vertical)
638                     {
639                         sourceOrthographicSize = sourceOrthographicSize / aspect;
640                     }
641                     else
642                     {
643                         sourceOrthographicSize = sourceOrthographicSize * aspect;
644                     }
645                 }
646
647                 KeyFrames orthographicSizeKeyFrames = new KeyFrames();
648                 orthographicSizeKeyFrames.Add(0.0f, sourceOrthographicSize);
649                 orthographicSizeKeyFrames.Add(1.0f, destinationOrthographicSize);
650                 cameraTransition.AnimateBetween(destinationCamera, "OrthographicSize", orthographicSizeKeyFrames, Animation.Interpolation.Linear, alphaFunction);
651
652                 orthographicSizeKeyFrames.Dispose();
653             }
654
655             float destinationNearPlaneDistance = destinationCamera.NearPlaneDistance;
656             float destinationFarPlaneDistance = destinationCamera.FarPlaneDistance;
657             destinationCamera.NearPlaneDistance = Math.Min(sourceCamera.NearPlaneDistance, destinationCamera.NearPlaneDistance);
658             destinationCamera.FarPlaneDistance = Math.Max(sourceCamera.FarPlaneDistance, destinationCamera.FarPlaneDistance);
659
660             cameraTransition.Finished += (s, e) =>
661             {
662                 this.GetSelectedCamera().NearPlaneDistance = destinationNearPlaneDistance;
663                 this.GetSelectedCamera().FarPlaneDistance = destinationFarPlaneDistance;
664                 inCameraTransition = false;
665                 CameraTransitionFinished?.Invoke(this, EventArgs.Empty);
666             };
667             cameraTransition.Play();
668
669             positionKeyFrames.Dispose();
670             orientationKeyFrames.Dispose();
671         }
672
673         /// <summary>
674         /// Release swigCPtr.
675         /// </summary>
676         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
677         [EditorBrowsable(EditorBrowsableState.Never)]
678         protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
679         {
680             Interop.SceneView.DeleteScene(swigCPtr);
681         }
682     }
683 }