即使将 planeDetection 设置为空,ARKit planeDetection 仍会继续

ARKit planeDectection continues even after setting planeDetection as empty

在我的应用程序中,我使用 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) {} 移除平面。

我的配置设置为启用水平面检测:

configuration?.planeDetection = .horizontal

这工作正常,我能够检测并创建正在检测表面的平面节点。

这里有两个问题:

  1. 按照 Apple docs,如果我想停止水平面检测,我应该可以将 planeDetection 设置为 []。在一个按钮中,我试图将 planeDetection 设置为空,但是在 运行 上,应用程序平面仍在应用程序中被检测到。也就是说,renderer(didAdd: )renderer(didUpdate: ) 方法仍然有效。为了确保我什至打印了它们的结果,并且即使在禁用 planeDetection 之后它们也可以运行。 我做错了什么吗?随意停止我的 renderer(didAdd: )renderer(didUpdate: ) 方法的可靠方法是什么?

  2. 有时会在同一位置检测到两个平面。有时,这两个平面会合并,但有时不会。 就最佳实践而言,如何避免这种情况?我尝试检测我的场景的截锥体中是否已经有一个 planeNode,不要添加新平面,但是这也会带来一些影响问题尤其是当添加了一架飞机时,但后来应该在同一个地方添加另一架飞机,而后者是一个委托功能正在更新。在这种情况下,甚至没有添加后者,因为前者仍在我的截锥体内。希望这是清楚的。 只是想知道如何最好地避免/避免这种情况?

渲染器方法的主体是通常的:

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))
    ...
}

非常感谢指点。

注:

The way I am currently thinking of managing both issues is to introduce a Bool which will be changed by a button - this will decide where renderer(didAdd: ) works or stops working. (I will not use the Bool on renderer(didUpdate: ) since it needs to update the already detected planes. Additionally, I will use the frustum logic so that only one plane is detected at one place. Lastly, I will track the number of updates my planes are having, if that doesn't reach a threshold, let's say 5, I will remove all those plane whose number of updates could not reach 5 from the scene. This might add some stability to User Experience, however I strongly feel that this will add both much complexity and more constraints than user would like to have.

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

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

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

  • 将您的飞机投影到 xz 平面上。由于ARKit只支持水平表面检测,所以这应该很容易。
  • 使用二维碰撞检测方法检查您的飞机是否发生碰撞。
  • 如果高于某个阈值的平面发生碰撞,则删除其中一个碰撞平面。您可能还想检查这两个平面在 3D 中是否足够接近。