Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

UnityによるHoloLensアプリケーション入門

8,455 views

Published on

MRTK2017.2.1.3の資料です。

Published in: Technology
  • Visit this site: tinyurl.com/sexinarea and find sex in your area for one night)) You can find me on this site too)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Sex in your area for one night is there tinyurl.com/hotsexinarea Copy and paste link in your browser to visit a site)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Girls for sex are waiting for you https://bit.ly/2TQ8UAY
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Meetings for sex in your area are there: https://bit.ly/2TQ8UAY
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Best site for flirting and sex in your area you can find there: https://bit.ly/2SlcOnO
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

UnityによるHoloLensアプリケーション入門

  1. 1. UnityによるHoloLens アプリケーション入門 石井勇一 2018/03(2018/04/04公開版)
  2. 2. 0. はじめに (C) 2018 石井 勇一 2
  3. 3. 研修の概要 本研修はUnityによるHoloLensアプリケーションの作成に必要な基礎知識を身につけるための 必要な機能について紹介します。 ◦ Unityが提供する多種多様なプラットフォーム対応を説明できる ◦ Unityの基本概念を理解して基本的な操作ができる ◦ Unityの基本コンポーネントとその制御スクリプトを簡単な物であれば自作できる ◦ HoloLensアプリケーションを作るために必要な機能について把握し、適切な提案ができる (C) 2018 石井 勇一 3
  4. 4. 使用しているソフトウェアについて ソフトウェア名 バージョン Unity Unity 2017.2.1.p1(MRTK対応バージョン) PC Windows 10 Fall Creators Update必須 Visual Studio 2017 MixedRealityToolkit‐Unity 2017.2.1.3 Hot Fix https://github.com/Microsoft/MixedRealityToolkit‐Unity/releases (C) 2018 石井 勇一 4
  5. 5. 目次 1. HoloLensアプリ開発入門 1. MixedRealityToolkit‐Unity とは 2. Input(Gaze/AirTap/Voiceなど) 3. Spatial Sound 4. Spatial Mapping 5. UX Controls 6. Spatial Understanding 7. Sharing 8. その他便利な機能や情報 (C) 2018 石井 勇一 5
  6. 6. 1.HoloLensアプリ開発入 (C) 2018 石井 勇一 6
  7. 7. HoloLens HoloLensのハードウェア仕様 ◦ https://developer.microsoft.com/en‐us/windows/mixed‐reality/hololens_hardware_details ◦ CPU: Intel 32 bit architecture ◦ GPU: HPU 1.0 (HoloLens専用に開発) ◦ RAM: 2GB ◦ Flash: 64GB ◦ Sensors: Depth Camera, Ambient light sensor, Image camera ◦ ETC: Bluetooth 4.0LE / Wi‐Fi 802.11ac / Speaker / Microphone OS: Windows 10 (Universal Windows Platform) (C) 2018 石井 勇一 7
  8. 8. HoloLensアプリ開発の流れ 1. UnityでWindows Store(Universal Windows Platform向け)に切り替えて開発 2. UnityからVisual Studioプロジェクトファイルの作成 3. Visual Studioでx86版のアプリをビルド&配備(HoloLensにインストール) (C) 2018 石井 勇一 8
  9. 9. (参考): UWPとは ユニバーサル Windows プラットフォーム (UWP) アプリとは ◦ https://docs.microsoft.com/ja‐jp/windows/uwp/get‐started/whats‐a‐uwp (C) 2018 石井 勇一 9
  10. 10. Unity標準機能によるHoloLens用設定 新規にプロジェクトを作成 プロジェクトの設定 ◦ File > Build &  Settingsを実行 ◦ Universal Windows Platformに切り替え ◦ Player Settingsボタンを押す ◦ Other Settingsの「Scripting Backend」を.NETに変 更 ◦ XR Settingsの「Virtual Reality Supported」を チェック。これでWindows Mixed Realityが選択さ れている ◦ Edit > Project Settings > Qualityを実行 ◦ Universal Windows Platformの設定をVery Low に変更 (C) 2018 石井 勇一 ここをクリック 10
  11. 11. Unity標準機能によるHoloLens用設定 シーンの設定 ◦ Main CameraのTransformコンポーネントの歯車アイコンをク リックして「Reset」を実行 ◦ Main CameraのCameraのClear FlagsをSolid Colorに変更 ◦ Main CameraのCameraのBackgroundを黒(0, 0, 0)に変更 ◦ Main CameraのCameraのClipping PlanesのNearを0.85に変更 以上の設定を毎プロジェクトごとに実施しなければならな いのでMRTKを使って一気に設定をする方法を紹介します。 (C) 2018 石井 勇一 11
  12. 12. HoloLensのためのカメラ設定 快適なカメラの設定 https://developer.microsoft.com/en‐us/windows/mixed‐reality/comfort (C) 2018 石井 勇一 12
  13. 13. HoloLensのためのカメラ設定 HoloLensのディスプレイは「光の加算」 ◦ 白色:明るく見える ◦ 黒色:透明に見える 黒が透明になる特性を活かして、実際に描画する3Dオブジェクト以外は黒にする ライティングや色に関する詳細情報 ◦ https://developer.microsoft.com/en‐us/windows/mixed‐reality/color,_light_and_materials (C) 2018 石井 勇一 13
  14. 14. Cubeを配置 物を配置する適切な位置 https://developer.microsoft.com/en‐us/windows/mixed‐reality/gaze_targeting (C) 2018 石井 勇一 14
  15. 15. Cubeを配置 [GameObject]‐[3D Object]‐[Cube]でCubeを配置 InspectorのTransformコンポーネント ◦ Position:  0, 0, 2 (前方2m先) ◦ Scale: 0.1, 0.1, 0.1(全体的に10分の1にする) UnityのCubeは一辺が1mの立方体です。そのスケールを0.1倍するので、一辺が10cmの立方 体になります。 (C) 2018 石井 勇一 15
  16. 16. 1.1 MixedRealityToolkit‐ Unity とは (C) 2018 石井 勇一 16
  17. 17. MixedRealityToolkit‐Unity Mixed Reality Toolkitは、Microsoft HoloLensとWindows Mixed Realityヘッドセットを対象とした アプリケーション開発のためのスクリプトとコンポーネントの集まりです。 MixedRealityToolkit ‐ UnityはMixedRealityToolkitベースのコードを使用しており、さらにUnityで 簡単に利用できるようになっています。 (C) 2018 石井 勇一 17
  18. 18. (C) 2018 石井 勇一 18
  19. 19. 提供機能概要(HoloLens限定) Input ◦ 視線(Gaze)、ジェスチャー、音声およびモーションコントローラなどの入力を活かすスクリプト。 Spatial Mapping ◦ HoloLensを使用して実際の世界にデジタルを持ち込むためのスクリプト。 Spatial Sound ◦ 空間オーディオをアプリケーションで実現するためのスクリプト。 (C) 2018 石井 勇一 19
  20. 20. 提供機能概要(HoloLens限定) UX Controls ◦ 共通のコントロールのように、アプリケーションにより良いUXを作成するための部品 Spatial Understanding ◦ ソファや壁などの部屋を「理解する」ためのスクリプト Sharing ◦ 複数のHoloLesnで同一の映像を見ることで共同作業を可能にします。 (C) 2018 石井 勇一 20
  21. 21. MRTKの導入と初期設定 Unityで新規にプロジェクトの作成 HoloToolkit‐Unity‐2017.2.1.3.unitypackageをインポート Mixed Reality Toolkit > Configure > Apply Mixed Reality Project Settingsを実行 (C) 2018 石井 勇一 21
  22. 22. MRTKの導入と初期設定 HoloLensの場合はそのままApplyをクリック これで P.8 で紹介した内容の設定が完了しま す。 それぞれの説明は次ページ以降で紹介。 (C) 2018 石井 勇一 22
  23. 23. MRTKの導入と初期設定 Target Windows Universal UWP ◦ Universal Windows Platformをターゲットとする Storeアプリケーションに切り替えます。 Enable XR ◦ Mixed Reality Supportを有効にします。 Build for Direct3D ◦ XAMLではなくDirect3Dをターゲットとするアプリ ケーションを作成します。 Target Occluded Devices ◦ VR hardwareの場合はチェックし、HoloLensの場 合はチェックを外します。 (C) 2018 石井 勇一 23
  24. 24. MRTKの導入と初期設定 Enable Sharing Services ◦ Sharing機能を使うときに有効にします。あとから も設定を変えられます。 Use Toolkit‐specific InputManager axes ◦ Xboxコントローラを使用するときはチェックする。 Project Settings/Inputの定義ファイルを上書き するので注意 Enable .NET scripting backend ◦ Scripting backendを .NETに変更する (C) 2018 石井 勇一 24
  25. 25. MRTKの導入と初期設定 シーンファイルを初期化 Mixed Reality Toolkit > Configure > Apply Mixed Reality Scene Settingsを実行 (C) 2018 石井 勇一 25
  26. 26. MRTKの導入と初期設定 HoloLensの場合はそのままApplyをクリック これで P.9 で紹介した内容の設定が完了しま す。 ですが、バグがあるので上手く動きません。 https://github.com/Microsoft/MixedRealityTo olkit‐Unity/issues/1790 これを修正するパッチはまだないのでこちら で用意しました。 (C) 2018 石井 勇一 26
  27. 27. MRTKの導入と初期設定 参考:Hierarchy のMixedRealityCameraParent の子要素のMixedRealityCameraにアタッチさ れているMixedRealityCameraManagerが実行 時にカメラの設定を変更します。 ◦ CameraのClear FlagsをSolid Colorに変更 ◦ CameraのBackgroundを黒(0, 0, 0)に変更 ◦ CameraのClipping PlanesのNearを0.85に変更 ただし、これはUnity上でプレイボタンを押し たときは「Opaque」扱いになるためSkybox+ QualityセッティングがUltraになってしまいます。 場合によってはこのスクリプトを無効化して手 動で設定することも考慮に入れてください。 Hierarchy View (C) 2018 石井 勇一 27
  28. 28. MRTKの導入と初期設定 Add the Mixed Reality Camera Prefab ◦ Mixed Reality Camera プレハブをシーンに追加します。本 来ならそのままで動作しますが、 Move Camera to Origin ◦ カメラの位置を(0, 0, 0)に設定します。 Add the Input Manager Prefab ◦ Input Managerプレハブを追加します。 Add the Default Cursor Prefab ◦ Default Cursorプレハブを追加します。 Update World Space Canvases ◦ 全てのWorld SpaceのCanvasに対して視線からのイベント を受け取れるようにUIRaycastCameraをデフォルトイベント カメラとして使用します。 ◦ 以後もCanvasをWorld Space に変えると自動的に追加お よび設定をします。 (C) 2018 石井 勇一 28
  29. 29. Cubeを配置 何も無いと寂しいのでCubeを配置しましょう。 位置やスケールは以下の通りにします。 ◦ Position(0, 0, 2) ◦ Scale(0.1, 0.1, 0.1) (C) 2018 石井 勇一 29
  30. 30. Unity Editor上で動作させる そのままPlayボタンを押すとUnity Editor上でも動作させることができます。 Unity Editor上での操作 ◦ 移動:マウスの右ボタンを押しながらWASDおよびQEキー ◦ 視線:マウスの右ボタンを押しながら動かす ◦ AirTap: マウスのボタンから手をいったん離し、Shiftキーを押しながらマウスの左ボタン Cubeに視線を合わせたり、外したり、AirTapしてみましょう Skyboxが表示されていますが問題ありません(実機に転送したり、リモート接続、 Simulate モードの時は自動的にHoloLens用にCameraの設定を変更します) (C) 2018 石井 勇一 30
  31. 31. アプリケーションのビルド方法 本来であればメニューのMixed Reality Toolkit > Build Windowの画面から適切な設定をするこ とでビルドおよびHoloLensへの配信が出来るようになっていますが、Visual Studioの内部バー ジョンの変更に伴い上手く動作しないことが多いです。 そのため少々手間ですが、Visual Studioを経由する方法を紹介します。 (C) 2018 石井 勇一 31
  32. 32. アプリケーションのビルド方法 Sceneの保存(Ctrl+S)、Projectの保存(File >  Save Project)は確実に実施する File > Build Settingsを開く Buildボタンを押す(Build & Runではない) (C) 2018 石井 勇一 32
  33. 33. アプリケーションのビルド方法 UWPでは直接アプリケーションのビルドは行 わずに、一度Visual Studio用のプロジェクト ファイル一式を生成します。 ここではそれらを格納するフォルダ名を指定 します。 お勧めは「新しいフォルダー」でフォルダを作 成してそこに格納する方法です。 名前は何でも良いですが、ここでは「App」と します。 フォルダを選択したら「フォルダの選択」ボタ ンを押す (C) 2018 石井 勇一 Appフォルダを作成してそれを指定する 33
  34. 34. アプリケーションのビルド方法 しばらくすると図の用の先ほど選択したフォ ルダを表示するようにエクスプローラーが起 動します。 選択したフォルダ(App)の中に移動します。 (C) 2018 石井 勇一 34
  35. 35. アプリケーションのビルド方法 フォルダの中に「Unityのプロジェクト名.sln」と いう名前のVisual Studio用のソリューション ファイルがありますのでそれをダブルクリック します。 (C) 2018 石井 勇一 35
  36. 36. アプリケーションのビルド方法 ビルドターゲットを「Release」、「x86」、「Device」に変更します。 (C) 2018 石井 勇一 36
  37. 37. アプリケーションのビルド方法 ReleaseにするのはDebug版では性能が出ないためです。 x86にするのはHoloLensが32bit版 IntelアーキテクチャCPUだからです(ATOM) DeviceにするのはHoloLensがUSBケーブルでPCに繋がっているときに奏します。 PC/HoloLensともに同一ネットワークにつながっている場合は「リモートコンピューター」を選び、 HoloLensのIPアドレスを入力することでケーブルレスで繋げることもできます。 (C) 2018 石井 勇一 37
  38. 38. HoloLens開発者モード HoloLensを起動 メニューの中から「Settings」を実行 (C) 2018 石井 勇一 38
  39. 39. HoloLens開発者モード 「Update & Security」を実行 (C) 2018 石井 勇一 39
  40. 40. HoloLens開発者モード 「For developer」を実行 (C) 2018 石井 勇一 40
  41. 41. HoloLens開発者モード Developer modeを「On」にする (C) 2018 石井 勇一 41
  42. 42. HoloLens開発者モード Device Portalを「On」にする (C) 2018 石井 勇一 42
  43. 43. HoloLensの設定 HoloLensをUSBケーブルでPCに接続 Edge(Webブラウザ)を起動 以下のURLを開く(HoloLens内に実装されているDevice Portalへアクセスする) ◦ http://127.0.0.1:10080/ 初回接続時はユーザ名とパスワード(パスワードは最低7文字以上)の作成をする。その際、 HoloLensに表示されているPINを使用する 裏技:もし誰かがユーザー登録していたとしても、5回連続間違えることでユーザー名とパス ワードを再設定できます。 (C) 2018 石井 勇一 43
  44. 44. HoloLensの設定 Device Portal画面 (C) 2018 石井 勇一 44
  45. 45. Visual Studioによる操作 Visual Studioの上部にあるDebug / ARM / Deviceを以下のようにに修正してください。 (C) 2018 石井 勇一 45
  46. 46. Visual Studioによる操作 [デバッグ]‐[デバッグなしで開始]またはCtrl + F5を押してコンパイル&リンク&配置(インストー ル)&実行をします。 それなりに時間が掛かります。その間にHoloLensがスリープしないように注意してください (Device Portalでスリープするまでの時間を変更できます)。 (C) 2018 石井 勇一 46
  47. 47. Visual Studioによる操作 もし途中でPINを聞かれた、HoloLensのSettingsの[Update & Security]‐[For Developer]のPaired  devicesの[Pair]ボタンを押して出てきた数字を入力して下さい。 (C) 2018 石井 勇一 47
  48. 48. Visual Studioによる操作 Visual Studioへの入力が終 わり、ボタンが「Done」に変 わったらクリックして閉じる (C) 2018 石井 勇一 48
  49. 49. 実行結果 2m先に一辺が10cmの立方体が表示されるはずです (C) 2018 石井 勇一 49
  50. 50. Holographic Remoting Player Unity上での再生でもある程度操作ができますが実機でテストしたくなることも多いです。 しかし、実機でテストするにはそれなりビルド時間が掛かります。 「Holographic Remoting Player」を使う事でこれらの問題点をある程度解決できます。 https://developer.microsoft.com/en‐us/windows/mixed‐reality/holographic_remoting_player PC側のシステム要件 ◦ Windows 10 Anniversary Update以降必須(現在はFall Creators Update) ◦ GeForce GTX 970 または AMD Radeon R9 290以上のグラフィックボード ◦ PCは可能であれば有線接続にして不要なホップ数を減らすことを推奨 (C) 2018 石井 勇一 50
  51. 51. Holographic Remoting Playerの使い方 HoloLensのストアから「Holographic Remoting Player」を探してインストールする ◦ https://www.microsoft.com/ja‐jp/store/p/holographic‐remoting‐player/9nblggh4sv40 アプリを起動すると図のような画面が表示される。このときのIPアドレスを覚える (C) 2018 石井 勇一 51
  52. 52. Holographic Remoting Playerの使い方 Unityの[Window]‐[Holographic Emulation]を開く HolographicウィンドウのEmulation Modeを 「Remote to Device」に変更 先ほど覚えたHoloLensのIPアドレスを「Remote  Machine」に入力 [Connect]ボタンを押す。 小技:このとき上手くつながらないことがあります。 その場合、「Enable Audio」のチェックを一度外し てから再度「Connect」ボタンを押して繋げて、 「Disconnect」してから再度「Enable Audio」をチェッ クしてから「Connect」ボタンを押すと繋がることが あります。あと音声は重たい様なのでビットレート (一番下のスライドバー)を下げると良いかも知れ ません。 (C) 2018 石井 勇一 52
  53. 53. Holographic Remoting Player利用時の 注意点 全体的に不安定です(特にUnity側)。そのためこまめにプロジェクトやシーンファイルのセーブ を忘れずに。 Unity Editor上でエミュレーションをするならHolographicウィンドウのEmulation Modeを 「Simulate in Editor」にする方法もあります。その際、Unity Editor内におけるHoloLensの動きは ジョイパッドを使用します。 ◦ https://docs.unity3d.com/ja/current/Manual/windowsholographic‐emulation.html (C) 2018 石井 勇一 53
  54. 54. 1.2 Input GAZE/AIRTAP/VOICEなど (C) 2018 石井 勇一 54
  55. 55. Gaze(視線) HoloLensの基本的な入力はGaze(視線)になります。 目標 ◦ カーソルのビジュアル デザインと動作 ◦ 視線に応じたカーソルのフィードバック ◦ 視線に応じたホログラムのフィードバック カーソルのデザイン原則 ◦ カーソルは常時表示します。 ◦ カーソルは適切なサイズに保ちます。 ◦ コンテンツの邪魔にならないようにします。 (C) 2018 石井 勇一 55
  56. 56. 視線はレイキャスト 始点から直線を伸ばしてその途中に何かが衝突するかどうかを調べる機能 始点 距離 ヒット (C) 2018 石井 勇一 ヒット しない 56 © UTJ/UCL
  57. 57. InputManager 視線に関する設定はInputManagerに適用されているGaze Managerで行います。 最大距離は「Max Gaze Collision Distance」で設定します(単位はm) (C) 2018 石井 勇一 57
  58. 58. 視線カーソル関連のプレハブ 特に凝ったことをしなければシーンにプレハブを入れるだけで利用可能です。 格納場所は Assets/HoloToolkit/Input/Prefabs/Cursor です。 利用可能なプレハブは次のスライドを参照 (C) 2018 石井 勇一 58
  59. 59. 視線カーソル関連のプレハブ BasicCursor.prefab ◦ ユーザーの視線に沿ったトーラス型(ドーナッツ型)の基本カーソル。 Cursor.prefab ◦ ユーザがホログラムを注視しているときにトーラス型、ホログラムへの注視が外れると半透明な球体 の形のカーソルに変わります。 CursorWithFeedback.prefab ◦ ユーザーの視線に沿ったトーラス型のカーソルに加えて、手を認識すると指のアイコンを表示する。 DefaultCursor.prefab ◦ ユーザーの視線に沿った3Dアニメーションカーソル。Unityのアニメーションシステムを使用してさまざ まな状態を処理します。 このカーソルは、HoloLensシェルのカーソルを模倣します。 (C) 2018 石井 勇一 59
  60. 60. Gaze関連イベント処理 注視されたときにイベントを発生させるためには以下のインタフェースを実装したスクリプトを 作成します。 IFocusable (C) 2018 石井 勇一 60 public interface IFocusable : IEventSystemHandler { void OnFocusEnter(); //フォーカス(注視)し始めたとき時 void OnFocusExit(); // フォーカス(注視)が外れた }
  61. 61. Gaze関連イベント処理 プログラム例 (C) 2018 石井 勇一 61 using UnityEngine; using HoloToolkit.Unity.InputModule; // IFocusableインタフェースを実装することで、注視された時とはずれたときにそれぞれメソッドが呼び出される public class GreetingUnitychan : MonoBehaviour, IFocusable { private Animator anim; void Start() { anim = GetComponent<Animator>(); } // フォーカス(注視)し始めたとき時 public void OnFocusEnter() { anim.SetTrigger("Greeting"); } // フォーカス(注視)が外れた public void OnFocusExit() { // 今回は特に実装無し } }
  62. 62. ジェスチャー関連のイベント 様々なジェスチャーが発生した時に対応する処理を書くには以下のインタフェースを実装します。 IInputHandler ◦ オブジェクトへのInputDown / 対象へのInputUp IInputClickHandler ◦ オブジェクトへのクリックイベント(AirTap) ISourceStateHandler ◦ 手の検出。対象を見ている状態で手が認識されている / 対象を見ている状態で手が認識から外れた IHoldHandle ◦ ホールドの検出。対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した IManipulationHandler ◦ ドラッグ操作。対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した / 途中でトラッキングが外れ た INavigationHandler ◦ ナビゲーション操作。対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した / 途中でトラッキング が外れた (C) 2018 石井 勇一 62
  63. 63. IInputHandlerインタフェース インタフェース (C) 2018 石井 勇一 63 public interface IInputHandler : IEventSystemHandler { void OnInputDown(InputEventData eventData); void OnInputUp(InputEventData eventData); }
  64. 64. IInputClickHandlerインタフェース インタフェース (C) 2018 石井 勇一 64 public interface IInputClickHandler : IEventSystemHandler { void OnInputClicked(InputClickedEventData eventData); }
  65. 65. ISourceStateHandlerインタフェース インタフェース (C) 2018 石井 勇一 65 public interface ISourceStateHandler : IEventSystemHandler { void OnSourceDetected(SourceStateEventData eventData); void OnSourceLost(SourceStateEventData eventData); }
  66. 66. IHoldHandleインタフェース インタフェース (C) 2018 石井 勇一 66 public interface IHoldHandler : IEventSystemHandler { void OnHoldStarted(HoldEventData eventData); void OnHoldCompleted(HoldEventData eventData); void OnHoldCanceled(HoldEventData eventData); }
  67. 67. IManipulationHandlerインタフェース インタフェース (C) 2018 石井 勇一 67 public interface IManipulationHandler : IEventSystemHandler { void OnManipulationStarted(ManipulationEventData eventData); void OnManipulationUpdated(ManipulationEventData eventData); void OnManipulationCompleted(ManipulationEventData eventData); void OnManipulationCanceled(ManipulationEventData eventData); }
  68. 68. INavigationHandlerインタフェース インタフェース (C) 2018 石井 勇一 68 public interface INavigationHandler : IEventSystemHandler { void OnNavigationStarted(NavigationEventData eventData); void OnNavigationUpdated(NavigationEventData eventData); void OnNavigationCompleted(NavigationEventData eventData); void OnNavigationCanceled(NavigationEventData eventData); }
  69. 69. 実装例 AirTapによって自分自身を消す (C) 2018 石井 勇一 69 using HoloToolkit.Unity.InputModule; using UnityEngine; // IInputClickHandlerを実装することで、注視&クリック(AirTap)時に呼び出されるメソッドが呼び出される public class HideCube : MonoBehaviour, IInputClickHandler { // 注視&クリック(AirTap)されると呼び出される public void OnInputClicked(InputClickedEventData eventData) { // 自分自身の削除 Destroy(gameObject); } }
  70. 70. 何も無い所をAirTapした時のイベントを 取得するには InputManager.Instance.AddGlobalListener()に登録する (C) 2018 石井 勇一 70 using HoloToolkit.Unity.InputModule; using UnityEngine; public class NothingSpaceClickHandler : MonoBehaviour, IInputClickHandler { void Start () { // 全てのジェスチャーイベントをキャッチできるようにする InputManager.Instance.AddGlobalListener(gameObject); } /// AirTapイベントのハンドラ public void OnInputClicked(InputClickedEventData eventData) { // 何もGazeしていないときだけ動作する if (!GazeManager.Instance.HitObject) { // ログを吐くだけ Debug.Log("Click on nothing point !!!!"); } } } 参考: http://blog.d‐yama7.com/archives/699
  71. 71. その他のイベントについて HoloLens+Unity開発 入力の取得まとめ編 by のしメモ アプリ開発ブログ http://www.noshimemo.com/entry/2017/01/28/133818 HoloLesnに対する操作とそれに対応するイベント発生を一つにまとめている動画がとても分か りやすい。 (C) 2018 石井 勇一 71
  72. 72. 1.3 Spatial Sound (C) 2018 石井 勇一 72
  73. 73. 空間音響 英語はSpatial Sound と言います。 HoloLensは実際の空間で数メートル先に物体を表示します。 そして、HoloLensはそこから音が発生しているかのように振舞うことができます。 (C) 2018 石井 勇一 73
  74. 74. Unityの設定 [Edit]‐[Project Settings]‐[Audio]を開く Spatializer Pluginを「MS HRTF Spatializer」に 変更 (C) 2018 石井 勇一 74 HRTF: 頭部伝達関数(Head-Related Impulse Response)
  75. 75. ユニティちゃんの設定 Audio Sourceコンポーネントを追加 設定を変更 ◦ Spatializeをチェック ◦ Play On Awakeのチェックを外す ◦ Spatial Blendを1(3D) ◦ 3D Sound Settingsを変更(次のスライド) (C) 2018 石井 勇一 75
  76. 76. ユニティちゃんの設定 AudioSourceの設定の続き ◦ Doppler Levelを0 ◦ Max Distanceを20 (C) 2018 石井 勇一 76
  77. 77. ユニティちゃんの設定 PlayAudioClipスクリプトを追加 (Assets/UnityCHan/Custom/Scripts/PlayAudioClip) Audio Clipsを0から3に変更してEnterキーを押す (C) 2018 石井 勇一 77
  78. 78. ユニティちゃんの設定 PlayAudioClipの設定の続き ◦ Element0~2に適当なAudio Clip(音声ファイル)をドラッグ&ドロップで設定する ◦ Assets/UnityChan/unitychan_voicepack_append_01に音声ファイルがあります。 (C) 2018 石井 勇一 78
  79. 79. Unity上で実行 Playボタンを押してみましょう。 ユニティちゃんに視線を合わせてAirTapすると設定した音声のどれかをランダムで喋ります。 動作が確認出来たらHoloLensにインストールして動作確認してみましょう。HoloLensでは空間 音響が試せるので、USBケーブルと人とPCに注意しながら移動したり顔を左右に振ってみて下 さい。 (C) 2018 石井 勇一 79
  80. 80. 応用 長時間再生する音声ファイルがあります。 Assets/UnityChan/Unite In The Sky (full) これをAirTapで再生停止できるCubeを作成してみましょう(図で示しているサンプルコードを参 照) 音声が少し大きいのでAudio Sourceの設定でVolumeを1から0.3などに変更するとよいでしょう。 音声の再生が始まったら近づいたり、離れたり、左右に頭を振ると空間音響の効果がよりはっ きりと分かると思います。 (C) 2018 石井 勇一 80
  81. 81. 応用 HoloLesn用に用意されているスクリプトがいくつかあります。 AudioEmitter.cs ◦ AudioSourceをカプセル化し、オーディオの影響(オクルージョンなど)の適用をサポートするクラスです。 AudioOccluder.cs ◦ ローパスフィルタと音量減衰を使用した簡単な形式のオーディオオクルージョンを実装するクラス。 IAudioInfluencer.cs ◦ AudioInfluencerに必要なメソッドを定義するインターフェース。 AudioOccluder.csで使用。 UAudioManager/UAudioManager.cs ◦ オーディオ全般を管理するクラス (C) 2018 石井 勇一 81
  82. 82. 応用 利用イメージ (C) 2018 石井 勇一 82 AudioOccluder AudioEmitterAudioEmitter 減衰して 聞こえる 何も影響を 受けずに聞こえる © UTJ/UCL
  83. 83. AudioEmitter.cs Update Interval ◦ オーディオへの影響の更新間隔(秒単位)。 0はすべてのフレームを更新することを示します。 Max Distance ◦ 最大距離 (単位はm)。 Max Objects ◦ 影響を受けるオブジェクトの最大数。 (C) 2018 石井 勇一 83
  84. 84. AudioOccluder.cs Cutoff Frequency ◦ ユーザーと AudioEmitter の間にある時に適用される最低周波数。 Volume Pass Through ◦ ユーザーと AudioEmitter の間にある時の音量の割合。 (C) 2018 石井 勇一 84
  85. 85. 応用 CubeにAudioEmitter.csをアタッチ 新たにCubeを作成して、Wallと名前を付ける。分かりやすく適当にマテリアルを作成して色を 付ける Wallの位置とスケールを調整 ◦ Position(0, 0, 1.5) ◦ Scale(0.3, 0.5, 0.05) WallにAudioOccluder.csをアタッチ AudioOccluderの値を以下のように修正 ◦ Cutoff Frequency: 600 ◦ Volume Pass Through: 0.5 (C) 2018 石井 勇一 85
  86. 86. 応用 Remote Playで試す場合はUnity Editorのシー ンビューでWallを左右にずらすと効果が分か ります。 実機に転送した場合はWallを回り込むとそ の効果が分かります。 (C) 2018 石井 勇一 86
  87. 87. 応用 UAudioManager.csを使うと、それぞれの音声を「AudioEvent」として名前を付けて、様々な設定 をまとめて管理できます。 (C) 2018 石井 勇一 87 UAudioManager (Singletone) Audio Bank (ScriptableObject) Audio Bank (ScriptableObject) Audio Event Bank (ScriptableObject) 音声を再生する スクリプト 音声の再生を依頼音声の再生方法を設定 Audio Event Bankを管理
  88. 88. Audio Bankの作成方法 Project Viewで右クリックして、Create > Audio Event Bankをクリック 「AudioEventBank」ファイルが生成される (C) 2018 石井 勇一 88
  89. 89. Audio Bankの設定 Audio Bankファイルを選択し、インスペクターからEventのAddボタンを押す (C) 2018 石井 勇一 89
  90. 90. Audio Bankの設定 設定例 ◦ NameはUAudioManager経由で再生するスクリ プトで指定する名前になります。 "/"を含めると サブメニューにすることができます。 ◦ Positioningを「Spatial Sound」にすると空間音響 になる。他にも2D/3Dなどもある。 ◦ Audio Event Interface Behaviorは音声ファイル の生成上限数(Instance Limit)を超えたときのア ルゴリズムを選択。Kill Oldestは古い音を止めて 再利用。Kill Newestは新しい音を止めて再利用。 (C) 2018 石井 勇一 90
  91. 91. UAudioManagerの設定 適当なGameObjectを作成してそこにアタッチする。 Default Banksを1以上の値にする(Audio Bank数分作成) 作成したAudio Bankをセットする (C) 2018 石井 勇一 91
  92. 92. 再生スクリプト HoloToolkit‐Unity‐Examples‐2017.2.1.3のUAudioManagerTestを参照 (C) 2018 石井 勇一 92 public class UAudioManagerTest : MonoBehaviour { [AudioEvent] public string Vocals3d; [AudioEvent]を付けておくと、 インスペクターからプルダウ ンメニューで選択できます。 UAudioManager.Instance.PlayEvent(Vocals3d); UAudioManager.InstanceでUAudioManagerのインス タンスを取得できます。PlayEvent()で音声を再生 します。AudioSourceコンポーネントは無ければ自 動的に追加します。 第二引数にAudioSourceコンポーネントへの参照を 指定するとそちらを使用します。
  93. 93. (C) 2018 石井 勇一 93
  94. 94. 1.4 Spatial Mapping (C) 2018 石井 勇一 94
  95. 95. Spatial Mappingとは HoloLensに搭載している複数のカメラを駆使して現実空間をリアルタイムにスキャンし、システ ム内に3Dモデルデータとして保存する機能です。データは逐次更新されます。 アプリケーションからも利用することができます。作成した3Dモデルデータにはコライダーが設 定されています。 (C) 2018 石井 勇一 95
  96. 96. Spatial Mappingを使う設定 [Mixed Reality Toolkit]‐[Configure]‐[Apply UWP Capability Settings]を実行(Capability=能力) (C) 2018 石井 勇一 96
  97. 97. Spatial Mappingを使う設定 Spatial Perceptionをチェックして「Apply」ボタ ンを押す その他のは「マイク」「カメラ(Webcam)」「イン ターネット接続(クライアントとサーバ)」などを 利用するときに同様の設定をします。 (C) 2018 石井 勇一 97
  98. 98. 【参考】UWPのCapabilityの設定 [Editor]‐[Project Settings]‐[Player]の Publishing Settingsの下の方にCapabilitiesの 設定があります。ここで設定してもOKです。 (C) 2018 石井 勇一 98
  99. 99. Spatial Mappingを使う設定 Assets/HoloToolkit/SpatialMapping/Prefabsにある SpatialMappingをHierarchyにドラッグ&ドロップする Unityではテストするときは、Holographicウィンドウで Emulation ModeをSimulate in Editorにし、適当なRoom を選択してください。 空間のスキャンは3.5秒間隔で行われますのでゆっく りと周りを見渡してください。 十分にスキャンが出来たと思ったらユニティちゃんの 床にあるCubeをAirTapしてユニティちゃんを落下させ てください。 上手くいくと床の上でユニティちゃんがとまります。机 の影になるように回り込むと、きちんと見えなくなると 思います。 (C) 2018 石井 勇一 99
  100. 100. Spatial Mappingを使う設定 Unityではテストするときは、HolographicウィンドウでEmulation ModeをSimulate in Editorにし、 適当なRoomを選択してください。 あるいはEmulation ModeをNoneにして、 SpatialMappingにアタッチされている ObjectSurfaceObserverのRoom Modelの右の◎ボタンを押して、 「MediumRoomWithHomeFurniture」を選択してから実行してください。これでダミールームデー タによるスキャン実験ができます。 (C) 2018 石井 勇一 100
  101. 101. クラス図 (C) 2018 石井 勇一 101 SpatialMappingSource SpatialMappingObserver SpatialMappingManager (Singleton) ObjectSurfaceObserver SpatialMappingObserverを操作するためのクラス ・スキャンの開始/停止 ・データソースからのデータの取り出しなど スキャンした空間データを扱う データソース Room Modelとして指定された スキャンデータを扱うデーソース 実機で空間すデータをスキャンする
  102. 102. インスペクターから設定できる内容 SpatialMapping.prefabにアタッチされているスク リプト SpatialMappingObserver.cs ◦ Triangles Per Cubic Meter 1立方メートルあたりに計算するポリゴン数。 ◦ Time Between Updates スキャンの更新間隔時間(単位は秒) ◦ Observer Volume Type 空間領域の形状と向き ◦ Axis Aligned Box: Worldアンカーと同じ軸の箱 ◦ Oriented Box: 傾きを指定できる(Orientationで指定) ◦ Sphere: 球体 ◦ Extents 空間領域の大きさ(単位はm) ◦ Origin 空間領域の開始位置 (C) 2018 石井 勇一 102
  103. 103. インスペクターから設定できる内容 SpatialMapping.prefabには3つのスクリプトが アタッチされています。 SpatialMappingManager ◦ Physics Layer 生成したメッシュのGameObjectのレイヤー番号 ◦ Surface Material メッシュに割り当てるマテリアル ◦ Auto Start Observer 空間スキャンを自動的に始めるかどうか ◦ Draw Visual Meshes メッシュの描画を行うかどうか ◦ Cast Shadow メッシュに影を表示するか (C) 2018 石井 勇一 103
  104. 104. インスペクターから設定できる内容 SpatialMapping.prefabには3つのスクリプトが アタッチされています。 ObjectSurfaceObserver ◦ Room Model 予めスキャン済みの部屋のモデルをプレハブを 指定する ◦ Simulated Update Period In Seconds シミュレートするアップデート間隔(単位は秒)。 ゼロ以上の場合、サーフェスオブジェクトはこの 期間に更新される場合に使用します。 これは、 Spatial Understandingライブラリなどのように更 新に応答するライブラリを使用する際に便利で す。負の場合、サーフェスは更新されません。 (C) 2018 石井 勇一 104
  105. 105. その他追加情報 HoloToolkitのSpatialMappingを理解する by D.YAMA Blog  ◦ http://blog.d‐yama7.com/archives/708 ここに各クラスのメソッドや利用例などが書かれています。 (C) 2018 石井 勇一 105
  106. 106. 1.5 UX Controls (C) 2018 石井 勇一 106
  107. 107. HoloLens用UI部品とサンプル 現在のバージョンで試せるデモがExampleに入っています。 (C) 2018 石井 勇一 107
  108. 108. UI部品 テキスト系とボタン系、その他に分かれています。 テキスト系 ◦ 3DTextPrefab 3D Text Meshを使用している。 ◦ UITextPrefab uGUIを使用。このプレハブのトップはCanvasなので注意。 (C) 2018 石井 勇一 108
  109. 109. UI部品 ボタン系 動作確認は InteractableObjectExamples.unity (C) 2018 石井 勇一 109
  110. 110. UI部品 ボタン系は「CompoundButtonスクリプト」を用いてインタラクティブな反応をするように設計さ れています。 このスクリプトを利用することで、HoloLensのジェスチャ入力に対して、任意のオブジェクトをイ ンタラクティブなボタンにすることができます。 「インタラクティブオブジェクト」に関する詳細はこちらを参照 https://developer.microsoft.com/en‐us/windows/mixed‐reality/interactable_object (C) 2018 石井 勇一 110
  111. 111. UI部品 ボタンの状態 ◦ Observation: デフォルトのアイドル状態 ◦ Targeted:オブジェクトが注視カーソルでターゲットに設定されているとき。 ◦ Pressed:エアタップジェスチャーでオブジェクトをクリックしたとき (C) 2018 石井 勇一 111
  112. 112. Compound Buttonクラス これはボタンコンポーネントのベースとなるクラス。 (C) 2018 石井 勇一 112
  113. 113. Compound Button Meshクラス カスタムメッシュやそれぞれの状態に応じた色やスケールなどをまとめて管理する (C) 2018 石井 勇一 113
  114. 114. Compound Button Iconクラス ボタンのアイコンを管理するクラス (C) 2018 石井 勇一 114
  115. 115. Compound Button Iconクラス アイコンの割り当ての手順 (C) 2018 石井 勇一 115
  116. 116. Compound Button Textクラス TextMeshコンポーネントによりボタンにテキ ストを表示する。 このスクリプトをCompoundButtonSpeechコン ポーネントと組み合わせて使用すると、ボタン をスピーチ入力のキーワードに自動的にリン クできます。 (C) 2018 石井 勇一 116
  117. 117. Compound Button Soundクラス 様々なボタンの状態に合わせたサウンドを 設定できます。 (C) 2018 石井 勇一 117
  118. 118. Compound Button Animクラス ボタンコンポーネントのベースクラス。実装サンプル例はButtonCheeseを参照 (C) 2018 石井 勇一 118
  119. 119. Compound Button Speechクラス このスクリプトを使用して、Speech Manager にボタン用のキーワードを自動的に登録しま す(このスクリプトはテスト済みではあります が、まだ実験的機能となっています) 。 この機能を利用するにはUWP Capabilityの 設定が必要です。 (C) 2018 石井 勇一 119
  120. 120. Compound Button Toggleクラス このスクリプトを使用して、トグルのオン/オフ状態を追加します(現時点では使用例が見当た らない) (C) 2018 石井 勇一 120
  121. 121. イベントの受信方法 InteractionReceiverの派生クラスを作成する と、複数のボタンイベントをまとめて管理する ことができます。 実装例はExamplesのUX/Scriptsにある ButtonReceiverExampleです。 (C) 2018 石井 勇一 121
  122. 122. InteractionReceiverでオーバーライド可 能メソッド (C) 2018 石井 勇一 122 #region Protected Virtual Callback Functions protected virtual void FocusEnter(GameObject obj, PointerSpecificEventData eventData) { } protected virtual void FocusExit(GameObject obj, PointerSpecificEventData eventData) { } protected virtual void InputDown(GameObject obj, InputEventData eventData) { } protected virtual void InputUp(GameObject obj, InputEventData eventData) { } protected virtual void InputClicked(GameObject obj, InputClickedEventData eventData) { } protected virtual void HoldStarted(GameObject obj, HoldEventData eventData) { } protected virtual void HoldCompleted(GameObject obj, HoldEventData eventData) { } protected virtual void HoldCanceled(GameObject obj, HoldEventData eventData) { } protected virtual void ManipulationStarted(GameObject obj, ManipulationEventData eventData) { } protected virtual void ManipulationUpdated(GameObject obj, ManipulationEventData eventData) { } protected virtual void ManipulationCompleted(GameObject obj, ManipulationEventData eventData) { } protected virtual void ManipulationCanceled(GameObject obj, ManipulationEventData eventData) { } protected virtual void NavigationStarted(GameObject obj, NavigationEventData eventData) { } protected virtual void NavigationUpdated(GameObject obj, NavigationEventData eventData) { } protected virtual void NavigationCompleted(GameObject obj, NavigationEventData eventData) { } protected virtual void NavigationCanceled(GameObject obj, NavigationEventData eventData) { } #endregion
  123. 123. ButtonReceiverExampleのコード (C) 2018 石井 勇一 123 // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. using HoloToolkit.Unity; using System.Collections.Generic; using UnityEngine; using HoloToolkit.Unity.Receivers; using HoloToolkit.Unity.InputModule; namespace HoloToolkit.Unity.Examples { public class ButtonReceiverExample : InteractionReceiver { public GameObject textObjectState; private TextMesh txt; void Start() { txt = textObjectState.GetComponentInChildren<TextMesh>(); }
  124. 124. ButtonReceiverExampleのコード (C) 2018 石井 勇一 124 protected override void FocusEnter(GameObject obj, PointerSpecificEventData eventData) { Debug.Log(obj.name + " : FocusEnter"); txt.text = obj.name + " : FocusEnter"; } protected override void FocusExit(GameObject obj, PointerSpecificEventData eventData) { Debug.Log(obj.name + " : FocusExit"); txt.text = obj.name + " : FocusExit"; } protected override void InputDown(GameObject obj, InputEventData eventData) { Debug.Log(obj.name + " : InputDown"); txt.text = obj.name + " : InputDown"; } protected override void InputUp(GameObject obj, InputEventData eventData) { Debug.Log(obj.name + " : InputUp"); txt.text = obj.name + " : InputUp"; } } }
  125. 125. その他の実装例 ExampleのUX/Scriptsを参照 (C) 2018 石井 勇一 125 Interactive IInputClickHandler IFocusable IInputHandler InteractiveButton InteractiveToggle InteractiveToggleButton
  126. 126. Exampleカスタムボタン Holographic button 全てのボタンはHoloToolkit‐Examples/UX/Prefabの下にあります。 (C) 2018 石井 勇一 126
  127. 127. Exampleカスタムボタン Mesh button (C) 2018 石井 勇一 127
  128. 128. Exampleカスタムボタン Traditional button (C) 2018 石井 勇一 128
  129. 129. Exampleカスタムボタン Other examples この他にも幾つかのアニメーション付き3D Meshボタンがあります。 (C) 2018 石井 勇一 129
  130. 130. 1.6 Spatial Understanding (C) 2018 石井 勇一 130
  131. 131. 空間の平面を把握 Spatial Mappingにより空間の把握ができるようになりましたが、実際に物を配置するときには それが「壁」「床」「天井」と認識する必要があります。 Spatial Understandingは、Fragmentsの開発中に空間把握の必要性に直面し開発されました。 https://www.microsoft.com/ja‐jp/hololens/apps/fragments ここで開発されたライブラリはカプセル化されて、MRTKで利用できるようになっています。 (C) 2018 石井 勇一 131
  132. 132. サンプルを動作させる Assets/HoloToolkit‐Examples/SpatialUnderstanding/Scenes/SpatialUnderstandingExampleを開く Spatial Mappingと同様にSpatial Perceptionの設定が必要です。 実行はHoloLens Emulation無し、あるいは実機で動作させてください。実行はHoloLens  Emulation無しの場合は、ダミールームを設定してください。 ある程度認識しないとメニューが出ません。部屋の中をうろうろして平面をたくさん見つけてくだ さい(床、壁、テーブル、椅子、天井など) (C) 2018 石井 勇一 132
  133. 133. サンプルを動作させる 上手くある程度以上の平面を検出できるとAirTapして完了というメッセージ(英語)がでるので、 AirTapします。するとメニューが表示されます。 (C) 2018 石井 勇一 133
  134. 134. サンプルを動作させる Topology Queries(位置の問い合わせ) ◦ Positions on wall  オブジェクトを配置できる壁の場所を教えてくれます。 ◦ Large positions on wall スペースが大きい壁の位置を示します。 ◦ Largest wall 認識した壁の中で一番大きい壁を教えてくれます。 ◦ Positions on floor 床にオブジェクトを配置します。 ◦ Large positions on floor スペースが大きい床の位置を教えてくれます。 ◦ Place objects positions オブジェクトを配置できる場所を示します。 (C) 2018 石井 勇一 134
  135. 135. サンプルを動作させる Shape Queries(形状の問い合わせ) ◦ All surfaces 認識した全ての平面を示します。 ◦ Sittable 座ることが可能な場所を教えてくれます。 ◦ Chair 認識した椅子を示してくれます。 ◦ Large surfaces  スペースの大きい平面を教えてくれます。 ◦ Large empty surfaces  障害物などがない大きな平面を示します。 ◦ Couch ソファーの場所を教えてくれます。 (C) 2018 石井 勇一 135
  136. 136. サンプルを動作させる Object Placement(物を配置する) ◦ On Floor 床に物を配置する ◦ On Wall 壁に物を配置する On Celling 天井に物を配置する ◦ On SurfaceEdge 狭い平面上に物を配置する ◦ On FloorAndCelling 床と天井に合わせて物を配置する ◦ RandomInAirAwayFromMe 自分から離れた空中にランダムに物を配置する ◦ OnEdge NearCenter 中心近くの端に物を配置する ◦ OnFloor AwayFromMe 自分から離れた床に物を配置する ◦ OnFloor NearMe 自分の近くの床に物を配置する (C) 2018 石井 勇一 136
  137. 137. Spatial Understanding関連スクリプト SpatialUnderstanding.cs ◦ スキャンプロセスの状態とフローを制御します。 SpatialUnderstandingCustomMesh.cs ◦ Understanding dllによって生成されたカスタムメッシュを処理します。 ◦ メッシュはスキャンフェーズ中に生成され、スキャンファイナライズにもう一度生成されます。 ◦ メッシュを使用して、スキャンの進行状況を視覚化することができます。 SpatialUnderstandingDll.cs ◦ マーシャリングヘルパ関数を含む主要なDLLの関数をカプセル化します。 ◦ DLL関数は以下の4つに分かれています。 ◦ 自分自身 ◦ SpatialUnderstandingDllTopology ◦ SpatialUnderstandingDllShapes ◦ SpatialUnderstandingDllObjectPlacement ◦ このクラスには、スキャンフロー、レイキャスト、および整列関数が含まれています。 (C) 2018 石井 勇一 137
  138. 138. Spatial Understanding関連スクリプト SpatialUnderstandingDllObjectPlacement.cs ◦ understanding dllのオブジェクト配置クエリをカプセル化します。 これらのクエリは、スキャンが完了するまで 有効ではありません。 SpatialUnderstandingDllShapes.cs ◦ understanding  dllの形状検出クエリをカプセル化します。 図形はAddShapeでユーザーによって定義され、分 析はActivateShapeAnalysisで開始されます。 これらのクエリは、スキャンが完了するまで有効ではありません。 形状定義は、コンポーネントのリストと、コンポーネント間の要件を定義する形状制約のリストで構成されま す。 各コンポーネントは、独自の形状コンポーネント制約のリストによって定義されます。 SpatialUnderstandingDllTopology.cs ◦ understanding  dllのトポロジクエリをカプセル化します。 これらのクエリは、スキャンが完了するまで有効では ありません。 SpatialUnderstandingSourceMesh.cs ◦ 入力メッシュをSpatial UnderstandingのDLLに提供します。 コンポーネントは、空間マッピングモジュールに依 存します。 空間マッピングのSurfaceObjectリストから更新された必要なdll形式のメッシュリストを保持します。 (C) 2018 石井 勇一 138
  139. 139. サンプルシーン SpatialUnderstandingExample (C) 2018 石井 勇一 139 SpatialMappingおよび SpatialUnderstandingプレハブが必要 サンプルシーンのメインプログラム
  140. 140. Spatial Understandingの設定 Spatial Understanding コンポーネント ◦ Update Period_During Scanning ◦ スキャン処理中に使用される更新期間(通常、スキャンが完 了した後よりも高速)(単位不明) ◦ Update Period_After Scanning ◦ スキャン処理が完了した後に使用される更新期間(単位不明) (C) 2018 石井 勇一 140
  141. 141. Spatial Understandingの設定 Spatial Understanding Custom Meshコンポー ネント ◦ Import Mesh Period ◦ スキャンフェーズ中に、メッシュをインポートする間隔を秒 単位で指定します。 0の値は、DLLからメッシュのインポート を行いません。 ◦ Mesh Material ◦ DLLによって生成されたカスタムメッシュをレンダリングする ために使用されるマテリアル。 ◦ Max Frame Time ◦ メッシュの処理に費やすフレームあたりの最大時間(ミリ 秒)。処理が1フレームに割り当てられている時間を超過し ないようにするために使用されます。 ◦ Create Mesh Colliders ◦ Meshコライダーを生成するかどうか。 (C) 2018 石井 勇一 141
  142. 142. サンプルプログラムの流れ AppState.csのStartメソッド(以下、すべてAppState.cs内のメソッド) (C) 2018 石井 勇一 142 namespace HoloToolkit.Examples.SpatialUnderstandingFeatureOverview { public class AppState : Singleton<AppState>, ISourceStateHandler, IInputClickHandler { private void Start() { // Default the scene & the HoloToolkit objects to the camera Vector3 sceneOrigin = CameraCache.Main.transform.position; Parent_Scene.transform.position = sceneOrigin; MappingObserver.SetObserverOrigin(sceneOrigin); InputManager.Instance.AddGlobalListener(gameObject); var keywordsToActions = new Dictionary<string, Action> { { "Toggle Scanned Mesh", ToggleScannedMesh }, { "Toggle Processed Mesh", ToggleProcessedMesh }, }; keywordRecognizer = new KeywordRecognizer(keywordsToActions.Keys.ToArray()); keywordRecognizer.OnPhraseRecognized += args => keywordsToActions[args.text].Invoke(); keywordRecognizer.Start(); } 音声入力 どこでも ハンドジェスチャー 入力
  143. 143. サンプルプログラムの流れ 必要なところだけ抜粋(AppState.cs) (C) 2018 石井 勇一 143 protected override void OnDestroy() { InputManager.Instance.RemoveGlobalListener(gameObject); } Start()で登録した どこでもハンドジェス チャー入力を削除
  144. 144. ハンドジェスチャー入力 ISourceStateHandler(手の検出), IInputClickHandler(AirTapの検出) (C) 2018 石井 勇一 144 public void OnSourceDetected(SourceStateEventData eventData) { // If the source has positional info and there is currently no visible source if (eventData.InputSource.SupportsInputInfo(eventData.SourceId, SupportedInputInfo.Position)) { trackedHandsCount++; } } public void OnSourceLost(SourceStateEventData eventData) { if (eventData.InputSource.SupportsInputInfo(eventData.SourceId, SupportedInputInfo.Position)) { trackedHandsCount--; } } public void OnInputClicked(InputClickedEventData eventData) { if ((SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Scanning) && !SpatialUnderstanding.Instance.ScanStatsReportStillWorking) { SpatialUnderstanding.Instance.RequestFinishScan(); } } 指を検出したタイミングで メッセージの色を変えるた めにカウントを記録 十分なデータがえらたタイ ミングで、AirTapで終了依 頼を発行するために使用
  145. 145. 音声入力 Spatial MappingのVisual MeshとSpatial UnderstandingのCustomMeshをそれぞれOn/Offする 実はキーボード入力でも最終的にここが呼ばれるようにプログラムされている(後述) (C) 2018 石井 勇一 145 private static void ToggleScannedMesh() { SpatialMappingManager.Instance.DrawVisualMeshes = !SpatialMappingManager.Instance.DrawVisualMeshes; Debug.Log("SpatialUnderstanding -> SpatialMappingManager.Instance.DrawVisualMeshes=" + SpatialMappingManager.Instance.DrawVisualMeshes); } private static void ToggleProcessedMesh() { SpatialUnderstanding.Instance.UnderstandingCustomMesh.DrawProcessedMesh = !SpatialUnderstanding.Instance.UnderstandingCustomMesh.DrawProcessedMesh; Debug.Log("SpatialUnderstanding -> SpatialUnderstanding.Instance.UnderstandingCustomMesh.DrawProcessedMesh=" + SpatialUnderstanding.Instance.UnderstandingCustomMesh.DrawProcessedMesh); }
  146. 146. Updateメソッド Spatial Understandingのステータスに合わせてメッセージを変える、キーボードの入力を監視 する処理を呼び出している (C) 2018 石井 勇一 146 private void Update() { Update_DebugDisplay(Time.deltaTime); Update_KeyboardInput(Time.deltaTime); }
  147. 147. Update_DebugDisplayメソッド DebugDisplayおよびDebugSubDisplayには3D  Text Meshコンポーネントがセットされています。 (C) 2018 石井 勇一 147 private void Update_DebugDisplay(float deltaTime) { // Basic checks if (DebugDisplay == null) { return; } // Update display text DebugDisplay.text = PrimaryText; DebugDisplay.color = PrimaryColor; DebugSubDisplay.text = DetailsText; }
  148. 148. 3つのプロパティについて PrimaryText、PrimaryColor、DetailsTextはすべて読み取り専用のプロパティとして定義されています。 それぞれの役割は以下のようになっています。 PrimaryText ◦ 現在のステータスに合わせてメインメッセージを表示(ユーザへの指示にもなっている) PrimaryColor ◦ ステータスに合わせてメッセージの色を変更。Understanding処理中/終わった、指を検出した/見失ったなど DetailsText ◦ Understandingで検出した物のサマリを表示。ある程度以上検出しないと表示されない。 (C) 2018 石井 勇一 148 public string PrimaryText { get { : :
  149. 149. スキャンの状態 SpatialUnderstandingクラスで定義されているScanStates (C) 2018 石井 勇一 149 ReadyToScan Scanning Finishing Done namespace HoloToolkit.Unity { public class SpatialUnderstanding : Singleton<SpatialUnderstanding> { // Enums public enum ScanStates { None, ReadyToScan, Scanning, Finishing, Done } } } RequestBeginScanningメソッド または AutoBeginScanningプロパティがtrue RequestFinishScanメソッド (DLL内部処理完了)
  150. 150. PrimaryTextプロパティの処理 ScanStateに合わせてメインメッセージを変更 SpaceVisualizer.cs ◦ SpaceQueryDescriptionを使用 LevelSolver.cs ◦ ObjectPlacementDescriptionを使用 (C) 2018 石井 勇一 150 public string PrimaryText { get { // 空間および物の配置のリストに対する検索結果を表示(優先度があります) if (!string.IsNullOrEmpty(SpaceQueryDescription)) { return SpaceQueryDescription; } else if (!string.IsNullOrEmpty(ObjectPlacementDescription)) { return ObjectPlacementDescription; } : :
  151. 151. 【参考】SpaceQueryDescriptionおよび ObjectPlacementDescriptionプロパティ SpaceQueryDescriptionおよびObjectPlacementDescriptionプロパティ 何方かの値をsetし、もう一方の値を""にする。 (C) 2018 石井 勇一 151 public string SpaceQueryDescription { get { return spaceQueryDescription; } set { spaceQueryDescription = value; objectPlacementDescription = ""; } } public string ObjectPlacementDescription { get { return objectPlacementDescription; } set { objectPlacementDescription = value; spaceQueryDescription = ""; } }
  152. 152. PrimaryTextプロパティの処理 ScanStateに合わせてメインメッセージを変更(続き) (C) 2018 石井 勇一 152 // Scan state if (SpatialUnderstanding.Instance.AllowSpatialUnderstanding){ switch (SpatialUnderstanding.Instance.ScanState) { case SpatialUnderstanding.ScanStates.Scanning: //スキャン中 // Get the scan stats IntPtr statsPtr = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceStatsPtr(); if (SpatialUnderstandingDll.Imports.QueryPlayspaceStats(statsPtr) == 0){ return "playspace stats query failed"; } // 終了させても良さそうかどうか調べる(これも複雑なコードが付いているプロパティ) if (DoesScanMeetMinBarForCompletion) { return "When ready, air tap to finalize your playspace"; // AirTapで終了するというメッセージを表示 } return "Walk around and scan in your playspace"; // まだ不十分なので歩き回ってスキャンしなさいと表示 : :
  153. 153. PrimaryTextプロパティの処理 ScanStateに合わせてメインメッセージを変更(続き) (C) 2018 石井 勇一 153 case SpatialUnderstanding.ScanStates.Finishing: // 終了処理中 return "Finalizing scan (please wait)"; case SpatialUnderstanding.ScanStates.Done: // 終了 return "Scan complete - Use the menu to run queries"; default: return "ScanState = " + SpatialUnderstanding.Instance.ScanState.ToString(); } } return ""; }
  154. 154. PrimaryColorプロパティの処理 ◦ ステータスに合わせてメッセージの色を変更。 (C) 2018 石井 勇一 154 public Color PrimaryColor { get { if (SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Scanning){ if (trackedHandsCount > 0) { return DoesScanMeetMinBarForCompletion ? Color.green : Color.red; } return DoesScanMeetMinBarForCompletion ? Color.yellow : Color.white; } // メニューを見ているときはそれを消す(実際には透明度15%にする) Vector3 hitPos, hitNormal; UnityEngine.UI.Button hitButton; float alpha = AppCursor.RayCastUI(out hitPos, out hitNormal, out hitButton) ? 0.15f : 1.0f; // 特殊ケース処理 & return (!string.IsNullOrEmpty(SpaceQueryDescription) || !string.IsNullOrEmpty(ObjectPlacementDescription)) ? (PrimaryText.Contains("processing") ? new Color(1.0f, 0.0f, 0.0f, 1.0f) : new Color(1.0f, 0.7f, 0.1f, alpha)) : new Color(1.0f, 1.0f, 1.0f, alpha); } }
  155. 155. DetailsTextプロパティの処理 ◦ 検索結果のサマリー (C) 2018 石井 勇一 155 public string DetailsText { get { if (SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.None) { return ""; } // スキャン統計は2番目に優先されます if ((SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Scanning) && (SpatialUnderstanding.Instance.AllowSpatialUnderstanding)) { // 統計情報が取得できていない場合は取得に失敗という文字列を返す IntPtr statsPtr = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceStatsPtr(); if (SpatialUnderstandingDll.Imports.QueryPlayspaceStats(statsPtr) == 0) { return "Playspace stats query failed"; } : :
  156. 156. PrimaryColorプロパティの処理 ◦ ステータスに合わせてメッセージの色を変更。 (C) 2018 石井 勇一 156 SpatialUnderstandingDll.Imports.PlayspaceStats stats = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceStats(); // 統計情報がゼロでなければ統計情報の表示を開始する if (stats.TotalSurfaceArea > kMinAreaForStats) { string subDisplayText = string.Format("totalArea={0:0.0}, horiz={1:0.0}, wall={2:0.0}", stats.TotalSurfaceArea, stats.HorizSurfaceArea, stats.WallSurfaceArea); subDisplayText += string.Format("¥nnumFloorCells={0}, numCeilingCells={1}, numPlatformCells={2}", stats.NumFloor, stats.NumCeiling, stats.NumPlatform); subDisplayText += string.Format("¥npaintMode={0}, seenCells={1}, notSeen={2}", stats.CellCount_IsPaintMode, stats.CellCount_IsSeenQualtiy_Seen + stats.CellCount_IsSeenQualtiy_Good, stats.CellCount_IsSeenQualtiy_None); return subDisplayText; } return ""; } return ""; } PlayspaceStatsクラスの定義は次 のスライドを参照
  157. 157. (C) 2018 石井 勇一 157 namespace HoloToolkit.Unity { public class SpatialUnderstandingDll { public class PlayspaceStats { public int IsWorkingOnStats; // 0 まだ統計を作成している場合 public float HorizSurfaceArea; // In m2 : 床から-0.15~1mの間にある上向きの全ての水平面 public float TotalSurfaceArea; // In m2 : すべて public float UpSurfaceArea; // In m2 : 床を含むすべての上向きな水平面 public float DownSurfaceArea; // In m2 : 天井を含むすべて下向きの水平面 public float WallSurfaceArea; // In m2 : 壁だけでない、すべての垂直面 public float VirtualCeilingSurfaceArea; // In m2 : 実質的な天井面の推定数 public float VirtualWallSurfaceArea; // In m2 : 実質的な壁の推定数 public int NumFloor; // 各フロアのリスト数(カウントを含む) public int NumCeiling; // 各天井のリスト数(カウントを含む) public int NumWall_XNeg; // 各壁においてX軸マイナス方向を向いている数(カウントを含む) public int NumWall_XPos; // 各壁においてX軸プラス方向を向いている数(カウントを含む) public int NumWall_ZNeg; // 各壁においてZ軸マイナス方向を向いている数(カウントを含む) public int NumWall_ZPos; // 各壁においてZ軸プラス方向を向いている数(カウントを含む) public int NumPlatform; // 床を含まない水平面の数 (例えばテーブルや椅子など)(カウントを含む) public int CellCount_IsPaintMode; // ペイントセル数(ペイント数で面積が推測できる)=> 1セルにつき8cm×8cm public int CellCount_IsSeenQualtiy_None; // 見えないセルの数 => 1セルにつき8cm×8cm public int CellCount_IsSeenQualtiy_Seen; // 見えるセルの数=> 1セルにつき8cm×8cm public int CellCount_IsSeenQualtiy_Good; // 良質な見えるセルの数 => 1セルにつき8cm×8cm }; } }
  158. 158. DoesScanMeetMinBarForCompletionプ ロパティ スキャン完了とするための必要最小限度を満たしているかどうかを判定して結果を返す (C) 2018 石井 勇一 158 public bool DoesScanMeetMinBarForCompletion { get { // 実際にスキャンしているか? if ((SpatialUnderstanding.Instance.ScanState != SpatialUnderstanding.ScanStates.Scanning) || (!SpatialUnderstanding.Instance.AllowSpatialUnderstanding)) { return false; } // 現在の統計情報を調べる IntPtr statsPtr = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceStatsPtr(); if (SpatialUnderstandingDll.Imports.QueryPlayspaceStats(statsPtr) == 0) { return false; } : :
  159. 159. DoesScanMeetMinBarForCompletionプ ロパティ スキャン完了とするための必要最小限度を満たしているかどうかを判定して結果を返す (C) 2018 石井 勇一 159 SpatialUnderstandingDll.Imports.PlayspaceStats stats = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceStats(); // 事前に設定した値と比較する if ((stats.TotalSurfaceArea > kMinAreaForComplete) || // トータルの表面領域 (stats.HorizSurfaceArea > kMinHorizAreaForComplete) || // 床から-0.15~1mの間にある上向きの全ての水平面 (stats.WallSurfaceArea > kMinWallAreaForComplete)) // 壁だけでない、すべての垂直面 { return true; } return false; } } // 事前設定 public float kMinAreaForStats = 5.0f; public float kMinAreaForComplete = 50.0f; public float kMinHorizAreaForComplete = 25.0f; public float kMinWallAreaForComplete = 10.0f;
  160. 160. 統計情報の利用 UI.csのSetupMenus() (C) 2018 石井 勇一 160 private void SetupMenus() { // Topology queries ButtonPanels[(int)Panels.Topology].Button.GetComponentInChildren<Text>().text = "Topology Queries"; ButtonPanels[(int)Panels.Topology].Button.onClick.AddListener(() => { SetActiveTab(Panels.Topology); }); AddButton("Position on wall", Panels.Topology, () => { SpaceVisualizer.Instance.Query_Topology_FindPositionOnWall(); timeLastQuery = DateTime.MinValue; }); AddButton("Large positions on wall", Panels.Topology, () => { SpaceVisualizer.Instance.Query_Topology_FindLargePositionsOnWalls(); timeLastQuery = DateTime.MinValue; }); AddButton("Largest wall", Panels.Topology, () => { SpaceVisualizer.Instance.Query_Topology_FindLargeWall(); timeLastQuery = DateTime.MinValue; }); : :
  161. 161. 統計情報の利用 UI.csのSetupMenus() (C) 2018 石井 勇一 161 private void SetupMenus() { // Topology queries ButtonPanels[(int)Panels.Topology].Button.GetComponentInChildren<Text>().text = "Topology Queries"; ButtonPanels[(int)Panels.Topology].Button.onClick.AddListener(() => { SetActiveTab(Panels.Topology); }); AddButton("Position on wall", Panels.Topology, () => { SpaceVisualizer.Instance.Query_Topology_FindPositionOnWall(); timeLastQuery = DateTime.MinValue; }); AddButton("Large positions on wall", Panels.Topology, () => { SpaceVisualizer.Instance.Query_Topology_FindLargePositionsOnWalls(); timeLastQuery = DateTime.MinValue; }); AddButton("Largest wall", Panels.Topology, () => { SpaceVisualizer.Instance.Query_Topology_FindLargeWall(); timeLastQuery = DateTime.MinValue; }); : :
  162. 162. 統計情報の利用 UI.csのSetupMenus() (C) 2018 石井 勇一 162 // Shape queries ButtonPanels[(int)Panels.Shapes].Button.GetComponentInChildren<Text>().text = "Shape Queries"; ButtonPanels[(int)Panels.Shapes].Button.onClick.AddListener(() => { SetActiveTab(Panels.Shapes); }); ReadOnlyCollection<string> customShapes = ShapeDefinition.Instance.CustomShapeDefinitions; for (int i = 0; i < customShapes.Count; ++i) { string shapeName = customShapes[i]; AddButton(shapeName, Panels.Shapes, () => { SpaceVisualizer.Instance.Query_Shape_FindShapeHalfDims(shapeName); timeLastQuery = DateTime.MinValue; }); } : :
  163. 163. 統計情報の利用 UI.csのSetupMenus() (C) 2018 石井 勇一 163 // Level solver ButtonPanels[(int)Panels.LevelSolver].Button.GetComponentInChildren<Text>().text = "Object Placement"; ButtonPanels[(int)Panels.LevelSolver].Button.onClick.AddListener(() => { SetActiveTab(Panels.LevelSolver); timeLastQuery = DateTime.MinValue; }); AddButton("On Floor", Panels.LevelSolver, () => { LevelSolver.Instance.Query_OnFloor(); timeLastQuery = DateTime.MinValue; }); AddButton("On Wall", Panels.LevelSolver, () => { LevelSolver.Instance.Query_OnWall(); timeLastQuery = DateTime.MinValue; }); : :
  164. 164. 統計情報の利用 UI.csのSetupMenus() (C) 2018 石井 勇一 164 public void Query_Topology_FindPositionOnWall() { ClearGeometry(); // 既に表示しているワイヤーフレームを消す(2回目を想定) // Spatial Undedrstandingが有効でなければ何もしない if (!SpatialUnderstanding.Instance.AllowSpatialUnderstanding) { return; } // セットアップ float minHeightOfWallSpace = 0.5f; // 壁とみなす最小の高さ(単位メートル) float minWidthOfWallSpace = 0.75f; // 壁とみなす最小の幅(単位メートル) float minHeightAboveFloor = 1.25f; // 壁とみなす床からの高さ(単位メートル) float minFacingClearance = 1.5f; // 壁の前に求める最小の空き領域(単位メートル) // 問い合わせ IntPtr resultsTopologyPtr = SpatialUnderstanding.Instance.UnderstandingDLL.PinObject(resultsTopology); int locationCount = SpatialUnderstandingDllTopology.QueryTopology_FindPositionsOnWalls( minHeightOfWallSpace, minWidthOfWallSpace, minHeightAboveFloor, minFacingClearance, resultsTopology.Length, resultsTopologyPtr); // 出力 HandleResults_Topology("Find Position On Wall", locationCount, new Vector3(minWidthOfWallSpace, minHeightOfWallSpace, 0.025f), Color.blue); }
  165. 165. 統計情報の利用 SpatialUnderstandingDllTopology.csのQueryTopology_FindPositionsOnWalls () (C) 2018 石井 勇一 165 /// <summary> ///パラメータで指定された基準を満たす壁のスペースを検索します。 /// </summary> /// <param name="minHeightOfWallSpace">クエリによって検出されるスペースの最小高さ。</param> /// <param name="minWidthOfWallSpace">クエリによって検出されるスペースの最小幅。</param> /// <param name="minHeightAboveFloor">そのスペースの下端と床の上との最小距離。</param> /// <param name="minFacingClearance">そのスペースの前方のゆとり空間の最小距離。</param> /// <param name="locationCount">locationDataでユーザーが指定したロケーション結果の数。</param> /// <param name="locationData">クエリによって検出されたスペースで満たされるTopologyResultのロケーション結果配列。</param> /// <returns>クエリによって検出されたスペースの数。 この値は、呼び出し元によって提供された結果の数によって制限されます(locationCount)</returns> // Queries (topology) [DllImport("SpatialUnderstanding", CallingConvention = CallingConvention.Cdecl)] public static extern int QueryTopology_FindPositionsOnWalls( [In] float minHeightOfWallSpace, [In] float minWidthOfWallSpace, [In] float minHeightAboveFloor, [In] float minFacingClearance, [In] int locationCount, // locationDataに割り当てられた領域を渡します。 [In, Out] IntPtr locationData); // TopologyResult
  166. 166. 統計情報の利用 ShapeDefinition.csのCreateCustomShapeDefinitions()にて、想定される形のデータを登録し、 統計情報から登録された形データを元に検索ができる。 「椅子」の定義例 (C) 2018 石井 勇一 166 // Chair shapeComponents = new List<SpatialUnderstandingDllShapes.ShapeComponent>() { new SpatialUnderstandingDllShapes.ShapeComponent( new List<SpatialUnderstandingDllShapes.ShapeComponentConstraint>() { SpatialUnderstandingDllShapes.ShapeComponentConstraint.Create_SurfaceHeight_Between(0.25f, 0.6f), SpatialUnderstandingDllShapes.ShapeComponentConstraint.Create_SurfaceCount_Min(1), SpatialUnderstandingDllShapes.ShapeComponentConstraint.Create_SurfaceArea_Min(0.035f), SpatialUnderstandingDllShapes.ShapeComponentConstraint.Create_IsRectangle(), SpatialUnderstandingDllShapes.ShapeComponentConstraint.Create_RectangleLength_Between(0.1f, 0.5f), SpatialUnderstandingDllShapes.ShapeComponentConstraint.Create_RectangleWidth_Between(0.1f, 0.4f), SpatialUnderstandingDllShapes.ShapeComponentConstraint.Create_SurfaceNotPartOfShape("Couch"), }), }; AddShape("Chair", shapeComponents);
  167. 167. 最小限度の設定の例 ZuQ9‐>Nn To 辛周(ズキューンとからまわり)さんのブログ ◦ HoloLens開発 SpatialUnderstanding事始め 空間検知と空間内の情報(天井、床、壁)の判定まで ◦ http://zuq9nn.blogspot.jp/2017/06/hololens‐spatialunderstanding.html ◦ HoloLensの開発 SpatialUnderstandingDllTopologyで壁にオブジェクト配置してみる ◦ http://zuq9nn.blogspot.jp/2017/09/hololensspatialunderstandingdlltopology.html (C) 2018 石井 勇一 167
  168. 168. 1.7 Sharing (C) 2018 石井 勇一 168
  169. 169. Sharingとは 2台以上のHoloLensで空間を共有する仕組み (C) 2018 石井 勇一 169 全く異なるリアル空間で同じものを見る たまたま同じリアル空間で同じものを見る
  170. 170. 接続形態 MixedRealityToolkitに含まれるSharing機能を使う ◦ サーバは独立したPCで実行 UNETやPhotonといったネットワーキングエンジンを使う ◦ UNET版はサンプルがあります。 TCP/UDPで独自に実装する ◦ 自由度が高いが、難易度も高い。多くの実装例がネットを探すと出てきます。 (C) 2018 石井 勇一 170
  171. 171. Sharingとは Sharingを実現するには2台以上のHoloLensとサーバが必要 (C) 2018 石井 勇一 171 Sharingサーバ (独立したPC) HoloLens HoloLens
  172. 172. Sharingとは Sharingを実現するには2台以上のHoloLensとサーバが必要 (C) 2018 石井 勇一 172 Sharingサーバ (HoloLens) HoloLens HoloLens ある一台のHoloLensをサーバ兼クライアントにする UNET版
  173. 173. Sharing時の問題点 HoloLensアプリは起動時にカメラの位置がPosition(0, 0, 0)、Rotation(0,0,0)になります。これが 基準点となり作られた座標系を「静止座標系(Stationary frame of reference)と言います。 そのため図のよう起動するとそれぞれ異なる静止座標系が構築されます。 (C) 2018 石井 勇一 173
  174. 174. Sharing時の問題点 そこで、それぞれの座標系に「アンカー」を共有し、それ以降はアンカーを基準に全ての物を 共有することで問題点を解決します。 これをSpatial anchor(空間アンカー)と呼びます。 実際にプログラムするときは「World Anchor」と呼ばれるクラスを使用します。 (C) 2018 石井 勇一 174
  175. 175. World Anchorについて World Anchorになりそうなもの ◦ 起動時の位置 ◦ 画像認識(VuforiaやOpenCVなどと組み合わせて同じ特徴を持つ画像を元に位置合わせをする) (C) 2018 石井 勇一 175
  176. 176. サンプルプログラムを実行 2つのフォルダーに分かれています (C) 2018 石井 勇一 176 独自サーバプログラムを使用 するバージョン UNETを使用するバージョン。 最初に起動したHoloLensアプリが サーバになる。
  177. 177. 独自サーバ版の利用方法 https://github.com/Microsoft/MixedRealityTo olkit‐Unity/releases で配布されているMixedRealityToolkit‐Unity‐ 2017.2.1.3.zipを取得し展開する (C) 2018 石井 勇一 177
  178. 178. 独自サーバ版の利用方法 MixedRealityToolkit‐Unity‐2017.2.1.3.zipの展開後のExternalフォルダをUnityで使用しているプ ロジェクトのトップディレクトリにコピーする (C) 2018 石井 勇一 178 Unityプロジェクト zipファイルの中にある Externalフォルダ コピーする
  179. 179. 独自サーバ版の利用方法 Unityの[Mixed Reality Toolkit]‐[Sharing Service]‐[Launch Sharing Service]を実行 (C) 2018 石井 勇一 179
  180. 180. 独自サーバ版の利用方法 コマンドプロンプトが表示される。初回起動時はネットワークの許可を求めるダイアログが表 示される。 表示されているIPアドレスを覚える。 一般的には一番上のアドレスを使用する。 (C) 2018 石井 勇一 180
  181. 181. 独自サーバ版の利用方法 Unityの[Mixed Reality Toolkit]‐[Configure]‐[Apply UWP Capability Settings]を実行 (C) 2018 石井 勇一 181
  182. 182. 独自サーバ版の利用方法 必須 ◦ Internet Client Server ◦ Private Network Client Server 今回のサンプルにおいて必要 ◦ Spatial Perception(UNET版で使用) (C) 2018 石井 勇一 182
  183. 183. 独自サーバ版の利用方法 SharingTestを開く [File]‐[Build & Settings]にてSharingTestを一番最初に起動するシーンに設定し、[Build]を実行 (C) 2018 石井 勇一 183
  184. 184. 独自サーバ版の利用方法 HoloLensにて、サーバのIPアドレスを入力し、 [Connect]ボタンを押す 上手くつながると中央左の赤い丸が緑に変 わる。 さらに後ろのメッセージにおいて、 WolrdAnchorを記録したというメッセージも表 示される。 またサーバー側のコマンドプロントにもクライ アントからの接続を表すメッセージが表示され る。 これを複数台のHoloLensから行う (C) 2018 石井 勇一 184
  185. 185. UNET版によるSharing Unityの[Mixed Reality Toolkit]‐[Configure]‐[Apply UWP Capability Settings]は同じ (C) 2018 石井 勇一 185
  186. 186. UNET版によるSharing SharingWithUnetExampleを開き、[File]‐[Build & Settings]にてSharingTestを一番最初に起動す るシーンに設定し、[Build]を実行 (C) 2018 石井 勇一 186
  187. 187. UNET版によるSharing 初回起動時は、左下の「Startボタン」をAirTapする 2台目以降のHoloLensにおいては1台目のHoloLensがリストに表示されるのでそれを選択して から、右下の「Join」ボタンをAirTap。 これで空間共有がうまくいくと、お互いにAirTapで弾を撃ちあえます。 (C) 2018 石井 勇一 187
  188. 188. Sharingに関する情報 お手軽にSharingの接続成功率と精度をあげる by d_yama ◦ http://blog.d‐yama7.com/archives/569 HoloToolkit‐UnityのSharingの仕組みをできるだけ簡単に理解する by @miyaura ◦ https://qiita.com/miyaura/items/da1d7bd253c3299327ba HoloLensの空間共有サービスを使ってみよう byフューチャーアーキテクト開発者ブログ ◦ https://future‐architect.github.io/articles/20170405/ HoloLensでSharingする前に確認したほうがいいこと by えむにわリソース ◦ http://m2wasabi.hatenablog.com/entry/2017/11/27/202300 (C) 2018 石井 勇一 188
  189. 189. UNETによる接続例 MRが楽しい by bluebirdofozさん ◦ SharingWithUNETについてまとめる その1(その7まであります) ◦ http://bluebirdofoz.hatenablog.com/entry/2018/01/03/225437 (C) 2018 石井 勇一 189
  190. 190. 1.8その他便利な機能や 情報 (C) 2018 石井 勇一 190
  191. 191. 知っていると便利な機能やスクリプト DebugEventLog ◦ Consoleメッセージを表示(Unity Editorからリモート実行す るときに便利かも) DebugPanelButton ◦ DebugEventLogプレハブの代わりにこちらを配置。実行時 にConsoleメッセージの表示/非表示ができるボタンが表 示される FPSDisplay ◦ fpsを表示(かなり字が小さいので注意) HeadsUpDirectionIndicator ◦ アタッチされているスクリプトのTargetに対象の GameObjectをセットするとその方向を常に表示する矢印 が表示される。ただし1つのゲームオブジェクトにしか使え ない(ネットを探すと様々な改良を加えている人たちがい ます)。 HeadsUpDirectionIndicatorPointer ◦ 上のプレハブから呼び出される矢印。直接は利用しない。 (C) 2018 石井 勇一 191
  192. 192. 知っていると便利な機能やスクリプト ホーム画面の様な動きをするスクリプト(Body‐Lock) ◦ Tagalong.cs、 SimpleTagalong.cs、 SphereBasedTagalong.cs (どれか一つ) 常にこちらを向くスクリプト ◦ Billboard.cs この二つのスクリプトを適当なGameObjectにアタッチする(例えばワールドスペースのCanvas) パラメーターが沢山あるので自分好みに調整する 改良版 ◦ HoloLens 用の Body‐Locked な UI を作ってみた by 凹みTips ◦ http://tips.hecomi.com/entry/2017/04/01/171121 (C) 2018 石井 勇一 192
  193. 193. ユーザのヘッドセットの調整支援 ユーザーがヘッドセットを調整して、デモのシナリオで十分な経験を得ることができます。 アプリをデモする際には、ユーザーがヘッドセットを正しく装着していることを確認することが重 要です。 このシーンでは、ユーザーの視野の端に境界線が表示され、4つの境界線がすべて表示され るまでヘッドセットを調整するよう指示されます。ユーザー(またはデモンストレーター)は、 AirTapまたは「I'm ready」と言って、実際の体験に進むことができます。 このシーンは、体験を開始する準備が整うと、ユーザーに見える最初のシーンになるように設 計されています。ユーザーは準備ができたら、シーケンスの次のシーンまたは HeadsetAdjustmentスクリプトのNextSceneNameプロパティで指定されたシーンを読み込みます。 ですが、どうもHoloToolkit‐Unity‐2017.2.1.3はバグってうまく動かなくなっている模様(いくつか 古いMRTKでは動作するらしい)。 (C) 2018 石井 勇一 193
  194. 194. 2つのSingletonパターンについて Mixed Reality Toolkit ‐ Unityが提供するSingletonパターンに使える機能について by @miyaura https://qiita.com/miyaura/items/d1c23b988e77e6e491f3 (C) 2018 石井 勇一 194
  195. 195. お問い合わせ 株式会社シーディングソフテック 石井 勇一 ◦ E‐mail: yuichi.ishii@seedingsoftech.jp ◦ Home Page: http://seedingsoftech.jp/ 個人的なお問い合わせ ◦ Twitter: @z_zabaglione ◦ Home Page: http://zabaglione.info/ 本資料をシーディングソフテックの書面による事前許可なく本資料を複製、再製、改変、発表、アッ プロード、掲示、転送、配布することを禁じます。 著者が作成したオリジナルのプログラムコードは個人・商用利用ともに一切の制限もなくロイヤリ ティフリーでご利用可能です。 画像、音声、3Dモデルデータなどのリソース類、その他のツールやプログラムなどは原著者の利用 許諾に従ってご利用ください。 (C) 2018 石井 勇一 195

×