即使将planeDetection设置为空

时间:2017-12-29 05:29:16

标签: ios swift arkit

在我的应用程序中,我使用ARKit的委托方法进行自动表面/平面检测:

  1. renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {}添加飞机。
  2. renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {} 更新飞机。
  3. renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {}删除飞机。
  4. 我的配置设置为启用水平平面检测:

    configuration?.planeDetection = .horizontal
    

    这很好用,我能够检测并创建检测表面的平面节点。

    这里有两个问题:

    1. 根据Apple docs,如果我想停止水平面检测,我应该可以将planeDetection设置为[]。在我尝试这样做的按钮中,我将planeDetection设置为空,但是在运行应用程序平面时仍然在应用程序中检测到。含义renderer(didAdd: )renderer(didUpdate: )方法仍在运作中。为了确保我甚至打印出他们的结果,即使在禁用planeDetection后它们也可以运行。 我做错了吗?什么是随意停止renderer(didAdd: )renderer(didUpdate: )方法的确定镜头方式?

    2. 在某些情况下,在同一个地方检测到两个平面。有时,这两架飞机合并,但在其他时候它们没有。 就最佳做法而言,如何避免这种情况?我尝试检测我的场景中是否已存在planeNode,不要添加新的平面,但是还有一些问题,特别是当有一个平面被添加时,但后来另一个平面应该被添加到同一个地方而后者是一个委托功能正在更新。在这种情况下,后者甚至没有被添加,因为前者仍然在我的视锥体之内。希望这很清楚。 只是想知道如何避免/避免这种情况最好?

    3. 渲染器方法体是通常的:

      func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
          guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
          let plane = SCNPlane(width: CGFloat(planeAnchor.extent.x),
                               height: CGFloat(planeAnchor.extent.z))
          ...
      }
      

      指针非常感谢。

      注意:

        

      我目前正在考虑管理这两个问题的方法是   介绍一个将通过按钮更改的Bool - 这将决定   其中渲染器(didAdd :)工作或停止工作。 (我不会用的   Bool on renderer(didUpdate :)因为它需要更新已经   检测到飞机。另外,我将使用 frustum 逻辑   在一个地方只检测到一个平面。最后,我会跟踪   我的飞机所具有的更新次数,如果没有达到   阈值,让我们说5,我​​将删除所有那些数量为的飞机   更新无法从现场达到5。这可能会增加一些   用户体验的稳定性,但我强烈认为这会   添加比用户想要的更多复杂性和更多约束   有

      我在思考正确的方向吗?在这里,人们迫切需要一些更好的逻辑。

1 个答案:

答案 0 :(得分:2)

1)您需要在更改ARSession的配置后再次调用run(_:options:)方法才能使其正常工作。

2)我不确定这是否是最佳做法,但您可以通过执行以下操作尝试手动检查飞机是否重叠:

  • 在xz平面上投影您的飞机。由于ARKit仅支持水平表面检测,因此应该相当容易。
  • 使用2D碰撞检测方法检查您的飞机是否发生碰撞。
  • 如果高于某个平面阈值的部分发生碰撞,则移除其中一个碰撞平面。您可能还想检查两个平面是否在3D中足够接近。