Как получить положение камеры SCNVector3 относительно ее направления ARKit Swift

Я пытаюсь прикрепить объект перед камерой, но проблема в том, что он всегда связан с начальным направлением камеры. Как я могу настроить / получить 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 ответ

Решение

Отредактировано, чтобы лучше ответить на вопрос теперь, когда это разъяснено в комментарии

Новый ответ:

Вы используете только положение камеры, поэтому, если камера поворачивается, это не влияет на шар.

То, что вы можете сделать, это получить матрицу преобразования шара и умножить ее на матрицу преобразования камеры, чтобы положение шара было относительно полного преобразования камеры, включая вращение.

например

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 единицы.

Другие вопросы по тегам