こんにちは。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の項目をご覧ください。