1

I have set up world origin in the rear camera using ARKit.

arView.debugOptions = [.showFeaturePoints, .showWorldOrigin]

And then I have set up a virtual object to the center position of world origin, that is (x, y, z) = (0, 0, 0).

Now, I want to move the object using user's eye movement(from front-camera) and simultaneously measure the angle of displacement of that object from world origin.

Is it possible with ARKit or RealityKit?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220

1 Answers1

0

Deviation Angle

You can calculate a model's deviation angle (relative to world origin (x:0, y:0, z:0)) by implementing the trigonometric atan2 function. For implementing a facial expression's recognition (to control model's movement) use the following technique.

Here I used DispatchQueue.main.asyncAfter() as a test method to move the model.

To convert radians to degrees I used the Rad * 180 / PI formula.

import RealityKit
import Combine

class ViewController: UIViewController {    
    @IBOutlet var arView: ARView!
    @IBOutlet var label: UILabel!
    var model = ModelEntity()
    var subs: [AnyCancellable] = []

    override func viewDidLoad() {
        super.viewDidLoad()    
        self.model = ModelEntity(mesh: .generateSphere(radius: 0.1))
        self.model.position.z = -10
        let transA = Transform(translation: [ 3, 0,-10])
        let transB = Transform(translation: [ 1, 0,-4 ])
        let transC = Transform(translation: [-1, 0,-2 ])
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.model.move(to: transA, relativeTo: nil, duration: 1)
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                self.model.move(to: transB, relativeTo: nil, duration: 1)
                DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                    self.model.move(to: transC, relativeTo: nil, duration: 1)
                }
            }
        }            
        let anchor = AnchorEntity(world: [0, 0, 0])
        anchor.addChild(self.model)
        arView.scene.anchors.append(anchor)
                
        arView.scene.subscribe(to: SceneEvents.Update.self) { _ in    
            let orb: Float = atan2(self.model.position.x, 
                                   self.model.position.z)   
            self.label.text = "Angle: \(String(format: "%.1f" 
                                              (orb * 180 / -.pi)))"
        }.store(in: &subs)
    }
}

Here's the scene's floor level, i.e. XZ plane.

Angles' range is -180...+180. To normalize a range to 0...360, use a corresponding math.

enter image description here

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220