空間認識システム データ プロバイダーの作成 — MRTK2

空間認識システムは、実世界の環境に関するデータをアプリケーションに提供するための拡張可能なシステムです。 新しいハードウェア プラットフォームまたは新しい形式の空間認識データのサポートを追加するために、カスタム データ プロバイダーが必要になる場合があります。

この記事では、空間認識システム用のカスタム データ プロバイダー (空間オブザーバーとも呼ばれる) を作成する方法について説明します。 ここに示すコード例は、エディターで 3D メッシュ データを読み込む場合に役立つSpatialObjectMeshObserver クラスの実装からのものです。

Note

この例で使用されているコードの完全なソース コードは、Assets/MRTK/Providers/ObjectMeshObserver フォルダー内にあります。

名前空間とフォルダー構造

データ プロバイダーは、次の 2 つの方法のいずれかで配布されます。

  1. サード パーティのアドオン
  2. Microsoft Mixed Reality Toolkit の一部

MRTK への新しいデータ プロバイダーの提出の承認プロセスは、ケース バイ ケースで異なり、最初の提案の時点で伝達されます。 提案は、新しい "機能要求" タイプの問題を作成することによって送信できます。

サード パーティのアドオン

Namespace

名前が競合する可能性を低減するために、データ プロバイダーには名前空間が必要です。 名前空間には次のコンポーネントを含めることをお勧めします。

  • アドオンの開発元の企業名
  • Feature area (機能領域)

たとえば、Contoso 社が作成して出荷する空間認識データ プロバイダーは "Contoso.MixedReality.Toolkit.SpatialAwareness" となります。

フォルダー構造

次の図に示すように、データ プロバイダーのソース コードをフォルダー階層で整理することをお勧めします。

フォルダー構造の例

ContosoSpatialAwareness フォルダーには、データ プロバイダーの実装が含まれており、Editor フォルダーには、インスペクター (およびその他の Unity エディター固有のコード) が含まれており、Profiles フォルダーには、事前に作成されたプロファイルのスクリプト実行可能なオブジェクトが 1 つ以上含まれています。

MRTK への送信

Namespace

空間認識システムのデータ プロバイダーを Mixed Reality Toolkit リポジトリに送信する場合、名前空間は Microsoft.MixedReality.Toolkit で始める必要があります (例: Microsoft.MixedReality.Toolkit.SpatialObjectMeshObserver)。

また、コードは、MRTK/Providers の下位のフォルダー (例: MRTK/Providers/ObjectMeshObserver) 内に配置する必要があります。

フォルダー構造

すべてのコードを MRTK/Providers の下位のフォルダー (例: MRTK/Providers/ObjectMeshObserver) 内に配置する必要があります。

空間データ オブジェクトを定義する

空間認識データ プロバイダーを作成する最初の手順は、そのプロバイダーでアプリケーションに提供されるデータの種類 (例: メッシュ、平面など) を決定することです。

すべての空間データ オブジェクトで IMixedRealitySpatialAwarenessObject インターフェイスを実装する必要があります。

Mixed Reality Toolkit の基盤には、新しいデータ プロバイダー内で使用または拡張できる次の空間オブジェクトが用意されています。

データ プロバイダーを実装する

インターフェイスまたは基本クラス継承を指定する

すべての空間認識データ プロバイダーで、IMixedRealitySpatialAwarenessObserver インターフェイスを実装する必要があります。これは、空間認識システムに必要な最小限の機能を指定します。 MRTK の基盤には、この必須機能の既定の実装を提供する BaseSpatialObserver クラスが含まれています。

public class SpatialObjectMeshObserver :
    BaseSpatialObserver,
    IMixedRealitySpatialAwarenessMeshObserver,
    IMixedRealityCapabilityCheck
{ }

Note

SpatialAwarenessMesh 機能のサポートを提供していることを示すために、SpatialObjectMeshObserver クラスでは IMixedRealityCapabilityCheck インターフェイスが使用されます。

MixedRealityDataProvider 属性を適用する

空間認識データ プロバイダーを作成するための重要な手順は、MixedRealityDataProvider 属性をクラスに適用することです。 この手順では、データ プロバイダーの既定のプロファイルとプラットフォーム (空間認識プロファイルで選択されている場合) と、名前、フォルダー パスなどを設定できます。

