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