Save and reuse a SCNGeometry for future use

85 views Asked by At

For my Scenekit project I found online a class called Terrain witch randomly generete some non regular terrain to be display in my game.

pic

The code generate every time a very well done terrain SCNGeometry using some sort of noise generator.(it calculate all the vertices every time I call this class)

Due to the large size of the terrain it really take long time to calculate all the vertices in order to create the terrain.

Since my terrain no need to change every time... is it possibile in some way to save the SCNGeometry locally to be reused? Or any other possible approach I could use in order to speed up this process? can't 'find to much online.

Thanks

2

There are 2 answers

3
ZAY On

To save your SCNNode containing the terrain geometry, you can do something like this:

// Write Data Function
func writeData() {
    let fixedFilename = String("SAVED-OBJECT") // just a reference Name
    let fullPath = getDocumentsDirectory().appendingPathComponent(fixedFilename)
    print("Full Path for write is: \(fullPath)")
    
    do {
        guard let data = try? NSKeyedArchiver.archivedData(withRootObject: yourGeometryNode, requiringSecureCoding: false)
            else { fatalError("can't encode data") }
        try data.write(to: fullPath)
    } catch {
        print("Couldn't write file")
    }
}

To read the saved SCNNode, do something like this:

// Read Data Function
func readData() {
    let fixedFilename = String("SAVED-OBJECT")
    let fullPath = getDocumentsDirectory().appendingPathComponent(fixedFilename)
    print("Full Path for Read is: \(fullPath)")
    
    guard let data = try? Data(contentsOf: fullPath) else {
        print("no data found")
        return }

    do {
        yourGeometryNode = try NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: data) {
        print("saved data found, reading-in")
        }
    } catch {
        print("error can't decode the saved data")
    }
}

I recommend this useful Helper-Function in addition:

// Helper Function
func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

Note: Child-Nodes will be saved as well.

0
mnuages On

SCNGeometry (like most SceneKit classes) conforms to the NSSecureCoding protocol that allows for archiving.