[MixedRealityDataProvider(
    typeof(IMixedRealitySpatialAwarenessSystem),
    SupportedPlatforms.WindowsEditor | SupportedPlatforms.MacEditor | SupportedPlatforms.LinuxEditor,
    "Spatial Object Mesh Observer",
    "ObjectMeshObserver/Profiles/DefaultObjectMeshObserverProfile.asset",
    "MixedRealityToolkit.Providers")]
public class SpatialObjectMeshObserver :
    BaseSpatialObserver,
    IMixedRealitySpatialAwarenessMeshObserver,
    IMixedRealityCapabilityCheck
{ }

IMixedRealityDataProvider メソッドを実装する

クラスを定義したら、次の手順として、IMixedRealityDataProvider インターフェイスの実装を提供します。

Note

BaseSpatialObserver クラスは、BaseService クラスを介して、IMixedRealityDataProvider メソッドの空の実装のみを提供します。 通常、これらのメソッドの詳細は、データ プロバイダー固有です。

データ プロバイダーで実装する必要があるメソッドは、次のとおりです。

  • Destroy()
  • Disable()
  • Enable()
  • Initialize()
  • Reset()
  • Update()

データ プロバイダーのロジックを実装する

次の手順として、特定のデータ プロバイダー インターフェイス (たとえば IMixedRealitySpatialAwarenessMeshObserver) を実装することにより、データ プロバイダーのロジックを追加します。 データ プロバイダーのこの部分は、通常、プラットフォーム固有です。

監視変更通知

デバイスによる環境の認識が変化したときにアプリケーションがそれに対応できるようにするために、データ プロバイダーは、IMixedRealitySpatialAwarenessObservationtHandler<T> インターフェイスで定義されたとおりに通知イベントを発生させます。

  • OnObservationAdded()
  • OnObservationRemoved()
  • OnObservationUpdated()

SpatialObjectMeshObserver の例からの次のコードは、メッシュ データが追加されたときに発生するイベントを示しています。

// The data to be sent when mesh observation events occur.
// This member variable is initialized as part of the Initialize() method.
private MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> meshEventData = null;

/// <summary>
/// Sends the observations using the mesh data contained within the configured 3D model.
/// </summary>
private void SendMeshObjects()
{
    if (!sendObservations) { return; }

    if (spatialMeshObject != null)
    {
        MeshFilter[] meshFilters = spatialMeshObject.GetComponentsInChildren<MeshFilter>();
        for (int i = 0; i < meshFilters.Length; i++)
        {
            SpatialAwarenessMeshObject meshObject = SpatialAwarenessMeshObject.Create(
                meshFilters[i].sharedMesh,
                MeshPhysicsLayer,
                $"Spatial Object Mesh {currentMeshId}",
                currentMeshId,
                ObservedObjectParent);

            meshObject.GameObject.transform.localPosition = meshFilters[i].transform.position;
            meshObject.GameObject.transform.localRotation = meshFilters[i].transform.rotation;

            ApplyMeshMaterial(meshObject);

            meshes.Add(currentMeshId, meshObject);

            // Initialize the meshEventData variable with data for the added event.
            meshEventData.Initialize(this, currentMeshId, meshObject);
            // Raise the event via the spatial awareness system.
            SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded);

            currentMeshId++;
        }
    }

    sendObservations = false;
}

Note

3D モデルは 1 回しか読み込まれないため、SpatialObjectMeshObserver クラスによって OnObservationUpdated イベントは発生しません。 WindowsMixedRealitySpatialMeshObserver クラスの実装は、監視対象のメッシュに対して OnObservationUpdated イベントを発生させる例を提供しています。

Unity Profiler インストルメンテーションを追加する

Mixed Reality アプリケーションでは、パフォーマンスが重要です。 どのコンポーネントでも、ある程度のオーバーヘッドが追加されるため、アプリケーションではこれらのオーバーヘッドを考慮する必要があります。 このため、すべての空間認識データ プロバイダーに、内部ループと頻繁に使用されるコード パスで Unity Profiler インストルメンテーションを含めることが重要です。

カスタム プロバイダーをインストルメント化するときに MRTK によって使用されるパターンを実装することをお勧めします。

        private static readonly ProfilerMarker UpdateObserverPerfMarker = new ProfilerMarker("[MRTK] WindowsMixedRealitySpatialMeshObserver.UpdateObserver");

        /// <summary>
        /// Requests updates from the surface observer.
        /// </summary>
        private void UpdateObserver()
        {
            using (UpdateObserverPerfMarker.Auto())
            {
                // Code to be measured.
            }
        }

Note

プロファイラー マーカーを識別するために使用される名前は任意です。 MRTK では、次のパターンが使用されます。

