How to add multiple SCNScenes to one SCNScene?

Viewed 505

I am trying to create an application that will allow to place 3d objects. I was able to write some code that works, but only with geometric objects. I need to add multiple SCNScenes to one scene. How do I implement this?

How I have tried:

let sceneView = SCNView()
sceneView.scene = SCNScene()
sceneView.allowsCameraControl = true
sceneView.autoenablesDefaultLighting = true
sceneView.backgroundColor = .gray
    
let firstScene = SCNScene(named: "Earth.usdz")!
let firstSceneNode = firstScene.rootNode.childNode(withName: "Earth", recursively: true)!
firstSceneNode.rotate(by: .init(0, 0, 0, 0), aroundTarget: SCNVector3(0, -30, 10))
sceneView.scene?.rootNode.addChildNode(firstSceneNode)
    
let secondScene = SCNScene(named: "Venus.usdz")!
let secondSceneNode = secondScene.rootNode.childNode(withName: "Venus", recursively: true)!
sceneView.scene?.rootNode.addChildNode(secondSceneNode)

When I delete secondScene everything works with one model.

Thanks!

2 Answers

Simply take the nodes you want out of each child scene (in this case it looks like you want the root node from each planet scene) and add them each as as child node in the scene you are going to present (ie a solar system scene).

In SceneKit each SCNScene can contain multiple SCNNodes connected to scene's root node. As you can see on the image these nodes can be not only geometry but also light fixtures, cameras or particle systems.

enter image description here

You can easily retrieve any desirable SCNNode with corresponding materials from any SCNScene tree and paste in into other scene (in this case into empty scene).

import SwiftUI
import SceneKit

struct ContentView: View {
    
    var body: some View {
        SceneKitView().ignoresSafeArea()
    }
}

struct SceneKitView: UIViewRepresentable {
    
    let sceneView = SCNView(frame: .zero)

    func makeUIView(context: Context) -> SCNView {
        
        sceneView.allowsCameraControl = true
        sceneView.autoenablesDefaultLighting = true
        sceneView.backgroundColor = .black
        sceneView.scene = SCNScene()
        
        let scene01 = SCNScene(named: "Earth.usdz")!
        let scene02 = SCNScene(named: "Mars.usdz")!
        let scene03 = SCNScene(named: "Sun.usdz")!

        let earthNode = scene01.rootNode.childNode(withName: "earthPlanet", 
                                                recursively: true)!
        earthNode.position.x = -1.0

        let marsNode = scene02.rootNode.childNode(withName: "marsPlanet", 
                                               recursively: true)!
        marsNode.position.x = 0.2

        let sunNode = scene03.rootNode.childNode(withName: "sunStar", 
                                              recursively: true)!
        sunNode.position.x = 1.5
        
        sceneView.scene?.rootNode.addChildNode(earthNode)
        sceneView.scene?.rootNode.addChildNode(marsNode)
        sceneView.scene?.rootNode.addChildNode(sunNode)
        return sceneView
    }
    func updateUIView(_ uiView: SCNView, context: Context) { }
}

P.S.

But you can't load multiple SCNScenes into single SCNScene.

Related