|
@@ -165,9 +165,6 @@ class BatchedMesh extends Mesh {
|
|
|
|
|
|
}
|
|
|
|
|
|
- // for debug
|
|
|
- // console.log( parameters.vertexShader, parameters.uniforms );
|
|
|
-
|
|
|
currentOnBeforeCompile.call( this, parameters, renderer );
|
|
|
|
|
|
};
|
|
@@ -177,66 +174,46 @@ class BatchedMesh extends Mesh {
|
|
|
|
|
|
}
|
|
|
|
|
|
- getGeometryCount() {
|
|
|
-
|
|
|
- return this._geometryCount;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getVertexCount() {
|
|
|
-
|
|
|
- return this._vertexCount;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getIndexCount() {
|
|
|
-
|
|
|
- return this._indexCount;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- applyGeometry( geometry ) {
|
|
|
+ _initializeGeometry( reference ) {
|
|
|
|
|
|
// @TODO: geometry.groups support?
|
|
|
// @TODO: geometry.drawRange support?
|
|
|
// @TODO: geometry.morphAttributes support?
|
|
|
|
|
|
- if ( this._geometryCount >= this._maxGeometryCount ) {
|
|
|
-
|
|
|
- // @TODO: Error handling
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
+ const geometry = this.geometry;
|
|
|
+ const maxVertexCount = this._maxVertexCount;
|
|
|
+ const maxGeometryCount = this._maxGeometryCount;
|
|
|
+ const maxIndexCount = this._maxIndexCount;
|
|
|
if ( this._geometryInitialized === false ) {
|
|
|
|
|
|
- for ( const attributeName in geometry.attributes ) {
|
|
|
+ for ( const attributeName in reference.attributes ) {
|
|
|
|
|
|
- const srcAttribute = geometry.getAttribute( attributeName );
|
|
|
+ const srcAttribute = reference.getAttribute( attributeName );
|
|
|
const { array, itemSize, normalized } = srcAttribute;
|
|
|
|
|
|
- const dstArray = new array.constructor( this._maxVertexCount * itemSize );
|
|
|
+ const dstArray = new array.constructor( maxVertexCount * itemSize );
|
|
|
const dstAttribute = new srcAttribute.constructor( dstArray, itemSize, normalized );
|
|
|
dstAttribute.setUsage( srcAttribute.usage );
|
|
|
|
|
|
- this.geometry.setAttribute( attributeName, dstAttribute );
|
|
|
+ geometry.setAttribute( attributeName, dstAttribute );
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( geometry.getIndex() !== null ) {
|
|
|
+ if ( reference.getIndex() !== null ) {
|
|
|
|
|
|
- const indexArray = this._maxVertexCount > 65536
|
|
|
- ? new Uint32Array( this._maxIndexCount )
|
|
|
- : new Uint16Array( this._maxIndexCount );
|
|
|
+ const indexArray = maxVertexCount > 65536
|
|
|
+ ? new Uint32Array( maxIndexCount )
|
|
|
+ : new Uint16Array( maxIndexCount );
|
|
|
|
|
|
- this.geometry.setIndex( new BufferAttribute( indexArray, 1 ) );
|
|
|
+ geometry.setIndex( new BufferAttribute( indexArray, 1 ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- const idArray = this._maxGeometryCount > 65536
|
|
|
- ? new Uint32Array( this._maxVertexCount )
|
|
|
- : new Uint16Array( this._maxVertexCount );
|
|
|
+ const idArray = maxGeometryCount > 65536
|
|
|
+ ? new Uint32Array( maxVertexCount )
|
|
|
+ : new Uint16Array( maxVertexCount );
|
|
|
// @TODO: What if attribute name 'id' is already used?
|
|
|
- this.geometry.setAttribute( 'id', new BufferAttribute( idArray, 1 ) );
|
|
|
+ geometry.setAttribute( 'id', new BufferAttribute( idArray, 1 ) );
|
|
|
|
|
|
this._geometryInitialized = true;
|
|
|
|
|
@@ -246,43 +223,84 @@ class BatchedMesh extends Mesh {
|
|
|
|
|
|
}
|
|
|
|
|
|
- const hasIndex = this.geometry.getIndex() !== null;
|
|
|
- const dstIndex = this.geometry.getIndex();
|
|
|
- const srcIndex = geometry.getIndex();
|
|
|
+ }
|
|
|
|
|
|
- // Assuming geometry has position attribute
|
|
|
- const srcPositionAttribute = geometry.getAttribute( 'position' );
|
|
|
+ getGeometryCount() {
|
|
|
|
|
|
- this._vertexStarts.push( this._vertexCount );
|
|
|
- this._vertexCounts.push( srcPositionAttribute.count );
|
|
|
+ return this._geometryCount;
|
|
|
|
|
|
- if ( hasIndex ) {
|
|
|
+ }
|
|
|
|
|
|
- this._indexStarts.push( this._indexCount );
|
|
|
- this._indexCounts.push( srcIndex.count );
|
|
|
+ getVertexCount() {
|
|
|
|
|
|
- }
|
|
|
+ return this._vertexCount;
|
|
|
|
|
|
- this._visibles.push( true );
|
|
|
- this._alives.push( true );
|
|
|
+ }
|
|
|
+
|
|
|
+ getIndexCount() {
|
|
|
+
|
|
|
+ return this._indexCount;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ applyGeometry( geometry ) {
|
|
|
+
|
|
|
+ this._initializeGeometry( geometry );
|
|
|
|
|
|
// @TODO: Error handling if exceeding maxVertexCount or maxIndexCount
|
|
|
+ if ( this._geometryCount >= this._maxGeometryCount ) {
|
|
|
|
|
|
+ // @TODO: Error handling
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const batchGeometry = this.geometry;
|
|
|
+ const visibles = this._visibles;
|
|
|
+ const alives = this._alives;
|
|
|
+ const matricesTexture = this._matricesTexture;
|
|
|
+ const matrices = this._matrices;
|
|
|
+ const matricesArray = this._matricesArray;
|
|
|
+ const vertexCount = this._vertexCount;
|
|
|
+ const indexCount = this._indexCount;
|
|
|
+
|
|
|
+ const indexCounts = this._indexCounts;
|
|
|
+ const indexStarts = this._indexStarts;
|
|
|
+ const vertexCounts = this._vertexCounts;
|
|
|
+ const vertexStarts = this._vertexStarts;
|
|
|
+
|
|
|
+ const hasIndex = batchGeometry.getIndex() !== null;
|
|
|
+ const dstIndex = batchGeometry.getIndex();
|
|
|
+ const srcIndex = geometry.getIndex();
|
|
|
+
|
|
|
+ // Assuming geometry has position attribute
|
|
|
+ const srcPositionAttribute = geometry.getAttribute( 'position' );
|
|
|
+
|
|
|
+ // push new geometry data range
|
|
|
+ vertexStarts.push( vertexCount );
|
|
|
+ vertexCounts.push( srcPositionAttribute.count );
|
|
|
+
|
|
|
+ // copy attribute data over
|
|
|
+ // @TODO: Handle case where geometry does not have common attributes
|
|
|
for ( const attributeName in geometry.attributes ) {
|
|
|
|
|
|
const srcAttribute = geometry.getAttribute( attributeName );
|
|
|
- const dstAttribute = this.geometry.getAttribute( attributeName );
|
|
|
+ const dstAttribute = batchGeometry.getAttribute( attributeName );
|
|
|
|
|
|
- dstAttribute.array.set( srcAttribute.array, this._vertexCount * dstAttribute.itemSize );
|
|
|
+ dstAttribute.array.set( srcAttribute.array, vertexCount * dstAttribute.itemSize );
|
|
|
dstAttribute.needsUpdate = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ( hasIndex ) {
|
|
|
|
|
|
+ // push new index range
|
|
|
+ indexStarts.push( indexCount );
|
|
|
+ indexCounts.push( srcIndex.count );
|
|
|
+
|
|
|
+ // copy index data over
|
|
|
for ( let i = 0; i < srcIndex.count; i ++ ) {
|
|
|
|
|
|
- dstIndex.setX( this._indexCount + i, this._vertexCount + srcIndex.getX( i ) );
|
|
|
+ dstIndex.setX( indexCount + i, vertexCount + srcIndex.getX( i ) );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -291,11 +309,11 @@ class BatchedMesh extends Mesh {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ // fill in the geometry ids
|
|
|
const geometryId = this._geometryCount;
|
|
|
this._geometryCount ++;
|
|
|
|
|
|
- const idAttribute = this.geometry.getAttribute( 'id' );
|
|
|
-
|
|
|
+ const idAttribute = batchGeometry.getAttribute( 'id' );
|
|
|
for ( let i = 0; i < srcPositionAttribute.count; i ++ ) {
|
|
|
|
|
|
idAttribute.setX( this._vertexCount + i, geometryId );
|
|
@@ -304,11 +322,17 @@ class BatchedMesh extends Mesh {
|
|
|
|
|
|
idAttribute.needsUpdate = true;
|
|
|
|
|
|
+ // extend new range
|
|
|
this._vertexCount += srcPositionAttribute.count;
|
|
|
|
|
|
- this._matrices.push( new Matrix4() );
|
|
|
- _identityMatrix.toArray( this._matricesArray, geometryId * 16 );
|
|
|
- this._matricesTexture.needsUpdate = true;
|
|
|
+ // push new visibility states
|
|
|
+ visibles.push( true );
|
|
|
+ alives.push( true );
|
|
|
+
|
|
|
+ // initialize matrix information
|
|
|
+ matrices.push( new Matrix4() );
|
|
|
+ _identityMatrix.toArray( matricesArray, geometryId * 16 );
|
|
|
+ matricesTexture.needsUpdate = true;
|
|
|
|
|
|
return geometryId;
|
|
|
|
|
@@ -316,17 +340,20 @@ class BatchedMesh extends Mesh {
|
|
|
|
|
|
deleteGeometry( geometryId ) {
|
|
|
|
|
|
- if ( geometryId >= this._alives.length || this._alives[ geometryId ] === false ) {
|
|
|
+ // Note: User needs to call optimize() afterward to pack the data.
|
|
|
+
|
|
|
+ const alives = this._alives;
|
|
|
+ const matricesArray = this._matricesArray;
|
|
|
+ const matricesTexture = this._matricesTexture;
|
|
|
+ if ( geometryId >= alives.length || alives[ geometryId ] === false ) {
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
- this._alives[ geometryId ] = false;
|
|
|
- _zeroScaleMatrix.toArray( this._matricesArray, geometryId * 16 );
|
|
|
- this._matricesTexture.needsUpdate = true;
|
|
|
-
|
|
|
- // User needs to call optimize() to pack the data.
|
|
|
+ alives[ geometryId ] = false;
|
|
|
+ _zeroScaleMatrix.toArray( matricesArray, geometryId * 16 );
|
|
|
+ matricesTexture.needsUpdate = true;
|
|
|
|
|
|
return this;
|
|
|
|