Search code examples
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:

    • Load Your Scene,
    • Ensure It Is Scaled To A Reasonable Size.

    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.