3

I've created an AR app that works pretty well, but I'm not a hug fan of the objects spawning in front of the camera every time. I would prefer to have them spawn in this field, further out for the camera, and facing predetermined directions. For example, I want a car to spawn in the same parking lot space every time, so when I walk out into the lot, I can see the car parked there like I left it, no matter which way I come at it from.

How can I spawn my objects based on their location? I would think it would have to do with replacing the plane detection with latitude and longitude coordinates, but I don't know how to go about this. Any help is greatly appreciated!

import UIKit
import RealityKit
import ARKit

class ViewController: UIViewController {

@IBOutlet var arView: ARView!

override func viewDidLoad() {
    super.viewDidLoad()
 
    arView.session.delegate = self
    
    showModel()
    overlayCoachingView()
    setupARView()
    
    arView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap(recognizer:))))
    
}

func showModel(){
    
    let anchorEntity = AnchorEntity(plane: .horizontal, minimumBounds:[0.2, 0.2])
    
    let entity = try! Entity.loadModel(named: "COW_ANIMATIONS")
    entity.setParent(anchorEntity)
    
    arView.scene.addAnchor(anchorEntity)
    
}
func overlayCoachingView () {
    
    let coachingView = ARCoachingOverlayView(frame: CGRect(x: 0, y: 0, width: arView.frame.width, height: arView.frame.height))
    
    coachingView.session = arView.session
    coachingView.activatesAutomatically = true
    coachingView.goal = .horizontalPlane
    
    view.addSubview(coachingView)
    
}
    
    // Load the "Box" scene from the "Experience" Reality File
   // let boxAnchor = try! Experience.loadBox()
    
    // Add the box anchor to the scene
    //arView.scene.anchors.append(boxAnchor)

func setupARView(){
    arView.automaticallyConfigureSession = false
    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = [.horizontal, .vertical]
    configuration.environmentTexturing = .automatic
    arView.session.run(configuration)
}

//object placement

@objc
func handleTap(recognizer: UITapGestureRecognizer){
    let location = recognizer.location(in:arView)
    
    let results = arView.raycast(from: location, allowing: .estimatedPlane, alignment: .horizontal)
    
    if let firstResult = results.first {
        let anchor = ARAnchor(name: "COW_ANIMATIONS", transform: firstResult.worldTransform)
        arView.session.add(anchor: anchor)
    } else {
        print("Object placement failed - couldn't find surface.")
    }
}

func placeObject(named entityName: String, for anchor: ARAnchor)  {
    let entity = try! ModelEntity.loadModel(named: entityName)
    
    entity.generateCollisionShapes(recursive: true)
    arView.installGestures([.rotation, .translation], for: entity)
    
    
    let anchorEntity = AnchorEntity(anchor: anchor)
    anchorEntity.addChild(entity)
    arView.scene.addAnchor(anchorEntity)
    
    
  }
 }
 extension ViewController: ARSessionDelegate {
  func session( session: ARSession, didAdd anchors: [ARAnchor]) {
  for anchor in anchors {
    if let anchorName = anchor.name, anchorName == "COW_ANIMATIONS" {
        placeObject(named: anchorName, for: anchor)
    }  }
}
}
Tyler Kurtz
  • 137
  • 9

1 Answers1

3

For geo location Apple made ARGeoTrackingConfiguration with corresponding ARGeoAnchors.

let location = CLLocationCoordinate2D(latitude: -18.9137, longitude: 47.5361)
let geoAnchor = ARGeoAnchor(name: "Tana", coordinate: location, altitude: 1250)
arView.session.add(anchor: geoAnchor)
let realityKitAnchor = AnchorEntity(anchor: geoAnchor)
arView.scene.anchors.append(realityKitAnchor)

At the moment it's working in the current cities and areas.

You can also use getGeoLocation(forPoint:completionHandler:) instance method that converts a position in the framework’s local coordinate system to GPS latitude, longitude and altitude.

arView.session.getGeoLocation(forPoint: xyzWorld) { (coord, alt, error) in
    let anchor = ARGeoAnchor(coordinate: coord, altitude: alt)
}
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 2
    Thank you for your response, and I'm sorry for the delayed reply. I've updated my post to include my current code. So, since I'm not in those cities, I'm unable to use the ARGeotrackingConfiguration? – Tyler Kurtz Oct 06 '20 at 02:36
  • Alas, if you're not in those cities you're unable to run `ARGeoTrackingConfig`. Let's wait for a moment Apple adds some new areas. – Andy Jazz Oct 06 '20 at 03:56
  • 1
    Thank you so much for the info! Also, I added you on LinkedIn! – Tyler Kurtz Oct 06 '20 at 14:40