ケーススタディ-HoloLens の空間マッピング機能の拡張Case study - Expanding the spatial mapping capabilities of HoloLens

Microsoft HoloLens 用の最初のアプリを作成する際には、デバイスでの空間マッピングの境界をどれだけまでにプッシュできるかについても説明しました。When creating our first apps for Microsoft HoloLens, we were eager to see just how far we could push the boundaries of spatial mapping on the device. Microsoft スタジオのソフトウェアエンジニアである Jeff Evertt は、新しいテクノロジがどのように開発され、ユーザーの実際の環境でのホログラムの配置方法をより細かく制御する必要がないかについて説明しています。Jeff Evertt, a software engineer at Microsoft Studios, explains how a new technology was developed out of the need for more control over how holograms are placed in a user's real-world environment.

注意

HoloLens 2 では、開発者向けの新しいシーンランタイムが実装されています。これは、環境を認識するアプリケーションの開発を直感的に行うように設計された、構造化された高レベルの環境表現を使用して、混合の現実開発HoloLens 2 implements a new Scene Understanding Runtime, that provides Mixed Reality developers with a structured, high-level environment representation designed to make developing for environmentally aware applications intuitive.

ビデオを見るWatch the video

空間マッピング以外Beyond spatial mapping

私たちは、1つの HoloLens のうち2つ目のゲームに取り組んでいましたが、ここでは、世界中のホログラムの手順を実行してきたときに、ユーザーに関するより高いレベルの理解が必要でした。environment.While we were working on Fragments and Young Conker, two of the first games for HoloLens, we found that when we were doing procedural placement of holograms in the physical world, we needed a higher level of understanding about the user's environment. 各ゲームには独自の配置ニーズがありました。たとえば、フラグメントでは、フロアやテーブルなどのさまざまなサーフェスを区別して、関連する場所に手掛かりを配置する必要がありました。Each game had its own specific placement needs: In Fragments, for example, we wanted to be able to distinguish between different surfaces—such as the floor or a table—to place clues in relevant locations. また、ソファや椅子など、holographic 文字が見られる可能性のある表面を特定できるようにする必要がありました。We also wanted to be able to identify surfaces that life-size holographic characters could sit on, such as a couch or a chair. Young Conker では、プレーヤーの部屋の中で、生成された画面をプラットフォームとして使用できるようにしたいと考えていました。In Young Conker, we wanted Conker and his opponents to be able to use raised surfaces in a player's room as platforms.

これらのゲームの開発パートナーであるAsobo スタジオは、この問題に直面し、HoloLens の空間マッピング機能を拡張するテクノロジを作成しました。Asobo Studios, our development partner for these games, faced this problem head-on and created a technology that extends the spatial mapping capabilities of HoloLens. これを使用すると、プレーヤーの部屋を分析し、壁、テーブル、椅子、床などの表面を特定できます。Using this, we could analyze a player's room and identify surfaces such as walls, tables, chairs, and floors. また、holographic オブジェクトの最適な配置を決定するために、一連の制約に対して最適化する機能が用意されています。It also gave us the ability to optimize against a set of constraints to determine the best placement for holographic objects.

空間を理解するコードThe spatial understanding code

Asobo の元のコードを取って、このテクノロジをカプセル化するライブラリを作成しました。We took Asobo's original code and created a library that encapsulates this technology. Microsoft と Asobo は、このコードをオープンソースにし、独自のプロジェクトで使用できるようにMixedRealityToolkitで使用できるようにしました。Microsoft and Asobo have now open-sourced this code and made it available on MixedRealityToolkit for you to use in your own projects. すべてのソースコードが含まれているので、ニーズに合わせてカスタマイズし、その機能強化をコミュニティと共有することができます。All the source code is included, allowing you to customize it to your needs and share your improvements with the community. このC++ソルバーのコードは UWP DLL にラップされ、 MixedRealityToolkit 内に含まれるドロップイン prefabを使用して Unity に公開されています。The code for the C++ solver has been wrapped into a UWP DLL and exposed to Unity with a drop-in prefab contained within MixedRealityToolkit.

Unity サンプルには多くの便利なクエリが含まれています。これを使用すると、壁上の空のスペースを検索したり、オブジェクトを天井に配置したり、床上の大きなスペースに配置したり、文字の位置を識別したり、その他のさまざまな空間を理解するクエリを実行したりできます。There are many useful queries included in the Unity sample that will allow you to find empty spaces on walls, place objects on the ceiling or on large spaces on the floor, identify places for characters to sit, and a myriad of other spatial understanding queries.

HoloLens によって提供される空間マッピングソリューションは、問題のある領域全体のニーズに対応できるように設計されていますが、空間を認識するモジュールは、2つの特定のゲームのニーズをサポートするように構築されています。While the spatial mapping solution provided by HoloLens is designed to be generic enough to meet the needs of the entire gamut of problem spaces, the spatial understanding module was built to support the needs of two specific games. そのため、そのソリューションは、特定のプロセスと一連の前提を中心に構築されています。As such, its solution is structured around a specific process and set of assumptions:

  • 固定サイズの playspace: ユーザーは、init 呼び出しの最大 playspace サイズを指定します。Fixed size playspace: The user specifies the maximum playspace size in the init call.
  • 1 回限りのスキャンプロセス: このプロセスには、ユーザーが再生領域を定義するための個別のスキャンフェーズが必要です。One-time scan process: The process requires a discrete scanning phase where the user walks around, defining the playspace. クエリ関数は、スキャンが完了するまで機能しません。Query functions will not function until after the scan has been finalized.
  • ユーザー駆動型の playspace "描画" : スキャンフェーズ中に、ユーザーが playspace を移動して表示し、含める必要がある領域を効果的に描画します。User driven playspace “painting”: During the scanning phase, the user moves and looks around the playspace, effectively painting the areas which should be included. 生成されたメッシュは、このフェーズでユーザーからのフィードバックを提供するために重要です。The generated mesh is important to provide user feedback during this phase.
  • 屋内で home または office セットアップ: クエリ関数は、フラットなサーフェイスと壁面を中心に設計されています。Indoors home or office setup: The query functions are designed around flat surfaces and walls at right angles. これは、ソフトな制限です。This is a soft limitation. ただし、スキャンフェーズでは、主要軸と補助軸に沿ってメッシュテセレーションを最適化するために、主軸分析が完了します。However, during the scanning phase, a primary axis analysis is completed to optimize the mesh tessellation along major and minor axis.

ルームスキャンプロセスRoom Scanning Process

空間を理解するためのモジュールを読み込むときは、最初にスペースをスキャンします。これにより、床、天井、壁など、使用可能なすべてのサーフェイスが識別され、ラベルが付けられます。When you load the spatial understanding module, the first thing you'll do is scan your space, so all the usable surfaces—such as the floor, ceiling, and walls—are identified and labeled. スキャン処理中は、部屋を見て、スキャンに含める必要がある領域を "ペイント" します。During the scanning process, you look around your room and "paint' the areas that should be included in the scan.

このフェーズで見たメッシュは、どの部分がスキャンされているかをユーザーが知ることができる視覚的なフィードバックの重要な部分です。The mesh seen during this phase is an important piece of visual feedback that lets users know what parts of the room are being scanned. 空間認識モジュールの DLL は、内部的に、8cm サイズの voxel キューブのグリッドとして playspace を格納します。The DLL for the spatial understanding module internally stores the playspace as a grid of 8cm sized voxel cubes. スキャンの初期部分では、主要なコンポーネント分析が完了して、部屋の軸が決定されます。During the initial part of scanning, a primary component analysis is completed to determine the axes of the room. 内部的には、これらの軸に合わせて voxel 領域を格納します。Internally, it stores its voxel space aligned to these axes. メッシュは、voxel ボリュームから isosurface を抽出することによって、約1秒ごとに生成されます。A mesh is generated approximately every second by extracting the isosurface from the voxel volume.

