[SOLVED] How do I specify a child node location relative to ARImageAnchor?

Issue

I have a RealityKit app that is doing some basic AR image tracking. It detects a rectangular-shaped image, and I am looking to place some spherical dots at each corner of the image. I know I can create the spheres themselves using a ModelEntity, but I haven’t been able to figure out how to specify the position of these relative to the established ARImageAnchor from the reference image.

I think I just need a counterpart to SceneKit’s addChildNode(SCNNode) function, which uses SCNVector3Make() to specify a position. I just haven’t been able to find a way to establish a relative position and assign a child node to the ARImageAnchor outside of these SceneKit functions. Is there something built into RealityKit that would accomplish this, or is there a way to use SceneKit to place the corner dots while still using my current setup with RealityKit for the AR reference image tracking?

Solution

Try the following approach:

import ARKit
import RealityKit
 
class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    var anchorEntity = AnchorEntity()
    let model_01 = ModelEntity(mesh: .generateSphere(radius: 0.03))
    let model_02 = ModelEntity(mesh: .generateSphere(radius: 0.03))
    let model_03 = ModelEntity(mesh: .generateSphere(radius: 0.03))
    let model_04 = ModelEntity(mesh: .generateSphere(radius: 0.03))
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)            
        arView.session.delegate = self
        
        guard let reference = ARReferenceImage.referenceImages(
                                                inGroupNamed: "AR Resources",
                                                      bundle: nil)
        else { return }
        
        let config = ARImageTrackingConfiguration()
        config.trackingImages = reference
        arView.session.run(config)
        
        self.anchorEntity.addChild(model_01)
        self.anchorEntity.addChild(model_02)
        self.anchorEntity.addChild(model_03)
        self.anchorEntity.addChild(model_04)    
        arView.scene.anchors.append(self.anchorEntity)
    }
}

Then implement session(_:didUpdate:) method:

extension ViewController: ARSessionDelegate {
    
    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
        
        guard let imageAnchor = anchors.first as? ARImageAnchor
        else { return }
        
        let width = Float(imageAnchor.referenceImage.physicalSize.width)
        let height = Float(imageAnchor.referenceImage.physicalSize.height)
        let x = imageAnchor.transform.columns.3.x
        let y = imageAnchor.transform.columns.3.y
        let z = imageAnchor.transform.columns.3.z
        
        let lowerLeft = SIMD3<Float>(x - width/2, y - height/2, z)
        let lowerRight = SIMD3<Float>(x + width/2, y - height/2, z)
        let upperRight = SIMD3<Float>(x + width/2, y + height/2, z)
        let upperLeft = SIMD3<Float>(x - width/2, y + height/2, z)
        
        self.model_01.position = lowerLeft
        self.model_02.position = lowerRight
        self.model_03.position = upperRight
        self.model_04.position = upperLeft
        
        self.anchorEntity = AnchorEntity(anchor: imageAnchor)
    }
}

enter image description here

Answered By – Andy Jazz

Answer Checked By – Marie Seifert (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *