Crashalot
Crashalot

Reputation: 34513

SceneKit: How to access and change colors of this OBJ file?

It's possible to open the OBJ file below and change the material colors from within the Xcode SceneKit Editor.

However, the documentation isn't clear how to access this same list of materials from within code, and change the colors programmatically. (See attachment.)

func enumerateChildObjects(of: AnyClass, root: MDLObject, using: (MDLObject, UnsafeMutablePointer<ObjCBool>) -> Void, stopPointer: UnsafeMutablePointer<ObjCBool>) seems like it might help, but it's not returning the same list of materials.

Code to load OBJ file into SceneKit:

    let modelPath = "model.obj"
    let url = NSURL(string: modelPath)

    let scene = SCNScene(named: modelPath)!
    sceneView.autoenablesDefaultLighting = true
    sceneView.allowsCameraControl = true
    sceneView.scene = scene
    sceneView.backgroundColor = UIColor.white

List of materials on right side (Xcode screenshot):

enter image description here

Download OBJ file (click Download link): https://poly.google.com/view/cKryD9VnDEZ

Upvotes: 1

Views: 3656

Answers (1)

Xartec
Xartec

Reputation: 2415

The SCNScene in which you load the OBJ file contains a .rootNode property, which in turn has a childNodes property that contain the SCNNodes in the scene/obj file. Each SCNNode has a .geometry property that contains a SCNGeometry that describes the model’s vertices. A SCNGeometry also has a .materials property. This is an array of SCNMaterials you can simply loop through.

For example, if there is only one node in the scene loaded from obj, then the mat23 material is scene.rootNode.childNodes.firstObject.geometry.materials.firstMaterial or scene.rootNode.childNodes.firstObject.geometry.materials[0]

Usually when you load a single object from an OBJ you assign the firstObject to a SCNNode, which you then add as a child to the rootNode of the scene of the SCNView. (Rather than assigning the entire scene from the obj).

In short, set up a scene programmatically, configure it and assign it to the SCNView. Don’t use the scene you create to load the OBJ file, but grab the first child node from that scene’s rootnode, and add that to your scene (and for example and array of Monsters). Each node you add has a geometry property which in turn has a Materials property (https://developer.apple.com/documentation/scenekit/scngeometry/1523472-materials ) containing the materials assigned to that node specifically.

So you don’t actually access the colors of the obj (nor its mtl file), you instead access the SCNMaterials Xcode created for each SCNNode.

Upvotes: 1

Related Questions