白の空間マッピングメッシュと、緑色の playspace メッシュについて理解する

白の空間マッピングメッシュと、緑色の playspace メッシュについて理解するSpatial mapping mesh in white and understanding playspace mesh in green

含まれている SpatialUnderstanding.cs ファイルは、スキャンフェーズプロセスを管理します。The included SpatialUnderstanding.cs file manages the scanning phase process. 次の関数を呼び出します。It calls the following functions:

  • SpatialUnderstanding_Init: 開始時に1回呼び出されます。SpatialUnderstanding_Init: Called once at the start.
  • GeneratePlayspace_InitScan: スキャンフェーズを開始する必要があることを示します。GeneratePlayspace_InitScan: Indicates that the scan phase should begin.
  • GeneratePlayspace_UpdateScan_DynamicScan: 各フレームを呼び出して、スキャンプロセスを更新します。GeneratePlayspace_UpdateScan_DynamicScan: Called each frame to update the scanning process. カメラの位置と向きは、前に説明した playspace の描画プロセスに使用されます。The camera position and orientation is passed in and is used for the playspace painting process, described above.
  • GeneratePlayspace_RequestFinish: playspace を終了するために呼び出されます。GeneratePlayspace_RequestFinish: Called to finalize the playspace. これは、スキャンフェーズ中に "描画された" 領域を使用して、playspace を定義およびロックします。This will use the areas “painted” during the scan phase to define and lock the playspace. アプリケーションでは、スキャンフェーズ中に統計のクエリを実行したり、ユーザーフィードバックを提供するためにカスタムメッシュを照会したりすることができます。The application can query statistics during the scanning phase as well as query the custom mesh for providing user feedback.
  • Import_UnderstandingMesh: スキャン中、モジュールによって提供され、prefab を理解するためのSpatialUnderstandingCustomMesh動作が、プロセスによって生成されたカスタムメッシュを定期的に照会します。Import_UnderstandingMesh: During scanning, the SpatialUnderstandingCustomMesh behavior provided by the module and placed on the understanding prefab will periodically query the custom mesh generated by the process. さらに、この処理は、スキャンが完了した後に実行されます。In addition, this is done once more after scanning has been finalized.

SpatialUnderstanding動作によって実行されるスキャンフローは、 initscanを呼び出し、その後、各フレームに対してアップデートを実行します。The scanning flow, driven by the SpatialUnderstanding behavior calls InitScan, then UpdateScan each frame. 統計クエリによって適切なカバレッジが報告されると、ユーザーは、 [Requestfinish] を呼び出して、スキャンフェーズの終了を示すことができます。When the statistics query reports reasonable coverage, the user can airtap to call RequestFinish to indicate the end of the scanning phase. 戻り値が DLL の処理を完了したことを示すまで、アップデートを引き続き呼び出すことができます。UpdateScan continues to be called until it’s return value indicates that the DLL has completed processing.

クエリThe queries

スキャンが完了すると、インターフェイスで次の3種類のクエリにアクセスできるようになります。Once the scan is complete, you'll be able to access three different types of queries in the interface:

  • トポロジクエリ: スキャンされたルームのトポロジに基づく高速クエリです。Topology queries: These are fast queries that are based on the topology of the scanned room.
  • Shape クエリ: トポロジクエリの結果を使用して、定義したカスタム図形に適した水平方向のサーフェイスを検索します。Shape queries: These utilize the results of your topology queries to find horizontal surfaces that are a good match to custom shapes that you define.
  • オブジェクト配置クエリ: オブジェクトの一連のルールと制約に基づいて最適な場所を検索する、より複雑なクエリです。Object placement queries: These are more complex queries that find the best-fit location based on a set of rules and constraints for the object.

