Возвращаемое значение ARRaycastQuery?
изначально необязательно.
Согласно документации Apple :
raycastQuery(from:allowing:alignment:)
метод экземпляра создает луч, который распространяется в положительном направлении. направление z от точки пространства экрана аргумента до определяет, существует ли какая-либо цель аргумента в физической среде где-либо вдоль луча . Если это так, ARKit возвращает трехмерную позицию, где луч пересекает цель.
Если луч не пересекает цель, объекта ARRaycastQuery?
нет. Итак, есть nil
.
func raycastQuery(from point: CGPoint,
allowing target: ARRaycastQuery.Target,
alignment: ARRaycastQuery.TargetAlignment) -> ARRaycastQuery?
Каковы две возможные причины возврата nil
?
- Нет обнаруженной плоскости, куда луч попадает
- Код логики c неверен
Решение:
Вот как может выглядеть ваш код:
@IBOutlet var sceneView: ARSCNView!
@IBAction func onTap(_ sender: UIGestureRecognizer) {
let tapLocation: CGPoint = sender.location(in: sceneView)
let estimatedPlane: ARRaycastQuery.Target = .estimatedPlane
let alignment: ARRaycastQuery.TargetAlignment = .any
let query: ARRaycastQuery? = sceneView.raycastQuery(from: tapLocation,
allowing: estimatedPlane,
alignment: alignment)
if let nonOptQuery: ARRaycastQuery = query {
let result: [ARRaycastResult] = sceneView.session.raycast(nonOptQuery)
guard let rayCast: ARRaycastResult = result.first
else { return }
self.loadGeometry(rayCast)
}
}
А вот метод получения модели :
func loadGeometry(_ result: ARRaycastResult) {
let scene = SCNScene(named: "art.scnassets/myScene.scn")!
let node: SCNNode? = scene.rootNode.childNode(withName: "model",
recursively: true)
node?.position = SCNVector3(result.worldTransform.columns.3.x,
result.worldTransform.columns.3.y,
result.worldTransform.columns.3.z)
self.sceneView.scene.rootNode.addChildNode(node!)
}