[NUI.Scene3D] Add ProjectionDirection in Camera
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 30 Sep 2022 10:46:51 +0000 (19:46 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 4 Oct 2022 11:26:36 +0000 (20:26 +0900)
Add new property to control major direction of camera FieldOfView.
It will effort to FieldOfView and OrthographicSize.

Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
src/Tizen.NUI.Scene3D/src/internal/CameraBindableProperty.cs
src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.Camera.cs
src/Tizen.NUI.Scene3D/src/public/Controls/Camera.cs

index 0e1ef47..5090d26 100755 (executable)
@@ -40,6 +40,28 @@ namespace Tizen.NUI.Scene3D
         });
 
         /// <summary>
+        /// ProjectionDirectionProperty
+        /// </summary>
+        internal static readonly BindableProperty ProjectionDirectionProperty = BindableProperty.Create(nameof(ProjectionDirection), typeof(ProjectionDirectionType), typeof(Tizen.NUI.Scene3D.Camera), ProjectionDirectionType.Vertical, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (Tizen.NUI.Scene3D.Camera)bindable;
+            if (newValue != null)
+            {
+                // Keep previous orthographicSize.
+                float orthographicSize = instance.OrthographicSize;
+                instance.InternalProjectionDirection = (ProjectionDirectionType)newValue;
+
+                // Recalculate orthographicSize by changed direction.
+                instance.OrthographicSize = orthographicSize;
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var instance = (Tizen.NUI.Scene3D.Camera)bindable;
+            return instance.InternalProjectionDirection;
+        });
+
+        /// <summary>
         /// FieldOfViewProperty
         /// </summary>
         internal static readonly BindableProperty FieldOfViewProperty = BindableProperty.Create(nameof(FieldOfView), typeof(float), typeof(Tizen.NUI.Scene3D.Camera), default(float), propertyChanged: (bindable, oldValue, newValue) =>
index f7e6b02..acb0089 100755 (executable)
@@ -57,6 +57,9 @@ namespace Tizen.NUI.Scene3D
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_CameraActor_Property_INVERT_Y_AXIS_get")]
             public static extern int InvertYAxisGet();
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_CameraActor_Property_PROJECTION_DIRECTION_get")]
+            public static extern int ProjectionDirectionGet();
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_CameraActor_Property")]
             public static extern global::System.IntPtr NewCameraProperty();
 
index 0d518a2..cb9ab3d 100755 (executable)
@@ -32,23 +32,6 @@ namespace Tizen.NUI.Scene3D
     /// <since_tizen> 10 </since_tizen>
     public partial class Camera : View
     {
-        /// <summary>
-        /// Enumeration for the projectionMode.
-        /// ProjectionMode defines how the camera shows 3D objects or scene on a 2D plane with projection.
-        /// </summary>
-        /// <since_tizen> 10 </since_tizen>
-        public enum ProjectionModeType
-        {
-            /// <summary>
-            /// Distance causes foreshortening; objects further from the camera appear smaller.
-            /// </summary>
-            Perspective,
-            /// <summary>
-            /// Relative distance from the camera does not affect the size of objects.
-            /// </summary>
-            Orthographic
-        }
-
         internal Camera(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
@@ -107,6 +90,40 @@ namespace Tizen.NUI.Scene3D
         }
 
         /// <summary>
+        /// Enumeration for the projectionMode.
+        /// ProjectionMode defines how the camera shows 3D objects or scene on a 2D plane with projection.
+        /// </summary>
+        /// <since_tizen> 10 </since_tizen>
+        public enum ProjectionModeType
+        {
+            /// <summary>
+            /// Distance causes foreshortening; objects further from the camera appear smaller.
+            /// </summary>
+            Perspective,
+            /// <summary>
+            /// Relative distance from the camera does not affect the size of objects.
+            /// </summary>
+            Orthographic
+        }
+
+        /// <summary>
+        /// Enumeration for the projectionDirection.
+        /// </summary>
+        /// This will be released at Tizen.NET API Level 10, so currently this would be used as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public enum ProjectionDirectionType
+        {
+            /// <summary>
+            /// Distance causes foreshortening; objects further from the camera appear smaller.
+            /// </summary>
+            Vertical,
+            /// <summary>
+            /// Relative distance from the camera does not affect the size of objects.
+            /// </summary>
+            Horizontal
+        }
+
+        /// <summary>
         /// Sets/Gets the projection mode.
         /// The default is Perspective
         /// </summary>
@@ -125,7 +142,41 @@ namespace Tizen.NUI.Scene3D
         }
 
         /// <summary>
+        /// <para>
+        /// Sets/Gets the projection direction.
+        /// Projection direction determine basic direction of projection relative properties.
+        /// It will be used when we need to calculate some values relative with aspect ratio.
+        /// <see cref="FieldOfView"/>, and <see cref="OrthographicSize"/>
+        /// </para>
+        /// <para>
+        /// For example, if aspect ratio is 4:3 and set fieldOfView as 60 degree.
+        /// If ProjectionDirectionType.Vertical, basic direction is vertical. so, FoV of horizontal direction become ~75.2 degree
+        /// If ProjectionDirectionType.Horizontal, basic direction is horizontal. so, FoV of vertical direction become ~46.8 degree
+        /// </para>
+        /// <note>
+        /// This property doesn't change <see cref="FieldOfView"/> and <see cref="OrthographicSize"/> value automatically.
+        /// So result scene might be changed.
+        /// </note>
+        /// <para>The default is Vertical.</para>
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ProjectionDirectionType ProjectionDirection
+        {
+            get
+            {
+                return (ProjectionDirectionType)GetValue(ProjectionDirectionProperty);
+            }
+            set
+            {
+                SetValue(ProjectionDirectionProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        /// <summary>
         /// Sets/Gets the field of view in Radians.
+        /// FieldOfView depends on <see cref="ProjectionDirection"/> value.
         /// The default field of view is 45 degrees.
         /// </summary>
         /// <since_tizen> 10 </since_tizen>
@@ -144,20 +195,32 @@ namespace Tizen.NUI.Scene3D
 
         /// <summary>
         /// Sets/Gets Orthographic Size of this camera.
-        /// OrthographicSize is height/2 of viewing cube of Orthographic projection.
-        /// Width of viewing cube is internally computed by using aspect ratio of Viewport.
+        /// OrthographicSize depends on <see cref="ProjectionDirection"/> value.
+        /// If ProjectoinDirection is Vertical, OrthographicSize is height/2 of viewing cube of Orthographic projection.
+        /// If ProjectoinDirection is Horizontal, OrthographicSize is width/2 of viewing cube of Orthographic projection.
+        /// Remained Width or Height of viewing cube is internally computed by using aspect ratio of Viewport.
         /// </summary>
         /// <since_tizen> 10 </since_tizen>
         public float OrthographicSize
         {
             get
             {
-                return TopPlaneDistance;
+                return InternalProjectionDirection == ProjectionDirectionType.Vertical ? TopPlaneDistance : RightPlaneDistance;
             }
             set
             {
-                float halfHeight = value;
-                float halfWidth = AspectRatio * value;
+                float halfHeight;
+                float halfWidth;
+                if(InternalProjectionDirection == ProjectionDirectionType.Vertical)
+                {
+                    halfHeight = value;
+                    halfWidth = AspectRatio * value;
+                }
+                else
+                {
+                    halfHeight = value / AspectRatio;
+                    halfWidth = value;
+                }
                 SetValue(TopPlaneDistanceProperty, halfHeight);
                 SetValue(BottomPlaneDistanceProperty, -halfHeight);
                 SetValue(LeftPlaneDistanceProperty, -halfWidth);
@@ -333,6 +396,24 @@ namespace Tizen.NUI.Scene3D
             }
         }
 
+        private ProjectionDirectionType InternalProjectionDirection
+        {
+            get
+            {
+                int returnValue = (int)ProjectionDirectionType.Vertical;
+                PropertyValue projectionDirection = GetProperty(Interop.Camera.ProjectionDirectionGet());
+                projectionDirection?.Get(out returnValue);
+                projectionDirection?.Dispose();
+                return (ProjectionDirectionType)returnValue;
+            }
+            set
+            {
+                PropertyValue setValue = new Tizen.NUI.PropertyValue((int)value);
+                SetProperty(Interop.Camera.ProjectionDirectionGet(), setValue);
+                setValue.Dispose();
+            }
+        }
+
         private float InternalFieldOfView
         {
             get
@@ -574,6 +655,34 @@ namespace Tizen.NUI.Scene3D
         }
 
         /// <summary>
+        /// Convert from vertical fov to horizontal fov consider with camera's AspectRatio.
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Radian ConvertFovFromVerticalToHorizontal(float aspect, Radian verticalFov)
+        {
+            if(verticalFov == null)
+            {
+                return null;
+            }
+            return new Radian(2.0f * (float)Math.Atan(Math.Tan(verticalFov.ConvertToFloat() * 0.5f) * aspect));
+        }
+
+        /// <summary>
+        /// Convert from horizontal fov to vertical fov consider with camera's AspectRatio.
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static Radian ConvertFovFromHorizontalToVertical(float aspect, Radian horizontalFov)
+        {
+            if(horizontalFov == null)
+            {
+                return null;
+            }
+            return new Radian(2.0f * (float)Math.Atan(Math.Tan(horizontalFov.ConvertToFloat() * 0.5f) / aspect));
+        }
+
+        /// <summary>
         /// Release swigCPtr.
         /// </summary>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)