// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using UnityEngine; namespace Microsoft.MixedReality.OpenXR { /// /// A spatial graph node represents a spatially tracked point provided by the driver. /// /// /// There are two types of spatial graph nodes: static and dynamic. /// /// A static spatial graph node tracks the pose of a fixed location in the world. /// The tracking of static nodes may slowly adjust the pose over time for better accuracy /// but the pose is relatively stable in the short term, such as between rendering frames. /// /// A dynamic spatial graph node tracks the pose of a physical object that moves /// continuously relative to reference spaces. The pose of a dynamic spatial graph node /// can be very different within the duration of a rendering frame. /// public class SpatialGraphNode { /// /// Creating a SpatialGraphNode with given static node id, or return null upon failure. /// /// /// The application typically obtains the Guid for the static node /// from other spatial graph driver APIs. For example, a static node id /// representing the tracking of a QR code can be obtained from HoloLens 2 QR code library. /// /// A GUID represents a spatial graph static node. /// Returns either a valid SpatialGraphNode object if succeeded /// or null if the given static node id cannot be found at the moment. public static SpatialGraphNode FromStaticNodeId(System.Guid id) { if (OpenXRContext.Current.IsSessionRunning && NativeLib.TryCreateSpaceFromStaticNodeId(id, out ulong spaceId)) { return new SpatialGraphNode() { Id = id, m_spaceId = spaceId, }; } else { return null; } } /// /// Creating a SpatialGraphNode with given dynamic node id, or return null upon failure. /// /// /// The application typically obtains the Guid for the dynamic node /// from other spatial graph driver APIs. For example, a dynamic node id /// representing the tracking of the Photo and Video camera on HoloLens 2 /// can be obtained from media foundation APIs for the camera. /// /// A GUID represents a spatial graph dynamic node. /// Returns either a valid SpatialGraphNode object if succeeded /// or null if the given dynamic node id cannot be found at the moment. public static SpatialGraphNode FromDynamicNodeId(System.Guid id) { if (OpenXRContext.Current.IsSessionRunning && NativeLib.TryCreateSpaceFromDynamicNodeId(id, out ulong spaceId)) { return new SpatialGraphNode() { Id = id, m_spaceId = spaceId, }; } else { return null; } } /// /// Get the Guid of the SpatialGraphNode /// public System.Guid Id { get; private set; } = System.Guid.Empty; /// /// Locate the SpatialGraphNode at the given frame time. /// The returned pose is in the current Unity scene origin space. /// /// /// Return true if the output pose is actively tracked, or return false indicating the node lost tracking. /// /// /// This function is typically used to locate the spatial graph node used in Unity's render pipeline /// at either OnUpdate or OnBeforeRender callbacks. Providing the correct input frameTime /// allows the runtime to provide correct motion prediction of the tracked node to the display time /// of the current rendering frame. /// /// Specify the to locate the spatial graph node. /// Output the pose when the function returns true. Discard the value if the function returns false. public bool TryLocate(FrameTime frameTime, out Pose pose) { pose = Pose.identity; return OpenXRContext.Current.IsSessionRunning && NativeLib.TryLocateSpatialGraphNodeSpace(m_spaceId, frameTime, out pose); } /// /// Locate the SpatialGraphNode at the given QPC time. /// The returned pose is in the current Unity scene origin space. /// /// /// Return true if the output pose is actively tracked, or return false indicating the node lost tracking. /// /// /// This function is typically used to locate the spatial graph node using historical timestamp /// obtained from other spatial graph APIs, for example the qpcTime of a IMFSample from media /// foundation APIs representing the time when a Photo and Video camera captured the image. /// Providing an accurate qpcTime from the camera sensor allows the runtime to locate precisely /// where the dynamic node was tracked when the image was taken. /// /// Specify the QPC (i.e. query performance counter) time to locate the spatial graph node. /// Output the pose when the function returns true. Discard the value if the function returns false. public bool TryLocate(long qpcTime, out Pose pose) { pose = Pose.identity; return OpenXRContext.Current.IsSessionRunning && NativeLib.TryLocateSpatialGraphNodeSpace(m_spaceId, qpcTime, out pose); } private SpatialGraphNode() { } private ulong m_spaceId = 0; } }