获取放置的 SCNNode 的世界 x、y 和 z - Swift

Getting the world x, y, and z of placed SCNNode - Swift

我的objective是在另一个包含SCNPlane的SCNNode中间生成一个SCNNode

SCNPlane 是在这样的渲染器函数中生成的:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

    let width = CGFloat(planeAnchor.extent.x)
    let height = CGFloat(planeAnchor.extent.z)
    let plane = SCNPlane(width: width, height: height)

    plane.materials.first?.diffuse.contents = UIColor.orange

    let planeNode = SCNNode(geometry: plane)

    let x = CGFloat(planeAnchor.center.x)
    let y = CGFloat(planeAnchor.center.y)
    let z = CGFloat(planeAnchor.center.z)
    planeNode.position = SCNVector3(x,y,z)
    planeNode.eulerAngles.x = -.pi / 2

    node.addChildNode(planeNode)
    node.name = "plane"

    loadSphere(x:x, y:y, z:z)

我正试图将球体放在平面的中间:

func loadSphere (x:CGFloat, y:CGFloat, z:CGFloat) {
    let idleScene = SCNScene(named: "art.scnassets/bounceFixed.dae")!

    // This node will be parent of all the animation models
    let node = SCNNode()

    for child in idleScene.rootNode.childNodes {
        node.addChildNode(child)
    }

    // Set up some properties
    node.name = "Sphere"

    node.position = SCNVector3(x, y, z)
    node.scale = SCNVector3(0.001, 0.001, 0.001)
    ...

但问题是,每当我 运行 时,x、y、z 最终都为零。我试过 sceneView.scene.rootNode.childNodes[3].worldPositionnode.worldPosition 之类的东西,但最终总是在相机的视野中而不是在平面的中间生成球体。

我在这里附上了一张图片,向您展示我所说的 "middle" 的意思。

请告诉我如何解决这个问题。

编辑:我的目标 post 是尝试获取平面节点的 x、y、z(中心)而不附加球体作为子节点。

最佳。

在没有真正看到您的模型或您添加 Sphere 的确切方式的情况下,我会冒险猜测,要么您没有将模型添加到正确的 SCNNode,要么 [=16] =] 你的模型没有居中。

如果你想在你的 SCNNode 中央放置一些东西,你可以将它的位置设置在 SCNVector3Zero 或者完全忽略它,例如

/// Loads An SCNSphere On A Generated SCNNode
///
/// - Parameter plane: SCNNode
func loadSphereOnPlane(_ plane: SCNNode) {

    let sphereNode = SCNNode()
    let sphereNodeGeometry = SCNSphere(radius: 0.01)
    sphereNodeGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
    sphereNode.geometry = sphereNodeGeometry
    plane.addChildNode(sphereNode)

}

您可以在 rendererDidAddNode 委托回调结束时调用它,例如:

loadSphereOnPlane(planeNode)

如果您的模型的枢轴没有居中,您可以使用类似这样的东西来改变它:

/// Changes The Pivot To The Center Of The Model
///
/// - Parameter model: SCNNode
func createCentralPivotFor(_ model: SCNNode){

    let (min, max) = model.boundingBox

    let dx = min.x + 0.5 * (max.x - min.x)
    let dy = min.y + 0.5 * (max.y - min.y)
    let dz = min.z + 0.5 * (max.z - min.z)
    model.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)

}

一个示例用法可能是这样的:

/// Loads Our Little Scatterbug
func loadScatterBugOnPlane(_ node: SCNNode) {

    let modelPath = "ARModels.scnassets/Scatterbug.scn"

    //1. Get The Reference To Our SCNScene & Get The Model Root Node
    guard let model = SCNScene(named: modelPath),
        let pokemonModel = model.rootNode.childNode(withName: "RootNode", recursively: false) else { return }

    let scatterBug = pokemonModel

    //2. Scale The Scatterbug
    scatterBug.scale = SCNVector3(0.002, 0.002, 0.002)

    //3. Set The Pivot
    createCentralPivotFor(scatterBug)

    //4. Add It To The Plane
    node.addChildNode(scatterBug)

}

您也可以在 rendererDidAddNode 委托回调结束时调用,例如:

两种方法的结果如下:

更新:

既然你现在已经改变了你的问题,你可以尝试这样的事情:

/// Loads An SCNSphere At The Position Of An ARAnchor
///
/// - Parameter plane: SCNNode
func loadSphereAtAnchorPosition(_ anchor: ARPlaneAnchor) {

    let sphereNode = SCNNode()
    let sphereNodeGeometry = SCNSphere(radius: 0.01)
    sphereNodeGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
    sphereNode.geometry = sphereNodeGeometry

    sphereNode.position = SCNVector3(anchor.transform.columns.3.x,
                                     anchor.transform.columns.3.y,
                                     anchor.transform.columns.3.z)

    augmentedRealityView?.scene.rootNode.addChildNode(sphereNode)

}

希望对您有所帮助...