I have a Scene
that I want to copy and then change it without effecting the original Scene.
Object3D copy
method is copying by reference.
How can I duplicate to an independent Scene
?
I have a Scene
that I want to copy and then change it without effecting the original Scene.
Object3D copy
method is copying by reference.
How can I duplicate to an independent Scene
?
Try clone()
.
Tried it but still the material
etc. are referenced to the original object.
After you clone the scene, traverse it and clone referenced properties like
myScene.traverse(function(object) {
if ( object.isMesh ) {
object.material = object.material.clone();
}
});
You need to do it as deep as you require, a cloned material will still share it’s program for example, in case you don’t want this to be referenced either.
@Fyrestar works
Thank you!
Here is some code that uses this example clone - I load one .obj, and make a pile of copies of it - setting the position and color of each one
Blockquote
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath(‘textures/cont1/’);
mtlLoader.load(‘container2.mtl’, function (materials) {
materials.preload();//var material = new THREE.MeshFaceMaterial(materials); materials.transparency = 0.2; materials.transparent = true; materials.opacity = 0.6; //material.depthWrite = false; // var objLoader = new THREE.OBJLoader(); objLoader.setMaterials(materials); objLoader.setPath('textures/cont1/'); objLoader.load('/Container2.obj', function (container) { for (var sc = 0; sc < posns.length; sc++) { var scale = posns[sc].scale; var rotation = posns[sc].rotation; var posn = posns[sc].position; var model3d = new THREE.Object3D(); //clone main obj model3d = container.clone(); //clone obnj meshes model3d.traverse(function (object) { if (object.isMesh) { object.material = object.material.clone(); } }); model3d.scale.x = parseFloat(scale.x); model3d.scale.y = parseFloat(scale.y); model3d.scale.z = parseFloat(scale.z); //container.position = new THREE.Vector3(posn.x, posn.y, posn.z); model3d.position.x = posn.x; model3d.position.y = posn.y; model3d.position.z = posn.z; model3d.rotation.x = rotation._x; model3d.rotation.y = rotation._y; model3d.rotation.z = rotation._z; var color = '999933';//default grey if (!posns[sc].color) { var rnd = (Math.random() * 100); if (rnd >90) { console.log('blue'); posns[sc].color = '456F87'; } else if (rnd > 50) { console.log('red'); posns[sc].color = 'C04B0C';// }else if (rnd > 20) { console.log('yellow'); posns[sc].color = 'F3CD8B'; }else { console.log('grey'); posns[sc].color = color; } } model3d.traverse(function (child) { if (child instanceof THREE.Mesh) { //var c = hexToRgb(color); var c = hexToRgb(posns[sc].color); child.material.color = new THREE.Color("rgb(" + c.r + ", " + c.g + ", " + c.b + ")"); //child.material.emissive.setHex(0xdaa514); //child.material.opacity = 1 + Math.sin(new Date().getTime() * .0025); child.castShadow = true; //default is false child.receiveShadow = false; //default } }); if (!model3d.userData.color) { model3d.userData.color = posns[sc].color; }; model3d.name = posns[sc].name; group = new THREE.Group(); scene.add(group); var textMaterial = new THREE.MeshBasicMaterial({ color: new THREE.Color(1, 1, 1), side: THREE.DoubleSide, wireframe: false }); var textShapes = font.generateShapes(model3d.name, .4); var geometry = new THREE.ShapeBufferGeometry(textShapes); geometry.computeBoundingBox(); var text = new THREE.Mesh(geometry, textMaterial); text.position.x = posn.x - ((geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2); text.position.y = posn.y + 5; text.position.z = posn.z + 0; group.add(text); group.add(model3d); containers.push(model3d); scene.add(model3d); } }, onProgress, onError);
});
Blockquote
Hello. you can throw off all the code? I will be very grateful, thanks.
Should the documentation for Object3D.clone() warn that materials will not be cloned ?
-jg-