Mixed Reality inbyggt interop i Unity

Varje Mixed Reality app får en HolographicSpace innan den börjar ta emot kameradata och återgivningsramar. I Unity tar motorn hand om dessa steg åt dig, hanterar holografiska objekt och uppdaterar internt som en del av återgivningsloopen.

I avancerade scenarier kan du dock behöva få åtkomst till de underliggande inbyggda objekten, till exempel HolographicCamera och aktuell HolographicFrame.

WindowsMixedRealityUtilities

Namespace:Microsoft.MixedReality.Toolkit.WindowsMixedReality
Typ:WindowsMixedRealityUtilities

MRTK tillhandahåller redan samlade typer över både äldre WSA och XR SDK via klassen WindowsMixedRealityUtilities .

public static HolographicFrame CurrentHolographicFrame { get; }
public static SpatialCoordinateSystem SpatialCoordinateSystem { get; }
public static SpatialInteractionManager SpatialInteractionManager { get; }

Ta bort inbyggda pekare

När du har hämtat IntPtr från någon av metoderna ovan (behövs inte för MRTK) använder du följande kodfragment för att konvertera dem till hanterade objekt.

Om du använder Microsoft.Windows.MixedReality.DotNetWinRT kan du skapa ett hanterat objekt från en inbyggd pekare med hjälp av FromNativePtr() metoden:

var worldOrigin = Microsoft.Windows.Perception.Spatial.SpatialCoordinateSystem.FromNativePtr(spatialCoordinateSystemPtr);

Annars kan du använda Marshal.GetObjectForIUnknown() och casta till den typ du vill ha:

#if ENABLE_WINMD_SUPPORT
var worldOrigin = Marshal.GetObjectForIUnknown(spatialCoordinateSystemPtr) as Windows.Perception.Spatial.SpatialCoordinateSystem;
#endif

Konvertera mellan koordinatsystem

Unity använder ett vänsterhänt koordinatsystem, medan Api:erna för Windows Perception använder högerhänta koordinatsystem. Om du vill konvertera mellan dessa två konventioner kan du använda följande hjälpverktyg:

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

Använda interna HolographicFrame-data

Anteckning

Om du ändrar tillståndet för de inbyggda objekt som tas emot via HolographicFrameNativeData kan det orsaka oförutsägbart beteende och återgivning av artefakter, särskilt om Unity också resonerar om samma tillstånd. Du bör till exempel inte anropa HolographicFrame.UpdateCurrentPrediction, eller så är den poseförutsägelse som Unity renderar med den ramen inte synkroniserad med den pose som Windows förväntar sig, vilket minskar hologramstabiliteten.

Om du behöver åtkomst till interna gränssnitt för återgivning eller felsökning använder du data från HolographicFrameNativeData i dina interna plugin-program eller C#-kod.

Här är ett exempel på hur du kan använda HolographicFrameNativeData för att hämta den aktuella ramens förutsägelse för fotontid med hjälp av XR SDK-tilläggen.

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

Se även