//////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2007-2020 , Inc. All Rights Reserved. // //////////////////////////////////////////////////////////////////////////////// using UnityEngine; using GCSeries.Core.Sdk; using GCSeries.Core.Utility; namespace GCSeries.Core { [ExecuteInEditMode] [DefaultExecutionOrder(ScriptPriority)] [DisallowMultipleComponent] public sealed partial class ZProvider : ZSingleton { public const int ScriptPriority = -1000; //////////////////////////////////////////////////////////////////////// // Inspector Fields //////////////////////////////////////////////////////////////////////// [Header("Screen Metrics")] [SerializeField] [Tooltip( "The profile of the reference display the application is being " + "designed for.")] private ZDisplay.Profile _displayReferenceProfile = ZDisplay.ReferenceProfile; [SerializeField] [Tooltip("The display reference size in meters.")] private Vector2 _displayReferenceSize = ZDisplay.GetSize(ZDisplay.ReferenceProfile); [SerializeField] [Tooltip("The display reference resolution in pixels.")] private Vector2Int _displayReferenceResolution = ZDisplay.GetNativeResolution(ZDisplay.ReferenceProfile); //////////////////////////////////////////////////////////////////////// // MonoBehaviour Callbacks //////////////////////////////////////////////////////////////////////// protected override void Awake() { base.Awake(); // Perform an update to initialize state. this.Update(); } protected override void OnApplicationQuit() { base.OnApplicationQuit(); State.ShutDown(); } private void Update() { if (IsInitialized) { RectInt windowRect = ZApplicationWindow.Rect; // Update the viewport's position and size based on the // current position and size of the application window. Viewport.Rect = windowRect; // Get the current display based on the center position // of the application window. if (!windowRect.Equals(this._previousWindowRect)) { CurrentDisplay = Context.DisplayManager.GetDisplay( (int)windowRect.center.x, (int)windowRect.center.y); } // Update the SDK's context. Context.Update(); this._previousWindowRect = windowRect; } this.UpdateScreenMetrics(); } //////////////////////////////////////////////////////////////////////// // Public Static Properties //////////////////////////////////////////////////////////////////////// /// /// Checks whether the provider has been properly initialized. /// /// /// /// In the scenario that the application is running on a non- /// device, is running on a system that doesn't have the System /// Software installed, etc., IsInitialized will be set to false. /// /// Please make sure to check this before attempting to retrieve /// the Context, HeadTarget, StylusTarget, and/or Viewport. /// public static bool IsInitialized => State.Instance.IsInitialized; /// /// Gets a reference to the SDK's primary context. /// /// /// /// The primary context will persist for the lifetime of the /// application. /// /// If ZProvider.IsInitialized is false, this property will be /// set to null. /// public static ZContext Context => State.Instance.Context; /// /// Gets a reference to the default head target (glasses). /// /// /// /// If ZProvider.IsInitialized is false, this property will be /// set to null. /// public static ZTarget HeadTarget => Context?.TargetManager.HeadTarget; /// /// Gets a reference to the default stylus target. /// /// /// /// If ZProvider.IsInitialized is false, this property will be /// set to null. /// public static ZTarget StylusTarget => Context?.TargetManager.StylusTarget; /// /// Gets a reference to the primary viewport. /// /// /// /// The viewport is responsible for managing information about the /// application window's position and size. /// /// Additionally, it manages the application's stereo frustum, which /// is responsible for computing the perspectives for the left and /// right eyes. /// /// If ZProvider.IsInitialized is false, this property will be /// set to null. /// public static ZViewport Viewport => State.Instance.Viewport; /// /// Gets the display that the application window is currently on. /// /// /// /// The center of the application window's viewport is used to /// determine which display it's currently on. /// /// If ZProvider.IsInitialized is false, this property will be /// set to null. /// public static ZDisplay CurrentDisplay { get; private set; } = null; /// /// The display reference size in meters. /// /// /// /// This is leveraged in use cases such as computing display scale /// factor. /// public static Vector2 DisplayReferenceSize { get; private set; } = ZDisplay.GetSize(ZDisplay.ReferenceProfile); /// /// The display reference resolution in pixels. /// public static Vector2Int DisplayReferenceResolution { get; private set; } = ZDisplay.GetNativeResolution(ZDisplay.ReferenceProfile); /// /// The current display size in meters. /// /// /// /// If ZProvider.IsInitialized is set to false, the DisplaySize will /// be set to the DisplayReferenceSize. /// public static Vector2 DisplaySize { get; private set; } = ZDisplay.GetSize(ZDisplay.ReferenceProfile); /// /// The current display resolution in pixels. /// /// /// /// If ZProvider.IsInitialized is set to false, the DisplayResolution /// will be set to the DisplayReferenceResolution. /// public static Vector2Int DisplayResolution { get; private set; } = ZDisplay.GetNativeResolution(ZDisplay.ReferenceProfile); /// /// The meters per pixel conversion factor computed from the current /// DisplaySize and DisplayResolution. /// public static Vector2 DisplayMetersPerPixel { get; set; } = ZDisplay.GetMetersPerPixel(ZDisplay.ReferenceProfile); /// /// The scale of the current display based on its size relative to the /// DisplayReferenceSize. /// public static Vector2 DisplayScale { get; private set; } = Vector2.one; /// /// The scale factor of the current display based on the DisplayScale. /// /// /// /// The current and only scale mode that is supported is "fit inside". /// public static float DisplayScaleFactor { get; set; } = 1; /// /// The size of the application window in meters. /// /// /// /// If ZProvider.IsInitialized is set to false, the window size (and /// aspect ratio) is locked to the display reference size. /// public static Vector2 WindowSize { get; private set; } = ZDisplay.GetSize(ZDisplay.ReferenceProfile); /// /// The size of the application window in pixels. /// /// /// /// If ZProvider.IsInitialized is set to false, the window size in /// pixels is locked to the display reference resolution. /// public static Vector2Int WindowSizePixels { get; private set; } = ZDisplay.GetNativeResolution(ZDisplay.ReferenceProfile); //////////////////////////////////////////////////////////////////////// // Private Methods //////////////////////////////////////////////////////////////////////// private void UpdateScreenMetrics() { // If the display reference profile is not custom, lock // the display reference size to the appropriate value. if (this._displayReferenceProfile != ZDisplay.Profile.Custom) { this._displayReferenceSize = ZDisplay.GetSize( this._displayReferenceProfile); this._displayReferenceResolution = ZDisplay.GetNativeResolution( this._displayReferenceProfile); } this._displayReferenceSize = Vector2.Max( ZDisplay.MinimumSize, this._displayReferenceSize); this._displayReferenceResolution = Vector2Int.Max( Vector2Int.one, this._displayReferenceResolution); // Update current display information. DisplayReferenceSize = this._displayReferenceSize; DisplayReferenceResolution = this._displayReferenceResolution; DisplaySize = CurrentDisplay?.Size ?? this._displayReferenceSize; DisplayResolution = CurrentDisplay?.NativeResolution ?? this._displayReferenceResolution; DisplayMetersPerPixel = new Vector2( DisplaySize.x / DisplayResolution.x, DisplaySize.y / DisplayResolution.y); DisplayScale = ZDisplay.GetScale(DisplayReferenceSize, DisplaySize); DisplayScaleFactor = Mathf.Min(DisplayScale.x, DisplayScale.y); // Update current window information. if (IsInitialized) { WindowSizePixels = ZApplicationWindow.Size; WindowSize = WindowSizePixels * DisplayMetersPerPixel; } else { WindowSizePixels = DisplayResolution; WindowSize = DisplaySize; } } //////////////////////////////////////////////////////////////////////// // Private Members //////////////////////////////////////////////////////////////////////// private RectInt _previousWindowRect; } }