Parcourir la source

BatchedMesh: Consolidate internal geometry information (#29687)

* Fix add instance bug

* Add todos for PR, instance count

* Progress towards replacing some geometry info

* remove remaining references to _drawRanges, _bounds, and _reservedRanges

* Fix rendering

* Remove unnecessary global fields

* Clean up

* Store draw range

* drawInfo -> instanceInfo

* Fix optimize

* revert "drawInfo" rename

* revert global changes to reduce noise

* Remove local variable name change to reduce noise

* remove accessors to reduce noise
Garrett Johnson il y a 1 an
Parent
commit
d74ecc563a
1 fichiers modifiés avec 135 ajouts et 177 suppressions
  1. 135 177
      src/objects/BatchedMesh.js

+ 135 - 177
src/objects/BatchedMesh.js

@@ -40,7 +40,7 @@ class MultiDrawRenderList {
 
 	}
 
-	push( drawRange, z, index ) {
+	push( start, count, z, index ) {
 
 		const pool = this.pool;
 		const list = this.list;
@@ -61,8 +61,8 @@ class MultiDrawRenderList {
 		list.push( item );
 		this.index ++;
 
-		item.start = drawRange.start;
-		item.count = drawRange.count;
+		item.start = start;
+		item.count = count;
 		item.z = z;
 		item.index = index;
 
@@ -92,12 +92,6 @@ const _renderList = /*@__PURE__*/ new MultiDrawRenderList();
 const _mesh = /*@__PURE__*/ new Mesh();
 const _batchIntersects = [];
 
-// @TODO: SkinnedMesh support?
-// @TODO: geometry.groups support?
-// @TODO: geometry.drawRange support?
-// @TODO: geometry.morphAttributes support?
-// @TODO: Support uniform parameter per geometry
-
 // copies data from attribute "src" into "target" starting at "targetOffset"
 function copyAttributeData( src, target, targetOffset = 0 ) {
 
@@ -170,33 +164,33 @@ class BatchedMesh extends Mesh {
 		this.boundingSphere = null;
 		this.customSort = null;
 
-		// stores visible, active, and geometry id per object
+		// stores visible, active, and geometry id per instance and reserved buffer ranges for geometries
 		this._drawInfo = [];
+		this._geometryInfo = [];
 
 		// instance, geometry ids that have been set as inactive, and are available to be overwritten
 		this._availableInstanceIds = [];
 		this._availableGeometryIds = [];
 
-		// geometry information
-		this._drawRanges = [];
-		this._reservedRanges = [];
-		this._bounds = [];
+		// used to track where the next point is that geometry should be inserted
+		this._nextIndexStart = 0;
+		this._nextVertexStart = 0;
+		this._geometryCount = 0;
+
+		// flags
+		this._visibilityChanged = true;
+		this._geometryInitialized = false;
 
+		// cached user options
 		this._maxInstanceCount = maxInstanceCount;
 		this._maxVertexCount = maxVertexCount;
 		this._maxIndexCount = maxIndexCount;
 
-		this._geometryInitialized = false;
-		this._geometryCount = 0;
+		// buffers for multi draw
 		this._multiDrawCounts = new Int32Array( maxInstanceCount );
 		this._multiDrawStarts = new Int32Array( maxInstanceCount );
 		this._multiDrawCount = 0;
 		this._multiDrawInstances = null;
-		this._visibilityChanged = true;
-
-		// used to track where the next point is that geometry should be inserted
-		this._nextIndexStart = 0;
-		this._nextVertexStart = 0;
 
 		// Local matrix per geometry by using data texture
 		this._matricesTexture = null;
@@ -389,7 +383,7 @@ class BatchedMesh extends Mesh {
 
 		}
 
-		const instanceDrawInfo = {
+		const drawInfo = {
 			visible: true,
 			active: true,
 			geometryIndex: geometryId,
@@ -403,18 +397,17 @@ class BatchedMesh extends Mesh {
 			this._availableInstanceIds.sort( ascIdSort );
 
 			drawId = this._availableInstanceIds.shift();
-			this._drawInfo[ drawId ] = instanceDrawInfo;
+			this._drawInfo[ drawId ] = drawInfo;
 
 		} else {
 
 			drawId = this._drawInfo.length;
-			this._drawInfo.push( instanceDrawInfo );
+			this._drawInfo.push( drawInfo );
 
 		}
 
 		const matricesTexture = this._matricesTexture;
-		const matricesArray = matricesTexture.image.data;
-		_identityMatrix.toArray( matricesArray, drawId * 16 );
+		_identityMatrix.toArray( matricesTexture.image.data, drawId * 16 );
 		matricesTexture.needsUpdate = true;
 
 		const colorsTexture = this._colorsTexture;
@@ -425,81 +418,60 @@ class BatchedMesh extends Mesh {
 
 		}
 
+		this._visibilityChanged = true;
 		return drawId;
 
 	}
 
-	addGeometry( geometry, vertexCount = - 1, indexCount = - 1 ) {
+	addGeometry( geometry, reservedVertexCount = - 1, reservedIndexCount = - 1 ) {
 
 		this._initializeGeometry( geometry );
 
 		this._validateGeometry( geometry );
 
-		// get the necessary range fo the geometry
-		const reservedRange = {
+		const geometryInfo = {
+			// geometry information
 			vertexStart: - 1,
 			vertexCount: - 1,
+			reservedVertexCount: - 1,
+
 			indexStart: - 1,
 			indexCount: - 1,
-		};
-
-		const reservedRanges = this._reservedRanges;
-		const drawRanges = this._drawRanges;
-		const bounds = this._bounds;
-
-		reservedRange.vertexStart = this._nextVertexStart;
-		if ( vertexCount === - 1 ) {
-
-			reservedRange.vertexCount = geometry.getAttribute( 'position' ).count;
+			reservedIndexCount: - 1,
 
-		} else {
+			// draw range information
+			start: - 1,
+			count: - 1,
 
-			reservedRange.vertexCount = vertexCount;
+			// state
+			boundingBox: null,
+			boundingSphere: null,
+			active: true,
+		};
 
-		}
+		const geometryInfoList = this._geometryInfo;
+		geometryInfo.vertexStart = this._nextVertexStart;
+		geometryInfo.reservedVertexCount = reservedVertexCount === - 1 ? geometry.getAttribute( 'position' ).count : reservedVertexCount;
 
 		const index = geometry.getIndex();
 		const hasIndex = index !== null;
 		if ( hasIndex ) {
 
-			reservedRange.indexStart = this._nextIndexStart;
-			if ( indexCount	=== - 1 ) {
-
-				reservedRange.indexCount = index.count;
-
-			} else {
-
-				reservedRange.indexCount = indexCount;
-
-			}
+			geometryInfo.indexStart = this._nextIndexStart;
+			geometryInfo.reservedIndexCount = reservedIndexCount === - 1 ? index.count : reservedIndexCount;
 
 		}
 
 		if (
-			reservedRange.indexStart !== - 1 &&
-			reservedRange.indexStart + reservedRange.indexCount > this._maxIndexCount ||
-			reservedRange.vertexStart + reservedRange.vertexCount > this._maxVertexCount
+			geometryInfo.indexStart !== - 1 &&
+			geometryInfo.indexStart + geometryInfo.reservedIndexCount > this._maxIndexCount ||
+			geometryInfo.vertexStart + geometryInfo.reservedIndexCount > this._maxVertexCount
 		) {
 
 			throw new Error( 'BatchedMesh: Reserved space request exceeds the maximum buffer size.' );
 
 		}
 
-		// add the reserved range and draw range objects
-		const drawRange = {
-			start: hasIndex ? reservedRange.indexStart : reservedRange.vertexStart,
-			count: - 1,
-			active: true,
-		};
-
-		const boundsInfo = {
-			boxInitialized: false,
-			box: new Box3(),
-
-			sphereInitialized: false,
-			sphere: new Sphere()
-		};
-
 		// update id
 		let geometryId;
 		if ( this._availableGeometryIds.length > 0 ) {
@@ -507,18 +479,14 @@ class BatchedMesh extends Mesh {
 			this._availableGeometryIds.sort( ascIdSort );
 
 			geometryId = this._availableGeometryIds.shift();
-			reservedRanges[ geometryId ] = reservedRange;
-			drawRanges[ geometryId ] = drawRange;
-			bounds[ geometryId ] = boundsInfo;
+			geometryInfoList[ geometryId ] = geometryInfo;
 
 
 		} else {
 
 			geometryId = this._geometryCount;
 			this._geometryCount ++;
-			reservedRanges.push( reservedRange );
-			drawRanges.push( drawRange );
-			bounds.push( boundsInfo );
+			geometryInfoList.push( geometryInfo );
 
 		}
 
@@ -526,8 +494,8 @@ class BatchedMesh extends Mesh {
 		this.setGeometryAt( geometryId, geometry );
 
 		// increment the next geometry position
-		this._nextIndexStart = reservedRange.indexStart + reservedRange.indexCount;
-		this._nextVertexStart = reservedRange.vertexStart + reservedRange.vertexCount;
+		this._nextIndexStart = geometryInfo.indexStart + geometryInfo.reservedIndexCount;
+		this._nextVertexStart = geometryInfo.vertexStart + geometryInfo.reservedVertexCount;
 
 		return geometryId;
 
@@ -547,20 +515,22 @@ class BatchedMesh extends Mesh {
 		const hasIndex = batchGeometry.getIndex() !== null;
 		const dstIndex = batchGeometry.getIndex();
 		const srcIndex = geometry.getIndex();
-		const reservedRange = this._reservedRanges[ geometryId ];
+		const geometryInfo = this._geometryInfo[ geometryId ];
 		if (
 			hasIndex &&
-			srcIndex.count > reservedRange.indexCount ||
-			geometry.attributes.position.count > reservedRange.vertexCount
+			srcIndex.count > geometryInfo.reservedIndexCount ||
+			geometry.attributes.position.count > geometryInfo.reservedVertexCount
 		) {
 
 			throw new Error( 'BatchedMesh: Reserved space not large enough for provided geometry.' );
 
 		}
 
-		// copy geometry over
-		const vertexStart = reservedRange.vertexStart;
-		const vertexCount = reservedRange.vertexCount;
+		// copy geometry buffer data over
+		const vertexStart = geometryInfo.vertexStart;
+		const reservedVertexCount = geometryInfo.reservedVertexCount;
+		geometryInfo.vertexCount = geometry.getAttribute( 'position' ).count;
+
 		for ( const attributeName in batchGeometry.attributes ) {
 
 			// copy attribute data
@@ -570,7 +540,7 @@ class BatchedMesh extends Mesh {
 
 			// fill the rest in with zeroes
 			const itemSize = srcAttribute.itemSize;
-			for ( let i = srcAttribute.count, l = vertexCount; i < l; i ++ ) {
+			for ( let i = srcAttribute.count, l = reservedVertexCount; i < l; i ++ ) {
 
 				const index = vertexStart + i;
 				for ( let c = 0; c < itemSize; c ++ ) {
@@ -582,14 +552,16 @@ class BatchedMesh extends Mesh {
 			}
 
 			dstAttribute.needsUpdate = true;
-			dstAttribute.addUpdateRange( vertexStart * itemSize, vertexCount * itemSize );
+			dstAttribute.addUpdateRange( vertexStart * itemSize, reservedVertexCount * itemSize );
 
 		}
 
 		// copy index
 		if ( hasIndex ) {
 
-			const indexStart = reservedRange.indexStart;
+			const indexStart = geometryInfo.indexStart;
+			const reservedIndexCount = geometryInfo.reservedIndexCount;
+			geometryInfo.indexCount = geometry.getIndex().count;
 
 			// copy index data over
 			for ( let i = 0; i < srcIndex.count; i ++ ) {
@@ -599,55 +571,45 @@ class BatchedMesh extends Mesh {
 			}
 
 			// fill the rest in with zeroes
-			for ( let i = srcIndex.count, l = reservedRange.indexCount; i < l; i ++ ) {
+			for ( let i = srcIndex.count, l = reservedIndexCount; i < l; i ++ ) {
 
 				dstIndex.setX( indexStart + i, vertexStart );
 
 			}
 
 			dstIndex.needsUpdate = true;
-			dstIndex.addUpdateRange( indexStart, reservedRange.indexCount );
+			dstIndex.addUpdateRange( indexStart, geometryInfo.reservedIndexCount );
 
 		}
 
+		// update the draw range
+		geometryInfo.start = hasIndex ? geometryInfo.indexStart : geometryInfo.vertexStart;
+		geometryInfo.count = hasIndex ? geometryInfo.indexCount : geometryInfo.vertexCount;
+
 		// store the bounding boxes
-		const bound = this._bounds[ geometryId ];
+		geometryInfo.boundingBox = null;
 		if ( geometry.boundingBox !== null ) {
 
-			bound.box.copy( geometry.boundingBox );
-			bound.boxInitialized = true;
-
-		} else {
-
-			bound.boxInitialized = false;
+			geometryInfo.boundingBox = geometry.boundingBox.clone();
 
 		}
 
+		geometryInfo.boundingSphere = null;
 		if ( geometry.boundingSphere !== null ) {
 
-			bound.sphere.copy( geometry.boundingSphere );
-			bound.sphereInitialized = true;
-
-		} else {
-
-			bound.sphereInitialized = false;
+			geometryInfo.boundingSphere = geometry.boundingSphere.clone();
 
 		}
 
-		// set drawRange count
-		const drawRange = this._drawRanges[ geometryId ];
-		const posAttr = geometry.getAttribute( 'position' );
-		drawRange.count = hasIndex ? srcIndex.count : posAttr.count;
 		this._visibilityChanged = true;
-
 		return geometryId;
 
 	}
 
 	deleteGeometry( geometryId ) {
 
-		const drawRanges = this._drawRanges;
-		if ( geometryId >= drawRanges.length || drawRanges[ geometryId ].active === false ) {
+		const geometryInfoList = this._geometryInfo;
+		if ( geometryId >= geometryInfoList.length || geometryInfoList[ geometryId ].active === false ) {
 
 			return this;
 
@@ -665,7 +627,7 @@ class BatchedMesh extends Mesh {
 
 		}
 
-		drawRanges[ geometryId ].active = false;
+		geometryInfoList[ geometryId ].active = false;
 		this._availableGeometryIds.push( geometryId );
 		this._visibilityChanged = true;
 
@@ -698,24 +660,22 @@ class BatchedMesh extends Mesh {
 
 		// Iterate over all geometry ranges in order sorted from earliest in the geometry buffer to latest
 		// in the geometry buffer. Because draw range objects can be reused there is no guarantee of their order.
-		const drawRanges = this._drawRanges;
-		const reservedRanges = this._reservedRanges;
-		const indices = drawRanges
+		const geometryInfoList = this._geometryInfo;
+		const indices = geometryInfoList
 			.map( ( e, i ) => i )
 			.sort( ( a, b ) => {
 
-				return reservedRanges[ a ].vertexStart - reservedRanges[ b ].vertexStart;
+				return geometryInfoList[ a ].vertexStart - geometryInfoList[ b ].vertexStart;
 
 			} );
 
 		const geometry = this.geometry;
-		for ( let i = 0, l = drawRanges.length; i < l; i ++ ) {
+		for ( let i = 0, l = geometryInfoList.length; i < l; i ++ ) {
 
 			// if a geometry range is inactive then don't copy anything
 			const index = indices[ i ];
-			const drawRange = drawRanges[ index ];
-			const reservedRange = reservedRanges[ index ];
-			if ( drawRange.active === false ) {
+			const geometryInfo = geometryInfoList[ index ];
+			if ( geometryInfo.active === false ) {
 
 				continue;
 
@@ -724,56 +684,55 @@ class BatchedMesh extends Mesh {
 			// if a geometry contains an index buffer then shift it, as well
 			if ( geometry.index !== null ) {
 
-				if ( reservedRange.indexStart !== nextIndexStart ) {
+				if ( geometryInfo.indexStart !== nextIndexStart ) {
 
-					const { indexStart, indexCount } = reservedRange;
+					const { indexStart, vertexStart, reservedIndexCount } = geometryInfo;
 					const index = geometry.index;
 					const array = index.array;
 
 					// shift the index pointers based on how the vertex data will shift
 					// adjusting the index must happen first so the original vertex start value is available
-					const elementDelta = nextVertexStart - reservedRange.vertexStart;
-					for ( let j = indexStart; j < indexStart + indexCount; j ++ ) {
+					const elementDelta = nextVertexStart - vertexStart;
+					for ( let j = indexStart; j < indexStart + reservedIndexCount; j ++ ) {
 
 						array[ j ] = array[ j ] + elementDelta;
 
 					}
 
-					index.array.copyWithin( nextIndexStart, indexStart, indexStart + indexCount );
-					index.addUpdateRange( nextIndexStart, indexCount );
+					index.array.copyWithin( nextIndexStart, indexStart, indexStart + reservedIndexCount );
+					index.addUpdateRange( nextIndexStart, reservedIndexCount );
 
-					reservedRange.indexStart = nextIndexStart;
+					geometryInfo.indexStart = nextIndexStart;
 
 				}
 
-				nextIndexStart += reservedRange.indexCount;
+				nextIndexStart += geometryInfo.reservedIndexCount;
 
 			}
 
 			// if a geometry needs to be moved then copy attribute data to overwrite unused space
-			if ( reservedRange.vertexStart !== nextVertexStart ) {
+			if ( geometryInfo.vertexStart !== nextVertexStart ) {
 
-				const { vertexStart, vertexCount } = reservedRange;
+				const { vertexStart, reservedVertexCount } = geometryInfo;
 				const attributes = geometry.attributes;
 				for ( const key in attributes ) {
 
 					const attribute = attributes[ key ];
 					const { array, itemSize } = attribute;
-					array.copyWithin( nextVertexStart * itemSize, vertexStart * itemSize, ( vertexStart + vertexCount ) * itemSize );
-					attribute.addUpdateRange( nextVertexStart * itemSize, vertexCount * itemSize );
+					array.copyWithin( nextVertexStart * itemSize, vertexStart * itemSize, ( vertexStart + reservedVertexCount ) * itemSize );
+					attribute.addUpdateRange( nextVertexStart * itemSize, reservedVertexCount * itemSize );
 
 				}
 
-				reservedRange.vertexStart = nextVertexStart;
+				geometryInfo.vertexStart = nextVertexStart;
 
 			}
 
-			nextVertexStart += reservedRange.vertexCount;
-			drawRange.start = geometry.index ? reservedRange.indexStart : reservedRange.vertexStart;
+			nextVertexStart += geometryInfo.reservedVertexCount;
 
 			// step the next geometry points to the shifted position
-			this._nextIndexStart = geometry.index ? reservedRange.indexStart + reservedRange.indexCount : 0;
-			this._nextVertexStart = reservedRange.vertexStart + reservedRange.vertexCount;
+			this._nextIndexStart = geometry.index ? geometryInfo.indexStart + geometryInfo.reservedIndexCount : 0;
+			this._nextVertexStart = geometryInfo.vertexStart + geometryInfo.reservedVertexCount;
 
 		}
 
@@ -791,17 +750,14 @@ class BatchedMesh extends Mesh {
 		}
 
 		// compute bounding box
-		const bound = this._bounds[ geometryId ];
-		const box = bound.box;
 		const geometry = this.geometry;
-		if ( bound.boxInitialized === false ) {
-
-			box.makeEmpty();
+		const geometryInfo = this._geometryInfo[ geometryId ];
+		if ( geometryInfo.boundingBox === null ) {
 
+			const box = new Box3();
 			const index = geometry.index;
 			const position = geometry.attributes.position;
-			const drawRange = this._drawRanges[ geometryId ];
-			for ( let i = drawRange.start, l = drawRange.start + drawRange.count; i < l; i ++ ) {
+			for ( let i = geometryInfo.start, l = geometryInfo.start + geometryInfo.count; i < l; i ++ ) {
 
 				let iv = i;
 				if ( index ) {
@@ -814,11 +770,11 @@ class BatchedMesh extends Mesh {
 
 			}
 
-			bound.boxInitialized = true;
+			geometryInfo.boundingBox = box;
 
 		}
 
-		target.copy( box );
+		target.copy( geometryInfo.boundingBox );
 		return target;
 
 	}
@@ -833,22 +789,19 @@ class BatchedMesh extends Mesh {
 		}
 
 		// compute bounding sphere
-		const bound = this._bounds[ geometryId ];
-		const sphere = bound.sphere;
 		const geometry = this.geometry;
-		if ( bound.sphereInitialized === false ) {
-
-			sphere.makeEmpty();
+		const geometryInfo = this._geometryInfo[ geometryId ];
+		if ( geometryInfo.boundingSphere === null ) {
 
+			const sphere = new Sphere();
 			this.getBoundingBoxAt( geometryId, _box );
 			_box.getCenter( sphere.center );
 
 			const index = geometry.index;
 			const position = geometry.attributes.position;
-			const drawRange = this._drawRanges[ geometryId ];
 
 			let maxRadiusSq = 0;
-			for ( let i = drawRange.start, l = drawRange.start + drawRange.count; i < l; i ++ ) {
+			for ( let i = geometryInfo.start, l = geometryInfo.start + geometryInfo.count; i < l; i ++ ) {
 
 				let iv = i;
 				if ( index ) {
@@ -863,11 +816,11 @@ class BatchedMesh extends Mesh {
 			}
 
 			sphere.radius = Math.sqrt( maxRadiusSq );
-			bound.sphereInitialized = true;
+			geometryInfo.boundingSphere = sphere;
 
 		}
 
-		target.copy( sphere );
+		target.copy( geometryInfo.boundingSphere );
 		return target;
 
 	}
@@ -982,6 +935,7 @@ class BatchedMesh extends Mesh {
 
 		// return early if the geometry is out of range or not active
 		const drawInfo = this._drawInfo;
+		const geometryInfoList = this._geometryInfo;
 		if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
 
 			return null;
@@ -989,7 +943,7 @@ class BatchedMesh extends Mesh {
 		}
 
 		// check if the provided geometryId is within the valid range
-		if ( geometryId < 0 || geometryId >= this._geometryCount ) {
+		if ( geometryId >= geometryInfoList.length || geometryInfoList[ geometryId ].active === false ) {
 
 			return null;
 
@@ -1022,10 +976,17 @@ class BatchedMesh extends Mesh {
 
 		}
 
-		const drawRange = this._drawRanges[ geometryId ];
+		const geometryInfo = this._geometryInfo[ geometryId ];
+		target.vertexStart = geometryInfo.vertexStart;
+		target.vertexCount = geometryInfo.vertexCount;
+		target.reservedVertexCount = geometryInfo.reservedVertexCount;
+
+		target.indexStart = geometryInfo.indexStart;
+		target.indexCount = geometryInfo.indexCount;
+		target.reservedIndexCount = geometryInfo.reservedIndexCount;
 
-		target.start = drawRange.start;
-		target.count = drawRange.count;
+		target.start = geometryInfo.start;
+		target.count = geometryInfo.count;
 
 		return target;
 
@@ -1087,8 +1048,8 @@ class BatchedMesh extends Mesh {
 	setGeometrySize( maxVertexCount, maxIndexCount ) {
 
 		// Check if we can shrink to the requested vertex attribute size
-		const validRanges = [ ...this._reservedRanges ].filter( ( range, i ) => this._drawRanges[ i ].active );
-		const requiredVertexLength = Math.max( ...validRanges.map( range => range.vertexStart + range.vertexCount ) );
+		const validRanges = [ ...this._geometryInfo ].filter( info => info.active );
+		const requiredVertexLength = Math.max( ...validRanges.map( range => range.vertexStart + range.reservedVertexCount ) );
 		if ( requiredVertexLength > maxVertexCount ) {
 
 			throw new Error( `BatchedMesh: Geometry vertex values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
@@ -1098,7 +1059,7 @@ class BatchedMesh extends Mesh {
 		// Check if we can shrink to the requested index attribute size
 		if ( this.geometry.index ) {
 
-			const requiredIndexLength = Math.max( ...validRanges.map( range => range.indexStart + range.indexCount ) );
+			const requiredIndexLength = Math.max( ...validRanges.map( range => range.indexStart + range.reservedIndexCount ) );
 			if ( requiredIndexLength > maxIndexCount ) {
 
 				throw new Error( `BatchedMesh: Geometry index values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
@@ -1140,7 +1101,7 @@ class BatchedMesh extends Mesh {
 	raycast( raycaster, intersects ) {
 
 		const drawInfo = this._drawInfo;
-		const drawRanges = this._drawRanges;
+		const geometryInfoList = this._geometryInfo;
 		const matrixWorld = this.matrixWorld;
 		const batchGeometry = this.geometry;
 
@@ -1169,8 +1130,8 @@ class BatchedMesh extends Mesh {
 			}
 
 			const geometryId = drawInfo[ i ].geometryIndex;
-			const drawRange = drawRanges[ geometryId ];
-			_mesh.geometry.setDrawRange( drawRange.start, drawRange.count );
+			const geometryInfo = geometryInfoList[ geometryId ];
+			_mesh.geometry.setDrawRange( geometryInfo.start, geometryInfo.count );
 
 			// get the intersects
 			this.getMatrixAt( i, _mesh.matrixWorld ).premultiply( matrixWorld );
@@ -1209,17 +1170,13 @@ class BatchedMesh extends Mesh {
 		this.boundingBox = source.boundingBox !== null ? source.boundingBox.clone() : null;
 		this.boundingSphere = source.boundingSphere !== null ? source.boundingSphere.clone() : null;
 
-		this._drawRanges = source._drawRanges.map( range => ( { ...range } ) );
-		this._reservedRanges = source._reservedRanges.map( range => ( { ...range } ) );
-
-		this._drawInfo = source._drawInfo.map( inf => ( { ...inf } ) );
-		this._bounds = source._bounds.map( bound => ( {
-			boxInitialized: bound.boxInitialized,
-			box: bound.box.clone(),
+		this._geometryInfo = source._geometryInfo.map( info => ( {
+			...info,
 
-			sphereInitialized: bound.sphereInitialized,
-			sphere: bound.sphere.clone()
+			boundingBox: info.boundingBox !== null ? info.boundingBox.clone() : null,
+			boundingSphere: info.boundingSphere !== null ? info.boundingSphere.clone() : null,
 		} ) );
+		this._drawInfo = source._drawInfo.map( info => ( { ...info } ) );
 
 		this._maxInstanceCount = source._maxInstanceCount;
 		this._maxVertexCount = source._maxVertexCount;
@@ -1284,7 +1241,7 @@ class BatchedMesh extends Mesh {
 		const drawInfo = this._drawInfo;
 		const multiDrawStarts = this._multiDrawStarts;
 		const multiDrawCounts = this._multiDrawCounts;
-		const drawRanges = this._drawRanges;
+		const geometryInfoList = this._geometryInfo;
 		const perObjectFrustumCulled = this.perObjectFrustumCulled;
 		const indirectTexture = this._indirectTexture;
 		const indirectArray = indirectTexture.image.data;
@@ -1331,8 +1288,9 @@ class BatchedMesh extends Mesh {
 					if ( ! culled ) {
 
 						// get the distance from camera used for sorting
+						const geometryInfo = geometryInfoList[ geometryId ];
 						const z = _temp.subVectors( _sphere.center, _vector ).dot( _forward );
-						_renderList.push( drawRanges[ geometryId ], z, i );
+						_renderList.push( geometryInfo.start, geometryInfo.count, z, i );
 
 					}
 
@@ -1386,9 +1344,9 @@ class BatchedMesh extends Mesh {
 
 					if ( ! culled ) {
 
-						const range = drawRanges[ geometryId ];
-						multiDrawStarts[ count ] = range.start * bytesPerElement;
-						multiDrawCounts[ count ] = range.count;
+						const geometryInfo = geometryInfoList[ geometryId ];
+						multiDrawStarts[ count ] = geometryInfo.start * bytesPerElement;
+						multiDrawCounts[ count ] = geometryInfo.count;
 						indirectArray[ count ] = i;
 						count ++;
 

粤ICP备19079148号