3つの主要なクエリに加えて、raycasting インターフェイスを使用して、タグ付きサーフェスの種類を取得し、カスタムの watertight ルームメッシュをコピーすることができます。In addition to the three primary queries, there is a raycasting interface which can be used to retrieve tagged surface types and a custom watertight room mesh can be copied out.

トポロジクエリTopology queries

DLL 内では、トポロジマネージャーは環境のラベル付けを処理します。Within the DLL, the topology manager handles labeling of the environment. 前述のように、データの大部分は、voxel ボリューム内に含まれる、1つのデータに格納されています。As mentioned above, much of the data is stored within surfels, which are contained within a voxel volume. さらに、 playspace情報構造体は、再生領域に関する情報を格納するために使用されます。これには、ワールドアラインメント (下記の詳細情報)、floor、および天井高さが含まれます。In addition, the PlaySpaceInfos structure is used to store information about the playspace, including the world alignment (more details on this below), floor, and ceiling height.

ヒューリスティックは、floor、シーリング、および壁面を決定するために使用されます。Heuristics are used for determining floor, ceiling, and walls. たとえば、1 ~ 2 の範囲を超える水平方向サーフェイスは、床面と見なされます。For example, the largest and lowest horizontal surface with greater than 1 m2 surface area is considered the floor. このプロセスでは、スキャン処理中のカメラパスも使用されることに注意してください。Note that the camera path during the scanning process is also used in this process.

トポロジマネージャーによって公開されるクエリのサブセットは、DLL を通じて公開されます。A subset of the queries exposed by the Topology manager are exposed out through the DLL. 公開されているトポロジクエリは次のとおりです。The exposed topology queries are as follows:

  • QueryTopology_FindPositionsOnWallsQueryTopology_FindPositionsOnWalls
  • QueryTopology_FindLargePositionsOnWallsQueryTopology_FindLargePositionsOnWalls
  • QueryTopology_FindLargestWallQueryTopology_FindLargestWall
  • QueryTopology_FindPositionsOnFloorQueryTopology_FindPositionsOnFloor
  • QueryTopology_FindLargestPositionsOnFloorQueryTopology_FindLargestPositionsOnFloor
  • QueryTopology_FindPositionsSittableQueryTopology_FindPositionsSittable

各クエリには、クエリの種類に固有のパラメーターのセットがあります。Each of the queries has a set of parameters, specific to the query type. 次の例では、必要なボリュームの最小の高さ & 幅、床の上の最小配置高さ、およびボリュームの前面にある最小のクリアランスの量をユーザーが指定しています。In the following example, the user specifies the minimum height & width of the desired volume, minimum placement height above the floor, and the minimum amount of clearance in front of the volume. すべての測定値は、メーターで計算されます。All measurements are in meters.

EXTERN_C __declspec(dllexport) int QueryTopology_FindPositionsOnWalls(
          _In_ float minHeightOfWallSpace,
          _In_ float minWidthOfWallSpace,
          _In_ float minHeightAboveFloor,
          _In_ float minFacingClearance,
          _In_ int locationCount,
          _Inout_ Dll_Interface::TopologyResult* locationData)

これらの各クエリは、 TopologyResult構造体の事前に割り当てられた配列を受け取ります。Each of these queries takes a pre-allocated array of TopologyResult structures. Locationcountパラメーターは、渡された配列の長さを指定します。The locationCount parameter specifies the length of the passed-in array. 戻り値は、返された場所の数を報告します。The return value reports the number of returned locations. この数は、渡されたLocationcountパラメーターを超えてはなりません。This number is never greater than the passed-in locationCount parameter.

TopologyResultには、返されたボリュームの中央の位置、フェーシングの方向 (通常は)、および検出された領域の大きさが含まれます。The TopologyResult contains the center position of the returned volume, the facing direction (i.e. normal), and the dimensions of the found space.

