获取实体锚点和相机之间的距离

Get distance between the entity anchor and the camera

我正在向我的 ARView 添加一个包含一个实体的场景。我想知道如何才能获得实体的锚点和相机之间的距离。我知道如何获取相机的当前位置,但我为 arScene 获取的位置一定是错误的,因为减去两个位置不会产生正确的位置。下面是一些代码。

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
  }
}

您需要对 RealityKit 场景中的所有几何体执行 Convex Raycast 两个端点之间的射线:

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
    }    
}

此外,正如@maxxfrazer 所建议的,您可以更轻松地访问相机变换:

let translate = arView.cameraTransform.translation

let x = translate.x
let y = translate.y
let z = translate.z

let transform: SIMD3<Float> = [x, y, z]