Когда вы делаете
node.position = SCNVector3Make(0, 0, 0);
self.sceneView.scene.rootNode.addChildNode(node)
, вы позиционируете узел модели в корневом узле сцены, положение которой определяется ARKit при запуске сцены.
Если вы хотите, чтобы модель отображалась перед камерой, вам нужно взять преобразование камеры (session.currentFrame?.camera.transform
), изменить компонент -z
и установить его в качестве позиции узла. Или, если вы хотите разместить вашу модель на поверхности, выполните raycast и используйте raycastResult
simdWorldPosition
в качестве simdWorldPosition
вашего * узла.
Определенно есть примеры raycast
вокруг, но в Короче говоря, сначала нужно определить запрос:
let bounds = sceneView.bounds
let screenCenter = CGPoint(x: bounds.midX, y: bounds.midY)
let query = sceneView.raycastQuery(from: screenCenter, allowing: .estimatedPlane, alignment: .horizontal)
Вышеприведенное описание определяет лучевую трансляцию, простирающуюся от центра экрана и находящую только горизонтальные поверхности. Пожалуйста, изучите документы для получения дополнительной информации о allowing
и alignment
вариантах.
Затем вы можете использовать session
, чтобы разыграть свой луч:
session.raycast(query)
Это вернет массив ARRaycastResult
. Вы можете просмотреть их и выбрать, если вы sh, но я обычно просто беру .first
один (примечание: он может быть пустым).
Затем вы захотите взять компонент перевода вашего raycastResult
преобразовать и назначить его как simdWorldPosition
вашего узла. Обратите внимание, что вы можете назначить все преобразование узлам simdWorldTransform
, но это также изменит ориентацию вашего узла, что вы можете или не хотите делать.
if let raycastResult = session.raycast(query).first {
node.simdWorldPosition = raycastResult.worldTransform.translation
}
О, я также нахожу это маленьким расширение для удобства:
extension float4x4 {
/**
Treats matrix as a (right-hand column-major convention) transform matrix
and factors out the translation component of the transform.
*/
var translation: SIMD3<Float> {
let translation = columns.3
return SIMD3<Float>(translation.x, translation.y, translation.z)
}
}
Это то, что позволяет вам сделать worldTransform.translation
в моем коде выше.