CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

iOS向け3Dスキャナ「Structure Sensor」のUnitySDKの使い方解説とTips紹介

HoloLensやTangoなど、最近のデバイスは空間認識機能に関するものが増えています。そこで、空間認識機能について学ぶため、iOSデバイスで使える赤外線センサの「Structure Sensor」を試してみました。

概要はこちらにまとめられてますのでご確認ください。

■Structure Sensorの概要

iOS用赤外線センサー「 Structure Sensor 」ファーストインプレッション - Natural Software

■Structure Sensorのアプリを試した感想

ポータブル3DスキャナのStructure Sensorが届きました | develog.holo

■ Structure Sensorで3Dサイズが計測できるアプリの紹介(ビジネス向け)

Structure Sensor App開発(3Dサイズ計測アプリ) | PointCloudConsortium

だいたいの内容はすでに皆さんが書かれているので、今回はUnityでアプリを作る方法を紹介したいと思います。

1.準備

公式サイトにアクセスし、「JOIN Developer Program」をクリックします。個人利用か企業での利用かを選択し名前とメールアドレスを入力します。入力するとURLがメールで届きます。Developer のページにあるダウンロードの部分をクリックすると、SDK一式をダウンロードできます。

2.UnitySDKについて

2.1 Unity SDKの概要

この中には、Xcodeのプロジェクトと、Unityのunity packageが入っています。ここではUnity側について解説します。UnityのSDKは2種類あります。

StructureUnityAR

Structure Sensorを使って、対象物のメッシュデータを取得し、UnityのCollisionを使ってGameobjectとの衝突判定をさせる機能です。

StructureUnityUBT

Structure Sensorのカメラでキャプチャした画像のフレーム単位の変化から、実空間の移動をUnity空間にマッチングさせる機能です。

なお、アプリ開発には以下の環境を準備する必要があります。()は、私の動作環境です。

  • Unity5.1.3f1以上 (Unity5.3.4f1)
  • Xcode 6.4 (7.3.1)
  • Mac OX 10.10.5 (10.11.5)
  • iOS 8.4 (iPhone SE 9.3.1)
  • Structure IO SDK ver0.5.5

また、前提として、2つのunity packageは排他的なので、別々のUnityプロジェクトで開発する必要があります。たとえば、StructureUnityAR.unitypackageをインポートした後、StructureUnityUBT.unitypackageを同じUnityプロジェクトにインポートすると、このようなエラーがでます。

StructureUnityAR.unitypackageとStructureUnityUBT.unitypackageを同じUnityにインポートした時のエラー画面

2-2. StructureUnityAR の概要

まずはダウンロードしたSDKから、StructureUnityAR.unitypackageをインポートします。インポートすると、3種類のサンプルシーンがあります。これをベースに開発するのがよいです。

StructureUnityAR SDKの3つのサンプルシーン

BallPhysics

空間のメッシュを取得して、"DropBall"ボタンをタップすると、たくさんボールが落ちてきます。メッシュにはColliderがついているので、ボールはメッシュに当たるとバウンドします。

メッシュは普段見えないようになっていて、ボールがぶつかると、この画像のようにぶつかった付近だけが見えます。

BallPhysicsの実行画面

Fetch

空間のメッシュを取得して、"Toggle Hoop"ボタンをタップすると、キャラクターが出てきます。キャラクターをタップして、星形のオブジェクトまで連れて行けばよいようです。

Fetchの実行画面

Simple

空間のメッシュを取得してカメラプレビューに重ねて表示します。これが基本のサンプルです。

Simpleの実行画面

文字がたくさんあるのは、ソフトの挙動をテキスト表示するようになっているためです。

ちなみに、空間スキャンをするためには、Assets/StructureUnityAR/Sample/Simple/Scripts/SimpleObject.csの処理を使います。

"Simple"の場合、ここで定義したCubeの大きさの範囲内にある物体をスキャンします。

2-3. StructureUnityUBTの概要

ダウンロードしたSDKから、StructureUnityUBT.unitypackageをインポートします。インポートすると、5種類のサンプルシーンがあります。

StructureUnityUBTの5つのサンプルシーン名

ただ、Example、Barehouse、Stackerの違いはよくわかりませんでした。ここでは、Example、MotionLoggingEnabled、SanFranciscoApartmentの3つを解説します。

Example

Structure Sensorを装着したiOSデバイスを持って歩き回ると、画面上のUnity空間が歩行量に合わせて移動します。

Exampleの実行画面

MotionLoggingEnabled

歩いた軌跡をUnity空間に保存する機能です。

MotionLoggingEnabledの実行画面

Structure Sensorを装着したiOSデバイスを持ってから、Record Pathボタンをタップします。

MotionLoggingEnabledで保存した軌跡の再生画面

Stop Recordingをタップするまでの歩いた軌跡がUnity空間で保存されます。Play Last Pathをタップすると、保存した軌跡に合わせて、カメラオブジェクトが動きます。

SanFranciscoApartment

これはStructure Sensorを使わずに、Unity EditorだけでExampleの雰囲気を体感するものです。

SanFranciscoApartmentの画面

