如何获取相机相对于其方向的SCNVector3位置ARKit Swift

时间:2019-01-12 17:30:31

标签: swift scenekit arkit scnvector3

我正在尝试在相机前面附加一个对象,但问题是它始终与相机的初始方向有关。即使相机的方向是向上还是向下,如何调整/获取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 个答案:

答案 0 :(得分:2)

已在评论中得到澄清,经过编辑可以更好地回答问题

新答案:

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

您可以做的是获取球的变换矩阵,然后将其乘以摄影机的变换矩阵,这样球的位置将相对于摄影机的完整变换,包括旋转。

例如

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个单位。