我使用以下代码将对象保持在屏幕前,并用相机移动它。在didUpdate frame: ARFrame
代理上,我调用getCameraPosition((。一切都很完美,现在我需要一个有效的解决方案来缩短处理时间。在目前的解决方案中,我觉得手机有时会挂断。如果存在PlaneInfinite&estimatedPlane不可用?这是我所做的视频链接。
extension ARView {
func getCameraPosition(from: CGPoint? = nil) -> Position {
let from = from ?? self.center
var result: ARRaycastResult?
if let raycast = self.raycast(from: from,
allowing: .existingPlaneInfinite,
alignment: .horizontal).last {
result = raycast
} else if let raycast = self.raycast(from: from,
allowing: .estimatedPlane,
alignment: .horizontal).last {
result = raycast
}
return result?.worldTransform.getPosition() ?? .zero
}
}
func session(_ session: ARSession, didUpdate frame: ARFrame) {
if self.viewModel.isFirstHorizontalPlanDetected {
DispatchQueue.main.async {
self.object.position = self.arView.currentPositionOfCamera()
}
}
}
这种情况下的最佳解决方案是使用trackedRaycast
方法:
let query: ARRaycastQuery = .init(origin: SIMD3<Float>(),
direction: SIMD3<Float>(),
allowing: .estimatedPlane,
alignment: .horizontal)
let repeated = arView.session.trackedRaycast(query) { results in
guard let result: ARRaycastResult = results.first
else { return }
let anchor = AnchorEntity(world: result.worldTransform)
anchor.addChild(model)
arView.scene.anchors.append(anchor)
}
repeated?.stopTracking()
此外,您必须实现ray(through:)
实例方法:
@MainActor func ray(through screenPoint: CGPoint) -> (origin: SIMD3<Float>,
direction: SIMD3<Float>)?