WASDキーでシーン内を移動できます。おそらく、Unityに慣れてない人向けです。UBT機能を使うために、いくつかのPrefabが準備されています。

UBTを使うためのPrefabの例

STPlayer

トラッキングさせるための機能が入ったPrefabです。原則、これをHierarchy Viewにドラッグしておきます。

StructureStatusUI

UI関係の機能が入っています。Hierarchy Viewにドラッグしておくと、debugログや、uGUIのテキスト表示、バッテリー状態の表示ができます。

また、MotionLoggingEnabledで使った、モーションパスを保存し、iTunes経由で取り出すこともできるようです。

MiniMapCanvas

STPlayerの動いた量を地図で表示します。

BarebonesPlayer

すいません、これはちょっとわかりませんでした。

3. HoloLensの空間スキャンのような描画を作ってみる

HoloLensには、一定時間で空間をスキャンするとき、アニメーション付きでメッシュが生成されます。

HoloLens Emulatorで作った空間スキャンメッシュの例

自動的にメッシュ生成のアニメーションをつけるとHoloLensのようになって面白いかも、ということで、アニメーション付きメッシュの自動生成方法を調べました。

まずは、StructureUnityARのunitypackgeをインポートします。Assets/StructureUnityAR/Samples/Simple/Scenesから、Simpleシーンを開きます。このまま、File→ Save Scene as で別名で保存します。

以下のようなスクリプトを準備します。


Clicking button emulation at 4 sec interval

また、AutoScanController.csをCubeにアタッチし、さらに、ActionButtonオブジェクトをAutoScanControllerコンポーネントにドラッグします。

AutoScanController.csの準備例

デバッグログは残りますが、これで実機を見ると、4秒おきにスキャンするアニメーションを見ることができます。

補足

やっていることは非常に単純で、単にSimpleアプリに実装されていたuGUIのボタンを4秒おきに押しているだけです。

Simpleアプリは、以下の処理でボタンがタップされるたびに内部の状態を1ずつインクリメントしています。


Part of Buttons.cs provided by Occipital Team

なので、そこを利用して、ボタンタップのエミュレーション処理を入れました。

ちなみに、ボタンタップのエミュレーションは下記のようなコードとuGUIのボタンがあれば再現できます。この場合、キーボードのEをクリックすると、ボタンタップに合わせた動きをします。


Emulation for clicking button of uGUI

4. Tips

4-1. ビルドエラーの対処方法

Unhandled Exception : System.TypeLoadException、というエラーがでるときは、Build SettingsのSwitch PlatformをiOSに変更します。

4-2. ビルド設定

UnityでXcodeのプロジェクトを生成するとき、Build Settingsの設定が不十分だと、

・実機転送に失敗する

・実機転送は成功するが、アプリが起動しない

・アプリは起動するが何も動かない

のどれかになります。わかるまで少し時間がかかりました。

では、設定方法です。

Resolution and Presentation

Resolution and Presentationの設定

Default OrientationをLandscape Leftにします。

Other Settings

 Other Settingsの設定

Automatic Graphics APIのチェックを外します。すると、OpenGLES2とMetalというAPIが表示されるので、Metalにカーソルを合わせて”ー”ボタンでdeleteします。Bundle Identifier は com.<文字列>.<文字列>のようにします。

また、Optimization / API Compatibility Level は.NET2.0にします。それ以外はスクショの通りです。

以後、ビルドしてUnityで動かすまでの手順については、下記をご覧ください。

iOSアプリを作ったことがない人が、Unityで作ったアプリをiOSデバイスに実機転送する方法(無料 ) - Cross Technology

4-3. 床をスキャンしてくれないときの対処方法

Structure Sensor で色々試しているとき、壁は認識するのですが、床が認識されませんでした。下記のようにQuality Settingsのレベルを下げたところ、認識するようになりました。(初期設定ではFantasiticになっていました)

Quality Settingsの設定画面

5. 感想

センサー関係はこれまでKinectくらいしか試したことがなかったので、色々と勉強になりました。

(Kinectを使う例)
Unityでモーションキャプチャを取れる、Cinema Mocapを試してみました - Cross Technology

もう一つの使い方である、3Dスキャナとしてはあまり使いこなせてません。たとえば、手元にあったLPIC公式キャラクタをスキャンしてみます。

スキャン対象のLPICぬいぐるみ

これをスキャンするとこうなります。

スキャン結果

このように、周囲の物体(床含む)が入り込んでしまいます。私のモデリング技術が低いので、この辺を取り除く方法がわかってません。

あと、今のところ、色情報はスキャンしないようです。

=======
2016/6/12 追記

@kaorun55 さんより、iPad であれば色情報も取得できそうという情報をいただきました。(私が試したのはiPhoneSEです)

@kaorun55さん、ありがとうございます。

ただ、私のiPadは古くてLightningケーブルが挿さらないため、確認ができない状態です。

しばらくiPadを買い換える予定がないので、確認は先になりそうですが、モデリングの勉強をするときになったら試してみたいと思います。
=======

空間認識としても色々可能性がありそうですが、3Dスキャナとしてもう少し使いやすいとさらによいなと思いました。