struct TopologyResult
     {
          DirectX::XMFLOAT3 position;
          DirectX::XMFLOAT3 normal;
          float width;
          float length;
     };

Unity サンプルでは、これらの各クエリが仮想 UI パネルのボタンにリンクされていることに注意してください。Note that in the Unity sample, each of these queries is linked up to a button in the virtual UI panel. サンプルでは、これらの各クエリのパラメーターを妥当な値にハードコーディングしています。The sample hard codes the parameters for each of these queries to reasonable values. その他の例については、サンプルコードのSpaceVisualizer.csを参照してください。See SpaceVisualizer.cs in the sample code for more examples.

クエリのシェイプShape queries

DLL 内で、shape analyzer (ShapeAnalyzer_W) はトポロジアナライザーを使用して、ユーザーが定義したカスタム図形と照合します。Inside of the DLL, the shape analyzer (ShapeAnalyzer_W) uses the topology analyzer to match against custom shapes defined by the user. Unity サンプルには、定義済みの一連の図形があります。これは、[クエリ] メニューの [図形] タブに表示されます。The Unity sample has a pre-defined set of shapes which are shown in the query menu, on the shape tab.

図形の分析は、水平方向のサーフェイスでのみ動作することに注意してください。Note that the shape analysis works on horizontal surfaces only. たとえば、ソファは、平らな座席の表面とソファの上面によって定義されています。A couch, for example, is defined by the flat seat surface and the flat top of the couch back. Shape クエリでは、特定のサイズ、高さ、および縦横範囲の2つのサーフェスが検索され、2つのサーフェスがアラインされ、接続されています。The shape query looks for two surfaces of a specific size, height, and aspect range, with the two surfaces aligned and connected. この Api の用語を使用して、ソファ座席とソファの背面の上部には形状コンポーネントがあり、アラインメント要件はシェイプコンポーネントの制約です。Using the APIs terminology, the couch seat and the top of the back of the couch are shape components and the alignment requirements are shape component constraints.

"Sittable" オブジェクトの Unity サンプル (ShapeDefinition.cs) で定義されているクエリの例を次に示します。An example query defined in the Unity sample (ShapeDefinition.cs), for “sittable” objects is as follows:

shapeComponents = new List<ShapeComponent>()
     {
          new ShapeComponent(
               new List<ShapeComponentConstraint>()
               {
                    ShapeComponentConstraint.Create_SurfaceHeight_Between(0.2f, 0.6f),
                    ShapeComponentConstraint.Create_SurfaceCount_Min(1),
                    ShapeComponentConstraint.Create_SurfaceArea_Min(0.035f),
               }),
     };
     AddShape("Sittable", shapeComponents);

各図形クエリは、一連の図形コンポーネントによって定義されます。各図形コンポーネントには、一連のコンポーネント制約と、コンポーネント間の依存関係を示す一連の図形制約があります。Each shape query is defined by a set of shape components, each with a set of component constraints and a set of shape constraints which lists dependencies between the components. この例では、1つのコンポーネント定義に3つの制約が含まれており、コンポーネント間に図形の制約はありません (コンポーネントが1つだけであるため)。This example includes three constraints in a single component definition and no shape constraints between components (as there is only one component).

これに対し、ソファ図形には、2つの図形コンポーネントと4つのシェイプ制約があります。In contrast, the couch shape has two shape components and four shape constraints. コンポーネントは、ユーザーのコンポーネントリスト内のインデックスによって識別されることに注意してください (この例では0と 1)。Note that components are identified by their index in the user’s component list (0 and 1 in this example).

shapeConstraints = new List<ShapeConstraint>()
        {
              ShapeConstraint.Create_RectanglesSameLength(0, 1, 0.6f),
              ShapeConstraint.Create_RectanglesParallel(0, 1),
              ShapeConstraint.Create_RectanglesAligned(0, 1, 0.3f),
              ShapeConstraint.Create_AtBackOf(1, 0),
        };

