Will three.js Object3D.clone () create a deep copy of the geometry?

I load models using the collada bootloader. The loader returns Object3D, "dae", with many child grids. I would like to instantiate the parent dae many times without duplicating the mesh. Can dae.clone () be used?

In other words: I would like to make small copies, everyone has their own transformation matrix, but they have the same geometry. What is the most effective way to do this?

+4
source share
3 answers

By default Object3D.clone()creates a deep copy. Let's look at the source

clone: function ( object, recursive ) {

    if ( object === undefined ) object = new THREE.Object3D();
    if ( recursive === undefined ) recursive = true;

    object.name = this.name;

    object.up.copy( this.up );

    object.position.copy( this.position );
    object.quaternion.copy( this.quaternion );
    object.scale.copy( this.scale );

    object.renderDepth = this.renderDepth;

    object.rotationAutoUpdate = this.rotationAutoUpdate;

    object.matrix.copy( this.matrix );
    object.matrixWorld.copy( this.matrixWorld );

    object.matrixAutoUpdate = this.matrixAutoUpdate;
    object.matrixWorldNeedsUpdate = this.matrixWorldNeedsUpdate;

    object.visible = this.visible;

    object.castShadow = this.castShadow;
    object.receiveShadow = this.receiveShadow;

    object.frustumCulled = this.frustumCulled;

    object.userData = JSON.parse( JSON.stringify( this.userData ) );

    if ( recursive === true ) {

        for ( var i = 0; i < this.children.length; i ++ ) {

            var child = this.children[ i ];
            object.add( child.clone() );

        }

    }

    return object;

}

As we can see, the function clonetakes two optional arguments:

  • Object3D .
  • , , .

, Object3D.children, , ( ).

, Object3D.clone(), , . Mesh.clone() Geometry Material.

THREE.Mesh.prototype.clone = function ( object ) {

    if ( object === undefined ) object = new THREE.Mesh( this.geometry, this.material );

    THREE.Object3D.prototype.clone.call( this, object );

    return object;

};
+7

, . .

: https://github.com/mrdoob/three.js/issues/5754

    /** Gives the aptitude for an object3D to clone recursively with its material cloned (normal clone does not clone material)*/

    THREE.Object3D.prototype.GdeepCloneMaterials = function() {
        var object = this.clone( new THREE.Object3D(), false );

        for ( var i = 0; i < this.children.length; i++ ) {

            var child = this.children[ i ];
            if ( child.GdeepCloneMaterials ) {
                object.add( child.GdeepCloneMaterials() );
            } else {
                object.add( child.clone() );
            }

        }
        return object;
    };

    THREE.Mesh.prototype.GdeepCloneMaterials = function( object, recursive ) {
        if ( object === undefined ) {
            object = new THREE.Mesh( this.geometry, this.material.clone() );
        }

        THREE.Object3D.prototype.GdeepCloneMaterials.call( this, object, recursive );

        return object;
    };
+2

copy clone Object3D .

First, it expands two new methods in THREE:

THREE.Object3D.prototype.deepClone = function ( recursive ) {

    return new this.constructor().deepCopy( this, recursive );

},
THREE.Object3D.prototype.deepCopy = function( source, recursive ) {

        if ( recursive === undefined ) recursive = true;

        this.name = source.name;

        this.up.copy( source.up );

        this.position.copy( source.position );
        this.quaternion.copy( source.quaternion );
        this.scale.copy( source.scale );

        this.matrix.copy( source.matrix );
        this.matrixWorld.copy( source.matrixWorld );
        if(source.material){
            //changed
            this.material = source.material.clone()
        }
        if(source.geometry){
            //changed
            this.geometry = source.geometry.clone()
        }
        this.matrixAutoUpdate = source.matrixAutoUpdate;
        this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;

        this.layers.mask = source.layers.mask;
        this.visible = source.visible;

        this.castShadow = source.castShadow;
        this.receiveShadow = source.receiveShadow;

        this.frustumCulled = source.frustumCulled;
        this.renderOrder = source.renderOrder;

        this.userData = JSON.parse( JSON.stringify( source.userData ) );

        if ( recursive === true ) {

            for ( var i = 0; i < source.children.length; i ++ ) {

                var child = source.children[ i ];
                this.add( child.deepClone() ); //changed

            }

        }

        return this;

    }

Secondly, if you want to deeply clone Object3D or a scene named originalObjJust dovar newObj = originalObj.deepClone()

0
source

Source: https://habr.com/ru/post/1531411/


All Articles