Ver código fonte

BatchedMesh: Add thrown errors (#27060)

* 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

* Remove PURE annotations
Garrett Johnson 1 ano atrás
pai
commit
23379064eb

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

@@ -19,7 +19,7 @@ const _zeroScaleMatrix = new Matrix4().set(
 );
 
 // Custom shaders
-const batchingParsVertex = `
+const batchingParsVertex = /* glsl */`
 #ifdef BATCHING
 	attribute float ${ ID_ATTR_NAME };
 	uniform highp sampler2D batchingTexture;
@@ -40,13 +40,13 @@ const batchingParsVertex = `
 #endif
 `;
 
-const batchingbaseVertex = `
+const batchingbaseVertex = /* glsl */`
 #ifdef BATCHING
 	mat4 batchingMatrix = getBatchingMatrix( ${ ID_ATTR_NAME } );
 #endif
 `;
 
-const batchingnormalVertex = `
+const batchingnormalVertex = /* glsl */`
 #ifdef BATCHING
 	objectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;
 	#ifdef USE_TANGENT
@@ -55,7 +55,7 @@ const batchingnormalVertex = `
 #endif
 `;
 
-const batchingVertex = `
+const batchingVertex = /* glsl */`
 #ifdef BATCHING
 	transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
 #endif
@@ -91,7 +91,6 @@ class BatchedMesh extends Mesh {
 		// @TODO: Support uniform parameter per geometry
 
 		this._matrices = [];
-		this._matricesArray = null;
 		this._matricesTexture = null;
 
 		// @TODO: Calculate the entire binding box and make frustumCulled true
@@ -123,9 +122,7 @@ class BatchedMesh extends Mesh {
 		const matricesArray = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
 		const matricesTexture = new DataTexture( matricesArray, size, size, RGBAFormat, FloatType );
 
-		this._matricesArray = matricesArray;
 		this._matricesTexture = matricesTexture;
-
 		this._customUniforms.batchingTexture.value = this._matricesTexture;
 		this._customUniforms.batchingTextureSize.value = size;
 
@@ -215,10 +212,6 @@ class BatchedMesh extends Mesh {
 
 			this._geometryInitialized = true;
 
-		} else {
-
-			// @TODO: Check if geometry has the same attributes set
-
 		}
 
 	}
@@ -245,21 +238,75 @@ class BatchedMesh extends Mesh {
 
 		this._initializeGeometry( geometry );
 
-		// @TODO: Error handling if exceeding maxVertexCount or maxIndexCount
+		// ensure we're not over geometry
 		if ( this._geometryCount >= this._maxGeometryCount ) {
 
-			// @TODO: Error handling
+			throw new Error( 'BatchedMesh: Maximum geometry count reached.' );
+
+		}
+
+		// check that the geometry doesn't have a version of our reserved id attribute
+		if ( geometry.getAttribute( ID_ATTR_NAME ) ) {
+
+			throw new Error( `BatchedMesh: Geometry cannot use attribute "${ ID_ATTR_NAME }"` );
 
 		}
 
+		// check to ensure the geometries are using consistent attributes and indices
 		const batchGeometry = this.geometry;
+		if ( Boolean( geometry.getIndex() ) !== Boolean( batchGeometry.getIndex() ) ) {
+
+			throw new Error( 'BatchedMesh: All geometries must consistently have "index".' );
+
+		}
+
+		for ( const attributeName in batchGeometry.attributes ) {
+
+			if ( attributeName === ID_ATTR_NAME ) {
+
+				continue;
+
+			}
+
+			if ( ! geometry.hasAttribute( attributeName ) ) {
+
+				throw new Error( `BatchedMesh: Added geometry missing "${ attributeName }". All geometries must have consistent attributes.` );
+
+			}
+
+			const srcAttribute = geometry.getAttribute( attributeName );
+			const dstAttribute = batchGeometry.getAttribute( attributeName );
+			if ( srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized ) {
+
+				throw new Error( 'BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );
+
+			}
+
+		}
+
+		// Assuming geometry has position attribute
+		const srcPositionAttribute = geometry.getAttribute( 'position' );
+		const vertexCount = this._vertexCount;
+		const indexCount = this._indexCount;
+		const maxVertexCount = this._maxVertexCount;
+		const maxIndexCount = this._maxIndexCount;
+
+		// check if we're going over our maximum buffer capacity
+		if (
+			geometry.getIndex() !== null &&
+			indexCount + geometry.getIndex().count > maxIndexCount ||
+			vertexCount + srcPositionAttribute.count > maxVertexCount
+		) {
+
+			throw new Error( 'BatchedMesh: Added geometry is larger than available buffer capacity.' );
+
+		}
+
 		const visible = this._visible;
 		const active = this._active;
 		const matricesTexture = this._matricesTexture;
 		const matrices = this._matrices;
 		const matricesArray = this._matricesTexture.image.data;
-		const vertexCount = this._vertexCount;
-		const indexCount = this._indexCount;
 
 		const indexCounts = this._indexCounts;
 		const indexStarts = this._indexStarts;
@@ -270,16 +317,18 @@ class BatchedMesh extends Mesh {
 		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 ) {
+		for ( const attributeName in batchGeometry.attributes ) {
+
+			if ( attributeName === ID_ATTR_NAME ) {
+
+				continue;
+
+			}
 
 			const srcAttribute = geometry.getAttribute( attributeName );
 			const dstAttribute = batchGeometry.getAttribute( attributeName );
@@ -359,9 +408,7 @@ class BatchedMesh extends Mesh {
 
 	optimize() {
 
-		// @TODO: Implement
-
-		return this;
+		throw new Error( 'BatchedMesh: Optimize function not implemented.' );
 
 	}
 
@@ -461,21 +508,23 @@ class BatchedMesh extends Mesh {
 
 	}
 
-	copy( source ) {
+	raycast() {
 
-		super.copy( source );
+		console.warn( 'BatchedMesh: Raycast function not implemented.' );
 
-		// @TODO: Implement
+	}
 
-		return this;
+	copy() {
 
-	}
+		// super.copy( source );
+
+		throw new Error( 'BatchedMesh: Copy function not implemented.' );
 
-	toJSON( meta ) {
+	}
 
-		// @TODO: Implement
+	toJSON() {
 
-		return super.toJSON( meta );
+		throw new Error( 'BatchedMesh: toJSON function not implemented.' );
 
 	}
 

BIN
examples/screenshots/webgl_mesh_batch.jpg


+ 1 - 1
examples/webgl_mesh_batch.html

@@ -104,7 +104,7 @@
 			geometries = [
 				new THREE.ConeGeometry( 1.0, 2.0 ),
 				new THREE.BoxGeometry( 2.0, 2.0, 2.0 ),
-				new THREE.SphereGeometry( 1.0 ),
+				new THREE.SphereGeometry( 1.0, 16, 8 ),
 			];
 
 		}