// 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;
}
}