Interopérabilité native Mixed Reality dans Unity

Chaque application Mixed Reality obtient un HolographicSpace avant de commencer à recevoir des données de caméra et à afficher des images. Dans Unity, le moteur s’occupe de ces étapes à votre place, en gérant les objets holographiques et en procédant à une mise à jour interne dans le cadre de sa boucle de rendu.

Toutefois, dans les scénarios avancés, vous devrez peut-être accéder aux objets natifs sous-jacents, tels que HolographicCamera et HolographicFrame actuel.

WindowsMixedRealityUtilities

Espace de noms :Microsoft.MixedReality.Toolkit.WindowsMixedReality
Type :WindowsMixedRealityUtilities

MRTK fournit des types déjà marshalés sur les sdk WSA et XR hérités via la classe WindowsMixedRealityUtilities .

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

Démarshalation des pointeurs natifs

Après avoir obtenu le IntPtr à partir de l’une des méthodes ci-dessus (non nécessaire pour MRTK), utilisez les extraits de code suivants pour les marshaler sur des objets managés.

Si vous utilisez Microsoft.Windows.MixedReality.DotNetWinRT, vous pouvez construire un objet managé à partir d’un pointeur natif à l’aide de la FromNativePtr() méthode :

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

Sinon, utilisez Marshal.GetObjectForIUnknown() et castez vers le type souhaité :

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

Conversion entre systèmes de coordonnées

Unity utilise un système de coordonnées gaucher, tandis que les API Windows Perception utilisent des systèmes de coordonnées droitiers. Pour effectuer une conversion entre ces deux conventions, vous pouvez utiliser les helpers suivants :

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

Utilisation de données natives HolographicFrame

Notes

La modification de l’état des objets natifs reçus via HolographicFrameNativeData peut entraîner un comportement et des artefacts de rendu imprévisibles, en particulier si Unity a également des raisons pour ce même état. Par exemple, vous ne devez pas appeler HolographicFrame.UpdateCurrentPrediction, sinon la prédiction de pose rendue par Unity avec cette image ne sera pas synchronisée avec la pose attendue par Windows, ce qui réduira la stabilité de l’hologramme.

Si vous avez besoin d’accéder à des interfaces natives à des fins de rendu ou de débogage, utilisez les données de HolographicFrameNativeData dans vos plug-ins natifs ou code C#.

Voici un exemple de la façon dont vous pouvez utiliser HolographicFrameNativeData pour obtenir la prédiction de l’image actuelle pour l’heure des photon à l’aide des extensions du SDK 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;
}

Voir aussi