Переглянути джерело

BufferGeometry: Retain interleaved data when using .clone().

Mugen87 5 роки тому
батько
коміт
54b5ef6364

+ 12 - 3
docs/api/en/core/InterleavedBuffer.html

@@ -98,13 +98,22 @@
 			Stores multiple values in the buffer, reading input values from a specified array.
 		</p>
 
-		<h3>[method:InterleavedBuffer clone]() </h3>
+		<h3>[method:InterleavedBuffer clone]( [param:Object data] ) </h3>
 		<p>
+			data - This object holds shared array buffers required for properly cloning geometries with interleaved attributes.<br/><br />
+
 			Creates a clone of this [name].
 		</p>
 
-		<h3>[method:BufferAttribute setUsage] ( [param:Usage value] ) </h3>
-		<p>Set [page:BufferAttribute.usage usage] to value.</p>
+		<h3>[method:InterleavedBuffer setUsage] ( [param:Usage value] ) </h3>
+		<p>Set [page:InterleavedBuffer.usage usage] to value.</p>
+
+		<h3>[method:InterleavedBuffer toJSON]( [param:Object data] ) </h3>
+		<p>
+			data - This object holds shared array buffers required for properly serializing geometries with interleaved attributes.<br/><br />
+
+			Serializes this [name].
+		</p>
 
 		<h2>Source</h2>
 

+ 13 - 4
docs/api/zh/core/InterleavedBuffer.html

@@ -103,13 +103,22 @@
 			将源队列数据拷贝到目标队列缓存中。
 		</p>
 
-		<h3>[method:InterleavedBuffer clone]() </h3>
+		<h3>[method:InterleavedBuffer clone]( [param:Object data] ) </h3>
 		<p>
-			克隆当前 [name]。
+			data - This object holds shared array buffers required for properly cloning geometries with interleaved attributes.<br/><br />
+
+			Creates a clone of this [name].
 		</p>
 
-		<h3>[method:BufferAttribute setUsage] ( [param:Usage value] ) </h3>
-		<p>Set [page:BufferAttribute.usage usage] to value.</p>
+		<h3>[method:InterleavedBuffer setUsage] ( [param:Usage value] ) </h3>
+		<p>Set [page:InterleavedBuffer.usage usage] to value.</p>
+
+		<h3>[method:InterleavedBuffer toJSON]( [param:Object data] ) </h3>
+		<p>
+			data - This object holds shared array buffers required for properly serializing geometries with interleaved attributes.<br/><br />
+
+			Serializes this [name].
+		</p>
 
 		<h2>源代码</h2>
 

+ 7 - 3
src/core/BufferGeometry.js

@@ -1136,6 +1136,10 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 		this.boundingBox = null;
 		this.boundingSphere = null;
 
+		// used for storing cloned, shared data
+
+		const data = {};
+
 		// name
 
 		this.name = source.name;
@@ -1146,7 +1150,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
 		if ( index !== null ) {
 
-			this.setIndex( index.clone() );
+			this.setIndex( index.clone( data ) );
 
 		}
 
@@ -1157,7 +1161,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 		for ( const name in attributes ) {
 
 			const attribute = attributes[ name ];
-			this.setAttribute( name, attribute.clone() );
+			this.setAttribute( name, attribute.clone( data ) );
 
 		}
 
@@ -1172,7 +1176,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
 			for ( let i = 0, l = morphAttribute.length; i < l; i ++ ) {
 
-				array.push( morphAttribute[ i ].clone() );
+				array.push( morphAttribute[ i ].clone( data ) );
 
 			}
 

+ 21 - 0
src/core/InstancedInterleavedBuffer.js

@@ -26,6 +26,27 @@ InstancedInterleavedBuffer.prototype = Object.assign( Object.create( Interleaved
 
 		return this;
 
+	},
+
+	clone: function ( data ) {
+
+		const ib = InterleavedBuffer.prototype.clone.call( this, data );
+
+		ib.meshPerAttribute = this.meshPerAttribute;
+
+		return ib;
+
+	},
+
+	toJSON: function ( data ) {
+
+		const json = InterleavedBuffer.prototype.toJSON.call( this, data );
+
+		json.isInstancedInterleavedBuffer = true;
+		json.meshPerAttribute = this.meshPerAttribute;
+
+		return json;
+
 	}
 
 } );

+ 1 - 1
src/core/InterleavedBuffer.d.ts

@@ -19,7 +19,7 @@ export class InterleavedBuffer {
 	uuid: string;
 
 	setUsage( usage: Usage ): InterleavedBuffer;
-	clone(): this;
+	clone( data: object ): this;
 	copy( source: InterleavedBuffer ): this;
 	copyAt(
 		index1: number,

+ 25 - 2
src/core/InterleavedBuffer.js

@@ -80,9 +80,32 @@ Object.assign( InterleavedBuffer.prototype, {
 
 	},
 
-	clone: function () {
+	clone: function ( data ) {
 
-		return new this.constructor().copy( this );
+		if ( data.arrayBuffers === undefined ) {
+
+			data.arrayBuffers = {};
+
+		}
+
+		if ( this.array.buffer._uuid === undefined ) {
+
+			this.array.buffer._uuid = MathUtils.generateUUID();
+
+		}
+
+		if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
+
+			data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer;
+
+		}
+
+		const array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] );
+
+		const ib = new InterleavedBuffer( array, this.stride );
+		ib.setUsage( this.usage );
+
+		return ib;
 
 	},
 

+ 1 - 1
src/core/InterleavedBufferAttribute.d.ts

@@ -25,7 +25,7 @@ export class InterleavedBufferAttribute {
 	readonly isInterleavedBufferAttribute: true;
 
 	applyMatrix4( m: Matrix4 ): this;
-	clone(): BufferAttribute;
+	clone( data?: object ): BufferAttribute;
 	getX( index: number ): number;
 	setX( index: number, x: number ): InterleavedBufferAttribute;
 	getY( index: number ): number;

+ 29 - 9
src/core/InterleavedBufferAttribute.js

@@ -157,25 +157,45 @@ Object.assign( InterleavedBufferAttribute.prototype, {
 
 	},
 
-	clone: function () {
+	clone: function ( data ) {
 
-		console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.' );
+		if ( data === undefined ) {
 
-		const array = [];
+			console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.' );
 
-		for ( let i = 0; i < this.count; i ++ ) {
+			const array = [];
 
-			const index = i * this.data.stride + this.offset;
+			for ( let i = 0; i < this.count; i ++ ) {
 
-			for ( let j = 0; j < this.itemSize; j ++ ) {
+				const index = i * this.data.stride + this.offset;
 
-				array.push( this.data.array[ index + j ] );
+				for ( let j = 0; j < this.itemSize; j ++ ) {
+
+					array.push( this.data.array[ index + j ] );
+
+				}
 
 			}
 
-		}
+			return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );
 
-		return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );
+		} else {
+
+			if ( data.interleavedBuffers === undefined ) {
+
+				data.interleavedBuffers = {};
+
+			}
+
+			if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
+
+				data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data );
+
+			}
+
+			return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized );
+
+		}
 
 	},