カスタム図形の定義を簡単に作成するために、Unity モジュールにラッパー関数が用意されています。Wrapper functions are provided in the Unity module for easy creation of custom shape definitions. コンポーネントとシェイプの制約の完全な一覧については、 ShapeComponentConstraintShapeConstraintの構造内のSpatialUnderstandingDll.csを参照してください。The full list of component and shape constraints can be found in SpatialUnderstandingDll.cs within the ShapeComponentConstraint and the ShapeConstraint structures.

青い四角形は、椅子の図形クエリの結果を強調表示します。

青い四角形は、椅子の図形クエリの結果を強調表示します。The blue rectangle highlights the results of the chair shape query.

オブジェクト配置のソルバーObject placement solver

オブジェクト配置クエリを使用すると、オブジェクトを配置する物理的な部屋の理想的な場所を識別できます。Object placement queries can be used to identify ideal locations in the physical room to place your objects. ソルバーは、オブジェクトのルールと制約を指定して、最適な場所を見つけます。The solver will find the best-fit location given the object rules and constraints. また、オブジェクトクエリは、オブジェクトがSolver_RemoveObjectまたはSolver_RemoveAllObjects呼び出しで削除されるまで保持され、制約された複数オブジェクトの配置が可能になります。In addition, object queries persist until the object is removed with Solver_RemoveObject or Solver_RemoveAllObjects calls, allowing constrained multi-object placement.

オブジェクト配置クエリは、3つの部分で構成されます。パラメーターを使用した配置の種類、規則の一覧、および制約の一覧です。Object placement queries consist of three parts: placement type with parameters, a list of rules, and a list of constraints. クエリを実行するには、次の API を使用します。To run a query, use the following API:

public static int Solver_PlaceObject(
                [In] string objectName,
                [In] IntPtr placementDefinition,    // ObjectPlacementDefinition
                [In] int placementRuleCount,
                [In] IntPtr placementRules,         // ObjectPlacementRule
                [In] int constraintCount,
                [In] IntPtr placementConstraints,   // ObjectPlacementConstraint
                [Out] IntPtr placementResult)

この関数は、オブジェクト名、配置定義、および規則と制約の一覧を受け取ります。This function takes an object name, placement definition, and a list of rules and constraints. ラッパー C#は、規則と制約の構築を簡単にする構築ヘルパー関数を提供します。The C# wrappers provide construction helper functions to make rule and constraint construction easy. 配置定義には、次のいずれかのクエリの種類が含まれます。The placement definition contains the query type — that is, one of the following:

public enum PlacementType
                {
                    Place_OnFloor,
                    Place_OnWall,
                    Place_OnCeiling,
                    Place_OnShape,
                    Place_OnEdge,
                    Place_OnFloorAndCeiling,
                    Place_RandomInAir,
                    Place_InMidAir,
                    Place_UnderFurnitureEdge,
                };

各配置型には、型に固有のパラメーターのセットがあります。Each of the placement types has a set of parameters unique to the type. Objectplacementdefinition構造体には、これらの定義を作成するための静的ヘルパー関数のセットが含まれています。The ObjectPlacementDefinition structure contains a set of static helper functions for creating these definitions. たとえば、床にオブジェクトを配置する場所を見つけるには、次の関数を使用します。For example, to find a place to put an object on the floor, you can use the following function:

public static ObjectPlacementDefinition Create_OnFloor(Vector3 halfDims)

配置の種類に加えて、一連のルールと制約を指定することができます。In addition to the placement type, you can provide a set of rules and constraints. 規則に違反することはありません。Rules cannot be violated. 型とルールを満たす配置場所は、最適な配置場所を選択するために、一連の制約に対して最適化されます。Possible placement locations that satisfy the type and rules are then optimized against the set of constraints to select the optimal placement location. 各ルールと制約は、指定された静的作成関数によって作成できます。Each of the rules and constraints can be created by the provided static creation functions. ルールと制約の構築関数の例を以下に示します。An example rule and constraint construction function is provided below.

