must
must

Reputation: 46

In Scenekit how to split one SCNNode into many nodes?

I trying to load a .obj file. how ever after loaded, secenekit only generate one node with a huge geometry which has many submeshes. Anyone has idea how to split this huge node into many nodes, each node owns one submesh form the original node? As I need to apply different physic on them. Thanks in advance.

I have tried following approach:

  1. manually parse the .obj file. this works but eat up too much memory
  2. after load the file, I get the huge node. then I do

            let geometry = SCNGeometry(sources: rootNode.geometry!.geometrySources, elements: [rootNode.geometry!.geometryElementAtIndex(count)])
            geometry.firstMaterial = rootNode.geometry!.materials[count]
            let node = SCNNode(geometry: geometry)
    

for each mesh (get from .obj file) this also work, but take a long time for rendering, I guess is because I copy the whole source for each node.

Upvotes: 1

Views: 727

Answers (1)

Hal Mueller
Hal Mueller

Reputation: 7646

It sounds like you have already found a couple of approaches that give you correct results, but they take too long to do at run time. So run with those, but do it in advance.

Run your manual OBJ parse, or your per-element geometry retrieval, in an auxiliary program. Archive that result to an SCNScene (or maybe SCNNodes). Embed the archive/archives in your public project. Unarchiving a .SCN file will be much faster than parsing and instantiating a big OBJ file.

Here's a function to archive a scene to a file. You can then embed the file in your project and open it the way the space ship is opened in the template code, or use the Xcode Scene Editor to tweak it.

func archiveToFile(fileName: String) -> Bool {
    let data = NSKeyedArchiver.archivedDataWithRootObject(gameView!.scene!)

    // Save data to file
    let DocumentDirURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)

    let fileURL = DocumentDirURL.URLByAppendingPathComponent(fileName).URLByAppendingPathExtension("scn")
    print("FilePath:", fileURL.path)

    if (!data.writeToURL(fileURL, atomically: true)) {
        return false
    }
    return true
}

Upvotes: 1

Related Questions