瀏覽代碼

BatchedMesh: Make data copying more robust, handle interleaved attributes (#27066)

* BatchedMesh: Remove unused fields

* BatchedMesh: Add thrown errors in unimplemented functions

* Add PURE and glsl identifiers

* Add more error handling

* More errors

* Fix batched index overrun

* BatchedMesh: Check for normalized, as well

* Fix screenshot

* Handle interleaved data

* Add comments, check if constructors are the same

* Move update setting

* Remove pure annotations
Garrett Johnson 1 年之前
父節點
當前提交
5e43514cf6
共有 1 個文件被更改,包括 31 次插入3 次删除
  1. 31 3
      examples/jsm/objects/BatchedMesh.js

+ 31 - 3
examples/jsm/objects/BatchedMesh.js

@@ -64,6 +64,36 @@ const batchingVertex = /* glsl */`
 // @TODO: SkinnedMesh support?
 // @TODO: SkinnedMesh support?
 // @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.
 // @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.
 
 
+// copies data from attribute "src" into "target" starting at "targetOffset"
+function copyAttributeData( src, target, targetOffset = 0 ) {
+
+	const itemSize = target.itemSize;
+	if ( src.isInterleavedBufferAttribute || src.array.constructor !== target.array.constructor ) {
+
+		// use the component getters and setters if the array data cannot
+		// be copied directly
+		const vertexCount = src.count;
+		for ( let i = 0; i < vertexCount; i ++ ) {
+
+			for ( let c = 0; c < itemSize; c ++ ) {
+
+				target.setComponent( i + targetOffset, c, src.getComponent( i, c ) );
+
+			}
+
+		}
+
+	} else {
+
+		// faster copy approach using typed array set function
+		target.array.set( src.array, targetOffset * itemSize );
+
+	}
+
+	target.needsUpdate = true;
+
+}
+
 class BatchedMesh extends Mesh {
 class BatchedMesh extends Mesh {
 
 
 	constructor( maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material ) {
 	constructor( maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material ) {
@@ -332,9 +362,7 @@ class BatchedMesh extends Mesh {
 
 
 			const srcAttribute = geometry.getAttribute( attributeName );
 			const srcAttribute = geometry.getAttribute( attributeName );
 			const dstAttribute = batchGeometry.getAttribute( attributeName );
 			const dstAttribute = batchGeometry.getAttribute( attributeName );
-
-			dstAttribute.array.set( srcAttribute.array, vertexCount * dstAttribute.itemSize );
-			dstAttribute.needsUpdate = true;
+			copyAttributeData( srcAttribute, dstAttribute, vertexCount );
 
 
 		}
 		}