如何获得相机的 SCNVector3 位置相对于它的方向 ARKit Swift
How to get the SCNVector3 position of the camera in relation to it's direction ARKit Swift
我正在尝试在相机前面附加一个对象,但问题是它始终与初始相机方向相关。我怎样才能 adjust/get 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)
编辑以更好地回答这个问题,因为它在评论中得到了澄清
新答案:
你只使用了相机的位置,所以如果相机旋转,它不会影响球。
你可以做的是获取球的变换矩阵并将其乘以相机的变换矩阵,这样球的位置将相对于相机的完整变换,包括旋转。
例如
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 使用节点层次结构,因此当一个节点是另一个节点的 "child" 时,它遵循其 "parent" 的位置、旋转和缩放。将一个对象附加到另一个对象(在本例中为相机)的正确方法是使其成为相机的 "child"。
然后,当您设置 "child" 节点的位置、旋转或变换的任何其他方面时,您是在相对于其父节点进行设置。因此,如果您将位置设置为 SCNVector3Make(0.0, 0.0, -0.4)
,它会在其 "parent" 平移之上以 Z 方向平移 -0.4 个单位。
所以要做出你想要的,应该是:
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 个单位。
我正在尝试在相机前面附加一个对象,但问题是它始终与初始相机方向相关。我怎样才能 adjust/get 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)
编辑以更好地回答这个问题,因为它在评论中得到了澄清
新答案:
你只使用了相机的位置,所以如果相机旋转,它不会影响球。
你可以做的是获取球的变换矩阵并将其乘以相机的变换矩阵,这样球的位置将相对于相机的完整变换,包括旋转。
例如
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 使用节点层次结构,因此当一个节点是另一个节点的 "child" 时,它遵循其 "parent" 的位置、旋转和缩放。将一个对象附加到另一个对象(在本例中为相机)的正确方法是使其成为相机的 "child"。
然后,当您设置 "child" 节点的位置、旋转或变换的任何其他方面时,您是在相对于其父节点进行设置。因此,如果您将位置设置为 SCNVector3Make(0.0, 0.0, -0.4)
,它会在其 "parent" 平移之上以 Z 方向平移 -0.4 个单位。
所以要做出你想要的,应该是:
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 个单位。