Unity での Mixed Reality 本来の相互運用
すべての Mixed Reality アプリでは、カメラ データの受信とフレームのレンダリングを開始する前に HolographicSpace を取得します。 Unity では、エンジンがこれらの手順を実行し、ホログラフィック オブジェクトを処理してレンダー ループの一部として内部的に更新します。
ただし、高度なシナリオでは、HolographicCamera や現在の HolographicFrame など、基になるネイティブ オブジェクトへのアクセスが必要になる場合があります。
WindowsMixedRealityUtilities
Namespace: Microsoft.MixedReality.Toolkit.WindowsMixedReality
Type: WindowsMixedRealityUtilities
MRTK は 、WindowsMixedRealityUtilities クラスを介して、レガシ WSA と XR SDK の両方で既にマーシャリングされた型を提供します。
public static HolographicFrame CurrentHolographicFrame { get; }
public static SpatialCoordinateSystem SpatialCoordinateSystem { get; }
public static SpatialInteractionManager SpatialInteractionManager { get; }
ネイティブ ポインターのマーシャリング解除
上記のいずれかのメソッドから IntPtr
を取得した後 (MRTK では不要)、次のコード スニペットを使用してそれらをマネージド オブジェクトにマーシャリングします。
Microsoft.Windows.MixedReality.DotNetWinRT を使用している場合、FromNativePtr()
メソッドを使用してネイティブ ポインターからマネージド オブジェクトを構築できます。
var worldOrigin = Microsoft.Windows.Perception.Spatial.SpatialCoordinateSystem.FromNativePtr(spatialCoordinateSystemPtr);
それ以外の場合は、Marshal.GetObjectForIUnknown()
を使用し、必要な型にキャストします。
#if ENABLE_WINMD_SUPPORT
var worldOrigin = Marshal.GetObjectForIUnknown(spatialCoordinateSystemPtr) as Windows.Perception.Spatial.SpatialCoordinateSystem;
#endif
座標系間の変換
Unity は左手座標系を使用し、Windows Perception API は右手座標系を使用します。 この 2 つの規則の間で変換するには、次のヘルパーを使用できます。
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);
}
}
HolographicFrame ネイティブ データの使用
Note
HolographicFrameNativeData を介して受け取ったネイティブ オブジェクトの状態を変更すると、予期しない動作やレンダリング アーティファクトが発生する可能性があります。Unity でもその同じ状態が推論される場合は特にそうです。 たとえば、HolographicFrame.UpdateCurrentPrediction は呼び出さないでください。そうしないと、Unity がそのフレームでレンダリングする姿勢予測は Windows が期待している姿勢と同期しなくなり、ホログラムの安定性が低下します。
レンダリングまたはデバッグの目的でネイティブ インターフェイスにアクセスする必要がある場合は、ネイティブ プラグインまたは C# コード内で HolographicFrameNativeData のデータを使用します。
次に示すのは、HolographicFrameNativeData を使用し、XR SDK 拡張機能を使用して Photon 時間の現在のフレームの予測を取得する方法の例です。
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;
}