1

I’m trying to make an entity hover in the same spot in front of the camera regardless of how I move the device and I’m not succeeding. I figure that I want to rotate around y (for lateral movement - yaw) and x (for vertical panning - pitch).

I’m getting the camera rotation from the ARCamera:

 let distance: Float = 2               // distance in front of camera
 let euler = camera.eulerAngles
 let yaw = euler.y + .pi
 let x = sin(yaw) * distance
 let z = cos(yaw) * distance
 let translation = SIMD3<Float>(x, 1, z)

 let transform = Transform(scale: .one, 
                        rotation: simd_quatf(), 
                     translation: translation)

 entity.transform = transform

First of all I’m not clear on why I needed to rotate by .pi keep the entity in front of the camera. Am I correct in thinking that the camera’s transform is initialized to wherever the camera is initially pointing and therefore the entity should be in front of the camera if the camera hasn’t moved?

Secondly, this all fails if I try to perform a similar operation around the x axis instead:

 let pitch = euler.x + .pi
 let y = sin(pitch) * distance
 let z = cos(pitch) * distance
 let translation = SIMD3<Float>(1, y, z)

Clearly I’m confused about what I’m doing here. Can someone straighten me out? Thanks

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Spiff
  • 783
  • 8
  • 9

1 Answers1

0

Using trigonometry for orbiting

Try this code to implement an eternal orbiting:

import UIKit
import RealityKit

class ViewController: UIViewController {        
    @IBOutlet var arView: ARView!
    var timer: Timer? = nil
    var count: CGFloat = 0.0
    var translate: SIMD3<Float>? = nil
    var box = ModelEntity()
    
    override func viewDidLoad() {
        super.viewDidLoad()            
        timer = Timer.scheduledTimer(timeInterval: 0.05,
                                           target: self,
                                         selector: #selector(updateSmoothly),
                                         userInfo: nil,
                                          repeats: true)
        
        self.box = ModelEntity(mesh: .generateBox(size: 0.4))
        let anchor = AnchorEntity(.camera)
        anchor.position.z = -0.5
        anchor.addChild(box)
        self.box.position.z = -1.0
        arView.scene.anchors.append(anchor)
    }        
    @objc func updateSmoothly() {
        self.count += 0.05                     
        let h = Float(sin(count))
        let v = Float(cos(count))
        // orbiting around Z and Y axis simultaneously
        self.translate = [h, v, 0] + [h, 0, v]  
        box.position = self.translate!
    }
}

And here's a cube orbiting around only Z axis.

self.translate = [h, v, 0]

enter image description here

Tip :

You can easily apply Orbiting behavior in Reality Composer.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • Thanks for your reply Andy Jazz. What I'm trying to accomplish is to have an entity sit in front of the screen all times. Think of a switch control, for example. I'm assuming that I need to react to changes in camera transform and move the entity to remain in the same spot in the field of view. – Spiff Jul 25 '22 at 15:43