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

Swift 如何在ARKit中使用trackedRaycast(uux0:updateHandler:)方法?,swift,scenekit,augmented-reality,arkit,realitykit,Swift,Scenekit,Augmented Reality,Arkit,Realitykit,随着时间的推移重复光线投射查询,以通知您物理环境中已更新的曲面 如何在ARKit中使用此函数 func trackedRaycast(_ query: ARRaycastQuery, updateHandler: @escaping ([ARRaycastResult]) -> Void) -> ARTrackedRaycast? 首先定义一个查询,如下所示 let bounds = sceneView.bounds let screenCenter

随着时间的推移重复光线投射查询,以通知您物理环境中已更新的曲面

如何在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
})
然后,如果在某个时刻您不再需要跟踪它/更新位置,您可以停止
updateHandler
执行:
trackedRaycast?.stopTracking()


请注意,如果正常光线投射由于查询约束或场景问题而失败,则trackedRaycast也将失败,并且您的
trackedRaycast
对象将为
nil

首先使用以下内容定义查询

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
})
然后,如果在某个时刻您不再需要跟踪它/更新位置,您可以停止
updateHandler
执行:
trackedRaycast?.stopTracking()


请注意,如果正常光线投射由于查询约束或场景问题而失败,则trackedRaycast也将失败,并且您的
trackedRaycast
对象将为
nil

Apple开发者文档中说了以下关于
trackedRaycast()
的内容:

trackedRaycast(uuquo;updateHandler:)
实例方法会随着时间的推移重复光线投射查询,以通知您物理环境中已更新的曲面。跟踪的光线投射包装了一个光线投射查询,
ARSession
会反复调用该查询,每次调用更新处理程序都会为您提供新的结果。准备停止跟踪的光线投射时,请调用
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()

苹果开发人员文档介绍了以下关于
trackedRaycast()

trackedRaycast(uuquo;updateHandler:)
实例方法会随着时间的推移重复光线投射查询,以通知您物理环境中已更新的曲面。跟踪的光线投射包装了一个光线投射查询,
ARSession
会反复调用该查询,每次调用更新处理程序都会为您提供新的结果。准备停止跟踪的光线投射时,请调用
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()

我通常不建议使用
.init(原点:,方向:,允许:,对齐:)
初始值设定项,除非1)您非常了解
原点
方向
向量,2)您需要从用户/手机的角度以外的角度进行光线投射。
.init(from:,allowing:,alignment:)
初始值设定项通常是您所需要的。感谢您提供有用的提示@jfriesenahn。我通常不建议使用
.init(origin:,direction:,allowing:,alignment:)
初始值设定项,除非1)您非常了解
origin
direction
向量,2)你需要从用户/手机的角度以外的角度进行光线投射。
.init(from:,allowing:,alignment:)
初始值设定项通常就是您所需要的。感谢您提供有用的提示,@jfriesenahn。