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

标签 swift arkit scnnode arscnview

我的目标是在另一个包含 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 这样的东西,但最终总是在相机而不是在飞机的中间。

我在这里附上了一张图片,向您展示我所说的“中间”是什么意思。

enter image description here

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

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

最好的。

最佳答案

如果没有真正看到您的模型,或者您究竟是如何添加 Sphere 的,我会冒险猜测,要么您没有将模型添加到正确的 SCNNode 中。 ,或者说 pivot你的模型没有居中。

如果你想在你的 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 的末尾调用它委托(delegate)回调例如:

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 委托(delegate)回调结束时调用,例如:

这两种方法的结果都是这样的:

enter image description here

更新:

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

/// 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)

}

希望对你有帮助

关于swift - 获取放置的 SCNNode 的世界 x、y 和 z - Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50340970/

相关文章:

ios - ARKit 图像检测 卡住相机

ios - 如何使用 ARKit 检测平面

swift - 如何在相机 ARKit 顶部添加半透明背景

ios - 更改 SCNText 上的字符串值不会产生任何变化

ios - 网络调用后绑定(bind)到 UIRefreshControl

ios - 为什么double类型的主窗口是可选的?

swift - 在 Swift 中将文本或数据 append 到文本文件

ios - 具有自动调整单元格的 Collection View 不再水平滚动