Interoperabilidad nativa de Mixed Reality en Unity

Cada aplicación Mixed Reality obtiene un HolographicSpace antes de empezar a recibir datos de cámara y representar fotogramas. En Unity, el motor se encarga de esos pasos para usted, controlando objetos holográficos y actualizando internamente como parte de su bucle de representación.

Sin embargo, en escenarios avanzados es posible que tenga que obtener acceso a los objetos nativos subyacentes, como HolographicCamera y holographicFrame actual.

WindowsMixedRealityUtilities

Espacio de nombres:Microsoft.MixedReality.Toolkit.WindowsMixedReality
Type:WindowsMixedRealityUtilities

MRTK proporciona tipos ya serializado en el SDK de WSA y XR heredados a través de la clase WindowsMixedRealityUtilities .

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

Desacoplar punteros nativos

Después de obtener de IntPtr uno de los métodos anteriores (no es necesario para MRTK), use los siguientes fragmentos de código para serializarlos en objetos administrados.

Si usa Microsoft.Windows.MixedReality.DotNetWinRT, puede construir un objeto administrado a partir de un puntero nativo mediante el FromNativePtr() método :

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

De lo contrario, use Marshal.GetObjectForIUnknown() y convierta al tipo que desee:

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

Conversión entre sistemas de coordenadas

Unity usa un sistema de coordenadas a la izquierda, mientras que las API de Percepción de Windows usan sistemas de coordenadas a la derecha. Para convertir entre estas dos convenciones, puede usar los siguientes asistentes:

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 de datos nativos de HolographicFrame

Nota:

Cambiar el estado de los objetos nativos recibidos a través de HolographicFrameNativeData puede provocar un comportamiento impredecible y representar artefactos, especialmente si Unity también tiene motivos sobre ese mismo estado. Por ejemplo, no debe llamar a HolographicFrame.UpdateCurrentPrediction o, de lo contrario, la predicción de la posición que Unity representa con ese fotograma dejará de estar sincronizada con la posición que Windows espera, lo que reducirá la estabilidad del holograma.

Si necesita acceso a interfaces nativas con fines de representación o depuración, use datos de HolographicFrameNativeData en los complementos nativos o el código de C#.

Este es un ejemplo de cómo puede usar HolographicFrameNativeData para obtener la predicción del fotograma actual para el tiempo de foton mediante las extensiones del SDK de XR.

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

Consulte también