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

问题描述 投票:0回答:2

我正在向我的

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
  }
}
swift augmented-reality arkit realitykit
2个回答
4
投票

您需要对 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]

0
投票

这对我在 iOS 上有效:

    let translate = arView.cameraTransform.translation
    let transform: SIMD3<Float> = [translate.x, translate.y, translate.z]
    let distance = simd_distance(entity.position(relativeTo: nil), transform)
© www.soinside.com 2019 - 2024. All rights reserved.