Get All ARAnchors of focused Camera in ARKIT

后端 未结 2 1020
情深已故
情深已故 2021-02-11 05:22

When application launched first a vertical surface is detected on one wall than camera focus to the second wall, in the second wall another surface is detected. T

2条回答
  •  南方客
    南方客 (楼主)
    2021-02-11 05:48

    The clue to the answer is in the beginning line of your if let statement.

    Lets break this down:

    When you say let anchor = sceneView.session.currentFrame?.anchors.first, you are referencing an optional array of ARAnchor, which naturally can have more than one element.

    Since your are always calling first e.g. index [0], you will always get the 1st ARAnchor which was added to the array.

    Since you now have 2 anchors, you would naturally need the last (latest) element. As such you can try this as a starter:

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

    Update: Since another poster has interpreted the question differently, in that they believe the question is how can I detect if an ARPlaneAnchor is in view? Let's approach it another way.

    First we need to take into consideration that the ARCamera has a Frostrum in which our content is shown:

    As such, we would then need to determine whether an ARPlaneAnchor was inViewOfFrostrum.

    First we will create 2 variables:

    var planesDetected = [ARPlaneAnchor: SCNNode]()
    var planeID: Int = 0
    

    The 1st to store the ARPlaneAnchor and its associated SCNNode, and the 2nd in order to provide a unique ID for each plane.

    In the ARSCNViewDelegate we can visualise an ARPlaneAnchor and then store it's information e.g:

    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
    
    }
    

    Now we have stored the detected planes, we then of course need to determine if any of these are in view of the ARCamera e.g:

    /// 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")
                }
    
            }
    
        }
    }
    

    Finally we then need to access this function which we could do in the following delegate method for example renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval):

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    
            detectPlaneInFrostrumOfCamera()
    }
    

    Hopefully both of these will point in the right direction...

提交回复
热议问题