How to create new instances of SCNNode with different texture

I am loading meshes from COLLADA files into SceneKit. Let's say I have a cube with a material that has a specific texture. Then in code I want to make new copies of this SCNNode - so far I have used clone

, and then I need to set a new texture. This is where it gets problematic, because if I get the named material of one of the cloned cubes and update its texture ( thematerialofmycube.diffuse.contents = @"somefile.png"

), it will set the same texture to all instances of the cube.clone

obviously doesn't copy things like geometry, materials and textures. So I tried to make a copy of the geometry itself, and also tried to create a new material by setting a new texture for the new material and adding that material to the new geometry's material array, as well as removing the old material.There seems to be no easy way to do it this way (materials named but exist in the array, so in theory, in theory, one name can have multiple materials, which leads to some cumbersome adding / removing objects from the array) and when I do this new textures appear, but they appear upside down and also the order of materials seems to be wrong as I get back textures instead of foreground textures and vice versa. I hope I don't need to draw all this in my 3D editor,there should be a good way to create new instances with arbitrarily given textures in code.

What I do on purpose, I drew the trump card in my 3D editor and exported it to COLLADA. Now I have 52 png trump faces - I need to obviously replace the faces of the new trump instances.

+3


source to share


3 answers


It seems that the order of the materials in this array is (very) important. If I insert a new material with the updated texture at the same array index as the one I am deleting, essentially replacing, then the textures are displayed on the correct face and not flipped up - i.e. they are displayed in the same way as with the original SCNNode. I haven't run this for a longer time yet to make sure it works consistently.



+1


source


[SCNNode clone] do this for efficiency reasons. Try this code (if you want to create SCNNode category:



//********************************************************
//<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// SCNNode duplicate
//********************************************************
//<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- (SCNNode *)duplicateNode:(SCNNode *)node
{
    SCNNode *newNode = [node clone];
    newNode.geometry = [node.geometry copy];
    newNode.geometry.firstMaterial = [node.geometry.firstMaterial copy];

    return newNode;
}

      

+1


source


Quick response:

fileprivate func deepCopyNode(node: SCNNode) -> SCNNode {
    let clone = node.clone()
    clone.geometry = node.geometry?.copy() as? SCNGeometry
    if let g = node.geometry {
        clone.geometry?.materials = g.materials.map{ $0.copy() as! SCNMaterial }
    }
    return clone
}

      

+1


source







All Articles