"[製品] クラス名.メソッド名 - オプションのメモ"

トレースを分析するときに特定のコンポーネントとメソッドを簡単に識別できるようにするために、カスタム データ プロバイダーで同様のパターンに従うことをお勧めします。

プロファイルとインスペクターを作成する

Mixed Reality Toolkit では、データ プロバイダーはプロファイルを使用して構成されます。

プロファイルを定義する

プロファイルの内容には、データ プロバイダーのアクセス可能なプロパティ (例: 更新間隔など) を反映させる必要があります。 各インターフェイスで定義されるすべてのユーザー構成可能プロパティをプロファイルに含める必要があります。

新しいデータ プロバイダーで既存のプロバイダーを拡張する場合、基本クラスをお勧めします。 たとえば、SpatialObjectMeshObserverProfileMixedRealitySpatialAwarenessMeshObserverProfile を拡張して、顧客が環境データとして使用される 3D モデルを提供できるようにします。

[CreateAssetMenu(
    menuName = "Mixed Reality Toolkit/Profiles/Spatial Object Mesh Observer Profile",
    fileName = "SpatialObjectMeshObserverProfile",
    order = 100)]
public class SpatialObjectMeshObserverProfile : MixedRealitySpatialAwarenessMeshObserverProfile
{
    [SerializeField]
    [Tooltip("The model containing the desired mesh data.")]
    private GameObject spatialMeshObject = null;

    /// <summary>
    /// The model containing the desired mesh data.
    /// </summary>
    public GameObject SpatialMeshObject => spatialMeshObject;
}

CreateAssetMenu 属性をプロファイル クラスに適用すると、顧客が [作成]>[アセット]>[Mixed Reality Toolkit]>[プロファイル] メニューを使用してプロファイル インスタンスを作成できるようになります。

インスペクターを実装する

プロファイル インスペクターは、プロファイルの内容を構成および表示するためのユーザー インターフェイスです。 各プロファイル インスペクターで、BaseMixedRealityToolkitConfigurationProfileInspector クラスを拡張する必要があります。

CustomEditor 属性により、インスペクターが適用されるアセットの種類が Unity に通知されます。

[CustomEditor(typeof(SpatialObjectMeshObserverProfile))]
public class SpatialObjectMeshObserverProfileInspector : BaseMixedRealityToolkitConfigurationProfileInspector
{ }

アセンブリ定義を作成する

Mixed Reality Toolkit では、アセンブリ定義 (.asmdef) ファイルを使用してコンポーネント間の依存関係を指定し、Unity によるコンパイル時間の短縮を支援します。

すべてのデータ プロバイダー用とそのエディター コンポーネント用のアセンブリ定義ファイルを作成することをお勧めします。

前の例のフォルダー構造を使用すると、ContosoSpatialAwareness データ プロバイダー用に 2 つの .asmdef ファイルが作成されることになります。

最初のアセンブリ定義は、データ プロバイダー用です。 この例では、ContosoSpatialAwareness という名前で、例の ContosoSpatialAwareness フォルダー内に配置されます。 このアセンブリ定義では、Microsoft.MixedReality.Toolkit に対する依存関係と、これが依存する他のアセンブリを指定する必要があります。

ContosoInputEditor アセンブリ定義では、プロファイル インスペクターとエディター固有のコードを指定します。 このファイルは、エディター コードのルート フォルダーに配置する必要があります。 この例では、このファイルは ContosoSpatialAwareness\Editor フォルダー内に配置されます。 このアセンブリ定義には、ContosoSpatialAwareness アセンブリへの参照と以下を含めます。

  • Microsoft.MixedReality.Toolkit
  • Microsoft.MixedReality.Toolkit.Editor.Inspectors
  • Microsoft.MixedReality.Toolkit.Editor.Utilities

データ プロバイダーを登録する

データ プロバイダーを作成したら、アプリケーションで使用される空間認識システムに登録することができます。

空間オブジェクト メッシュ オブザーバーの選択

パッケージ化と配布

サード パーティ コンポーネントとして配布されるデータ プロバイダーには、パッケージ化と配布に関する特定の詳細を含めますが、この詳細は開発者の裁量に任されます。 最も一般的な解決策は、.unitypackage を生成し、Unity Asset Store を通じて配布する方法です。

データ プロバイダーが Microsoft Mixed Reality Toolkit パッケージの一部として送信され、受理されると、Microsoft MRTK チームは、それを MRTK オファリングの一部としてパッケージ化し、配布します。

関連項目