こんにちは。HoloLensチームの野元です。
先日、待ちに待ったHoloLens2が発売されましたね!手元にHoloLens2が来るのを今か今かと待ち望んでいる今日この頃です。(笑)
HoloLensを使用すると空間をスキャンしてメッシュデータを取得することが出来ます。
HoloLens1ではHTK(HoloToolKit)のSpatialMappingを使ってメッシュデータを取得していましたが、HoloLens2ではMRTK(MixedRealityToolkit)のSpatialAwarenessを使用しメッシュデータの取得する必要があります。(HoloLens1でもMRTKは使えます。)
HoloLens2がいつ手に入ってもいいように、MRTKを使用したメッシュデータの取得方法を見ていくことにします。
MRTK is 何?
MRTKは、Mixed Reality Toolkitの略称であり、Virtual Reality (VR) 及び Augmented Reality (AR) の Mixed Reality エクスペリエンスを構築するためのクロスプラットフォームツールキットのことです。
HoloLensアプリケーションを作る際には、MRTKがないと始まらないレベルで重要です。
詳しく知りたい方は、MRTK公式ドキュメントをご覧ください。
検証環境
- Windows 10 SDK (10.0.18362.0)
- Unity 2018.4.2.f1
- Visual Studio 2019
- Microsoft Mixed Reality Toolkit v2.1.0
方法その1. メッシュデータを全件取得する
下記の通りにすると、HoloLensがスキャンしたメッシュデータを一括で取得することできます。
// SpatialAwarenessSystemをIMixedRealityDataProviderAccessにキャストしてオブザーバーを取得します
var access = CoreServices.SpatialAwarenessSystem as IMixedRealityDataProviderAccess;
// 利用可能な最初のメッシュオブザーバーを取得します。通常、登録されているのは1つだけです。
var observer = access.GetDataProvider< IMixedRealitySpatialAwarenessMeshObserver>();
// 既知のすべてのメッシュをループします
foreach (SpatialAwarenessMeshObject meshObject in observer.Meshes.Values)
{
// ここでメッシュが取れます
Mesh mesh = meshObject.Filter.mesh;
// 以降はお好みの処理をどうぞ!
}
方法その2. メッシュデータの差分を取得する
下記の通りにすると、HoloLensがスキャンしたメッシュデータを逐一差分で取得することができます。
// タイプを簡素化します
using SpatialAwarenessHandler = IMixedRealitySpatialAwarenessObservationHandler< SpatialAwarenessMeshObject>;
public class MeshObservationExample : MonoBehaviour, SpatialAwarenessHandler
{
private bool isRegistered = false;
private void OnEnable()
{
RegisterEventHandlers();
}
private void OnDisable()
{
UnregisterEventHandlers();
}
/// SpatialAwarenessSystemイベントを登録します
private void RegisterEventHandlers()
{
if (!isRegistered && (CoreServices.SpatialAwarenessSystem != null))
{
CoreServices.SpatialAwarenessSystem.RegisterHandler< SpatialAwarenessHandler>(this);
isRegistered = true;
}
}
/// SpatialAwarenessSystemイベントを登録解除します
private void UnregisterEventHandlers()
{
if (isRegistered && (CoreServices.SpatialAwarenessSystem != null))
{
CoreServices.SpatialAwarenessSystem.UnregisterHandler< SpatialAwarenessHandler>(this);
isRegistered = false;
}
}
/// メッシュが追加されたときに呼ばれます
public void OnObservationAdded(MixedRealitySpatialAwarenessEventData< SpatialAwarenessMeshObject> eventData)
{
// メッシュ追加時の処理を記述します
}
/// メッシュが更新されたときに呼ばれます
public void OnObservationUpdated(MixedRealitySpatialAwarenessEventData< SpatialAwarenessMeshObject> eventData)
{
// メッシュ更新時の処理を記述します
}
/// メッシュが削除されたときに呼ばれます
public void OnObservationRemoved(MixedRealitySpatialAwarenessEventData< SpatialAwarenessMeshObject> eventData)
{
// メッシュ削除時の処理を記述します
}
}
まとめ
周辺環境は常に変化していくと思うので、HoloLensの空間スキャンデータの差分をハンドリングする方がベターがと思います。
さらに詳しく知りたい方は、SpatialAwarenessの項目をご覧ください。