Я немного изменил Пример Apple о распознавании изображений в ARKit 1.5, чтобы каждый раз, когда изображение распознавалось, я отображал некоторую текстовую геометрию перед ним.
К сожалению, я заметил, что когдаПри нажатии кнопки сброса в представлении StatusView геометрия моего текста не удаляется, а только перемещается где-то вокруг нового центра сцены.
Вместо этого, если я нажимаю кнопку возврата (потому что я встроил контроллер основного видав контроллере навигации, чтобы запустить сеанс AR с помощью кнопки, а не автоматически, как в примере), и снова запустить сеанс, затем все исчезает правильно.
Анализируя код, я могу подтвердить, что обакнопка сброса и переход назад и вперед из ViewController запускают ту же функцию, как показано ниже
func resetTracking() {
guard let referenceImages = loadImageReferences() else {
fatalError("Missing expected asset catalog resources.")
}
let configuration = ARWorldTrackingConfiguration()
configuration.detectionImages = referenceImages
configuration.planeDetection = [.horizontal, .vertical]
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
statusViewController.scheduleMessage("Look around to detect images", inSeconds: 7.5, messageType: .contentPlacement)
}
Как я уже говорил, эта функция вызывается либо в ViewDidLoad
методе ViewController
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
sceneView.session.delegate = self
// debug scene to see feature points and world's origin ARSCNDebugOptions.showFeaturePoints,
self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin]
// Hook up status view controller callback(s).
statusViewController.restartExperienceHandler = { [unowned self] in
self.restartExperience()
}
}
func restartExperience() {
guard isRestartAvailable else { return }
isRestartAvailable = false
statusViewController.cancelAllScheduledMessages()
resetTracking()
// Disable restart for a while in order to give the session time to restart.
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
self.isRestartAvailable = true
}
}
, а также после нажатия кнопки сброса в StatusViewController.
@IBAction private func restartExperience(_ sender: UIButton) {
restartExperienceHandler()
}
var restartExperienceHandler: () -> Void = {}
для дальнейшей справки, я могу создать следующий текст
func createBillboardText(text: String, position: SCNNode, width: CGFloat, height: CGFloat){
let newText = splitString(every: 10, string: text)
let textGeometry = SCNText(string: newText, extrusionDepth: 1.0)
textGeometry.firstMaterial!.diffuse.contents = UIColor.red
let textNode = SCNNode(geometry: textGeometry)
// Update object's pivot to its center
// https://stackoverflow.com/questions/44828764/arkit-placing-an-scntext-at-a-particular-point-in-front-of-the-camera
let (min, max) = textGeometry.boundingBox
let dx = min.x + 0.5 * (max.x - min.x)
let dy = min.y + 0.5 * (max.y - min.y)
let dz = min.z + 0.5 * (max.z - min.z)
textNode.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)
textNode.scale = SCNVector3(0.005, 0.005, 0.005)
let plane = SCNPlane(width: width, height: height)
let blueMaterial = SCNMaterial()
blueMaterial.diffuse.contents = UIColor.blue
blueMaterial.transparency = 0
plane.firstMaterial = blueMaterial
let parentNode = SCNNode(geometry: plane) // this node will hold our text node
let yFreeConstraint = SCNBillboardConstraint()
yFreeConstraint.freeAxes = [.Y] // optionally
parentNode.constraints = [yFreeConstraint] // apply the constraint to the parent node
parentNode.addChildNode(textNode)
position.addChildNode(parentNode)
sceneView.autoenablesDefaultLighting = true
}
, вызываемый в методе func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
как self.createBillboardText(text: message, position: node, width: referenceImage.physicalSize.width, height: referenceImage.physicalSize.height )
Я также нашел этот поток но я понятия не имею, как вызвать эту функцию на сцене.