【问题标题】:RealityKit – Keep object always in front of screenRealityKit – 将对象始终保持在屏幕前
【发布时间】:2021-09-08 16:09:00
【问题描述】:

我正在使用以下代码将对象保持在屏幕前并使用相机移动它。在 didUpdate frame: ARFrame 委托上,我调用 getCameraPosition()。 一切都很完美, 现在我需要一个有效的解决方案来缩短处理时间。在当前的解决方案中,我觉得有时电话会挂起。如果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()
            }
        }           
    }

【问题讨论】:

  • "在 didUpdateFrame 委托上我调用 getCameraPosition()" Que!?在哪里?
  • 我没有得到你。每次调用 didUpdate 框架委托时,我都会获得新的职位。你可以看到有问题的代码。
  • 如果您存储self.center 值,您可能不需要切换到主线程。除此之外,按照@andy-fedoroff 的建议使用 ARRaycastQuery 是可行的方法
  • 正确的@maxxfrazer
  • @maxxfrazer,感谢您在 Medium 上的故事。他们太棒了))

标签: swift augmented-reality arkit realitykit


【解决方案1】:

这种情况下最好的解决方案是使用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>)?

【讨论】:

  • 我已经试过了。我想随着手机的移动移动物体的距离。如果您看到问题中给出的链接,则当我上下倾斜手机时,对象会走得更远更近。
  • Stackoverflow 没有给我这个更新答案的通知。
  • 我需要在每一帧上都这样做吗?
  • 感谢您的链接,它有宝藏。正如我所看到的,他们还更新了每一帧的正方形。直接光线投射和使用查询:查询会提高性能吗?
  • 谢谢先生!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 2011-02-07
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多