RealityKit – 始终将对象保持在屏幕前 [英] RealityKit – Keep object always in front of screen

查看:39
本文介绍了RealityKit – 始终将对象保持在屏幕前的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用下面的代码将对象保持在屏幕前并用相机移动它.在 didUpdate frame: ARFrame 委托上,我调用 getCameraPosition().一切都很完美,现在我需要一个有效的解决方案来缩短处理时间.在目前的解决方案中,我感觉电话有时会挂掉.如果 existingPlaneInfinite &估计飞机不可用?这是我所做工作的链接视频.

I am using the below code to keep the object in front of a screen and to move it with the camera. On didUpdate frame: ARFrame delegate I call getCameraPosition(). All is working perfect, Now I need an efficient solution to improve processing time. In the current solution, I feel that the phone hangs sometimes. And what if existingPlaneInfinite & estimatedPlane are not available? Here is the video link of what I have done.

  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方法:

The best solution in this case is to use trackedRaycast method:

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:)实例方法:

Also, you have to implement ray(through:) instance method:

@MainActor func ray(through screenPoint: CGPoint) -> (origin: SIMD3<Float>, 
                                                   direction: SIMD3<Float>)?

这篇关于RealityKit – 始终将对象保持在屏幕前的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