MRが楽しい

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

MRTKでHoloLens2の空間メッシュの詳細レベルや範囲を動的に切り替える

本日はMRTKの小ネタ枠です。
MRTKで空間メッシュの詳細レベルや範囲を動的に切り替える方法を記事にします。
今回はメッシュの詳細レベルを切り替える方法です。

SpatialAwarenessの設定

MRTKを利用してHoloLens2アプリを作成する場合、空間メッシュはSpatialAwarenessの設定で管理されます。
SpatialAwarenessの詳細レベルをスクリプトから操作するにはSpatialAwarenessMeshObserverのLevelOfDetailにアクセスします。
learn.microsoft.com
learn.microsoft.com

使用しているXRプラグインによって取得すべきMeshObserverの種類が変わることに注意が必要です。

// Unity OpenXR pluginを選択している場合
var openXRSpatialAwarenessMeshObserver =
    CoreServices.GetSpatialAwarenessSystemDataProvider<OpenXRSpatialAwarenessMeshObserver>();
openXRSpatialAwarenessMeshObserver.LevelOfDetail = SpatialAwarenessMeshLevelOfDetail.Fine;

// Built-in Unity pluginsを選択している場合
var mixedRealitySpatialAwarenessMeshObserver =
    CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
mixedRealitySpatialAwarenessMeshObserver.LevelOfDetail = SpatialAwarenessMeshLevelOfDetail.Fine;

サンプルプロジェクトの作成

MRTKを使った基本プロジェクトの環境構築手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

今回はデフォルトの DefaultMixedRealityToolkitConfigurationProfile で作成したプロジェクトを利用します。

サンプルスクリプト

SpatialAwarenessの詳細レベルを[表示(Visible)][オクルージョン(Occlusion)][非表示(None)]に切り替える関数を持った以下のスクリプトを作成しました。
・SpatialAwarenessStatusSwitch.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using Microsoft.MixedReality.Toolkit;
using Microsoft.MixedReality.Toolkit.SpatialAwareness;
using Microsoft.MixedReality.Toolkit.XRSDK.OpenXR;

public class SpatialAwarenessStatusSwitch : MonoBehaviour
{
    public void SwitchCoarse()
    {
        // 利用可能なOpenXRメッシュオブザーバーを取得する
        var openXRSpatialAwarenessMeshObserver =
            CoreServices.GetSpatialAwarenessSystemDataProvider<OpenXRSpatialAwarenessMeshObserver>();

        // 荒い(Coarse)に設定する
        openXRSpatialAwarenessMeshObserver.LevelOfDetail = SpatialAwarenessMeshLevelOfDetail.Coarse;
    }
    
    public void SwitchMedium()
    {
        // 利用可能なOpenXRメッシュオブザーバーを取得する
        var openXRSpatialAwarenessMeshObserver =
            CoreServices.GetSpatialAwarenessSystemDataProvider<OpenXRSpatialAwarenessMeshObserver>();

        // 中(Medium)に設定する
        openXRSpatialAwarenessMeshObserver.LevelOfDetail = SpatialAwarenessMeshLevelOfDetail.Medium;
    }
    
    public void SwitchFine()
    {
        // 利用可能なOpenXRメッシュオブザーバーを取得する
        var openXRSpatialAwarenessMeshObserver =
            CoreServices.GetSpatialAwarenessSystemDataProvider<OpenXRSpatialAwarenessMeshObserver>();

        // 細かい(Fine)に設定する
        openXRSpatialAwarenessMeshObserver.LevelOfDetail = SpatialAwarenessMeshLevelOfDetail.Fine;
    }

    public void SwitchCustom1()
    {
        // 利用可能なOpenXRメッシュオブザーバーを取得する
        var openXRSpatialAwarenessMeshObserver =
            CoreServices.GetSpatialAwarenessSystemDataProvider<OpenXRSpatialAwarenessMeshObserver>();

        // カスタム(Custom)の1立法メートル辺り1ポリゴンに設定する
        openXRSpatialAwarenessMeshObserver.LevelOfDetail = SpatialAwarenessMeshLevelOfDetail.Custom;

        openXRSpatialAwarenessMeshObserver.TrianglesPerCubicMeter = 1;
    }

    public void SwitchCustom10()
    {
        // 利用可能なOpenXRメッシュオブザーバーを取得する
        var openXRSpatialAwarenessMeshObserver =
            CoreServices.GetSpatialAwarenessSystemDataProvider<OpenXRSpatialAwarenessMeshObserver>();

        // カスタム(Custom)の1立法メートル辺り10ポリゴンに設定する
        openXRSpatialAwarenessMeshObserver.LevelOfDetail = SpatialAwarenessMeshLevelOfDetail.Custom;
        openXRSpatialAwarenessMeshObserver.TrianglesPerCubicMeter = 10;
    }
}

作成したサンプルスクリプトを適当なオブジェクトにアタッチし、シーンに配置したボタンから関数を呼び出せるようにしました。


HoloLens2上での動作確認

アプリケーションをビルドしてHoloLens2にデプロイします。
ボタン操作で空間メッシュの詳細レベルを切り替えることができれば成功です。

荒い(Coarse)


中(Medium)


細かい(Fine)


カスタム(Custom)

今回カスタム(Custom)の設定についてはメッシュの詳細レベルが変化せず、機能しませんでした。
以下のドキュメントページによると「全てプラットフォームで適用されることは保証されません」とあるため、HoloLens2かつOpenXR pluginを利用している環境では適用されない可能性が高いです。
learn.microsoft.com