public static ObjectPlacementRule Create_AwayFromPosition(
                    Vector3 position, float minDistance)
               public static ObjectPlacementConstraint Create_NearPoint(
                    Vector3 position, float minDistance = 0.0f, float maxDistance = 0.0f)

次に示すオブジェクト配置クエリでは、画面の端に半分のメーターキューブを配置し、その他の場所にある他のオブジェクトから、ルームの中央付近に移動するための場所を探しています。The object placement query below is looking for a place to put a half meter cube on the edge of a surface, away from other previously place objects and near the center of the room.

List<ObjectPlacementRule> rules = 
          new List<ObjectPlacementRule>() {
               ObjectPlacementRule.Create_AwayFromOtherObjects(1.0f),
          };

     List<ObjectPlacementConstraint> constraints = 
          new List<ObjectPlacementConstraint> {
               ObjectPlacementConstraint.Create_NearCenter(),
          };

     Solver_PlaceObject(
          “MyCustomObject”,
          new ObjectPlacementDefinition.Create_OnEdge(
          new Vector3(0.25f, 0.25f, 0.25f), 
          new Vector3(0.25f, 0.25f, 0.25f)),
          rules.Count,
          UnderstandingDLL.PinObject(rules.ToArray()),
          constraints.Count,
          UnderstandingDLL.PinObject(constraints.ToArray()),
          UnderstandingDLL.GetStaticObjectPlacementResultPtr());

成功した場合、配置位置、次元、および向きを含むObjectplacement Ementresult構造体が返されます。If successful, an ObjectPlacementResult structure containing the placement position, dimensions and orientation is returned. また、配置は、配置されたオブジェクトの DLL の内部リストに追加されます。In addition, the placement is added to the DLL’s internal list of placed objects. 後続の配置クエリでは、このオブジェクトが考慮されます。Subsequent placement queries will take this object into account. Unity サンプルのLevelSolver.csファイルには、クエリの例が多数含まれています。The LevelSolver.cs file in the Unity sample contains more example queries.

青いボックスには、"カメラの位置から離れています" ルールを使用して、3か所のフロアクエリの結果が表示されます。

青いボックスには、"カメラの位置から離れています" ルールを使用して、3か所のフロアクエリの結果が表示されます。The blue boxes show the result from three Place On Floor queries with "away from camera position" rules.

テクニックTips:

  • レベルまたはアプリケーションのシナリオに必要な複数のオブジェクトの配置位置を解決する場合は、まず、必要以上に大きなオブジェクトを解決して、スペースが見つかる確率を最大化します。When solving for placement location of multiple objects required for a level or application scenario, first solve indispensable and large objects to maximize the probability that a space can be found.
  • 配置順序は重要です。Placement order is important. オブジェクトの配置が見つからない場合は、制限の少ない構成を試してください。If object placements cannot be found, try less constrained configurations. 一連のフォールバック構成を設定することは、多くの部屋構成で機能をサポートするために不可欠です。Having a set of fallback configurations is critical to supporting functionality across many room configurations.

射線のキャストRay casting

3つの主要なクエリに加えて、射線のキャストインターフェイスを使用して、タグ付きサーフェス型を取得できます。また、ルームがスキャンされて完了した後に、カスタムの watertight playspace メッシュをコピーできます。ラベルは、床、天井、および壁面。In addition to the three primary queries, a ray casting interface can be used to retrieve tagged surface types and a custom watertight playspace mesh can be copied out After the room has been scanned and finalized, labels are internally generated for surfaces like the floor, ceiling, and walls. PlayRaycastResult Eraycast関数は、光線を受け取り、光線が既知のサーフェイスと競合している場合は、その表面に関する情報をの形式で返します。The PlayspaceRaycast function takes a ray and returns if the ray collides with a known surface and if so, information about that surface in the form of a RaycastResult.

