three.js Object3D.clone()会创建几何的深层副本吗?

Bus*_*icK 4 three.js

我正在使用collada装载机加载模型.加载器返回一个带有许多子网格的Object3D"dae".我想多次实例化父"dae"对象而不重复网格.我可以使用dae.clone()吗?

换句话说:我想制作浅色的副本,它们都有自己的变换矩阵,但共享相同的几何形状.最有效的方法是什么?

Jon*_*xon 7

默认情况下Object3D.clone()会创建深层副本.我们来看看源代码

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;

}
Run Code Online (Sandbox Code Playgroud)

我们可以看到该clone函数接受两个可选参数:

  1. 要克隆Object3D到的对象.
  2. 一个标志,指示是否递归克隆子项.

所以是的,可以制作相关的浅拷贝Object3D.children,但这不是你想要的(基于你的评论).

我相信你实际上可以使用默认行为Object3D.clone()来获得你想要的东西.Mesh.clone()不克隆GeometryMaterial属性.

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;

};
Run Code Online (Sandbox Code Playgroud)


Sta*_*ola 5

这是我用来深度克隆对象材质的几个函数。您可以根据您的需要修改它

另请考虑此信息: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;
    };
Run Code Online (Sandbox Code Playgroud)