diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 50ce3779ab8e9d..a4e5edb487c73b 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -6,6 +6,8 @@ import { Euler } from '../math/Euler.js'; import { Layers } from './Layers.js'; import { Matrix3 } from '../math/Matrix3.js'; import { generateUUID } from '../math/MathUtils.js'; +import { BufferAttribute } from './BufferAttribute.js'; +import { BufferGeometry} from './BufferGeometry.js'; let _object3DId = 0; @@ -962,6 +964,7 @@ class Object3D extends EventDispatcher { } + clone( recursive ) { return new this.constructor().copy( this, recursive ); @@ -969,6 +972,36 @@ class Object3D extends EventDispatcher { } copy( source, recursive = true ) { + + + if( recursivie ){ + + // Copy VALUES, not just references to the source Attribute array + // This fixes e.g. 'cumulative rotations' etc, for clones which would + // apply transformations to their predecessors, otherwise + + let originalGeometry = source.geometry; + let newGeometry = new BufferGeometry(); + + // create new containers for attributes + Object.keys(originalGeometry.attributes).forEach((key, idx) => { + + // get, use the correct 'typed array', dimension it + var arrayType = (''+originalGeometry.attributes[key].array.constructor).split(' ')[1].split('(')[0]; + newGeometry.attributes[key] = new BufferAttribute(new window[arrayType]( + originalGeometry.attributes[key].array.length), + originalGeometry.attributes[key].itemSize, + originalGeometry.attributes[key].normalized ) + + // ...and copy values into them + originalGeometry.attributes[key].array.forEach((v, i) => { + newGeometry.attributes[key].array[i] = originalGeometry.attributes[key].array[i]; + }); + }) + + this.source.geometry = newGeometry; + } + this.name = source.name;