Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scene is modified when rendering callback

I had the following code which produced the error:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

    if anchor is ARImageAnchor {  

        let phoneScene = SCNScene(named: "Phone_01.scn")!
        let phoneNode = phoneScene.rootNode.childNode(withName: "parentNode", recursively: true)!

        // rotate the phone node
        let rotationAction = SCNAction.rotateBy(x: 0, y: 0.5, z: 0, duration: 1)
        let inifiniteAction = SCNAction.repeatForever(rotationAction)
        phoneNode.runAction(inifiniteAction)          
        phoneNode.position = SCNVector3(anchor.transform.columns.3.x,anchor.transform.columns.3.y + 0.1,anchor.transform.columns.3.z)              
        node.addChildNode(phoneNode)
    }                 
}

Scene is modified in a rendering callback of another scene.

So I replaced it with the following:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

    if anchor is ARImageAnchor {

        DispatchQueue.global().async {

            let phoneScene = SCNScene(named: "Phone_01.scn")!
            let phoneNode = phoneScene.rootNode.childNode(withName: "parentNode", recursively: true)!

            DispatchQueue.main.async {

                // rotate the phone node
                let rotationAction = SCNAction.rotateBy(x: 0, y: 0.5, z: 0, duration: 1)
                let inifiniteAction = SCNAction.repeatForever(rotationAction)
                phoneNode.runAction(inifiniteAction)
                phoneNode.position = SCNVector3(anchor.transform.columns.3.x,anchor.transform.columns.3.y + 0.1,anchor.transform.columns.3.z) 
                node.addChildNode(phoneNode)
            }  
        }
    }    
}

And now the error is gone and everything works OK. My question is: is that the correct solution? Should I switch to background thread to load the scene and then to main thread to add the nodes. Are nodes even added on the main thread?

like image 628
john doe Avatar asked Aug 16 '18 22:08

john doe


1 Answers

Try something like this in the method delegate. This was an example of an old proyect.

DispatchQueue.main.async {
        if let imageAnchor = anchor as? ARImageAnchor {

            let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
            plane.firstMaterial?.diffuse.contents = UIColor(white: 1.0, alpha: 0.5)

            let planeNode = SCNNode(geometry: plane)
            planeNode.eulerAngles.x = -.pi
            node.addChildNode(planeNode)

            ...

        }
    }
like image 135
Diego Isco Avatar answered Oct 31 '22 19:10

Diego Isco