当应用首先启动应用时,在一个墙壁上检测到垂直表面而不是相机聚焦到第二个墙壁,在第二个墙壁中检测到另一个表面。第一道墙现在对ARCamera来说不再可见了,但是这段代码为我提供了第一道墙的锚。但是我需要第二道墙的锚点,现在是可见/聚焦在相机中。
varbinary
答案 0 :(得分:4)
答案的线索在if let
声明的开头。
让我们打破这个:
当你说let anchor = sceneView.session.currentFrame?.anchors.first
时,你引用了一个ARAnchor
的可选数组,它自然可以包含多个元素。
由于您始终致电first
,例如index [0],您将始终获得添加到数组中的第一个ARAnchor
。
由于你现在有2个锚点,你自然需要最后一个(最新)元素。因此,你可以尝试这个作为首发:
if let anchor = sceneView.session.currentFrame?.anchors.last {
let node = sceneView.node(for: anchor)
addNode(position: SCNVector3Zero, anchorNode: node)
} else {
debugPrint("anchor node is nil")
}
<强>更新强> 由于另一张海报以不同的方式解释了这个问题,因为他们认为问题是如何检测是否有ARPlaneAnchor?让我们采用另一种方式。
首先,我们需要考虑到ARCamera有一个Frostrum,其中显示了我们的内容:
因此,我们需要确定ARPlaneAnchor是否为inViewOfFrostrum
。
首先,我们将创建2个变量:
var planesDetected = [ARPlaneAnchor: SCNNode]()
var planeID: Int = 0
第一个存储ARPlaneAnchor
及其关联的SCNNode
和第二个,以便为每个平面提供唯一的ID。
在ARSCNViewDelegate
我们可以看到一个ARPlaneAnchor,然后存储它的信息,例如:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. Get The Current ARPlaneAnchor
guard let anchor = anchor as? ARPlaneAnchor else { return }
//2. Create An SCNode & Geometry To Visualize The Plane
let planeNode = SCNNode()
let planeGeometry = SCNPlane(width: CGFloat(anchor.extent.x), height: CGFloat(anchor.extent.z))
planeGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
planeNode.geometry = planeGeometry
//3. Set The Position Based On The Anchors Extent & Rotate It
planeNode.position = SCNVector3(anchor.center.x, anchor.center.y, anchor.center.z)
planeNode.eulerAngles.x = -.pi / 2
//4. Add The PlaneNode To The Node & Give It A Unique ID
node.addChildNode(planeNode)
planeNode.name = String(planeID)
//5. Store The Anchor & Node
planesDetected[anchor] = planeNode
//6. Increment The Plane ID
planeID += 1
}
现在我们已经存储了检测到的平面,然后我们当然需要确定是否有任何这些是针对ARCamera的,例如:
/// Detects If An Object Is In View Of The Camera Frostrum
func detectPlaneInFrostrumOfCamera(){
//1. Get The Current Point Of View
if let currentPointOfView = augmentedRealityView.pointOfView{
//2. Loop Through All The Detected Planes
for anchorKey in planesDetected{
let anchor = anchorKey.value
if augmentedRealityView.isNode(anchor, insideFrustumOf: currentPointOfView){
print("ARPlaneAnchor With ID \(anchor.name!) Is In View")
}else{
print("ARPlaneAnchor With ID \(anchor.name!) Is Not In View")
}
}
}
}
最后,我们需要访问此功能,我们可以在以下delegate
方法中执行此操作,例如renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)
:
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
detectPlaneInFrostrumOfCamera()
}
希望这些都能指向正确的方向......
答案 1 :(得分:0)
为了使当前的节点处于观察点,您可以执行以下操作:
var targettedAnchorNode: SCNNode?
if let anchors = sceneView.session.currentFrame?.anchors {
for anchor in anchors {
if let anchorNode = sceneView.node(for: anchor), let pointOfView = sceneView.pointOfView, sceneView.isNode(anchorNode, insideFrustumOf: pointOfView) {
targettedAnchorNode = anchorNode
break
}
}
if let targettedAnchorNode = targettedAnchorNode {
addNode(position: SCNVector3Zero, anchorNode: targettedAnchorNode)
} else {
debugPrint("Targetted node not found")
}
} else {
debugPrint("Anchors not found")
}
如果您想获得所有聚焦节点,请将它们收集到满足指定条件的数组中
祝你好运!