見出し画像

Magic Leap2 空間メッシュの構築

はじめに

Magic Leap2 による空間メッシュの生成処理について説明します。
Magic Leap SDK 1.1.0-dev2で発生した不具合対策や現バージョンでも発生する不具合についての回避ポイントも説明します。


OnePlanet XR について

https://1planet.co.jp/xrconsulting.html

このブログ記事は OnePlanet XR によるものです。
OnePlanet XR は、AR/MR/VPS技術に専門特化したコンサルティングサービスです。豊富な実績を元に、AR/MR技術を活用した新たな事業の立ち上げ支援や、社内業務のデジタル化/DX推進など、貴社の必要とするイノベーションを実現いたします。

ご相談から受け付けております。ご興味ございましたらお問い合わせください。


Magic Leap2 の 空間メッシュの実装方法について

Magic Leap2 で空間を認識してメッシュを生成するシンプルなデモアプリケーションを作成します。


開発環境 / 動作環境

Unity Editor 2022.2.0b8.3023
Magic Leap SDK 1.1.0
Magic Leap Unity 1.3.0
Magic Leap XR Plugin 7.0.0.pre.1
Magic Lea 2 OS 1.1.0 (B3E.221128.08-R.092)


ヒエラルキー

Meshing Subsystem Component

シーンを新規作成します。Main Cameraは削除し、XR Rigのプレファブをヒエラルキーに配置します。
Game Objectを作成し、名前を Meshing Subsystem Component にします。

MeshingSubsystemComponentを追加

作成した Meshing Subsystem Component に Packages/com.magicleap.unitysdk/Runtime/Subsystems配下にあるMeshingSubsystemComponentを追加します。

メッシュのParentを作成

生成したメッシュの親となるGame Objectを作成します。

メッシュのプレファブを作成

Meshing Subsystem Component が生成するメッシュのプレファブを作成します。
Mesh PrefabというGame Objectを作成します。Mesh Prefabに Mesh Filter と Mesh Rendererを追加します。

Mesh Prefabのマテリアルを作成

Mesh Prefab 用の マテリアルを作成します。Shaderは Universal Render Pipeline/Lit にします。(ここではBase Map のカラーを黄色にしていますが、黒に近い色でなければ、どのようなカラー設定でも問題ありません。)

マテリアルを設定

Mesh Prefabに先程、作成したMesh Materialを設定します。

Mesh Prefab をプレファブ化

Mesh Prefabをプレファブ化します。その後、ヒエラルキーにあるMesh Prefabを削除します。

Meshing Subsystem Component の設定

作成したMesh ParentやMesh Prefabを Meshing Subsystem Componentに設定します。Scale はすべて10にします。(10メートル圏内を対象にメッシュデータが生成されます。)Request Vertex Confidence にチェックを入れます。


権限とMeshing Subsystem Component の移動処理

メッシュ機能の利用する場合、権限を有効にする必要があります。起動時にメッシュ機能によるパーミッションダイアログを表示するようにします。
また、メッシュ生成中にMeshing Subsystem Component のポジションをカメラと同期を取るようにします。

Meshing Sample というGame Object 作成し、MeshingSampleというスクリプトをMeshing Sample の Game Object に追加します。スクリプトは以下になります。

using UnityEngine;
using UnityEngine.XR.MagicLeap;

public class MeshingSample : MonoBehaviour
{
    [SerializeField]
    private GameObject _meshingSubsystemComponent = null;

    private readonly MLPermissions.Callbacks _permissionCallbacks = new MLPermissions.Callbacks();

    private void Awake()
    {
        _permissionCallbacks.OnPermissionGranted += OnPermissionGranted;
        _permissionCallbacks.OnPermissionDenied += OnPermissionDenied;
    }
    // Start is called before the first frame update
    void Start()
    {
        MLPermissions.RequestPermission(MLPermission.SpatialMapping, _permissionCallbacks);
    }

    void Update()
    {
        if (_meshingSubsystemComponent.GetComponent<MeshingSubsystemComponent>().enabled)
        {
            _meshingSubsystemComponent.transform.position = Camera.main.transform.position;
        }
    }

    private void OnDestroy()
    {
        _permissionCallbacks.OnPermissionGranted -= OnPermissionGranted;
        _permissionCallbacks.OnPermissionDenied -= OnPermissionDenied;
    }

    private void OnPermissionGranted(string permission)
    {
        Debug.Log("Spatial Mapping Permission Granted");
        _meshingSubsystemComponent.GetComponent<MeshingSubsystemComponent>().enabled = true;
    }
    private void OnPermissionDenied(string permission)
    {
        Debug.Log("Spatial Mapping Permission Denied");
    }
}

Meshing Sample の Meshing Subsystem Component に ヒエラルキーにあるMeshing Subsystem Component の Game Object を設定します。


実行

空間内でメッシュが生成されます。


注意

起動しても何も表示されない場合

Magic Leap Unity 1.2.0 では起動後に何も表示されない事象が発生。もし、当事象が発生した場合、以下のコードを追加してください。

        void Awake()
        {
            MeshingSubsystem.Extensions.MLMeshing.Config.SetCustomMeshBlockRequests(CustomBlockRequests);
        }
        
        MeshingSubsystem.Extensions.MLMeshing.MeshBlockRequest[] CustomBlockRequests(MeshingSubsystem.Extensions.MLMeshing.MeshBlockInfo[] blockInfos)
        {
            var blockRequests = new MeshingSubsystem.Extensions.MLMeshing.MeshBlockRequest[blockInfos.Length];
            for (int i = 0; i < blockInfos.Length; ++i)
            {
                var blockInfo = blockInfos[i];
                var distanceFromCamera = Vector3.Distance(_camera.transform.position, blockInfo.pose.position);
                if (distanceFromCamera > 1)
                    blockRequests[i] = new MeshingSubsystem.Extensions.MLMeshing.MeshBlockRequest(blockInfo.id, MeshingSubsystem.Extensions.MLMeshing.LevelOfDetail.Minimum);
                else
                    blockRequests[i] = new MeshingSubsystem.Extensions.MLMeshing.MeshBlockRequest(blockInfo.id, MeshingSubsystem.Extensions.MLMeshing.LevelOfDetail.Maximum);
            }

            return blockRequests;
        }

上記の対応を実施しても同じ事象が発生した場合、生成するメッシュで設定しているマテリアルが原因で引き起こす可能性があります。今回の記事で説明しているものでないマテリアルを使用している場合、同じような事象が発生する可能性があります。


OnePlanet XR

https://1planet.co.jp/xrconsulting.html

AR/MR/VPS技術に専門特化したコンサルティングサービス

Magic Leap2 を使ったソリューションのご検討の方からのお問い合わせ、お待ちしております。


お問い合わせ先

https://1planet.co.jp/xrconsulting.html#op_form


OnePlanet Tech Magazine

Magic Leap1 、Magic Leap2、スマホAR(Niantic Lightship ARDK、WebAR、VPSなど)といったAR技術全般をブログマガジンを連載しています。