如何在 ARKit 中使用 trackedRaycast(_:updateHandler:) 方法?

How to use trackedRaycast(_:updateHandler:) method in ARKit?

Repeats a ray-cast query over time to notify you of updated surfaces in the physical environment.

如何在 ARKit 中使用这个函数?

func trackedRaycast(_ query: ARRaycastQuery, 
              updateHandler: @escaping ([ARRaycastResult]) -> Void) -> ARTrackedRaycast?

首先定义一个类似

的查询
let bounds = sceneView.bounds
let screenCenter = CGPoint(x: bounds.midX, y: bounds.midY)
let query = sceneView.raycastQuery(from: screenCenter, allowing: .estimatedPlane, alignment: .horizontal)

然后使用更新处理程序启动 trackedRaycast:

let trackedRaycast = sceneView.castTrackedRay(for: query, updateHandler: { results in
    guard let result = results.first else { return }
    // Do something with results
    // Maybe adjust a relevent node's position
    someNode.simdWorldPosition = result.worldTransform.position
})

然后,如果在某个时候您不再需要跟踪 it/update 位置,您可以停止 updateHandler 执行:trackedRaycast?.stopTracking()

请注意,如果普通光线投射由于查询约束或场景问题而失败,那么 trackedRaycast 也会失败并且您的 trackedRaycast 对象将是 nil.

Apple Developer 文档对 trackedRaycast() 说了以下内容:

trackedRaycast(_:updateHandler:) instance method repeats a ray-cast query over time to notify you of updated surfaces in the physical environment. A tracked ray cast wraps a ray-cast query that the ARSession calls repeatedly, each time invoking your update handler to provide you with new results. When you're ready to stop a tracked ray cast, call stopTracking().

因此,这是您可以在项目中使用的代码片段:

import RealityKit
import ARKit

@IBOutlet var arView: ARView!
let scene = try! Experience.loadScene()

let raycastQuery: ARRaycastQuery = .init(origin: [0,0,0],
                                      direction: [7,7,7],
                                       allowing: .estimatedPlane,
                                      alignment: .horizontal)

let repeatRaycast = self.arView.session.trackedRaycast(raycastQuery) { results in

    // Update Handler's content
    guard let result: ARRaycastResult = results.first
    else { return }

    let anchor = AnchorEntity(world: result.worldTransform)
    anchor.addChild(self.scene)

    self.arView.scene.anchors.append(anchor)
}

那你就可以停止追踪了:

repeatRaycast?.stopTracking()