2016-11-23 64 views
0

我一直在試圖將對象放置到房間與spatialunderstandingExample現場拍攝的數據。但是代碼對我來說真的不可理解。有沒有人使用空間工具實現這個功能?任何幫助?HoloToolkit空間理解和對象放置

https://github.com/Microsoft/HoloToolkit-Unity/tree/master/Assets/HoloToolkit-Examples/SpatialUnderstanding/SpatialUnderstanding-FeatureOverview/Scripts

所有腳本都在這裏,在UI腳本Query_OnFloor_AwayFromMe()被調用,然後我有點失去跟蹤代碼,直到從linedrawer腳本draw_box被調用。在draw_box中,我嘗試了以下操作以將全息圖帶到那裏,但沒有顯示出來。

mydummy.SetActive(true); 
    mydummy.transform.position = new Vector3(center.x,center.y,center.z); 
+0

根據您以前的問題(http://stackoverflow.com/questions/40728179/hololens-placing-objects-with-spatial-understanding/40729295#40729295),您已成功替換爲您的全息圖的默認框自己的,但你正在努力得到它的正確和規模的地方,大小合適,之前我張貼的答案,是正確的? –

+0

我想我沒有,但它是一個遊戲物體我忘了關。所以我再次回到那裏:( – firativerson

+1

如果你可以發佈的地方你目前的代碼,我要看看它。 –

回答

0

我將從試圖解釋本示例中發生的事情開始。從UI.cs中的調用開始到Query_OnFloor_AwayFromMe()...

  1. 這會調用LevelSolver.cs。在此方法是創建一個新的PlacementQuery對象並調用PlaceObjectAsync。
  2. PlaceObjectAsync創建了以System.Threading.Tasks.Task.Run通話主叫地方空間理解的實際工作是越來越做了一個新的線程。這項工作必須在一個單獨的線程,因爲它需要很長的時間,所以它需要跨越多個幀將被執行的程序將會執行期間鎖定來完成。
  3. 在新線程PlaceObject被調用時,這將實際調用空間理解(SpatialUnderstandingDllObjectPlacement.Solver_PlaceObject),這是對C++ HoloToolkit的調用,這是需要很長時間的調用。完成後,結果將添加到基本上是工作隊列的placementResults中。
  4. 在LevelSolver.cs有一個更新的方法,這將調用每一個團結繪製一個新的幀的時間。在這裏調用Draw_PlacementResults。
  5. Draw_PlacementResults循環遍歷placementResults工作隊列中的每個結果,並調用LineDrawer.cs中的Draw_AnimatedBox
  6. 這就是您如何訪問我們在上一個問題中討論的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。

+0

這是你的實際代碼?在MyProcessPlacementResults()我不能離隊放置導致它沒有讓我,我試圖讓他們一個個仍然沒有工作... – firativerson

+1

是的,它是我的代碼,我撕出來一個更大的項目,這是不是基於你的工作了的例子。你是對的,我placementResults是一個實際的隊列,我將修改我的答案,試圖解決這個問題。 –

+0

謝謝卡梅倫期待它 – firativerson