2017-07-10 53 views
7

嘿,我試圖找出如何保持代替簡單的節點是我走在它周圍ARKit如何保持ARKit SCNNode到位

代碼:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { 

    if let planeAnchor = anchor as? ARPlaneAnchor { 

    if planeDetected == false { // Bool only allows 1 plane to be added 
      planeDetected = true 
     self.addPlane(node: node, anchor: planeAnchor) 
    } 

    } 
} 

這增加了SCNNode

func addPlane(node: SCNNode, anchor: ARPlaneAnchor) { 

    // We add the anchor plane here 

    let showDebugVisuals = Bool() 
    let plane = Plane(anchor, showDebugVisuals) 
    planes[anchor] = plane 
    node.addChildNode(plane) 



    // We add our custom SCNNode here 

    let scene = SCNScene(named: "art.scnassets/PlayerModel.scn")! 
    let Body = scene.rootNode.childNode(withName: "Body", recursively: true)! 

    Body.position = SCNVector3.positionFromTransform(anchor.transform) 
    Body.movabilityHint = .movable 
    wrapperNode.position = SCNVector3.positionFromTransform(anchor.transform) 

    wrapperNode.addChildNode(Body) 

    scnView.scene.rootNode.addChildNode(wrapperNode) 

伊夫嘗試添加一個平面/錨節點,並把「身體」節點在,但它依然繼續。我想也許它與更新功能有關。

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { 
} 

或者最有可能的位置設置

wrapperNode.position = SCNVector3.positionFromTransform(anchor.transform) 

Iv'e通過互聯網上的每個源/項目文件/視頻看了看,沒有人有一個簡單的解決這個簡單的問題。

+0

有沒有簡單的解決方案。您應該使用表面檢測來獲得更好的結果,但對象仍然會稍微移動一點。 –

+0

好的,謝謝你確認這不是一個簡單的解決方案。 – Hunter

回答

16

在這裏可能會發生兩種「四處移動」。


一個是ARKit不斷完善的設備在真實世界中的位置如何映射到抽象協調你把虛擬內容空間的估計。例如,假設你把虛擬物體在(0, 0, -0.5) ,然後將您的設備向左移動10釐米。只有ARKit精確跟蹤移動,虛擬對象纔會錨定在物理空間中。但視覺 - 慣性測距不是一門精確的科學,所以ARKit可能認爲你向左移動了10.5釐米 - 在這種情況下,你的虛擬物體似乎會向右滑動5毫米,即使它位置在ARKit/SceneKit座標空間中。

除了希望蘋果使設備具有更好的傳感器,更好的相機或更好的CPU/GPU並改善世界跟蹤科學之外,您無法真正做到這一點。 (在適當的時候,這可能是一個安全的賭注,儘管這可能不符合你當前的項目提供幫助。)


既然你還面臨着飛機的檢測,還有另一種皺紋。 ARKit不斷改進對檢測到的飛機位置的估計。所以,即使飛機的實際位置不變,它在ARKit/SceneKit座標空間中的位置也是如此。

這種運動通常是一件好事 - 如果您希望虛擬物體出現在真實世界的表面上,您需要確定該表面的位置。當平面檢測更加確定表面的位置時,您會看到一些移動,但是在短時間後,當您將攝像機移動到計劃錨定的虛擬對象時,您應該看到的移動更少,而不是那些在世界上浮動的虛擬對象空間。


在你的代碼,但是,你不就是坐飛機檢測的優勢,使您的自定義內容(從「PlayerModel.scn」)堅持以面錨點:

wrapperNode.position = SCNVector3.positionFromTransform(anchor.transform) 
wrapperNode.addChildNode(Body) 
scnView.scene.rootNode.addChildNode(wrapperNode) 

此代碼使用初始的平面錨的位置在世界空間位置wrapperNode(因爲你使它成爲根節點的孩子)。如果您將wrapperNode作爲平面主播節點的子節點(您在renderer(_:didAdd:for:)中收到的節點),則它會保持與平面相連,因爲ARKit會優化其對平面位置的估計。最初你會有更多的動作,但隨着飛機探測「穩定下來」,你的虛擬物體將「滑落」得更少。 (當你使節點成爲飛機的一個孩子時,你不需要設置它的位置 - 零位表示它在飛機的正確位置。在任何情況下,你只需要相對於這架飛機 - 即上/下/沿它多遠。)

+0

謝謝你很好的答案! – Hunter

+0

Apple Dev在這個項目中提供了更多的細節示例 https://github.com/gao0122/ARKit-Example-by-Apple 它可以解釋一切正確和簡單。 – mychar

相關問題