Recommended
PDF
建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】
PPTX
OpenVRやOpenXRの基本的なことを調べてみた
PDF
PPTX
ARマーカーを利用したHoloLens同士の位置合わせ
PPTX
World Locking Tools V1.0.0について~ 機能と導入 ~
PDF
【Unite Tokyo 2019】「今からでも大丈夫。Vuforia EngineでつくるAR の世界」
PDF
【Unity道場】新しいPrefabワークフロー入門
PPTX
HoloLensでONNXを使って推論(Custom Vision - Object Detection編)
PDF
MRTK V2.3 Spatial Awareness
PDF
【Unity道場 2月】シェーダを書けるプログラマになろう
PPTX
PDF
Unity dojo amplifyshadereditor101_jpn-jp
PDF
【Unity】より良い表現のためのライティング戦略
PDF
【Unity】 Behavior TreeでAIを作る
PDF
Nintendo Switch『OCTOPATH TRAVELER』はこうして作られた
PDF
PPTX
HoloLens2とPCで、WebRTCで映像をやりとり
PDF
HoloLens で OpenCV をどう使うか レーザーポインター 認識で試してみた
PDF
PDF
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
PDF
PDF
PDF
Dockerfile を書くためのベストプラクティス解説編
PDF
PDF
PDF
新入社員のための大規模ゲーム開発入門 サーバサイド編
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PDF
【Dialogflow cx】はじめてみよう google cloud dialogflow cx 編
PDF
PPTX
Mixed Reality Toolkit V2開発環境構築(2020/01版)
More Related Content
PDF
建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】
PPTX
OpenVRやOpenXRの基本的なことを調べてみた
PDF
PPTX
ARマーカーを利用したHoloLens同士の位置合わせ
PPTX
World Locking Tools V1.0.0について~ 機能と導入 ~
PDF
【Unite Tokyo 2019】「今からでも大丈夫。Vuforia EngineでつくるAR の世界」
PDF
【Unity道場】新しいPrefabワークフロー入門
PPTX
HoloLensでONNXを使って推論(Custom Vision - Object Detection編)
What's hot
PDF
MRTK V2.3 Spatial Awareness
PDF
【Unity道場 2月】シェーダを書けるプログラマになろう
PPTX
PDF
Unity dojo amplifyshadereditor101_jpn-jp
PDF
【Unity】より良い表現のためのライティング戦略
PDF
【Unity】 Behavior TreeでAIを作る
PDF
Nintendo Switch『OCTOPATH TRAVELER』はこうして作られた
PDF
PPTX
HoloLens2とPCで、WebRTCで映像をやりとり
PDF
HoloLens で OpenCV をどう使うか レーザーポインター 認識で試してみた
PDF
PDF
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
PDF
PDF
PDF
Dockerfile を書くためのベストプラクティス解説編
PDF
PDF
PDF
新入社員のための大規模ゲーム開発入門 サーバサイド編
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PDF
【Dialogflow cx】はじめてみよう google cloud dialogflow cx 編
Similar to UnityによるHoloLensアプリケーション入門
PDF
PPTX
Mixed Reality Toolkit V2開発環境構築(2020/01版)
PPTX
PDF
PDF
ノンプログラミングで始めようHoloLensコンテンツ開発
PPTX
Windows Mixed Reality デバイスリリース直前! ~HoloLens開発総集編~
PDF
PDF
#MRDevDaysJP HoloLens 2 アプリ開発入門
PPTX
HoloLens/Windows Mixed Reality開発環境構築
PDF
PDF
【Unite 2018 Tokyo】Windows Mixed Reality 最新アプリ開発情報 ~HoloLens からVRまで~
PPTX
HoloLens/Windows Mixed Reality Device開発環境構築(2018/5版)
PPTX
PDF
PDF
PDF
はじめての HoloLens セッションの集大成お見せします!
PDF
20160723 unibook lt大会_発表資料(HoloLensのアプリ開発)
PPTX
PPTX
PDF
More from Yuichi Ishii
PDF
PDF
第1回 【初心者向け】Unity+Oculus Riftで次世代の3Dゲームを作って感じるワークショップ
PDF
Looking glass + leap motionアプリ開発メモ
PDF
PlayMaker入門 (Version 1.7.8)
PDF
PDF
PDF
「Cube Climb」 VR Game Jam 2016 in Japan Autumn
PDF
Team run アセット縛りの Game Jam【第1弾:ユニティちゃんファイティングモーション編】
PDF
PPTX
PPTX
PDF
PDF
PDF
Recently uploaded
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):コアマイクロシステムズ株式会社 テーマ 「AI HPC時代のトータルソリューションプロバイダ」
PPTX
2025年11月24日情報ネットワーク法学会大井哲也発表「API利用のシステム情報」
PDF
論文紹介:DiffusionRet: Generative Text-Video Retrieval with Diffusion Model
PDF
論文紹介:HiLoRA: Adaptive Hierarchical LoRA Routing for Training-Free Domain Gene...
PDF
論文紹介:MotionMatcher: Cinematic Motion Customizationof Text-to-Video Diffusion ...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):Pacific Teck Japan テーマ2「『Slinky』 SlurmとクラウドのKuber...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):Pacific Teck Japan テーマ3「『TrinityX』 AI時代のクラスターマネジメ...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):日本ヒューレット・パッカード合同会社 テーマ1「大規模AIの能力を最大限に活用するHPE Comp...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):エヌビディア合同会社 テーマ1「NVIDIA 最新発表製品等のご案内」
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):日本ヒューレット・パッカード合同会社 テーマ3「IT運用とデータサイエンティストを強力に支援するH...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):富士通株式会社 テーマ1「HPC&AI: Accelerating material develo...
PPTX
ChatGPTのコネクタ開発から学ぶ、外部サービスをつなぐMCPサーバーの仕組み
PDF
ニューラルプロセッサによるAI処理の高速化と、未知の可能性を切り拓く未来の人工知能
PDF
AI開発の最前線を変えるニューラルネットワークプロセッサと、未来社会における応用可能性
PDF
膨大なデータ時代を制する鍵、セグメンテーションAIが切り拓く解析精度と効率の革新
UnityによるHoloLensアプリケーション入門 1. 2. 3. 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. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 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. 63. 64. 65. 66. 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. 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. 実装例
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. 何も無い所を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. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 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. 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. 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. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 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. サンプルプログラムの流れ
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. 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. 音声入力
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. 147. 148. 149. 150. 151. 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. 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. 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. 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. 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. (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. 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. 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. 統計情報の利用
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. 統計情報の利用
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. 統計情報の利用
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. 統計情報の利用
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. 統計情報の利用
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. 統計情報の利用
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. 最小限度の設定の例
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. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. お問い合わせ
株式会社シーディングソフテック 石井 勇一
◦ E‐mail: yuichi.ishii@seedingsoftech.jp
◦ Home Page: http://seedingsoftech.jp/
個人的なお問い合わせ
◦ Twitter: @z_zabaglione
◦ Home Page: http://zabaglione.info/
本資料をシーディングソフテックの書面による事前許可なく本資料を複製、再製、改変、発表、アッ
プロード、掲示、転送、配布することを禁じます。
著者が作成したオリジナルのプログラムコードは個人・商用利用ともに一切の制限もなくロイヤリ
ティフリーでご利用可能です。
画像、音声、3Dモデルデータなどのリソース類、その他のツールやプログラムなどは原著者の利用
許諾に従ってご利用ください。
(C) 2018 石井 勇一 195