render didAdd node for anchor function not being called

Hello, I was making an app which detects a plane and puts a plane over it. But it seems as if the function is not being called. Here's the code:



    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        // Checking if the planeAnchor exists
        guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
       
        // Declaring some variables for future use
        let width = CGFloat(planeAnchor.extent.x)
        let height = CGFloat(planeAnchor.extent.z)
        //The plane(geometry) for the node
        let plane = SCNPlane(width: width, height: height)

        // The planeNode for the plane anchor
        let planeNode = SCNNode(geometry: plane)
        //Setting up the plane node
        planeNode.geometry?.firstMaterial?.diffuse.contents = UIColor.init(red: 0, green: 0, blue: 1, alpha: 0.4)
        planeNode.geometry?.firstMaterial?.isDoubleSided = true

        // Some variables for future use
        let x = CGFloat(planeAnchor.center.x)
        let y = CGFloat(planeAnchor.center.y)
        let z = CGFloat(planeAnchor.center.z)
        // The plane node's position
        planeNode.position = SCNVector3(x,y,z)
        // This is done so that the plane node is horizontal
        planeNode.eulerAngles.x = -.pi / 2

        // Adding the planeNode to the rootNode??
        node.addChildNode(planeNode)
       
        // Informing the user that a plane anchor has been found
        mainLabel.text = "Found a plane anchor!"
       
    }


viewDidLoad function


    override public func viewDidLoad() {
        sceneView.session.run(configuration)
        sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
        view.addSubview(sceneView)
        sceneView.delegate = self
        configuration.planeDetection = .horizontal
     
    }


What's wrong? The mainLabel's text never changes...


By the way, the viewDidLoad function is public because my class is a public class.

Accepted Reply

Hello,


You called sceneView.session.run(configuration) before you enabled plane detection. You need to fully configure your ARConfiguration before you run it.


So, changing your viewDidLoad to this would probably fix your issue:


    override public func viewDidLoad() { 
        configuration.planeDetection = .horizontal
        sceneView.session.run(configuration) 
        sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin] 
        view.addSubview(sceneView) 
        sceneView.delegate = self 
 }

Replies

Hello,


You called sceneView.session.run(configuration) before you enabled plane detection. You need to fully configure your ARConfiguration before you run it.


So, changing your viewDidLoad to this would probably fix your issue:


    override public func viewDidLoad() { 
        configuration.planeDetection = .horizontal
        sceneView.session.run(configuration) 
        sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin] 
        view.addSubview(sceneView) 
        sceneView.delegate = self 
 }

Additionally, if you wish to make changes to the configuration while it is running, you can do so. Simply call sceneView.session.run(configuration) again after you have made the changes to your configuration, so this would also work:


override public func viewDidLoad() {
        sceneView.session.run(configuration)
        sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
        view.addSubview(sceneView)
        sceneView.delegate = self
        configuration.planeDetection = .horizontal
        sceneView.session.run(configuration)
    }

Thanks for helping me. But it still doesn't work..

My best guess is that, after you run your plane detection configuration in viewDidLoad, you are calling sceneView.session.run somewhere else with a basic ARWorldTrackingConfiguration() (maybe in viewWillAppear?)


If you remain stuck on this issue you should request technical support!

And by the way, I am doing all this in a swift playground book. This code is in the sources folder and this view controller has been called on in LiveView.swift. Does this matter?

I also get this warning at the function beginning:



Instance method 'renderer(_:didAdd:for:)' nearly matches optional requirement 'renderer(_:didAdd:for:)' of protocol 'ARSCNViewDelegate'
Make 'renderer(_:didAdd:for:)' non-public to silence this warning.

Hi, thank you for helping me. I resolved this issue. Actually, the warning gave me a clue as working solutions (from other sources) did not have the warning. The warning insisted me to turn the function private and it said it nearly matched the requirements of the required function so I decided to remove the function all together and tried to use another function and this time, I typed the renderer(_: ,nodeFor:) -> SCNNode? function. This resolved the issue. It was probably an error of mine. Also the solution that you have to fully configure the ARConfiguration really helped me else I would be stuck again. Once again, thank you for helping.

Also, Can you please help me with this question: https://forums.developer.apple.com/thread/114260 . I would be grateful to you if you did.