我將從試圖解釋本示例中發生的事情開始。從UI.cs中的調用開始到Query_OnFloor_AwayFromMe()...
- 這會調用LevelSolver.cs。在此方法是創建一個新的PlacementQuery對象並調用PlaceObjectAsync。
- PlaceObjectAsync創建了以System.Threading.Tasks.Task.Run通話主叫地方空間理解的實際工作是越來越做了一個新的線程。這項工作必須在一個單獨的線程,因爲它需要很長的時間,所以它需要跨越多個幀將被執行的程序將會執行期間鎖定來完成。
- 在新線程PlaceObject被調用時,這將實際調用空間理解(SpatialUnderstandingDllObjectPlacement.Solver_PlaceObject),這是對C++ HoloToolkit的調用,這是需要很長時間的調用。完成後,結果將添加到基本上是工作隊列的placementResults中。
- 在LevelSolver.cs有一個更新的方法,這將調用每一個團結繪製一個新的幀的時間。在這裏調用Draw_PlacementResults。
- Draw_PlacementResults循環遍歷placementResults工作隊列中的每個結果,並調用LineDrawer.cs中的Draw_AnimatedBox
- 這就是您如何訪問我們在上一個問題中討論的Draw_Box的調用。
所以,另一個問題是如何修改這個例子來把你自己的模型放在適當的位置。我建議在LevelSolver.cs中進行修改。嘗試改變更新(),以這樣的:
private void Update()
{
// Can't do any of this till we're done with the scanning phase
if (SpatialUnderstanding.Instance.ScanState != SpatialUnderstanding.ScanStates.Done)
{
return;
}
// Make sure the solver has been initialized
if (!IsSolverInitialized &&
SpatialUnderstanding.Instance.AllowSpatialUnderstanding)
{
InitializeSolver();
}
// Constraint queries
if (SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Done)
{
Update_Queries();
}
// Handle async query results
ProcessPlacementResults();
MyProcessPlacementResults();
}
這將導致其停止繪畫工具盒,而是稱之爲「MyProcessPlacementResults」處理做的結果的東西。我會向LevelSolver.cs添加一個像這樣的方法。 (在代碼中,我借用我創建一個樹)
private void MyProcessPlacementResults()
{
if (placementResults.Count > 0)
{
var toPlace = placementResults.Dequeue();
var rotation = Quaternion.LookRotation(toPlace.Result.Forward, Vector3.up);
CreateTree(toPlace.Result.Position, rotation);
}
}
下面是我用實際實例樹中的正確位置代碼:
private GameObject ThisIsYourCustomModelInMineItWasATree;
private Vector3 TheSizeIPassedToSpatialUnderstanding = new Vector3(1, 1, 1);
public void CreateHologram(Vector3 positionCenter, Quaternion rotation)
{
ThisIsYourCustomModelInMineItWasATree = GameObject.CreatePrimitive(PrimitiveType.Sphere);
GameObject newObject = Instantiate(ThisIsYourCustomModelInMineItWasATree, positionCenter, rotation) as GameObject;
if (newObject != null)
{
// Set the parent of the new object the GameObject it was placed on
newObject.transform.parent = gameObject.transform;
newObject.transform.localScale = StretchToFit(ThisIsYourCustomModelInMineItWasATree, TheSizeIPassedToSpatialUnderstanding);
newObject.AddComponent<MeshCollider>();
}
}
和公正的這裏完整性是我習慣了縮放到所需大小的代碼:
private Vector3 StretchToFit(GameObject obj, Vector3 desiredSize)
{
var curBounds = GetBoundsForAllChildren(obj).size;
return new Vector3(desiredSize.x/curBounds.x/2, desiredSize.y, desiredSize.z/curBounds.z/2);
}
private Bounds GetBoundsForAllChildren(GameObject findMyBounds)
{
Bounds result = new Bounds(Vector3.zero, Vector3.zero);
foreach (var renderer in findMyBounds.GetComponentsInChildren<Renderer>())
{
if (result.extents == Vector3.zero)
{
result = renderer.bounds;
}
else
{
result.Encapsulate(renderer.bounds);
}
}
return result;
}
我也改變了私有變量placementResults從列表添加到隊列。我這樣做是因爲列表被用來在每一幀中繪製一個框。我們希望有一個隊列,因爲我們要一次實例化一個新的對象,並讓Unity引擎管理。找到這行:
private List<PlacementResult> placementResults = new List<PlacementResult>();
並將其更改爲:
private Queue<PlacementResult> placementResults = new Queue<PlacementResult>();
做出這樣的轉變,你將需要解決幾個地方之後。刪除方法Draw_PlacementResults,它不再被使用。更改調用placementResults.Add的兩個位置到placementResults.Enqueue。
根據您以前的問題(http://stackoverflow.com/questions/40728179/hololens-placing-objects-with-spatial-understanding/40729295#40729295),您已成功替換爲您的全息圖的默認框自己的,但你正在努力得到它的正確和規模的地方,大小合適,之前我張貼的答案,是正確的? –
我想我沒有,但它是一個遊戲物體我忘了關。所以我再次回到那裏:( – firativerson
如果你可以發佈的地方你目前的代碼,我要看看它。 –