首页 文章

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

提问于
浏览
2

在我的应用程序中,我使用 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:在哪里工作或停止工作.(我不会在 renderer(didUpdate:上使用 Bool),因为它需要更新已检测到的飞机。另外,我将使用平截头体逻辑,以便在一处仅检测到一个平面。最后,我将跟踪飞机的更新数量,如果未达到阈值(例如 5),则将从场景中删除所有更新数量不能达到 5 的飞机。这可能会增加用户体验的稳定性,但是我强烈感觉这会增加用户想要的复杂性和约束。

我在想正确的方向吗?迫切需要一些更好的逻辑。

1 回答

  • 2
    1. 更改ARSession的配置后,您需要再次调用run(_:options:)方法,以使其起作用。

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

    • 将飞机投射到 xz-plane 上。由于 ARKit 仅支持水平表面检测,因此这应该相当容易。

    • 使用 2D 碰撞检测方法检查飞机是否碰撞。

    • 如果高于某个平面阈值的部分发生碰撞,请除去其中一个碰撞平面。您可能还需要检查两个平面在 3D 中是否足够靠近彼此。

相关问题