SpatialUnderstandingを使ってみる(その1)

前のエントリでSpatialMappingからPlaneを生成するのを行いました。
今回は、より空間マッピングを使いこなすために、SpatialUnderstandingを見てみることにします。
ただ、SpatialUnderstandingは非常に分量が多く、なかなか全貌が見えないので、なんとなく理解した部分から書いてみようと思います。
まずは、ZuQ9Nn(ズキューン)さんが書かれている解説をご確認ください

お疲れ様です。ZuQ9->Nnです。 久しぶりのHoloLens開発の進捗。 今回はSpatialUnderstandingです。 SpatialUnderstandingはクラス名、メソッド名が長くまた公式のサンプル HoloToolkit-Examples > Sp...
HoloToolkit-Examples > SpatialUnderstanding > SpatialUnderstanding-FeatureOverview から、空間マッピングを解析する部分をシンプルな形で再構成されています。
SpatialUnderstandingはSceneに配置すればそれだけで動作はするのですが、動作の状況を表示して、解析が一定以上進んだら

SpatialUnderstanding.Instance.RequestFinishScan();

を使用して解析を終了する、という流れになっています。
ZuQ9Nn(ズキューン)さんも参考にされた下記のサイトを見ると、更に別のSpatialUnderstandingの使い方のサンプルが載っていました。

SpatialUnderstandingには、空間を解析する機能に加えて、オブジェクトを配置する(正確には配置場所を決めてくれる)機能があります。
配置の条件として、壁や床などの配置場所の指定、ほかのオブジェクトや床や壁ととどのくらい離れているか、などの制約をつけることができます。
配置条件としては下記が使用できます。

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

ルールとしては下記があります。

public enum ObjectPlacementRuleType
{
    Rule_AwayFromPosition,
    Rule_AwayFromWalls,
    Rule_AwayFromOtherObjects,
};

制約としては下記があります。

public enum ObjectPlacementConstraintType
{
    Constraint_NearPoint,
    Constraint_NearWall,
    Constraint_AwayFromWalls,
    Constraint_NearCenter,
    Constraint_AwayFromOtherObjects,
    Constraint_AwayFromPoint
};

上記の条件とルール(複数)、制約(複数)を組み合わせて、よさげなオブジェクト配置場所を決めてもらうことができます。
場所を決めてもらうメソッドそのものは、SpatialUnderstandingDllObjectPlacementの下記メソッドになります

public static extern int Solver_PlaceObject(
 [In, MarshalAs(UnmanagedType.LPStr)] string objectName,
 [In] IntPtr placementDefinition,// ObjectPlacementDefinition
 [In] int placementRuleCount,
 [In] IntPtr placementRules, // ObjectPlacementRule
 [In] int constraintCount,
 [In] IntPtr placementConstraints,// ObjectPlacementConstraint
 [Out] IntPtr placementResult);// ObjectPlacementResult

DLLに処理を依頼しているのでその中身はわかりませんが、用意すべき引数は上記となります。
IntPtr型の引数を作成するには、

SpatialUnderstanding.Instance.UnderstandingDLL.PinObject();

を使用します。
例えばObjectPlacementRuleの引数を作成するには、まず、SpatialUnderstandingDllObjectPlacement.ObjectPlacementRuleのルール作成メソッドを使用します。

SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(float);

生成したルールを必要な分だけList<>に格納します。
そして、そのListを上記のPinObject()の引数にすれば、IntPtrを得ることができます。
依頼が終わったら、

SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticObjectPlacementResult();

で結果を取り出すことができます。
結果はObjectPlacementResult型になっているので、clone()してから使用してください。

 public class ObjectPlacementResult : ICloneable
 {
  public object Clone()
  {
  return this.MemberwiseClone();
  }
  public Vector3 Position;
  public Vector3 HalfDims;
  public Vector3 Forward;
  public Vector3 Right;
  public Vector3 Up;
 };

resultのPositionやForwardが特定できたので、これを使って配置したいオブジェクトをInstantiateする、という流れになります。
Indubitable Developmentのサンプルコードでは、ルールや制約、結果などを独自のクラスや構造体に格納しているので、分量は多いですが使いやすいソースになっています。
その分、独自で簡単なサンプルをつくるのが難しかったので、次回の記事ではそのあたりを作ってみたいと思います。
https://torikasyu.com/?p=959

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク