https://torikasyu.com/?p=956
前回、サンプルコードから、SpatialUnderstandingの配置条件・ルール・制約を使ってオブジェクトを配置する機能を見てみました。今回は実際にそれを動かすシンプルなソースコードを紹介します。
全体のUnityプロジェクトは下記になります。
◆Update()
void Update() { if (DoesScanMeetMinBarForCompletion && (SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Scanning) && !SpatialUnderstanding.Instance.ScanStatsReportStillWorking) { SpatialUnderstanding.Instance.RequestFinishScan(); } if (!_triggered && SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Done) { _triggered = true; CreateScene(); } }
まず、オブジェクトの配置を行うためには、SpatialUnderstandingの空間認識が終了(ScanStateがDone)していなければなりません。終了するためには、RequestFinishScan()をコールします。
◆CreateScene()
void CreateScene() { // DLLの初期化 SpatialUnderstandingDllObjectPlacement.Solver_Init(); var halfBoxDims = boxFullDims * .5f; // 他のオブジェクトから離す距離 var disctanceFromOtherObjects = halfBoxDims.x > halfBoxDims.z ? halfBoxDims.x * 3f : halfBoxDims.z * 3f; // 作成したいオブジェクトの数 var desiredLocationCount = 3; for (int i = 0; i < desiredLocationCount; ++i) { // ルールの作成(複数追加可能) var placementRules = new List<spatialUnderstandingDllObjectPlacement.ObjectPlacementRule>(); placementRules.Add(SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(disctanceFromOtherObjects)); // 制約の作成(複数追加可能) var placementConstraints = new List<spatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint>(); placementConstraints.Add(SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint.Create_AwayFromOtherObjects()); // 定義の作成(1つだけ) SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition placementDefinition = SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnFloor(halfBoxDims); int ret = SpatialUnderstandingDllObjectPlacement.Solver_PlaceObject( "my placement", SpatialUnderstanding.Instance.UnderstandingDLL.PinObject(placementDefinition), placementRules.Count, SpatialUnderstanding.Instance.UnderstandingDLL.PinObject(placementRules.ToArray()), placementConstraints.Count, SpatialUnderstanding.Instance.UnderstandingDLL.PinObject(placementConstraints.ToArray()), SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticObjectPlacementResultPtr() ); if (ret > 0) { SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult placementResult = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticObjectPlacementResult(); var rotation = Quaternion.LookRotation(placementResult.Forward, Vector3.up); var obj = Instantiate(toPlaceObj, placementResult.Position, rotation); } } }
オブジェクトの配置を決めるために、配置条件・ルール・制約を作成します。作成したものをDLLにはポインタで渡します。
配置場所の決定がうまくいくと、placementResultに結果が返ってきますので、その中の値を使って配置したいオブジェクトをInstantinateします。
ソースコード内のコメントにも書いていますが、制約とルールは複数追加することができます。追加すればするほど思った通りの場所に置くことができるようになりますが、処理が重くなりますので、複数オブジェクトの配置の際にはスレッドの使用を検討したほうがよさそうです。