代码之家  ›  专栏  ›  技术社区  ›  Tal Zion

如何获得相机相对于其方向的SCNvector3位置arkit swift

  •  1
  • Tal Zion  · 技术社区  · 6 年前

    我试图在相机前面附加一个物体,但问题是它总是与相机的初始方向有关。我如何调整/获取 SCNVector3 将物体放在前面的位置,即使相机的方向是向上还是向下?

    我现在就是这样做的:

    let ballShape = SCNSphere(radius: 0.03)
    let ballNode = SCNNode(geometry: ballShape)
    let viewPosition = sceneView.pointOfView!.position
    ballNode.position = SCNVector3Make(viewPosition.x, viewPosition.y, viewPosition.z - 0.4)
    sceneView.scene.rootNode.addChildNode(ballNode)
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   ciclopez    6 年前

    经过编辑,以便在评论中澄清后更好地回答问题。

    新答案:

    您只使用相机的位置,因此如果相机旋转,它不会影响球。

    你所能做的就是得到球的变换矩阵,并将其乘以相机的变换矩阵,这样球的位置将相对于相机的全变换,包括旋转。

    例如

    let ballShape = SCNSphere(radius: 0.03)
    let ballNode = SCNNode(geometry: ballShape)
    ballNode.position = SCNVector3Make(0.0, 0.0, -0.4)
    let ballMatrix = ballNode.transform
    let cameraMatrix = sceneView.pointOfView!.transform
    let newBallMatrix = SCNMatrix4Mult(ballMatrix, cameraMatrix)
    ballNode.transform = newBallMatrix
    sceneView.scene.rootNode.addChildNode(ballNode)
    

    或者,如果您只想让scnvector3的位置准确回答您的问题(这样球就不会旋转):

    ...
    let newBallMatrix = SCNMatrix4Mult(ballMatrix, cameraMatrix)
    let newBallPosition = SCNVector3Make(newBallMatrix.m41, newBallMatrix.m42, newBallMatrix.m43)
    ballNode.position = newBallPosition
    sceneView.scene.rootNode.addChildNode(ballNode)
    

    老回答:

    您只使用相机的位置,因此当相机旋转时,它不会影响球。

    scenekit使用一个节点层次结构,因此当一个节点是另一个节点的“子”节点时,它遵循其“父”节点的位置、旋转和缩放。将一个对象附加到另一个对象(在本例中是相机)的正确方法是使其成为相机的“子对象”。

    然后,当您设置“子”节点转换的位置、旋转或任何其他方面时,您将相对于其父节点进行设置。所以如果你把位置设为 SCNVector3Make(0.0, 0.0, -0.4) ,它的翻译是-0.4单位在Z之上的“父”翻译。

    所以要想得到你想要的,应该是:

    let ballShape = SCNSphere(radius: 0.03)
    let ballNode = SCNNode(geometry: ballShape)
    ballNode.position = SCNVector3Make(0.0, 0.0, -0.4)
    let cameraNode = sceneView.pointOfView
    cameraNode?.addChildNode(ballNode)
    

    这样,当相机旋转时,球会精确地跟随它的旋转,但会与相机分离-0.4个单位。

    推荐文章