ARKit之路-ARCoaching

版权声明:Davidwang原创文章,严禁用于任何商业途径,授权后方可转载。

  通过前面的学习我们知道,ARKit建立环境理解需要一定时间,这个时间长短取决于用户设备摄像头采集的图像质量(可信的特征点数量)和空间计算结果,在这个过程中,使用者可能并不知道ARKit正在进行这个工作,特别是对没有AR应用使用经验的人而言,会让他们感到困惑和迷茫。因此,为消除使用者的焦虑,同时更快的建立环境跟踪,应该给予使用者视觉或者文字引导,指导他们进行下一步操作。

  ARKit提供了一个名为ARCoachingOverlayView的视图用于引导使用者进行操作,该视图共包括4种类型:指导使用者移动设备、指导使用者继续移动设备、指导使用者放慢设备移动速度、指导使用者如何重定位。在ARSession初始化时或者跟踪受限时,会显示如下图所示视图,引导用户移动设备检测水平平面或者垂直平面。
在这里插入图片描述

  如果ARKit收集的环境信息还不足以检测平面,会显示如下图左图所示视图,引导用户通过继续移动设备以便ARKit收集更多环境信息,如果在这个过程中,用户移动设备速度过快,会造成采集的图像质量下降,这时会显示如下图右图所示视图,引导用户降低设备移动速度。

  当ARKit收集到足够信息时,引导视图会自动消失,AR进入到正常跟踪状态。
在这里插入图片描述

  重定位(relocalization)也是容易让使用者困惑的操作,不按照ARKit设定的方式进行特定环境扫描,重定位可能永远都无法成功。因此,引导使用者回到原工作环境中进行环境扫描非常重要,在进行重定位时,会显示如下图所示视图,引导使用者返回到ARSession中断前的环境中以便更好的进行重定位工作。

在这里插入图片描述

  ARCoachingOverlayView提供一个标准的引导程序,在ARSession初始化或者跟踪受限时引导使用者进行下一步操作。在使用ARCoachingOverlayView时需要提供一个目标(goal),即在什么情况下引导结束,这个目标可以是检测到水平平面、垂直平面或者是跟踪建立。在ARKit中,这个目标由ARCoachingOverlayView.Goal枚举定义,该枚举各枚举项如下表所示。

枚举项描述
anyPlane任何平面,即包括垂直平面和水平平面
horizontalPlane水平平面
tracking建立世界跟踪
verticalPlane垂直平面

  ARCoachingOverlayView的基本工作方式是,在达到开发人员指定的目标前,会显示引导视图指导使用者进行下一步操作,在达到指定目标后,则引导视图会自动消失。如果在AR应用运行过程中,由于某些原因导致跟踪受限或者需要重定位,也会显示引导视图。

  在RealityKit中,使用ARCoachingOverlayView的基本步骤如下:
  (1)设置ARCoachingOverlayView.goal为指定的目标;
  (2)设置ARCoachingOverlayView.sesseion为当前使用的ARSession;
  (3)根据需要使用代理方法。一般情况下我们会使用代理方法,因为我们不希望在引导视图未消失前出现UI元素或者虚拟元素,通过使用代理方法,在引导视图完成目标后才会在场景中加载虚拟元素。典型的使用ARCoachingOverlayView的方法如下代码清单所示。

struct ARViewContainer: UIViewRepresentable {
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = .horizontal
        arView.session.run(config, options:[ ])
        arView.addCoaching()
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
    }
}

extension ARView: ARCoachingOverlayViewDelegate{
    func addCoaching() {
        let coachingOverlay = ARCoachingOverlayView()
        coachingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        self.addSubview(coachingOverlay)
        coachingOverlay.goal = .horizontalPlane
        coachingOverlay.session = self.session
        coachingOverlay.delegate = self
    }
    public func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) {
      self.placeBox()
    }
    @objc func placeBox(){
        let boxMesh = MeshResource.generateBox(size: 0.15)
        var boxMaterial = SimpleMaterial(color:.white,isMetallic: false)
        let planeAnchor = AnchorEntity(plane:.horizontal)
        do {
            boxMaterial.baseColor = try .texture(.load(named: "Box_Texture.jpg"))
            boxMaterial.tintColor = UIColor.white.withAlphaComponent(0.9999)
            let boxEntity  = ModelEntity(mesh:boxMesh,materials:[boxMaterial])
            planeAnchor.addChild(boxEntity)
            self.scene.addAnchor(planeAnchor)
        } catch {
            print("找不到文件")
        }
    }
    
}

  上述代码使用ARCoachingOverlayView对使用者的操作进行引导,并使用了代理方法coachingOverlayViewDidDeactivate(),在达到目标后在场景中加载一个立方体。

  使用ARCoachingOverlayView的代理方法,必须要遵循ARCoachingOverlayViewDelegate协议,该协议定义了3个可选(optional)方法,如下表所示。

方法描述
coachingOverlayViewWillActivate(ARCoachingOverlayView)在ARCoachingOverlayView激活时调用
coachingOverlayViewDidDeactivate(ARCoachingOverlayView)在ARCoachingOverlayView完成目标消失时调用
coachingOverlayViewDidRequestSessionReset(ARCoachingOverlayView)在重定位时,当用户点击“Start Over”按钮要求重置ARSession时调用

  ARCoachingOverlayView有一个布尔类型的activatesAutomatically属性(该属性默认为true),用于指示ARCoachingOverlayView是否自动激活(如在跟踪受限时或者需要重定位时),默认情况下是会自动激活,在激活前,我们可以通过coachingOverlayViewWillActivate(_:)代理方法执行一些必要操作,如隐藏UI、暂停AR进程等等。

  在允许重定位时,ARKit会在ARSession中断后尝试重新建立虚实联系,在这种情况下, ARCoachingOverlayView也会激活,并且会出现一个“Start Over”按钮,该按钮允许使用者直接重置ARSession而不是重定位。如果使用者点击“Start Over”按钮,coachingOverlayViewDidRequestSessionReset( ) 代理方法就会执行,因此可以在该方法里执行一些ARSession重置的操作,典型的代码如下代码清单所示。

func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) {    
    // 重置session.
    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = [.horizontal, .vertical]
    session.run(configuration, options: [.resetTracking])
    // 其他操作...  
}

如果我们没有执行该方法,那么ARKit会自动执行ARSession重置,并清除所有ARAnchor。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_DavidWang_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值