【问题标题】:Resetting ARKit coordinates重置 ARKit 坐标
【发布时间】:2019-04-10 02:34:12
【问题描述】:

我有一个简单的问题。如果我想开始游戏并将棋盘放在我面前:

gameBoard!.position = SCNVector3(0, 0, -0.6)

这在我离开游戏并再次回来之前有效。我可以在相机前或0.6m 在我面前的完全相同的位置显示游戏板吗?我可能已经搬到另一个位置了。

【问题讨论】:

  • 您需要将游戏板放置在距离相机所见位置 0.6m 处。要么重置摄像头,要么根据摄像头的位置计算板子的位置。
  • @AllenHumphreys 发生这种情况时,我的应用程序会冻结。你看过这方面的任何文档吗?
  • 我的评论基于使用 SceneKit,但我的假设是 ARKit 有一个与 SceneKit 非常相似的相机概念。
  • @AllenHumphreys 你能给我一个如何重置相机或位置的示例代码吗?

标签: swift scenekit augmented-reality arkit


【解决方案1】:

如果您想重置您的 ARSession,您必须暂停、移除所有节点并通过重置跟踪和移除锚点重新运行会话。

我做了一个重置​​按钮,每当我想重置时都会这样做:

@IBAction func reset(_ sender: Any) {

    sceneView.session.pause()
    sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in
        node.removeFromParentNode()
    }
    sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}

或者把它放在你的会话被中断的功能中!

【讨论】:

  • 这似乎工作正常。我把重置放在 UIApplicationWillEnterForeground 通知中,所以每次用户回来时它都会重置游戏板位置。
【解决方案2】:

当您再次在 ARSession 上调用 run 时,使用选项 resetTracking 应该可以实现这一点。

例子:

if let configuration = sceneView.session.configuration {
    sceneView.session.run(configuration,
                          options: .resetTracking)
}

【讨论】:

    【解决方案3】:

    在 ARKit 框架中重置 ARSession 非常简单:

    class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {
    
        @IBOutlet var arView: ARSCNView!
        @IBOutlet weak var sessionInfoLabel: UILabel!
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            let configuration = ARWorldTrackingConfiguration()
            configuration.planeDetection = [.horizontal, .vertical]
            arView.session.run(configuration)
            arView.session.delegate = self
        }
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            arView.session.pause()
        }
        func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
            guard let planeAnchor = anchor as? ARPlaneAnchor else { 
                return 
            }
            let plane = Plane(anchor: planeAnchor, in: arView)
            node.addChildNode(plane)
        }
        func sessionInterruptionEnded(_ session: ARSession) {
            resetSessionTracking()
            sessionInfoLabel.text = "ARSession's interruption has ended" 
        }
        private func resetSessionTracking() {
            let config = ARWorldTrackingConfiguration()
            config.planeDetection = [.vertical, .horizontal]
            arView.scene.rootNode.enumerateChildNodes { (childNode, _) in
                childNode.removeFromParentNode()
            }
            arView.session.run(config, options: [.removeExistingAnchors, 
                                                 .resetTracking, ])
        }
    }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      “这在我离开游戏并再次回来之前有效。”

      您无法在后台跟踪摄像头位置。每当您的应用进入后台并且相机关闭时,您就会失去位置,并且会调用 sessionWasInterrupted(_:)

      会话在无法接收到摄像头或动作时被中断 传感数据。每当相机捕获时,会话中断就会发生 不可用——例如,当您的应用程序在后台或在后台时 是多个前台应用程序——或者当设备太忙而无法处理时 运动传感器数据。

      【讨论】:

      • 如何重置相机?
      • @slimboy 你什么意思?应用从后台返回后,相机会自动重置。
      猜你喜欢
      • 1970-01-01
      • 2017-11-27
      • 2017-12-29
      • 2020-02-09
      • 2018-03-09
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多