I'm adding a scene to my ARView
that contains one entity. I was wondering how I would be able to get the distance between the entity's anchor and the camera. I know how to get the current position of the camera, but the position I'm getting for the arScene
must be wrong since subtracting both positions doesn't yield the right position. Here is some code below.
import RealityKit
class ViewController: UIViewController, ARSessionDelegate {
let arScene = try! TestProj.loadScene()
@IBOutlet var sceneView: ARView!
override func viewDidLoad() {
...
sceneView.scene.addAnchor(arScene)
...
}
func session(_ session: ARSession, didUpdate frame: ARFrame) {
// Calculate distance here
let cameraPos = frame.camera.transform.columns.3
let entityPos = // Position of entity's anchor
let distance = // Find distance here
}
}
You need to perform a Convex Raycast
against all the geometry in the RealityKit's scene for a ray between two end points:
import UIKit
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
let entity = ModelEntity(mesh: .generateBox(size: 0.4))
entity.name = "Cube"
let anchor = AnchorEntity(world: [0,0,0])
anchor.addChild(entity)
arView.scene.anchors.append(anchor)
// For every entity that could be hit,
// we must generate a collision shape.
entity.generateCollisionShapes(recursive: true)
}
@IBAction func onTap(_ sender: UITapGestureRecognizer) {
let query: CollisionCastQueryType = .nearest
let mask: CollisionGroup = .default
let camera = arView.session.currentFrame?.camera
let x = (camera?.transform.columns.3.x)!
let y = (camera?.transform.columns.3.y)!
let z = (camera?.transform.columns.3.z)!
let transform: SIMD3<Float> = [x, y, z]
let raycasts: [CollisionCastHit] = arView.scene.raycast(
from: transform,
to: [0, 0, 0],
query: query,
mask: mask,
relativeTo: nil)
guard let raycast: CollisionCastHit = raycasts.first
else { return }
print(raycast.distance) // Distance from the ray origin to the hit
print(raycast.entity.name) // The entity that was hit
print(raycast.position) // The position of the hit
}
}
Also, as @maxxfrazer suggested, you can access camera transforms more easily:
let translate = arView.cameraTransform.translation
let x = translate.x
let y = translate.y
let z = translate.z
let transform: SIMD3<Float> = [x, y, z]