Interoperabilidade nativa de Realidade Mista em Unity
Cada aplicativo de Realidade Mista recebe um HolographicSpace antes de começar a receber dados da câmera e renderizar quadros. No Unity, o mecanismo cuida dessas etapas para você, manipulando objetos holográficos e atualizando internamente como parte de seu loop de renderização.
No entanto, em cenários avançados, talvez seja necessário obter acesso aos objetos nativos subjacentes, como HolographicCamera e HolographicFrame atual.
WindowsMixedRealityUtilities
Espaço de nomes: Microsoft.MixedReality.Toolkit.WindowsMixedReality
Tipo: WindowsMixedRealityUtilities
O MRTK fornece tipos já empacotados no WSA herdado e no XR SDK por meio da classe WindowsMixedRealityUtilities .
public static HolographicFrame CurrentHolographicFrame { get; }
public static SpatialCoordinateSystem SpatialCoordinateSystem { get; }
public static SpatialInteractionManager SpatialInteractionManager { get; }
Desempacotamento de ponteiros nativos
Depois de obter o IntPtr
de um dos métodos acima (não necessário para MRTK), use os seguintes trechos de código para empacotá-los para objetos gerenciados.
Se você estiver usando Microsoft.Windows.MixedReality.DotNetWinRT, poderá construir um objeto gerenciado a partir de um ponteiro nativo usando o FromNativePtr()
método:
var worldOrigin = Microsoft.Windows.Perception.Spatial.SpatialCoordinateSystem.FromNativePtr(spatialCoordinateSystemPtr);
Caso contrário, use Marshal.GetObjectForIUnknown()
e converta para o tipo desejado:
#if ENABLE_WINMD_SUPPORT
var worldOrigin = Marshal.GetObjectForIUnknown(spatialCoordinateSystemPtr) as Windows.Perception.Spatial.SpatialCoordinateSystem;
#endif
Conversão entre sistemas de coordenadas
Unity usa um sistema de coordenadas canhoto, enquanto as APIs de perceção do Windows usam sistemas de coordenadas destros. Para converter entre essas duas convenções, você pode usar os seguintes auxiliares:
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);
}
}
Usando dados nativos do HolographicFrame
Nota
Alterar o estado dos objetos nativos recebidos via HolographicFrameNativeData pode causar comportamento imprevisível e artefatos de renderização, especialmente se Unity também raciocina sobre esse mesmo estado. Por exemplo, você não deve chamar HolographicFrame.UpdateCurrentPrediction, ou então a previsão de pose que o Unity renderiza com esse quadro estará fora de sincronia com a pose que o Windows está esperando, o que reduzirá a estabilidade do holograma.
Se você precisar de acesso a interfaces nativas para fins de renderização ou depuração, use dados de HolographicFrameNativeData em seus plugins nativos ou código C#.
Aqui está um exemplo de como você pode usar HolographicFrameNativeData para obter a previsão do quadro atual para o tempo de fóton usando as extensões 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;
}