//////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2007-2020 , Inc. All Rights Reserved. // //////////////////////////////////////////////////////////////////////////////// using System; using UnityEngine; using GCSeries.Core.Extensions; using GCSeries.Core.Interop; namespace GCSeries.Core.Sdk { public class ZFrustum : ZNativeResource { public ZFrustum(ZViewport viewport, IntPtr nativePtr) : base(nativePtr) { this._viewport = viewport; this.CameraOffset = DefaultCameraOffset; this.DisplayEulerAngles = ZDisplay.DefaultEulerAngles; this.PortalModeFlags = ZPortalMode.None; } //////////////////////////////////////////////////////////////////////// // Public Static Members //////////////////////////////////////////////////////////////////////// public static readonly float DefaultIpd = 0.06f; public static readonly float DefaultNearClip = 0.03f; public static readonly float DefaultFarClip = 100.0f; public static readonly Vector3 DefaultCameraOffset = Vector3.back * 0.25f; public static readonly float CoupledZoneDepth = -0.13f; public static readonly float UncoupledZoneDepth = 0.3f; //////////////////////////////////////////////////////////////////////// // Public Properties //////////////////////////////////////////////////////////////////////// /// /// Gets/sets the physical separation, or inter-pupillary distance, /// between the eyes in meters. (Default: 0.06) /// public float Ipd { get { return this.GetAttributeFloat(ZFrustumAttribute.Ipd); } set { this.SetAttribute(ZFrustumAttribute.Ipd, value); } } /// /// Gets/sets the near clipping plane for the frustum in meters. /// (Default: 0.03) /// public float NearClip { get { return this.GetAttributeFloat(ZFrustumAttribute.NearClip); } set { this.SetAttribute(ZFrustumAttribute.NearClip, value); } } /// /// Gets/sets the far clipping plane for the frustum in meters. /// (Default: 1000) /// public float FarClip { get { return this.GetAttributeFloat(ZFrustumAttribute.FarClip); } set { this.SetAttribute(ZFrustumAttribute.FarClip, value); } } /// /// Gets/sets the display's desired euler angles in degrees about the /// X, Y, and Z axes. These angles are only used when PortalMode.Angle /// is not enabled on the frustum. (Default: [x=90, y=0, z=0]) /// public Vector3 DisplayEulerAngles { get { float x = this.GetAttributeFloat( ZFrustumAttribute.DisplayAngleX); float y = this.GetAttributeFloat( ZFrustumAttribute.DisplayAngleY); float z = this.GetAttributeFloat( ZFrustumAttribute.DisplayAngleZ); return new Vector3(x, y, z); } set { this.SetAttribute(ZFrustumAttribute.DisplayAngleX, value.x); this.SetAttribute(ZFrustumAttribute.DisplayAngleY, value.y); this.SetAttribute(ZFrustumAttribute.DisplayAngleZ, value.z); } } /// /// Gets/sets the offset of the camera in meters relative to the /// center of the application window's viewport. This offset is /// used when computing the transformation from viewport to camera /// space. (Default: [x=0, y=0, z=-0.25]) /// public Vector3 CameraOffset { get { ZVector3 cameraOffset; ZPlugin.LogOnError(ZPlugin.GetFrustumCameraOffset( this._nativePtr, out cameraOffset), "GetFrustumCameraOffset"); return cameraOffset.ToVector3(); } set { ZPlugin.LogOnError(ZPlugin.SetFrustumCameraOffset( this._nativePtr, value.ToZVector3()), "SetFrustumCameraOffset"); } } /// /// Gets/sets the flags leveraged to enable features such as /// angle-awareness. /// /// /// /// In portal mode, the scene is fixed relative to the physical /// world, not the viewport. Refer to ZPortalMode for details on /// portal modes available. /// public ZPortalMode PortalModeFlags { get { ZPortalMode portalModeFlags = ZPortalMode.None; ZPlugin.LogOnError(ZPlugin.GetFrustumPortalMode( this._nativePtr, out portalModeFlags), "GetFrustumPortalMode"); return portalModeFlags; } private set { ZPlugin.LogOnError( ZPlugin.SetFrustumPortalMode(this._nativePtr, value), "SetFrustumPortalMode"); } } /// /// Gets/sets the frustum's current head pose. /// public Pose HeadPose { get { ZPose headPose; ZPlugin.LogOnError( ZPlugin.GetFrustumHeadPose(this._nativePtr, out headPose), "GetFrustumHeadPose"); return headPose.ToPose(); } set { ZPlugin.LogOnError(ZPlugin.SetFrustumHeadPose( this._nativePtr, value.ToZPose()), "SetFrustumHeadPose"); } } /// /// Computes the default head pose for most optimal /// viewing perspective. /// public Pose DefaultHeadPose { get { Matrix4x4 displayToTrackerMatrix = this._viewport.GetCoordinateSpaceTransform( ZCoordinateSpace.Display, ZCoordinateSpace.Tracker); // Create the pose in display space. Pose pose = new Pose( Vector3.back * this.CameraOffset.magnitude, Quaternion.identity); // Transform the pose to tracker space before // it is returned. return pose.GetTransformedBy(displayToTrackerMatrix); } } //////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// /// Gets the view matrix for the specified eye. /// /// /// /// The view matrix is right-handed because Unity cameras expect /// view matrices to be right-handed. /// /// /// /// The eye (left, right, or center) to retrieve the view matrix for. /// /// /// /// The view matrix for the specified eye. /// public Matrix4x4 GetViewMatrix(ZEye eye) { ZMatrix4 viewMatrix; ZPlugin.LogOnError(ZPlugin.GetFrustumViewMatrix( this._nativePtr, eye, out viewMatrix), "GetFrustumViewMatrix"); return viewMatrix.ToMatrix4x4(false); } /// /// Gets a scaled view matrix for the specified eye. /// /// /// /// The view matrix is right-handed because Unity cameras expect /// view matrices to be right-handed. /// /// /// /// The eye (left, right, or center) to retrieve the view matrix for. /// /// /// The scale to apply to the resultant view matrix. /// /// /// /// The scaled view matrix for the specified eye. /// public Matrix4x4 GetViewMatrix(ZEye eye, Vector3 scale) { Matrix4x4 viewMatrix = Matrix4x4.Scale(scale) * this.GetViewMatrix(eye); return viewMatrix.ToPoseMatrix(); } /// /// Gets the projection matrix for the specified eye. /// /// /// /// The projection matrix is right-handed because Unity cameras /// expect projection matrices to be right-handed. /// /// /// /// The eye (left, right, or center) to retrieve the projection /// matrix for. /// /// /// /// The projection matrix for the specified eye. /// public Matrix4x4 GetProjectionMatrix(ZEye eye) { ZMatrix4 projectionMatrix; ZPlugin.LogOnError(ZPlugin.GetFrustumProjectionMatrix( this._nativePtr, eye, out projectionMatrix), "GetFrustumProjectionMatrix"); return projectionMatrix.ToMatrix4x4(false); } /// /// Gets the frustum planes (left, right, top, bottom, near, and far) /// for the specified eye. /// /// /// /// The eye (left, right, or center) to retrieve the frustum /// planes for. /// /// /// /// The frustum planes for the specified eye. /// public FrustumPlanes GetPlanes(ZEye eye) { ZFrustumBounds bounds; ZPlugin.LogOnError( ZPlugin.GetFrustumBounds(this._nativePtr, eye, out bounds), "GetFrustumBounds"); return bounds.ToFrustumPlanes(); } /// /// Get the position of the specified eye in the specified /// coordinate space. /// /// /// /// The eye (left, right, or center) to retrieve the position for. /// /// /// The coordinate space (Tracker, Display, Viewport, or Camera) /// to retrieve the eye position in. /// /// /// /// The position of the specified eye in the specified /// coordinate space. /// public Vector3 GetEyePosition( ZEye eye, ZCoordinateSpace coordinateSpace) { ZVector3 eyePosition; ZPlugin.LogOnError(ZPlugin.GetFrustumEyePosition( this._nativePtr, eye, coordinateSpace, out eyePosition), "GetFrustumEyePosition"); return eyePosition.ToVector3(); } /// /// Gets a float value for the specified frustum attribute. /// /// /// /// The frustum attribute to retrieve the float value for. /// /// /// /// The float value for the specified frustum attribute. /// public float GetAttributeFloat(ZFrustumAttribute attribute) { float value = 0; ZPlugin.LogOnError(ZPlugin.GetFrustumAttributeF32( this._nativePtr, attribute, out value), "GetFrustumAttributeF32"); return value; } /// /// Gets a boolean value for the specified frustum attribute. /// /// /// /// The frustum attribute to retrieve the boolean value for. /// /// /// /// The boolean value for the specified frustum attribute. /// public bool GetAttributeBool(ZFrustumAttribute attribute) { bool value = false; ZPlugin.LogOnError(ZPlugin.GetFrustumAttributeB( this._nativePtr, attribute, out value), "GetFrustumAttributeB"); return value; } /// /// Sets the float value for the specified frustum attribute. /// /// /// /// The frustum attribute to update. /// /// /// The float value to update the frustum attribute with. /// public void SetAttribute(ZFrustumAttribute attribute, float value) { ZPlugin.LogOnError(ZPlugin.SetFrustumAttributeF32( this._nativePtr, attribute, value), "SetFrustumAttributeF32"); } /// /// Sets the boolean value for the specified frustum attribute. /// /// /// /// The frustum attribute to update. /// /// /// The boolean value to update the frustum attribute with. /// public void SetAttribute(ZFrustumAttribute attribute, bool value) { ZPlugin.LogOnError(ZPlugin.SetFrustumAttributeB( this._nativePtr, attribute, value), "SetFrustumAttributeB"); } //////////////////////////////////////////////////////////////////////// // Private Members //////////////////////////////////////////////////////////////////////// private ZViewport _viewport = null; } }