web-dev-qa-db-ja.com

ARKit SCNNodeを適切に保持する方法

ちょっと私は把握しようとしている。単純なノードを適切に保持する方法。 ARKitで歩き回るとき

コード:

 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)

私はPlane/Anchor Nodeを追加して、その中に「Body」ノードを配置しようとしましたが、まだ動きます。更新機能と関係があるのではないかと思いました。

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

またはおそらく位置設定

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

Iv'eは、インターネット上のすべてのソース/プロジェクトファイル/ビデオを調べましたが、この単純な問題に対する単純な解決策はありません。

20
Hunter

ここで発生する可能性のある2種類の「移動」があります。


1つは、ARKitは、現実世界でのデバイスの位置が、仮想コンテンツを配置する抽象的な座標空間にどのようにマッピングされるかの推定を継続的に改善していることです。たとえば、仮想オブジェクトを_(0, 0, -0.5)_に置き、デバイスを10 cmだけ左に移動します。仮想オブジェクトは、ARKitが動きを正確に追跡する場合にのみ、物理空間に固定されているように見えます。しかし、視覚慣性オドメトリは正確な科学ではないため、ARKitはあなたが左に10.5 cm移動したと考える可能性があります。その場合、仮想オブジェクトは右に5 mmだけ「スリップ」しているように見えますARKit/SceneKit座標空間の位置は一定のままです。

希望Appleは、より良いセンサー、より良いカメラ、またはより良いCPU/GPUを備えたデバイスを作成し、世界追跡の科学を改善します。おそらく、それはおそらくあなたの現在のプロジェクトには役に立たないでしょうが、それはおそらく安全な賭けです)


飛行機の検出も扱っているため、別のしわがあります。 ARKitは、検出された平面の位置の推定値を継続的に改善しています。そのため、平面の実際の位置は変化していませんが、ARKit/SceneKit座標空間での位置は変化しています。

通常、この種の動きは良いことです。仮想オブジェクトを現実世界の表面に固定して表示する場合は、その表面がどこにあるかを確認する必要があります。平面の検出によりサーフェスの位置がより確実になるため、ある程度の動きが見られますが、少し時間が経つと、平面に固定された仮想オブジェクトのカメラを動かすときの「スリップ」が少なくなります。スペース。


ただし、コードでは、(「PlayerModel.scn」からの)カスタムコンテンツをプレーンアンカーに固定するためにプレーン検出を利用していません。

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

このコードは、プレーンアンカーのinitial位置を使用して、ワールドスペース内のwrapperNodeを配置します(ルートノードの子にするため)。代わりにwrapperNodeをプレーンアンカーのノード(renderer(_:didAdd:for:)で受け取ったノード)の子にすると、ARKitがプレーンの位置の推定を洗練するため、プレーンにアタッチされたままになります。最初はもう少し動きがありますが、平面検出が「安定」すると、仮想オブジェクトの「滑り」が少なくなります。

(ノードを平面の子にする場合、その位置を設定する必要はありません—ゼロの位置は、平面が正しい場所にあることを意味します。いずれにしても、平面に対してのみ位置を設定する必要があります。どれだけ上/下/それに沿って)

27
rickster