RealityKit——让物体始终在屏幕前
RealityKit – Keep object always in front of screen
我正在使用以下代码将对象保持在屏幕前并随相机移动它。在 didUpdate frame: ARFrame
委托上,我调用 getCameraPosition()。
一切都很完美,
现在我需要一个有效的解决方案来缩短处理时间。在当前的解决方案中,我觉得 phone 有时会挂起。如果 existingPlaneInfinite 和 estimatedPlane 不可用怎么办?
这是我所做的视频 link。
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>)?
我正在使用以下代码将对象保持在屏幕前并随相机移动它。在 didUpdate frame: ARFrame
委托上,我调用 getCameraPosition()。
一切都很完美,
现在我需要一个有效的解决方案来缩短处理时间。在当前的解决方案中,我觉得 phone 有时会挂起。如果 existingPlaneInfinite 和 estimatedPlane 不可用怎么办?
这是我所做的视频 link。
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>)?