Native Mixed Reality-Interop in Unity
Jede Mixed Reality-App erhält ein HolographicSpace , bevor sie mit dem Empfangen von Kameradaten und Renderingframes beginnt. In Unity kümmert sich das Modul um diese Schritte für Sie, die Behandlung von Holographic-Objekten und die interne Aktualisierung als Teil der Renderschleife.
In erweiterten Szenarien müssen Sie jedoch möglicherweise Zugriff auf die zugrunde liegenden nativen Objekte erhalten, z . B. HolographicCamera und aktuelle HolographicFrame.
WindowsMixedRealityUtilities
Namespace: Microsoft.MixedReality.Toolkit.WindowsMixedReality
Typ: WindowsMixedRealityUtilities
MRTK bietet bereits ge marshallte Typen sowohl für ältere WSA- als auch für XR-SDK über die WindowsMixedRealityUtilities-Klasse .
public static HolographicFrame CurrentHolographicFrame { get; }
public static SpatialCoordinateSystem SpatialCoordinateSystem { get; }
public static SpatialInteractionManager SpatialInteractionManager { get; }
Entmarshaling nativer Zeiger
Verwenden Sie nach dem IntPtr
Abrufen einer der oben genannten Methoden (nicht erforderlich für MRTK) die folgenden Codeausschnitte, um sie zu verwalteten Objekten zu marshallen.
Wenn Sie Microsoft.Windows.MixedReality.DotNetWinRT verwenden, können Sie mithilfe der FromNativePtr()
Methode ein verwaltetes Objekt aus einem systemeigenen Zeiger erstellen:
var worldOrigin = Microsoft.Windows.Perception.Spatial.SpatialCoordinateSystem.FromNativePtr(spatialCoordinateSystemPtr);
Verwenden Marshal.GetObjectForIUnknown()
Und umwandeln Sie andernfalls den gewünschten Typ:
#if ENABLE_WINMD_SUPPORT
var worldOrigin = Marshal.GetObjectForIUnknown(spatialCoordinateSystemPtr) as Windows.Perception.Spatial.SpatialCoordinateSystem;
#endif
Konvertieren zwischen Koordinatensystemen
Unity verwendet ein linkshändiges Koordinatensystem, während die Windows-Wahrnehmungs-APIs rechtshändige Koordinatensysteme verwenden. Um zwischen diesen beiden Konventionen zu konvertieren, können Sie die folgenden Hilfsprogramme verwenden:
namespace NumericsConversion
{
public static class NumericsConversionExtensions
{
public static UnityEngine.Vector3 ToUnity(this System.Numerics.Vector3 v) => new UnityEngine.Vector3(v.X, v.Y, -v.Z);
public static UnityEngine.Quaternion ToUnity(this System.Numerics.Quaternion q) => new UnityEngine.Quaternion(q.X, q.Y, -q.Z, -q.W);
public static UnityEngine.Matrix4x4 ToUnity(this System.Numerics.Matrix4x4 m) => new UnityEngine.Matrix4x4(
new Vector4( m.M11, m.M12, -m.M13, m.M14),
new Vector4( m.M21, m.M22, -m.M23, m.M24),
new Vector4(-m.M31, -m.M32, m.M33, -m.M34),
new Vector4( m.M41, m.M42, -m.M43, m.M44));
public static System.Numerics.Vector3 ToSystem(this UnityEngine.Vector3 v) => new System.Numerics.Vector3(v.x, v.y, -v.z);
public static System.Numerics.Quaternion ToSystem(this UnityEngine.Quaternion q) => new System.Numerics.Quaternion(q.x, q.y, -q.z, -q.w);
public static System.Numerics.Matrix4x4 ToSystem(this UnityEngine.Matrix4x4 m) => new System.Numerics.Matrix4x4(
m.m00, m.m10, -m.m20, m.m30,
m.m01, m.m11, -m.m21, m.m31,
-m.m02, -m.m12, m.m22, -m.m32,
m.m03, m.m13, -m.m23, m.m33);
}
}
Verwenden systemeigener HolographicFrame-Daten
Hinweis
Das Ändern des Zustands der systemeigenen Objekte, die über HolographicFrameNativeData empfangen werden, kann zu unvorhersehbaren Verhaltensweisen und Renderingartefakten führen, insbesondere, wenn Unity auch gründe für diesen Zustand. Sie sollten z. B. holographicFrame.UpdateCurrentPrediction nicht aufrufen, oder die Posenvorhersage, die Unity mit diesem Frame rendert, ist nicht synchron mit der von Windows erwarteten Pose, was die Stabilität des Hologramms verringert.
Wenn Sie Zugriff auf systemeigene Schnittstellen zum Rendern oder Debuggen benötigen, verwenden Sie Daten aus HolographicFrameNativeData in Ihren nativen Plug-Ins oder C#-Code.
Hier ist ein Beispiel dafür, wie Sie HolographicFrameNativeData verwenden können, um die Vorhersage des aktuellen Frames für photonenzeit mithilfe der XR SDK-Erweiterungen abzurufen.
using System;
using System.Runtime.InteropServices;
public static bool GetCurrentFrameDateTime(out DateTime frameDateTime)
{
#if ENABLE_WINMD_SUPPORT
IntPtr holographicFramePtr = UnityEngine.XR.WindowsMR.WindowsMREnvironment.CurrentHolographicRenderFrame;
if (holographicFramePtr != IntPtr.Zero)
{
var holographicFrame = Marshal.GetObjectForIUnknown(holographicFramePtr) as Windows.Graphics.Holographic.HolographicFrame;
frameDateTime = holographicFrame.CurrentPrediction.Timestamp.TargetTime.DateTime;
return true;
}
#endif
frameDateTime = DateTime.MinValue;
return false;
}