即使将 planeDetection 设置为空,ARKit planeDetection 仍会继续
ARKit planeDectection continues even after setting planeDetection as empty
在我的应用程序中,我使用 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))
...
}
非常感谢指点。
注:
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 中是否足够接近。
在我的应用程序中,我使用 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))
...
}
非常感谢指点。
注:
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 中是否足够接近。