Udostępnij za pośrednictwem


Natywna międzyoperacyjność rzeczywistości mieszanej w środowisku Unity

Każda aplikacja rzeczywistości mieszanej pobiera przestrzeń HolographicSpace przed rozpoczęciem odbierania danych aparatu i ramek renderowania. Aparat aparatu Unity zajmuje się tymi krokami, obsługując obiekty Holographic i wewnętrznie aktualizując ją w ramach pętli renderowania.

Jednak w zaawansowanych scenariuszach może być konieczne uzyskanie dostępu do bazowych obiektów natywnych, takich jak HolographicCamera i current HolographicFrame.

WindowsMixedRealityUtilities

Przestrzeń nazw: Microsoft.MixedReality.Toolkit.WindowsMixedReality
Typ: WindowsMixedRealityUtilities

Zestaw NARZĘDZI MRTK udostępnia już typy marshalled zarówno w starszych zestawach WSA, jak i XR SDK za pośrednictwem klasy WindowsMixedRealityUtilities .

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

Rozwikłanie natywnych wskaźników

Po uzyskaniu IntPtr z jednej z powyższych metod (nie jest to konieczne dla zestawu narzędzi MRTK) użyj poniższych fragmentów kodu, aby przeprowadzić ich marshaling do zarządzanych obiektów.

Jeśli używasz elementu Microsoft.Windows.MixedReality.DotNetWinRT, możesz utworzyć obiekt zarządzany z natywnego wskaźnika przy użyciu FromNativePtr() metody :

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

W przeciwnym razie użyj Marshal.GetObjectForIUnknown() i rzutuj do żądanego typu:

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

Konwertowanie między układami współrzędnych

Aparat Unity używa leworęcznego systemu współrzędnych, podczas gdy interfejsy API percepcji systemu Windows używają układów współrzędnych praworęcznych. Aby przekonwertować między tymi dwiema konwencjami, możesz użyć następujących pomocników:

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

Korzystanie z danych natywnych HolographicFrame

Uwaga

Zmiana stanu obiektów natywnych odebranych za pośrednictwem elementu HolographicFrameNativeData może spowodować nieprzewidywalne zachowanie i renderowanie artefaktów, zwłaszcza jeśli aparat Unity również jest przyczyną tego samego stanu. Na przykład nie należy wywoływać elementu HolographicFrame.UpdateCurrentPrediction ani przewidywania pozy, które aparat Unity renderuje z tej ramki, nie będzie zsynchronizowany z pozą oczekiwaną przez system Windows, co zmniejszy stabilność hologramu.

Jeśli potrzebujesz dostępu do interfejsów natywnych na potrzeby renderowania lub debugowania, użyj danych z elementu HolographicFrameNativeData w wtyczki natywne lub kod języka C#.

Oto przykład sposobu użycia elementu HolographicFrameNativeData w celu uzyskania przewidywania bieżącej ramki na potrzeby czasu fotonu przy użyciu rozszerzeń zestawu XR SDK.

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

Zobacz też