arkitscnscenearscnviewarcameratransformation-matrix

ARKit transform whole scene


I have this SCNScene which is quite nice and contains some nSCNNodes... Now I want to display this Scene in an ARSCNView. But, my whole scene is built with x,y,z >= 0 aka if I'd just set the screen my whole scene would be behind the camera.

I also can't render my scene inside the view, after I have the currentFrame because there are just too many nodes and it gets stuck...

So: I'm searching for a way to somehow transform my SCNScene, so that it doesn't change itself, but get's a proper position in front of the camera (which is 0,0,0) and maybe gets scaled down a little.

Is that even possible? If so what transformations would I have to do on which objects?

Thanks for reading :)


Solution

  • Assuming I am interpreting you correctly, you want to do two things:

    In the first part of your question you say that you can't load the model because there are too many nodes. Since you havent posted any code it's hard to provide a concrete solution but this might help.

    (a) In your SCNScene create an EmptyNode and call it 'Root' etc, then make all your actual scene elements a child of this e.g:

    enter image description here

    Since we now have a 'Root' node which holds the scene we can simply do this to load it:

      func loadScene(){
    
        //1. Get The Name Of The SCNSceme
        guard let hugeScene = SCNScene(named: "SceneKitAssets.scnassets/HugeScene.scn"),
               //2. Get The Root Node Which Holds All Your Content
               let sceneNode = hugeScene.rootNode.childNode(withName: "Root", recursively: false) else { return }
    
        //3. Add It To Your ARSCNView
        self.augmentedRealityView?.scene.rootNode.addChildNode(sceneNode)
    
        //4. Set The Scenes Position 1.5m Away From The Camera
         sceneNode.position =  SCNVector3(0, 0, -1.5)
    
        //5. Scale It To A Reasonable Size
        sceneNode.scale = SCNVector3(0.2,0.2,0.2)
    }
    

    You could also look at loading it on a background thread e.g:

     DispatchQueue.global(qos: .background).async {
            self.loadScene()
     }
    

    You will need to experiment with scale etc, but this should get you started.