Mixed Reality natywną międzyoperacją w akodzie Aparatu Unity

Każda aplikacja Mixed Reality pobiera holographicSpace przed rozpoczęciem odbierania danych z aparatu i renderowania ramek. Aparat aparatu Unity zajmuje się tymi krokami, obsługując obiekty Holographic i wewnętrznie aktualizując je 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
Type: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; }

Unmarshaling natywnych wskaźników

Po uzyskaniu IntPtr metody z jednej z powyższych metod (nie jest to wymagane w przypadku 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 na podstawie 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ż powoduje ten sam stan. Na przykład nie należy wywoływać elementu HolographicFrame.UpdateCurrentPrediction ani przewidywać pozy, które aparat Unity renderuje z tej ramki, nie będzie zsynchronizowany z 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 natywnych wtyczkach lub kodzie 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ż