struct RaycastResult
     {
          enum SurfaceTypes
          {
               Invalid, // No intersection
               Other,
               Floor,
               FloorLike,         // Not part of the floor topology, 
                                  //     but close to the floor and looks like the floor
               Platform,          // Horizontal platform between the ground and 
                                  //     the ceiling
               Ceiling,
               WallExternal,
               WallLike,          // Not part of the external wall surface, 
                                  //     but vertical surface that looks like a 
                                  //    wall structure
               };
               SurfaceTypes SurfaceType;
               float SurfaceArea;   // Zero if unknown 
                                        //  (i.e. if not part of the topology analysis)
               DirectX::XMFLOAT3 IntersectPoint;
               DirectX::XMFLOAT3 IntersectNormal;
     };

内部的には、raycast は、playspace の計算された8cm キューブ voxel 表現に対して計算されます。Internally, the raycast is computed against the computed 8cm cubed voxel representation of the playspace. 各 voxel には、処理されたトポロジデータ (とも呼ばれます) を持つ surface 要素のセットが含まれています。Each voxel contains a set of surface elements with processed topology data (also known as surfels). 交差する voxel セルに含まれているが比較され、トポロジ情報の検索に使用される最適な一致が得られます。The surfels contained within the intersected voxel cell are compared and the best match used to look up the topology information. このトポロジデータには、 SurfaceTypes列挙型の形式で返されるラベルと、交差するサーフェイスの表面領域が含まれます。This topology data contains the labeling returned in the form of the SurfaceTypes enum, as well as the surface area of the intersected surface.

Unity のサンプルでは、カーソルは各フレームに射線をキャストします。In the Unity sample, the cursor casts a ray each frame. 最初に、Unity の colliders に対して2番目は、モジュールの世界表現を理解するためのものです。最後に、UI 要素に対してを実行します。First, against Unity’s colliders; second, against the understanding module’s world representation; and finally, against the UI elements. このアプリケーションでは、UI は優先順位を取得し、結果を理解し、最後に Unity の colliders を取得します。In this application, UI gets priority, then the understanding result, and finally, Unity’s colliders. SurfaceTypeは、カーソルの横にテキストとして報告されます。The SurfaceType is reported as text next to the cursor.

Raycast 結果レポートを床と交差させることができます。

Raycast 結果レポートを床と交差させることができます。Raycast result reporting intersection with the floor.

コードを入手するGet the code

オープンソースコードはMixedRealityToolkitで入手できます。The open-source code is available in MixedRealityToolkit. プロジェクトでコードを使用する場合は、 HoloLens Developer フォーラムでお知らせください。Let us know on the HoloLens Developer Forums if you use the code in a project. 何をしているかをお待ちください。We can't wait to see what you do with it!

作成者についてAbout the author

Jeff Evertt, Software Engineering Lead at Microsoft Jeff Everttは、育成から開発を体験できるようになったころから HoloLens で働いてきたソフトウェアエンジニアリングリードです。Jeff Evertt is a software engineering lead who has worked on HoloLens since the early days, from incubation to experience development. HoloLens より前は、さまざまなプラットフォームやゲームで Xbox Kinect とゲーム業界で働いていました。Before HoloLens, he worked on the Xbox Kinect and in the games industry on a wide variety of platforms and games. Jeff は、ロボットやグラフィックス、そしてビープ音が鳴り目立つ色ライトを使用したことに情熱を持っています。Jeff is passionate about robotics, graphics, and things with flashy lights that go beep. 新しいものを学習し、ソフトウェア、ハードウェア、特に2つの重なり合う領域で作業しています。He enjoys learning new things and working on software, hardware, and particularly in the space where the two intersect.

関連項目See also