【发布时间】:2018-06-09 14:42:26
【问题描述】:
在我的应用程序中,我使用 ARKit 的委托方法来自动检测表面/平面:
-
renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {}添加飞机。 -
renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {}更新飞机。 -
renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {}删除飞机。
我的配置设置为启用水平面检测:
configuration?.planeDetection = .horizontal
这工作正常,我能够检测并创建正在检测表面的平面节点。
这里有两个问题:
根据 Apple docs,如果我想停止水平平面检测,我应该能够将 planeDetection 设置为
[]。在我试图做的一个按钮中,我将 planeDetection 设置为空,但是在运行应用程序时,仍然在应用程序中检测到平面。意思是,renderer(didAdd: )和renderer(didUpdate: )方法仍然可以运行。为了确保我什至打印了他们的结果,并且即使在禁用 planeDetection 之后它们也可以运行。 我做错了吗?随意停止我的renderer(didAdd: )和renderer(didUpdate: )方法的可靠方法是什么?有时会在同一位置检测到两个平面。有时,这两个平面会合并,但有时它们不会合并。 就最佳实践而言,如何避免这种情况?我尝试检测场景的平截头体中是否已经存在 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))
...
}
非常感谢指针。
注意:
我目前考虑管理这两个问题的方式是 引入将由按钮更改的 Bool - 这将决定 renderer(didAdd: ) 工作或停止工作的地方。 (我不会使用 Bool on renderer(didUpdate: ) 因为它需要更新已经 检测到的飞机。此外,我将使用 frustum 逻辑,以便 在一个地方只检测到一架飞机。最后,我会追踪 我的飞机正在更新的数量,如果没有达到 阈值,比如说 5,我将删除所有那些 更新无法从现场达到 5。这可能会增加一些 用户体验的稳定性,但我强烈认为这将 增加了比用户想要的更多的复杂性和更多的约束 有。
我的想法是否正确?伙计们,这里迫切需要一些更好的逻辑。
【问题讨论】:
-
我认为您需要在更改其配置后再次在会话中调用
run()。 -
天哪!我怎么能忘记这样做 :( 非常感谢,就是这样。我打电话给
run()并且它有效。关于我问题的第二部分的任何想法? -
我不确定这是否是最佳做法,但我前几天就你的第二个问题写了一个答案,你可以看看:stackoverflow.com/questions/47980670/arkit-floating-planes/…
-
看了一下,试试这个逻辑。同时,如果您可以将您的两个 cmets 和 post and answer 结合起来,我会检查一下,因为实际上这两个组合构成了一个很好的答案。再次感谢!