private State() { try { // Initialize logging for the plugin. ZPlugin.InitializeLogging(); // Initialize the zSpace context. this.Context = new ZContext(); // Attempt to retrieve the zSpace display. ZDisplay display = this.Context.DisplayManager.GetDisplay( ZDisplayType.zSpace); // Create and initialize the primary viewport. this.Viewport = this.Context.CreateViewport( (display != null) ? display.Position : Vector2Int.zero); this.IsInitialized = true; } catch { if (Application.isPlaying) { Debug.LogWarning( "Failed to properly initialize the zSpace " + "Provider. Reverting to mock tracker-less, " + "monoscopic 3D."); } this.Dispose(); } }
//////////////////////////////////////////////////////////////////////// // Public Static Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Enables the zSpace XR Overlay. /// </summary> public static void Enable() { EditorWindow gameViewWindow = EditorWindowExtensions.GetGameViewWindow(); // Update the Game View window's title text as an indicator // that the zSpace XR Overlay is enabled. gameViewWindow.titleContent.text = "Game zSpace"; // Parent the GameView window to the XR Overlay. // NOTE: A side effect of calling GetWindowHandle() will // place the associated Editor Window in focus. ZPlugin.SetXROverlayParentWindowHandle( gameViewWindow.GetWindowHandle()); // Register XR Overlay callbacks. ZPlugin.SetXROverlayOnDestroyCallback( Marshal.GetFunctionPointerForDelegate(s_onDestroyedCallback)); // Initialize the XR Overlay's position and size. RectInt rect = gameViewWindow.GetClientRect(); ZPlugin.SetXROverlayDimensions( rect.x, rect.y, rect.width, rect.height); // Create the XR Overlay. ZPlugin.CreateXROverlay(); ZPlugin.SetXROverlayEnabled(true); // Force the application to run in the background while the XR // Overlay is enabled. This is necessary since upon creation, the // XR Overlay steals focus from the GameView window and causes // the application to pause. Application.runInBackground = true; }
/// <summary> /// Start a vibration based on a pattern specified by /// the on period, off period, repeat count, and intensity. /// </summary> /// /// <param name="onPeriod"> /// The time in seconds that the vibration will be active in /// a single cycle. /// </param> /// <param name="offPeriod"> /// The time in seconds that the vibration will be inactive /// in a single cycle. /// </param> /// <param name="numTimes"> /// The number of times to repeat the vibration cycle. /// </param> /// <param name="intensity"> /// The intensity value between 0 and 1 (inclusive) of the vibration. /// The 0 value corresponds to no vibration and 1 corresponds to full /// vibration. /// </param> public void StartVibration( float onPeriod, float offPeriod, int numTimes, float intensity) { ZPlugin.LogOnError(ZPlugin.StartTargetVibration( this._nativePtr, onPeriod, offPeriod, numTimes, intensity), "StartTargetVibration"); }
private void UpdateOverlay() { // If this is not the main camera, early out since // overlay rendering can only support one camera. if (!this.CompareTag("MainCamera")) { return; } // If the XR Overlay is enabled, render to it. if (ZPlugin.IsXROverlayActive() && ZPlugin.IsXROverlayEnabled()) { this.RefreshOverlayTextures(); this.RenderOverlayTextures(); // Set the left and right textures for the XR Overlay. ZPlugin.SetXROverlayTextures( this._leftTexturePtr, this._rightTexturePtr); // Issue plugin event to queue up left and right textures // to be copied and rendered by the XR Overlay. ZPlugin.IssueEvent(ZPluginEvent.QueueXROverlayFrame); } }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Refreshes the internal cache of information corresponding to /// all active displays. /// </summary> /// /// <remarks> /// This method is expensive performance-wise and should be called /// sparingly (if at all). /// </remarks> public void RefreshDisplays() { this.ClearCache(); ZPlugin.LogOnError( ZPlugin.RefreshDisplays(this._context.NativePtr), "RefreshDisplays"); }
/// <summary> /// The ZContext constructor. /// </summary> /// /// <remarks> /// Will throw an exception if the zSpace SDK failed to initialize. /// </remarks> public ZContext() { ZPlugin.ThrowOnError(ZPlugin.Initialize(out this._nativePtr)); this.DisplayManager = new ZDisplayManager(this); this.TargetManager = new ZTargetManager(this); this.MouseEmulator = new ZMouseEmulator(this); this.MouseEmulator.Target = this.TargetManager.StylusTarget; }
/// <summary> /// Gets a boolean value for the specified frustum attribute. /// </summary> /// /// <param name="attribute"> /// The frustum attribute to retrieve the boolean value for. /// </param> /// /// <returns> /// The boolean value for the specified frustum attribute. /// </returns> public bool GetAttributeBool(ZFrustumAttribute attribute) { bool value = false; ZPlugin.LogOnError(ZPlugin.GetFrustumAttributeB( this._nativePtr, attribute, out value), "GetFrustumAttributeB"); return(value); }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Gets the view matrix for the specified eye. /// </summary> /// /// <remarks> /// The view matrix is right-handed because Unity cameras expect /// view matrices to be right-handed. /// </remarks> /// /// <param name="eye"> /// The eye (left, right, or center) to retrieve the view matrix for. /// </param> /// /// <returns> /// The view matrix for the specified eye. /// </returns> public Matrix4x4 GetViewMatrix(ZEye eye) { ZMatrix4 viewMatrix; ZPlugin.LogOnError(ZPlugin.GetFrustumViewMatrix( this._nativePtr, eye, out viewMatrix), "GetFrustumViewMatrix"); return(viewMatrix.ToMatrix4x4(false)); }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Gets whether the specified button is pressed. /// </summary> /// /// <param name="id"> /// The integer id of the specified button. /// </param> /// /// <returns> /// True if the specified button is pressed. False otherwise. /// </returns> public bool IsButtonPressed(int id) { bool isPressed = false; ZPlugin.LogOnError(ZPlugin.IsTargetButtonPressed( this._nativePtr, id, out isPressed), "IsTargetButtonPressed"); return(isPressed); }
/// <summary> /// Gets a reference to a trackable target of a specified type at a /// specified index. /// </summary> /// /// <param name="targetType"> /// The target type. /// </param> /// <param name="index"> /// The index to retrieve the target at. /// </param> /// /// <returns> /// A reference to the trackable target if found. Null otherwise. /// </returns> public ZTarget GetTarget(ZTargetType targetType, int index = 0) { IntPtr targetNativePtr = IntPtr.Zero; ZPlugin.LogOnError(ZPlugin.GetTargetByType( this._context.NativePtr, targetType, index, out targetNativePtr), "GetTargetByType"); return(this.GetOrCreateCachedResource(targetNativePtr)); }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Gets the associated mouse button that is mapped to the specified /// button id. /// </summary> /// /// <param name="buttonId"> /// The id of the button to retrieve the associated mouse button for. /// </param> /// /// <returns> /// The mouse button mapped to the specified button id. /// </returns> public ZMouseButton GetButtonMapping(int buttonId) { ZMouseButton mouseButton = ZMouseButton.Unknown; ZPlugin.LogOnError(ZPlugin.GetMouseEmulationButtonMapping( this._context.NativePtr, buttonId, out mouseButton), "GetMouseEmulationButtonMapping"); return(mouseButton); }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Performs a raycast against the display using a ray generated /// from the specified tracker space pose. /// </summary> /// /// <param name="pose"> /// The tracker space pose to base the ray on. /// </param> /// /// <returns> /// The result of the raycast. /// </returns> public ZDisplayIntersectionInfo Raycast(Pose pose) { ZDisplayIntersectionInfo intersectionInfo; ZPlugin.LogOnError(ZPlugin.IntersectDisplay( this._nativePtr, pose.ToZPose(), out intersectionInfo), "IntersectDisplay"); return(intersectionInfo); }
/// <summary> /// Gets a float value for the specified frustum attribute. /// </summary> /// /// <param name="attribute"> /// The frustum attribute to retrieve the float value for. /// </param> /// /// <returns> /// The float value for the specified frustum attribute. /// </returns> public float GetAttributeFloat(ZFrustumAttribute attribute) { float value = 0; ZPlugin.LogOnError(ZPlugin.GetFrustumAttributeF32( this._nativePtr, attribute, out value), "GetFrustumAttributeF32"); return(value); }
/// <summary> /// Gets the frustum planes (left, right, top, bottom, near, and far) /// for the specified eye. /// </summary> /// /// <param name="eye"> /// The eye (left, right, or center) to retrieve the frustum /// planes for. /// </param> /// /// <returns> /// The frustum planes for the specified eye. /// </returns> public FrustumPlanes GetPlanes(ZEye eye) { ZFrustumBounds bounds; ZPlugin.LogOnError( ZPlugin.GetFrustumBounds(this._nativePtr, eye, out bounds), "GetFrustumBounds"); return(bounds.ToFrustumPlanes()); }
/// <summary> /// Gets the projection matrix for the specified eye. /// </summary> /// /// <remarks> /// The projection matrix is right-handed because Unity cameras /// expect projection matrices to be right-handed. /// </remarks> /// /// <param name="eye"> /// The eye (left, right, or center) to retrieve the projection /// matrix for. /// </param> /// /// <returns> /// The projection matrix for the specified eye. /// </returns> public Matrix4x4 GetProjectionMatrix(ZEye eye) { ZMatrix4 projectionMatrix; ZPlugin.LogOnError(ZPlugin.GetFrustumProjectionMatrix( this._nativePtr, eye, out projectionMatrix), "GetFrustumProjectionMatrix"); return(projectionMatrix.ToMatrix4x4(false)); }
/// <summary> /// Gets a display based on a specified index. /// </summary> /// /// <param name="index"> /// The index to retrieve the display for. /// </param> /// /// <returns> /// The display at the specified index. /// </returns> public ZDisplay GetDisplay(int index) { IntPtr displayNativePtr = IntPtr.Zero; ZPlugin.LogOnError(ZPlugin.GetDisplayByIndex( this._context.NativePtr, index, out displayNativePtr), "GetDisplayByIndex"); return(this.GetOrCreateCachedResource(displayNativePtr)); }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Gets the number of trackable targets of a specified type that /// are currently supported. /// </summary> /// /// <param name="targetType"> /// The target type. /// </param> /// /// <returns> /// The number of supported trackable targets of a specified type. /// </returns> public int GetNumTargets(ZTargetType targetType) { int numTargets = 0; ZPlugin.LogOnError(ZPlugin.GetNumTargetsByType( this._context.NativePtr, targetType, out numTargets), "GetNumTargetsByType"); return(numTargets); }
/// <summary> /// Gets the number of displays of a specified type that are /// currently active. /// </summary> /// /// <param name="displayType"> /// The display type. /// </param> /// /// <returns> /// The number of displays of a specified type that are currently /// active. /// </returns> public int GetNumDisplays(ZDisplayType displayType) { int numDisplays = 0; ZPlugin.LogOnError(ZPlugin.GetNumDisplaysByType( this._context.NativePtr, displayType, out numDisplays), "GetNumDisplaysByType"); return(numDisplays); }
/// <summary> /// Gets the number of displays that are currently active. /// </summary> /// /// <returns> /// The number of displays that are currently active. /// </returns> public int GetNumDisplays() { int numDisplays = 0; ZPlugin.LogOnError( ZPlugin.GetNumDisplays(this._context.NativePtr, out numDisplays), "GetNumDisplays"); return(numDisplays); }
/// <summary> /// Get the position of the specified eye in the specified /// coordinate space. /// </summary> /// /// <param name="eye"> /// The eye (left, right, or center) to retrieve the position for. /// </param> /// <param name="coordinateSpace"> /// The coordinate space (Tracker, Display, Viewport, or Camera) /// to retrieve the eye position in. /// </param> /// /// <returns> /// The position of the specified eye in the specified /// coordinate space. /// </returns> public Vector3 GetEyePosition( ZEye eye, ZCoordinateSpace coordinateSpace) { ZVector3 eyePosition; ZPlugin.LogOnError(ZPlugin.GetFrustumEyePosition( this._nativePtr, eye, coordinateSpace, out eyePosition), "GetFrustumEyePosition"); return(eyePosition.ToVector3()); }
//////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////// public void Dispose() { this.Viewport?.Dispose(); this.Context?.Dispose(); this.Viewport = null; this.Context = null; this.IsInitialized = false; ZPlugin.ShutDownLogging(); }
public ZViewport(IntPtr nativePtr) : base(nativePtr) { // Retrieve and cache the frustum handle. IntPtr frustumNativePtr = IntPtr.Zero; ZPlugin.LogOnError( ZPlugin.GetFrustum(nativePtr, out frustumNativePtr), "GetFrustum"); this.Frustum = new ZFrustum(this, frustumNativePtr); }
/// <summary> /// Disables the zSpace XR Overlay. /// </summary> public static void Disable() { // Restore the Game View window's title text. EditorWindow gameViewWindow = EditorWindowExtensions.GetGameViewWindow(); gameViewWindow.titleContent.text = s_gameViewName; // Restore whether the application was original set to run in // the background. Application.runInBackground = s_runInBackground; // Shut down and destroy the XR Overlay. ZPlugin.DestroyXROverlay(); }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Gets the transformation matrix that represents the mapping /// between two specified coordinate spaces. /// </summary> /// /// <param name="from"> /// The coordinate space to map from. /// </param> /// <param name="to"> /// The coordinate space to map to. /// </param> /// /// <returns> /// The coordinate space transformation matrix. /// </returns> public Matrix4x4 GetCoordinateSpaceTransform( ZCoordinateSpace from, ZCoordinateSpace to) { if (from == to) { return(Matrix4x4.identity); } ZMatrix4 matrix; ZPlugin.LogOnError(ZPlugin.GetCoordinateSpaceTransform( this._nativePtr, from, to, out matrix), "GetCoordinateSpaceTransform"); return(matrix.ToMatrix4x4()); }
//////////////////////////////////////////////////////////////////////// // Private Static Methods //////////////////////////////////////////////////////////////////////// private static void OnUpdate() { if (!Application.isPlaying || !EditorPrefs.GetBool(ZMenu.EnableXROverlayMenuItem)) { return; } // Check if there is a pending recreate request and if // so, recreate the XR Overlay. if (s_recreateRequest) { Enable(); s_recreateRequest = false; } // If the XR Overlay is active, update it. if (ZPlugin.IsXROverlayActive()) { EditorWindow gameViewWindow = EditorWindowExtensions.GetGameViewWindow(); // Update the XR Overlay's position and size. RectInt rect = gameViewWindow.GetClientRect(); ZPlugin.SetXROverlayDimensions( rect.x, rect.y, rect.width, rect.height); // Update whether the XR Overlay is enabled based on whether // it is currently overlapped. bool isGameViewFocused = gameViewWindow.IsFocused(); bool isGameViewOverlapped = gameViewWindow.IsOverlappedBy( EditorWindow.focusedWindow); if (isGameViewFocused) { ZPlugin.SetXROverlayEnabled(true); } else if (isGameViewOverlapped) { ZPlugin.SetXROverlayEnabled(false); } } }
/// <summary> /// Gets the string value of the specified display attribute. /// </summary> /// /// <param name="attribute"> /// The attribute to retrieve the string value for. /// </param> /// /// <returns> /// The string value of the specified display attribute. /// </returns> public string GetAttribute(ZDisplayAttribute attribute) { // Get the string attribute size. int size = 0; ZPlugin.LogOnError(ZPlugin.GetDisplayAttributeStrSize( this._nativePtr, attribute, out size), "GetDisplayAttributeStrSize"); // Get the string attribute value. StringBuilder buffer = new StringBuilder(size); ZPlugin.LogOnError(ZPlugin.GetDisplayAttributeStr( this._nativePtr, attribute, buffer, size), "GetDisplayAttributeStr"); return(buffer.ToString()); }
//////////////////////////////////////////////////////////////////////// // Protected Methods //////////////////////////////////////////////////////////////////////// protected override void Dispose(bool disposing) { if (this._isDisposed) { return; } this._isDisposed = true; // Free managed objects. if (disposing) { this.Frustum = null; } ZPlugin.LogOnError(ZPlugin.DestroyViewport(this._nativePtr), "DestroyViewport"); base.Dispose(disposing); }
//////////////////////////////////////////////////////////////////////// // Protected Methods //////////////////////////////////////////////////////////////////////// protected override void Dispose(bool disposing) { if (this._isDisposed) { return; } this._isDisposed = true; // Free managed objects. if (disposing) { this.DisplayManager.ClearCache(); this.TargetManager.ClearCache(); } // Free unmanaged objects. ZPlugin.LogOnError(ZPlugin.ShutDown(this._nativePtr), "ShutDown"); // Call to base class implementation. base.Dispose(disposing); }
/// <summary> /// Creates an instance of the ZViewport class at the specified /// virtual desktop position. /// </summary> /// /// <param name="position"> /// The (x, y) virtual desktop position in pixels corresponding /// to the viewport's top-left corner. /// </param> /// /// <returns> /// An instance of the ZViewport class. /// </returns> public ZViewport CreateViewport(Vector2Int position) { // Create the viewport. IntPtr viewportNativePtr; ZPlugin.LogOnError( ZPlugin.CreateViewport(this._nativePtr, out viewportNativePtr), "CreateViewport"); ZViewport viewport = new ZViewport(viewportNativePtr); viewport.Position = position; // Update the context to ensure the appropriate display // angle has been passed to the viewport's frustum. this.Update(); // Initialize the frustum. ZFrustum frustum = viewport.Frustum; frustum.HeadPose = frustum.DefaultHeadPose; return(viewport); }
//////////////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////////////// /// <summary> /// Updates the internal state of the context. /// </summary> /// /// <remarks> /// In general, this method should only be called once per frame. /// /// The update is responsible for capturing the latest tracking /// information, forwarding the latest head pose information to all /// active frustums, etc. /// </remarks> public void Update() { ZPlugin.LogOnError(ZPlugin.Update(this._nativePtr), "Update"); }