SceneKit——递归克隆一个节点
SceneKit – Clone a node recursively
我正在尝试递归克隆所有节点(包括它们的 material)。我想在不影响原始节点 (materials) 的情况下更改克隆节点中的某些 material 属性。
这是我目前所做的,但它似乎没有用。在新节点上所做的任何更改仍会反映在原始节点上。
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];
}];
来自联机文档:
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.
试试这个代码:
#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
我正在尝试递归克隆所有节点(包括它们的 material)。我想在不影响原始节点 (materials) 的情况下更改克隆节点中的某些 material 属性。
这是我目前所做的,但它似乎没有用。在新节点上所做的任何更改仍会反映在原始节点上。
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];
}];
来自联机文档:
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.
试试这个代码:
#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