Share via


Realtà mista'interoperabilità nativa in Unity

Ogni app Realtà mista ottiene un HolographicSpace prima di iniziare a ricevere i dati della fotocamera e i fotogrammi di rendering. In Unity il motore si occupa di questi passaggi, gestisce gli oggetti Holographic e l'aggiornamento interno come parte del ciclo di rendering.

Tuttavia, negli scenari avanzati potrebbe essere necessario accedere agli oggetti nativi sottostanti, ad esempio HolographicCamera e HolographicFrame corrente.

WindowsMixedRealityUtilities

Spazio dei nomi:Microsoft.MixedReality.Toolkit.WindowsMixedReality
Tipo:WindowsMixedRealityUtilities

MRTK offre tipi già marshalled in WSA legacy e XR SDK tramite la classe WindowsMixedRealityUtilities .

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

Scollegamento dei puntatori nativi

Dopo aver ottenuto l'oggetto da uno dei metodi precedenti (non necessario per MRTK), usare i frammenti di codice seguenti per eseguire il IntPtr marshalling degli oggetti gestiti.

Se si usa Microsoft.Windows.MixedReality.DotNetWinRT, è possibile costruire un oggetto gestito da un puntatore nativo usando il FromNativePtr() metodo:

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

In caso contrario, usare Marshal.GetObjectForIUnknown() e eseguire il cast per il tipo desiderato:

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

Conversione tra sistemi di coordinate

Unity usa un sistema di coordinate a sinistra, mentre le API Di Percezione di Windows usano sistemi di coordinate destro-mano. Per convertire tra queste due convenzioni, è possibile usare gli helper seguenti:

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

Uso dei dati nativi di HolographicFrame

Nota

La modifica dello stato degli oggetti nativi ricevuti tramite HolographicFrameNativeData può causare un comportamento imprevedibile e gli artefatti di rendering, soprattutto se Unity per motivi relativi allo stesso stato. Ad esempio, non è consigliabile chiamare HolographicFrame.UpdateCurrentPrediction oppure la stima della posizione con cui Unity esegue il rendering di tale frame sarà non sincronizzata con la posizione prevista da Windows, che ridurrà la stabilità dell'ologramma.

Se è necessario accedere alle interfacce native per il rendering o il debug, usare i dati di HolographicFrameNativeData nei plug-in nativi o nel codice C#.

Ecco un esempio di come è possibile usare HolographicFrameNativeData per ottenere la stima del frame corrente per il tempo di fotona usando le estensioni 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;
}

Vedere anche