Eric Wang
Eric Wang

Reputation: 164

Where is the .camera AnchorEntity located?

When adding a child to my AnchorEntity(.camera), it appears as if the child is spawning behind my camera (meaning I can only see my child when I turn around). I have also tried to add a mesh to my Anchor directly but unfortunately ARKit / RealityKit does not render the mesh when you are inside of it (which because its centered around the camera, is theoretically always the case. However, it could also be the case that its always located behind the screen [where the user is] and I'm never able to see it).

Also, oddly enough the child entity does not move with the camera AnchorEntity despite setting the translation transform to (0,0,0).

My two questions are:

  1. Is the .camera anchor actually located right where the physical iPad / camera is located or is it located further back (perhaps where the user would normally hold the iPad)?

  2. How do you get a child entity of the AnchorEntity(.camera) to move as the iPad / camera moves in real space?

Upvotes: 5

Views: 2759

Answers (1)

Andy Jazz
Andy Jazz

Reputation: 58113

Answer to the first question

In RealityKit and ARKit frameworks ARCamera node has a pivot point like other entities (nodes) have, and it's located at the point where lens is attached to the camera body (at bayonet level). This pivot can tether AnchorEntity(.camera). In other words, virtual camera and real-world camera have that pivot point approximately at the same place.

So, if you attach RealityKit's AnchorEntity to a camera's pivot, you place it to the coordinates where camera's bayonet is located. And this AnchorEntity(.camera) will be tracked automatically without a need to implement session(_:didUpdate:) method.

However, if attach ARKit's ARAnchor to the camera's pivot, you have to implement session(_:didUpdate:) method to constantly update a position and orientation of that anchor for every ARFrame.

enter image description here

Answer to the second question

If you want to constantly update model's position in RealityKits at 60 fps (when ARCamera moves and rotates) you need to use the following approach:

import ARKit
import RealityKit

class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let box = MeshResource.generateBox(size: 0.25)            
        let material = SimpleMaterial(color: .systemPink, isMetallic: true)
        let boxEntity = ModelEntity(mesh: box, materials: [material])
        
        let cameraAnchor = AnchorEntity(.camera)        // ARCamera anchor
        cameraAnchor.addChild(boxEntity)
        arView.scene.addAnchor(cameraAnchor)
        
        boxEntity.transform.translation = [0, 0,-0.5]   // Box offset 0.5 m
    }
}

Or you can use ARKit's great old .currentFrame instance property in session(_:didUpdate:) delegate method:

extension ViewController: ARSessionDelegate {

    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {

        guard let transform = arView.session.currentFrame?.camera.transform
        else { return }
    
        let arkitAnchor = ARAnchor(transform: transform)
        arView.session.add(anchor: arkitAnchor)            // add to session

        let anchor = AnchorEntity(anchor: arkitAnchor)
        anchor.addChild(boxEntity)
        arView.scene.addAnchor(anchor)                     // add to scene
    }
}

class ViewController: UIViewController {

    @IBOutlet var arView: ARView!
    var boxEntity = ModelEntity(...)

    override func viewDidLoad() {
        super.viewDidLoad()
        arView.session.delegate = self                 // Session's delegate
    }
}

To find out how to save the ARCamera Pose over time, read the following post.

Upvotes: 11

Related Questions