前のエントリでSpatialMappingからPlaneを生成するのを行いました。
今回は、より空間マッピングを使いこなすために、SpatialUnderstandingを見てみることにします。
ただ、SpatialUnderstandingは非常に分量が多く、なかなか全貌が見えないので、なんとなく理解した部分から書いてみようと思います。
まずは、ZuQ9Nn(ズキューン)さんが書かれている解説をご確認ください
SpatialUnderstandingはSceneに配置すればそれだけで動作はするのですが、動作の状況を表示して、解析が一定以上進んだら
SpatialUnderstanding.Instance.RequestFinishScan();
を使用して解析を終了する、という流れになっています。
ZuQ9Nn(ズキューン)さんも参考にされた下記のサイトを見ると、更に別の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