Home > OS >  SceneKit – Clone a node recursively
SceneKit – Clone a node recursively

Time:04-08

I am trying to clone all nodes (including their material) recursively. I want to change certain material properties in the cloned nodes without impacting the original node(materials).

This is what I have so far, but it does not seem to be working. Any change made on the new nodes is still reflected on the original nodes.

SCNNode *newRoot = [self.root clone];

[newRoot enumerateHierarchyUsingBlock:^(SCNNode * _Nonnull node, BOOL * _Nonnull stop) {
    SCNNode *oldNode = [self.root childNodeWithName:node.name recursively:YES];
    node.geometry = [oldNode.geometry copy];
    node.geometry.materials = [oldNode.geometry.materials copy];
}];

CodePudding user response:

Try this code:

#import "GameViewController.h"

@implementation GameViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    SCNView *sceneView = (SCNView *)self.view;
    SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/ship.scn"];
    sceneView.scene = scene;
    sceneView.allowsCameraControl = YES;
    sceneView.autoenablesDefaultLighting = YES;
    
    SCNMaterial *material = [SCNMaterial material];
    material.lightingModelName = SCNLightingModelPhysicallyBased;
    material.diffuse.contents = [NSColor redColor];
    
    SCNNode *ship = [scene.rootNode childNodeWithName:@"ship" 
                                          recursively:YES].childNodes[0];
    
    SCNNode *shipCopy = [ship clone];
    shipCopy.position = SCNVector3Make(10, 0, 0);
    
    SCNGeometry *geometryCopy = (SCNGeometry *)[ship.geometry copy];
    shipCopy.geometry = geometryCopy;
    [shipCopy.geometry replaceMaterialAtIndex:0 withMaterial:material];
    [scene.rootNode addChildNode:shipCopy];
}
@end

enter image description here

CodePudding user response:

From the online documentation:

Cloning or copying a node creates a duplicate of the node object, but not the geometries, lights, cameras, and other SceneKit objects attached to it—instead, each copied node shares references to these objects.

This behavior means that you can use cloning to, for example, place the same geometry at several locations within a scene without maintaining multiple copies of the geometry and its materials. However, it also means that changes to the objects attached to one node will affect other nodes that share the same attachments. For example, to render two copies of a node using different materials, you must copy both the node and its geometry before assigning a new material.

  • Related