Mixed Reality közötti natív interop a Unityben

Minden Mixed Reality kap egy HolographicSpace-t, mielőtt megkezdi a kameraadatok fogadását és a képkockák renderelését. A Unityben a motor gondoskodik ezekről a lépésekről, és a holografikus objektumokat kezeli, és belsőleg frissíti a renderelési ciklus részeként.

Speciális forgatókönyvekben azonban szükség lehet a mögöttes natív objektumokhoz, például a HolographicCamera és a jelenlegi HolographicFrame objektumhoz való hozzáférésre.

WindowsMixedRealityUtilities

Névtér:Microsoft.MixedReality.Toolkit.WindowsMixedReality
Típus:WindowsMixedRealityUtilities

Az MRTK a WindowsMixedRealityUtilities osztályon keresztül már meglévő WSA- és XR SDK-típusokat is biztosít.

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

Natív mutatók egységes használata

A fenti módszerek egyikének beszerzése után (az MRTK-hoz nem szükséges) az alábbi kódrészletek használatával felügyelt objektumokra lehet IntPtr őket összepárosodni.

Ha Microsoft.Windows. MixedReality.DotNetWinRT, a metódussal natív mutatóból is létre lehet majd építeni egy felügyelt objektumot:

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

Ellenkező esetben használja a Marshal.GetObjectForIUnknown() és a típust a kívánt típusra:

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

Átalakítás koordinátarendszerek között

A Unity bal oldali koordinátarendszert használ, míg Windows észlelési API-k jobb oldali koordinátarendszereket. A két konvenció közötti átalakításhoz a következő segítőket használhatja:

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

A HolographicFrame natív adatainak használata

Megjegyzés

A HolographicFrameNativeData használatával fogadott natív objektumok állapotának módosítása kiszámíthatatlan viselkedést és renderelési összetevők megjelenítését okozhatja, különösen akkor, ha a Unity az azonos állapot miatt is szól. Ne hívja meg például a HolographicFrame.UpdateCurrentPredictiont, különben a Unity által a kerettel renderelt pozíció-előrejelzés nincs szinkronban az Windows által várt pozícióval, ami csökkenti a hologramstabilitását.

Ha renderelési vagy hibakeresési célból hozzá kell férni a natív felületekhez, használja a HolographicFrameNativeData adatait a natív beépülő modulokban vagy a C#-kódban.

Lássunk egy példát arra, hogyan lehet a HolographicFrameNativeData használatával lekérte az aktuális képkocka fényképes időre vonatkozó előrejelzését az XR SDK-bővítmények használatával.

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

Lásd még: