Przeglądaj źródła

BatchedMesh: add `deleteInstance()` (#29449)

* BatchedMesh: add `deleteInstance()`

* BatchedMesh: prioritize reusing freed instance ids when adding instance
Jordan Lane 1 rok temu
rodzic
commit
44cb404c69
2 zmienionych plików z 32 dodań i 10 usunięć
  1. 9 0
      docs/api/en/objects/BatchedMesh.html
  2. 23 10
      src/objects/BatchedMesh.js

+ 9 - 0
docs/api/en/objects/BatchedMesh.html

@@ -258,6 +258,15 @@
 			Adds a new instance to the [name] using the geometry of the given geometryId and returns a new id referring to the new instance to be used
 			Adds a new instance to the [name] using the geometry of the given geometryId and returns a new id referring to the new instance to be used
 			by other functions.
 			by other functions.
 		</p>
 		</p>
+		<h3>
+			[method:Integer deleteInstance]( [param:Integer instanceId] )
+		</h3>
+		<p>
+			[page:Integer instanceId]: The id of an instance to remove from the [name] that was previously added via "addInstance".
+		</p>
+		<p>
+			Removes an existing instance from the [name] using the given instanceId.
+		</p>
 
 
 		<h3>
 		<h3>
 			[method:Integer setGeometryAt]( [param:Integer geometryId], [param:BufferGeometry geometry] )
 			[method:Integer setGeometryAt]( [param:Integer geometryId], [param:BufferGeometry geometry] )

+ 23 - 10
src/objects/BatchedMesh.js

@@ -145,6 +145,9 @@ class BatchedMesh extends Mesh {
 		// stores visible, active, and geometry id per object
 		// stores visible, active, and geometry id per object
 		this._drawInfo = [];
 		this._drawInfo = [];
 
 
+		// instance ids that have been set as inactive, and are available to be overwritten
+		this._availableInstanceIds = [];
+
 		// geometry information
 		// geometry information
 		this._drawRanges = [];
 		this._drawRanges = [];
 		this._reservedRanges = [];
 		this._reservedRanges = [];
@@ -344,23 +347,36 @@ class BatchedMesh extends Mesh {
 
 
 	addInstance( geometryId ) {
 	addInstance( geometryId ) {
 
 
+		const atCapacity = this._drawInfo.length >= this.maxInstanceCount;
+
 		// ensure we're not over geometry
 		// ensure we're not over geometry
-		if ( this._drawInfo.length >= this._maxInstanceCount ) {
+		if ( atCapacity && this._availableInstanceIds.length === 0 ) {
 
 
 			throw new Error( 'BatchedMesh: Maximum item count reached.' );
 			throw new Error( 'BatchedMesh: Maximum item count reached.' );
 
 
 		}
 		}
 
 
-		this._drawInfo.push( {
-
+		const instanceDrawInfo = {
 			visible: true,
 			visible: true,
 			active: true,
 			active: true,
 			geometryIndex: geometryId,
 			geometryIndex: geometryId,
+		};
 
 
-		} );
+		let drawId = null;
+
+		// Prioritize using previously freed instance ids
+		if ( this._availableInstanceIds.length > 0 ) {
+
+			drawId = this._availableInstanceIds.pop();
+			this._drawInfo[ drawId ] = instanceDrawInfo;
+
+		} else {
+
+			drawId = this._drawInfo.length;
+			this._drawInfo.push( instanceDrawInfo );
+
+		}
 
 
-		// initialize the matrix
-		const drawId = this._drawInfo.length - 1;
 		const matricesTexture = this._matricesTexture;
 		const matricesTexture = this._matricesTexture;
 		const matricesArray = matricesTexture.image.data;
 		const matricesArray = matricesTexture.image.data;
 		_identityMatrix.toArray( matricesArray, drawId * 16 );
 		_identityMatrix.toArray( matricesArray, drawId * 16 );
@@ -609,11 +625,8 @@ class BatchedMesh extends Mesh {
 	}
 	}
 	*/
 	*/
 
 
-	/*
 	deleteInstance( instanceId ) {
 	deleteInstance( instanceId ) {
 
 
-		// Note: User needs to call optimize() afterward to pack the data.
-
 		const drawInfo = this._drawInfo;
 		const drawInfo = this._drawInfo;
 		if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
 		if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
 
 
@@ -622,12 +635,12 @@ class BatchedMesh extends Mesh {
 		}
 		}
 
 
 		drawInfo[ instanceId ].active = false;
 		drawInfo[ instanceId ].active = false;
+		this._availableInstanceIds.push( instanceId );
 		this._visibilityChanged = true;
 		this._visibilityChanged = true;
 
 
 		return this;
 		return this;
 
 
 	}
 	}
-	*/
 
 
 	// get bounding box and compute it if it doesn't exist
 	// get bounding box and compute it if it doesn't exist
 	getBoundingBoxAt( geometryId, target ) {
 	getBoundingBoxAt( geometryId, target ) {

粤ICP备19079148号