Browse Source

BufferGeometryUtils.mergeAttributes: Add support for interleaved buffers (#27591)

* Add support for interleaved attributes to mergeAttributes

* Fix use of offset
Garrett Johnson 1 year ago
parent
commit
687df5c3c2
1 changed files with 23 additions and 11 deletions
  1. 23 11
      examples/jsm/utils/BufferGeometryUtils.js

+ 23 - 11
examples/jsm/utils/BufferGeometryUtils.js

@@ -311,13 +311,6 @@ function mergeAttributes( attributes ) {
 
 
 		const attribute = attributes[ i ];
 		const attribute = attributes[ i ];
 
 
-		if ( attribute.isInterleavedBufferAttribute ) {
-
-			console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. InterleavedBufferAttributes are not supported.' );
-			return null;
-
-		}
-
 		if ( TypedArray === undefined ) TypedArray = attribute.array.constructor;
 		if ( TypedArray === undefined ) TypedArray = attribute.array.constructor;
 		if ( TypedArray !== attribute.array.constructor ) {
 		if ( TypedArray !== attribute.array.constructor ) {
 
 
@@ -350,22 +343,41 @@ function mergeAttributes( attributes ) {
 
 
 		}
 		}
 
 
-		arrayLength += attribute.array.length;
+		arrayLength += attribute.count * itemSize;
 
 
 	}
 	}
 
 
 	const array = new TypedArray( arrayLength );
 	const array = new TypedArray( arrayLength );
+	const result = new BufferAttribute( array, itemSize, normalized );
 	let offset = 0;
 	let offset = 0;
 
 
 	for ( let i = 0; i < attributes.length; ++ i ) {
 	for ( let i = 0; i < attributes.length; ++ i ) {
 
 
-		array.set( attributes[ i ].array, offset );
+		const attribute = attributes[ i ];
+		if ( attribute.isInterleavedBufferAttribute ) {
+
+			const tupleOffset = offset / itemSize;
+			for ( let j = 0, l = attribute.count; j < l; j ++ ) {
+
+				for ( let c = 0; c < itemSize; c ++ ) {
 
 
-		offset += attributes[ i ].array.length;
+					const value = attribute.getComponent( j, c );
+					result.setComponent( j + tupleOffset, c, value );
+
+				}
+
+			}
+
+		} else {
+
+			array.set( attribute.array, offset );
+
+		}
+
+		offset += attribute.count * itemSize;
 
 
 	}
 	}
 
 
-	const result = new BufferAttribute( array, itemSize, normalized );
 	if ( gpuType !== undefined ) {
 	if ( gpuType !== undefined ) {
 
 
 		result.gpuType = gpuType;
 		result.gpuType = gpuType;