#swift #xcode #touch #coordinates #augmented-reality
Вопрос:
Я создаю код для отображения символов AR на обложке книги, которую я снял. Иногда персонаж появляется не в нужном месте, поэтому я хочу, чтобы он появлялся там, где его коснулись на экране.
Проблема: Символы появляются сразу после запуска приложения, но исчезают, когда я прикасаюсь к экрану.
Что я попробовал: я поместил обнаруженную позицию касания в глобальную переменную и использовал ее в качестве координат AR. Отслеживание было остановлено, и якорь воспроизводился повторно при каждом касании экрана.
Код приведен ниже.
import UIKit
import SceneKit
import ARKit
class ARViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet weak var sceneView: ARSCNView!
// global variables of AR position
var arCoordX:CGFloat = 0
var arCoordY:CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
sceneView.showsStatistics = true
// touch recognizer
let tap = UITapGestureRecognizer(target: self, action: #selector(touchedScreen(touch:)))
view.addGestureRecognizer(tap)
}
// get touch coordinate and use it as a position of textNode.
@objc func touchedScreen(touch: UITapGestureRecognizer) {
let touchPoint = touch.location(in: self.view)
print(touchPoint)
let configuration = ARImageTrackingConfiguration()
if let imageToTrack = ARReferenceImage.referenceImages(inGroupNamed: "ARResources", bundle: Bundle.main){
configuration.trackingImages = imageToTrack
DispatchQueue.main.async {
self.arCoordX = touchPoint.x
self.arCoordY = touchPoint.y
}
configuration.maximumNumberOfTrackedImages = 1
}
// Touch the screen to reset the image.
sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARImageTrackingConfiguration()
configuration.isAutoFocusEnabled = true
if let imageToTrack = ARReferenceImage.referenceImages(inGroupNamed: "ARResources", bundle: Bundle.main){
configuration.trackingImages = imageToTrack
configuration.maximumNumberOfTrackedImages = 1
}
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause()
}
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
// define imageAnchor
if let imageAnchor = anchor as? ARImageAnchor {
let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
plane.firstMaterial?.diffuse.contents = UIColor(red: 0, green: 0, blue: 1.0, alpha: 0.5)
let planeNode = SCNNode(geometry: plane)
planeNode.position = SCNVector3()
planeNode.eulerAngles.x = -.pi / 2
node.addChildNode(planeNode)
// define textNode
let textGeometry = SCNText(string: "Swift text book", extrusionDepth: 1.0)
textGeometry.firstMaterial?.diffuse.contents = UIColor.red
textGeometry.font = UIFont(name: "HiraginoSans-W6", size: 20)
let textNode = SCNNode(geometry: textGeometry)
textNode.removeFromParentNode()
textNode.scale = SCNVector3(0.001, 0.001, 0.001)
// want to change text position using global variables.
textNode.position = SCNVector3(arCoordX,arCoordY,0.01 )
planeNode.addChildNode(textNode)
}
return node
}
}