共用方式為


Unity 中的混合實境原生 Interop

每個混合實境應用程式 會在開始接收相機數據和轉譯畫面之前取得 HolographicSpace 。 在 Unity 中,引擎會為您處理這些步驟、處理全像攝影物件,並在內部更新作為轉譯迴圈的一部分。

不過,在進階案例中,您可能需要存取基礎原生物件,例如 HolographicCamera 和目前的 HolographicFrame

WindowsMixedRealityUtilities

命名空間:Microsoft.MixedReality.Toolkit.WindowsMixedReality
類型:WindowsMixedRealityUtilities

MRTK 透過 WindowsMixedRealityUtilities 類別,跨舊版 WSA 和 XR SDK 提供已封送處理的類型。

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

取消擷取原生指標

從上述其中一個方法取得 IntPtr 之後(MRTK 不需要),請使用下列代碼段將它們封送處理至 Managed 物件。

如果您使用 Microsoft.Windows.MixedReality.DotNetWinRT,您可以使用 方法來從原生指標 FromNativePtr() 建構 Managed 物件:

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

否則,請使用 Marshal.GetObjectForIUnknown() 並轉換成您想要的類型:

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

在座標系統之間轉換

Unity 使用左手座標系統,而 Windows Perception API 則使用右手座標系統。 若要在這兩個慣例之間轉換,您可以使用下列協助程式:

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

使用 HolographicFrame 原生數據

注意

變更透過 HolographicFrameNativeData 接收的原生對象狀態可能會導致無法預期的行為和轉譯成品,特別是 Unity 也造成該相同狀態的原因。 例如,您不應該呼叫 HolographicFrame.UpdateCurrentPrediction,否則 Unity 使用該畫面呈現的姿勢預測將會與 Windows 預期的姿勢不同步,這會降低 全像投影穩定性

如果您需要存取原生介面以進行轉譯或偵錯,請在原生外掛程式或 C# 程式代碼中使用 HolographicFrameNativeData 中的數據。

以下範例說明如何使用 HolographicFrameNativeData,透過 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;
}

另請參閱