Interopérabilité native Mixed Reality dans Unity
Chaque application de réalité mixte obtient un HolographicSpace avant de commencer à recevoir des données de caméra et des images de rendu. Dans Unity, le moteur s’occupe de ces étapes pour vous, de la gestion des objets Holographiques et de la mise à jour en 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 dans le 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émarshaling des pointeurs natifs
Après avoir obtenu l’une IntPtr
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 et convertissez Marshal.GetObjectForIUnknown()
le type souhaité :
#if ENABLE_WINMD_SUPPORT
var worldOrigin = Marshal.GetObjectForIUnknown(spatialCoordinateSystemPtr) as Windows.Perception.Spatial.SpatialCoordinateSystem;
#endif
Conversion entre les systèmes de coordonnées
Unity utilise un système de coordonnées gaucher, tandis que les API Perception Windows utilisent des systèmes de coordonnées de droite. 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
Remarque
La modification de l’état des objets natifs reçus via HolographicFrameNativeData peut entraîner un comportement imprévisible et des artefacts de rendu, en particulier si Unity raisonne également sur ce même état. Par exemple, vous ne devez pas appeler HolographicFrame.UpdateCurrentPrediction, ou bien la prédiction de pose que Unity affiche avec cette trame sera hors de synchronisation avec la pose attendue par Windows, ce qui réduira la stabilité de l’hologramme.
Si vous avez besoin d’accéder aux 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 le temps 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;
}