3Dスキャナ「Structure Sensor」のアプリをUnityで開発する方法をまとめました

HoloLensやTangoなど、最近のデバイスは空間認識機能に関するものが増えています。

そこで、空間認識機能について学ぶため、iOSバイスで使える赤外線センサの「Structure Sensor」を試してみました。

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

■Structure Sensorの概要

www.naturalsoftware.jp

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

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


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

www.pointcloud.jp


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

=================================
目次

1.準備

2.UnitySDKについて

2-1. Unity SDKの概要

2-2. StructureUnityAR の概要

2-3. StructureUnityUBTの概要

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

4. Tips

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

4-2. ビルド設定

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

5. 感想

=================================

1.準備

公式サイトにアクセスし、「JOIN Developer Program」をクリックします。

f:id:Takyu:20160611052105j:plain

個人利用か企業での利用かを選択します。

f:id:Takyu:20160611052205j:plain

名前とメールアドレスの入力を求められます。入力するとURLがメールで届きます。

ちなみに、「JOIN Developer Program」のページには「 Retrieve your login information.」とあります。

しかし、ここをクリックしてもログイン画面にいくわけではなく、再度メールアドレスを入力することになります。

f:id:Takyu:20160611052429j:plain

一度入れたらブックマークしておくのがおすすめです。

(注)メールに送られたURLは個人で異なる("https://developer.structure.io/portal?key=AAAAA"のようになっている)ので、JOIN Developer Programをクリックした本人のみが使うことを前提としているようです。


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)


また、前提として、2つのunity packageは排他的なので、別々のUnityプロジェクトで開発する必要があります。

たとえば、StructureUnityAR.unitypackageをインポートした後、StructureUnityUBT.unitypackageを同じUnityプロジェクトにインポートすると、このようなエラーがでます。

f:id:Takyu:20160611060811p:plain

2-2. StructureUnityAR の概要

f:id:Takyu:20160611060943j:plain

まずはダウンロードしたSDKから、StructureUnityAR.unitypackageをインポートします。

インポートすると、3種類のサンプルシーンがあります。これをベースに開発するのがよいです。

f:id:Takyu:20160611062727p:plain

BallPhysics

空間のメッシュを取得して、"DropBall"ボタンをタップすると、たくさんボールが落ちてきます。

メッシュにはColliderがついているので、ボールはメッシュに当たるとバウンドします。

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

f:id:Takyu:20160611092110j:plain

Fetch

空間のメッシュを取得して、"Toggle Hoop"ボタンをタップすると、キャラクターが出てきます。

キャラクターをタップして、星形のオブジェクトまで連れて行けばよいようです。

f:id:Takyu:20160611102030j:plain

Simple

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

f:id:Takyu:20160529132430j:plain

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


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

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

2-3. StructureUnityUBTの概要

ダウンロードしたSDKから、StructureUnityUBT.unitypackageをインポートします。

インポートすると、5種類のサンプルシーンがあります。

f:id:Takyu:20160611081023p:plain

ただ、Example、Barehouse、Stackerの違いはよくわかりませんでした。

ここでは、Example、MotionLoggingEnabled、SanFranciscoApartmentの3つを解説します。

Example

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

f:id:Takyu:20160611081423j:plain

MotionLoggingEnabled

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

f:id:Takyu:20160611081911j:plain

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


f:id:Takyu:20160529123513j:plain


Stop Recordingをタップするまでの歩いた軌跡がUnity空間で保存されます。

Play Last Pathをタップすると、保存した軌跡に合わせて、カメラオブジェクトが動きます。

SanFranciscoApartment

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

f:id:Takyu:20160611085159j:plain

WASDキーでシーン内を移動できます。おそらく、Unityに慣れてない人向けです。



UBT機能を使うために、いくつかのPrefabが準備されています。

f:id:Takyu:20160611085909j:plain

STPlayer

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

StructureStatusUI

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

また、MotionLoggingEnabledで使った、モーションパスを保存することもできるようです。

f:id:Takyu:20160611090456j:plain
(マニュアルから抜粋しました)

MiniMapCanvas

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

BarebonesPlayer

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

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

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

f:id:Takyu:20160508154938g:plain


自動的にメッシュ生成のアニメーションをつけると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コンポーネントにドラッグします。

f:id:Takyu:20160611095409j:plain

デバッグログは残りますが、これで実機を見ると、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. ビルドエラーの対処方法

f:id:Takyu:20160611080907p:plain

このようなエラーがでるときは、Build SettingsのSwitch PlatformをiOSに変更します。

4-2. ビルド設定

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

・実機転送に失敗する

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

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

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




では、設定方法です。

Resolution and Presentation

f:id:Takyu:20160611103241j:plain


Default OrientationをLandscape Leftにします。

Other Settings

f:id:Takyu:20160530113226p:plain


Automatic Graphics APIのチェックを外します。

すると、OpenGLES2とMetalというAPIが表示されるので、Metalにカーソルを合わせて”ー”ボタンでdeleteします。

Bundle Identifier は com.<文字列>.<文字列>のようにします。


また、Optimization / API Compatibility Level は.NET2.0にします。

それ以外はスクショの通りです。


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

magicbullet.hatenablog.jp

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

Structure Sensor で色々試しているとき、壁は認識するのですが、床が認識されませんでした。

下記のようにQuality Settingsのレベルを下げたところ、認識するようになりました。
(初期設定ではFantasiticになっていました)

f:id:Takyu:20160611122629j:plain

5.感想

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

(Kinectを使う例)
magicbullet.hatenablog.jp

もう一つの使い方である、3Dスキャナとしてはあまり使いこなせてません。

たとえば、LPIC公式キャラクタをスキャンしてみます。

f:id:Takyu:20160611124627j:plain

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

f:id:Takyu:20160611124609j:plain

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

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

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

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

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

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

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


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