MRが楽しい

MRやVRについて学習したことを書き残す

MRTK v2のドキュメントを少しずつ読み解く コードによるメッシュオブザーバーの構成

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。
f:id:bluebirdofoz:20210202230656j:plain

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

前回項目の続きです。
bluebirdofoz.hatenablog.com

コードによるメッシュオブザーバーの構成

この記事では SpatialAwareness システムの MeshObserver データプロバイダーをプログラムで構成するための主要なメカニズムといくつかの API について説明します。

メッシュオブザーバーへのアクセス

IMixedRealitySpatialAwarenessMeshObserver インターフェイスを実装するメッシュオブザーバークラスはプラットフォーム固有のメッシュデータを SpatialAwareness システムに提供します。
SpatialAwareness プロファイルでは複数のオブザーバーを構成できます。

SpatialAwareness システムのデータプロバイダーへのアクセスは、他の MRTK サービスの場合とほとんど同じです。
GetDataProviderAPIを介してアクセスするには SpatialAwareness サービスを IMixedRealityDataProviderAccess インターフェイスにキャストする必要があります。
以下のように、実行時にメッシュオブザーバーオブジェクトに直接アクセスできます。

// Use CoreServices to quickly get access to the IMixedRealitySpatialAwarenessSystem
// CoreServices を使用して IMixedRealitySpatialAwarenessSystem にアクセスします。
var spatialAwarenessService = CoreServices.SpatialAwarenessSystem;

// Cast to the IMixedRealityDataProviderAccess to get access to the data providers
// IMixedRealityDataProviderAccess にキャストして、データプロバイダーにアクセスします。
var dataProviderAccess = spatialAwarenessService as IMixedRealityDataProviderAccess;

var meshObserver = dataProviderAccess.GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

CoreServices.GetSpatialAwarenessSystemDataProvider() ヘルパーは以下に示すようにアクセスパターンを簡素化します。

// Get the first Mesh Observer available, generally we have only one registered
// 利用可能な最初のメッシュオブザーバーを入手します。通常、登録されているのは1つだけです。
var meshObserver = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

// Get the SpatialObjectMeshObserver specifically
// SpatialObjectMeshObserver を取得します
var meshObserverName = "Spatial Object Mesh Observer";
var spatialObjectMeshObserver = dataProviderAccess.GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(meshObserverName);

メッシュ観測の開始と停止

SpatialAwareness システムを扱う際の最も一般的なタスクの1つは、実行時に機能を動的にオフ/オンにすることです。
これは以下の API を介してオブザーバーごとに実行されます。
・IMixedRealitySpatialAwarenessObserver.Resume
・IMixedRealitySpatialAwarenessObserver.Suspend

// Get the first Mesh Observer available, generally we have only one registered
// 利用可能な最初のメッシュオブザーバーを入手します。通常、登録されているのは1つだけです。
var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

// Suspends observation of spatial mesh data
// 空間メッシュデータの観測を一時停止します。
observer.Suspend();

// Resumes observation of spatial mesh data
// 空間メッシュデータの観測を再開します。
observer.Resume();

すべてのメッシュ観測の開始と停止

一般にアプリケーションで全てのメッシュ観察を開始/停止するときに便利です。
これは SpatialAwareness システムの以下の API を通じて実行できます。
・ResumeObservers()
・SuspendObservers()

// Resume Mesh Observation from all Observers
// 全てのオブザーバーからメッシュ観測を再開します。
CoreServices.SpatialAwarenessSystem.ResumeObservers();

// Suspend Mesh Observation from all Observers
// 全てのオブザーバーからのメッシュ観測を一時停止します。
CoreServices.SpatialAwarenessSystem.SuspendObservers();

メッシュの列挙とアクセス

メッシュへのアクセスはオブザーバーごとに実行できます。
IMixedRealitySpatialAwarenessMeshObserver API を介してメッシュオブザーバーに認識されているメッシュを列挙できます。

エディタで実行している場合は AssetDatabase.CreateAsset() を使用してMeshオブジェクトをアセットファイルに保存できます。

バイスで実行している場合 MeshFilter データをモデルファイルタイプにシリアル化するために利用できるコミュニティおよびストアプラグインがあります(以下はOBJの例です)。

// Get the first Mesh Observer available, generally we have only one registered
// 利用可能な最初のメッシュオブザーバーを入手します。通常、登録されているのは1つだけです。
var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

// Loop through all known Meshes
// 既知のすべてのメッシュをループします。
foreach (SpatialAwarenessMeshObject meshObject in observer.Meshes.Values)
{
    Mesh mesh = meshObject.Filter.mesh;
    // Do something with the Mesh object
    // Mesh オブジェクトで何らかの処理を行います。
}

空間メッシュの表示と非表示

以下のサンプルコードを使用して、プログラムでメッシュを非表示/表示することができます。

// Get the first Mesh Observer available, generally we have only one registered
// 利用可能な最初のメッシュオブザーバーを入手します。通常、登録されているのは1つだけです。
var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

// Set to not visible
// 非表示に設定します。
observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.None;

// Set to visible and the Occlusion material
// 可視に設定し、オクルージョンマテリアルを設定します。
observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.Occlusion;

メッシュ観測イベントへの登録


コンポーネントは IMixedRealitySpatialAwarenessObservationHandler を実装してから、SpatialAwareness システムに登録してメッシュ監視イベントを受信できます。

DemoSpatialMeshHandler(Assets/MRTK/Examples/Demos/SpatialAwareness/Scripts) スクリプトは、メッシュオブザーバーイベントをリッスンするための便利な例および開始点です。

以下は DemoSpatialMeshHandler スクリプトとメッシュ監視イベントリスニングの簡略化された例です。

// Simplify type
// タイプを簡略化
using SpatialAwarenessHandler = IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessMeshObject>;

public class MyMeshObservationExample : MonoBehaviour, SpatialAwarenessHandler
{
    private void OnEnable()
    {
        // Register component to listen for Mesh Observation events, typically done in OnEnable()
        // メッシュ観測イベントをリッスンするコンポーネントを登録します。通常は OnEnable() で実行します。
        CoreServices.SpatialAwarenessSystem.RegisterHandler<SpatialAwarenessHandler>(this);
    }

    private void OnDisable()
    {
        // Unregister component from Mesh Observation events, typically done in OnDisable()
        // メッシュ監視イベントからコンポーネントの登録を解除します。通常は OnDisable() で実行します。
        CoreServices.SpatialAwarenessSystem.UnregisterHandler<SpatialAwarenessHandler>(this);
    }

    public virtual void OnObservationAdded(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData)
    {
        // Do stuff
    }

    public virtual void OnObservationUpdated(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData)
    {
        // Do stuff
    }

    public virtual void OnObservationRemoved(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData)
    {
        // Do stuff
    }
}