Browse Source

Remove need for non indexed geometry from MeshSurfaceSampler (#26268)

Garrett Johnson 2 years ago
parent
commit
4ef4914cd8
1 changed files with 55 additions and 38 deletions
  1. 55 38
      examples/jsm/math/MeshSurfaceSampler.js

+ 55 - 38
examples/jsm/math/MeshSurfaceSampler.js

@@ -23,19 +23,10 @@ class MeshSurfaceSampler {
 
 	constructor( mesh ) {
 
-		let geometry = mesh.geometry;
-
-		if ( geometry.index ) {
-
-			console.warn( 'THREE.MeshSurfaceSampler: Converting geometry to non-indexed BufferGeometry.' );
-
-			geometry = geometry.toNonIndexed();
-
-		}
-
-		this.geometry = geometry;
+		this.geometry = mesh.geometry;
 		this.randomFunction = Math.random;
 
+		this.indexAttribute = this.geometry.index;
 		this.positionAttribute = this.geometry.getAttribute( 'position' );
 		this.normalAttribute = this.geometry.getAttribute( 'normal' );
 		this.colorAttribute = this.geometry.getAttribute( 'color' );
@@ -56,49 +47,62 @@ class MeshSurfaceSampler {
 
 	build() {
 
+		const indexAttribute = this.indexAttribute;
 		const positionAttribute = this.positionAttribute;
 		const weightAttribute = this.weightAttribute;
 
-		const faceWeights = new Float32Array( positionAttribute.count / 3 );
+		const totalFaces = indexAttribute ? ( indexAttribute.count / 3 ) : ( positionAttribute.count / 3 );
+		const faceWeights = new Float32Array( totalFaces );
 
 		// Accumulate weights for each mesh face.
 
-		for ( let i = 0; i < positionAttribute.count; i += 3 ) {
+		for ( let i = 0; i < totalFaces; i ++ ) {
 
 			let faceWeight = 1;
 
+			let i0 = 3 * i;
+			let i1 = 3 * i + 1;
+			let i2 = 3 * i + 2;
+
+			if ( indexAttribute ) {
+
+				i0 = indexAttribute.getX( i0 );
+				i1 = indexAttribute.getX( i1 );
+				i2 = indexAttribute.getX( i2 );
+
+			}
+
 			if ( weightAttribute ) {
 
-				faceWeight = weightAttribute.getX( i )
-					+ weightAttribute.getX( i + 1 )
-					+ weightAttribute.getX( i + 2 );
+				faceWeight = weightAttribute.getX( i0 )
+					+ weightAttribute.getX( i1 )
+					+ weightAttribute.getX( i2 );
 
 			}
 
-			_face.a.fromBufferAttribute( positionAttribute, i );
-			_face.b.fromBufferAttribute( positionAttribute, i + 1 );
-			_face.c.fromBufferAttribute( positionAttribute, i + 2 );
+			_face.a.fromBufferAttribute( positionAttribute, i0 );
+			_face.b.fromBufferAttribute( positionAttribute, i1 );
+			_face.c.fromBufferAttribute( positionAttribute, i2 );
 			faceWeight *= _face.getArea();
 
-			faceWeights[ i / 3 ] = faceWeight;
+			faceWeights[ i ] = faceWeight;
 
 		}
 
 		// Store cumulative total face weights in an array, where weight index
 		// corresponds to face index.
 
-		this.distribution = new Float32Array( positionAttribute.count / 3 );
-
+		const distribution = new Float32Array( totalFaces );
 		let cumulativeTotal = 0;
 
-		for ( let i = 0; i < faceWeights.length; i ++ ) {
+		for ( let i = 0; i < totalFaces; i ++ ) {
 
 			cumulativeTotal += faceWeights[ i ];
-
-			this.distribution[ i ] = cumulativeTotal;
+			distribution[ i ] = cumulativeTotal;
 
 		}
 
+		this.distribution = distribution;
 		return this;
 
 	}
@@ -170,9 +174,22 @@ class MeshSurfaceSampler {
 
 		}
 
-		_face.a.fromBufferAttribute( this.positionAttribute, faceIndex * 3 );
-		_face.b.fromBufferAttribute( this.positionAttribute, faceIndex * 3 + 1 );
-		_face.c.fromBufferAttribute( this.positionAttribute, faceIndex * 3 + 2 );
+		// get the vertex attribute indices
+		const indexAttribute = this.indexAttribute;
+		let i0 = faceIndex * 3;
+		let i1 = faceIndex * 3 + 1;
+		let i2 = faceIndex * 3 + 2;
+		if ( indexAttribute ) {
+
+			i0 = indexAttribute.getX( i0 );
+			i1 = indexAttribute.getX( i1 );
+			i2 = indexAttribute.getX( i2 );
+
+		}
+
+		_face.a.fromBufferAttribute( this.positionAttribute, i0 );
+		_face.b.fromBufferAttribute( this.positionAttribute, i1 );
+		_face.c.fromBufferAttribute( this.positionAttribute, i2 );
 
 		targetPosition
 			.set( 0, 0, 0 )
@@ -184,24 +201,24 @@ class MeshSurfaceSampler {
 
 			if ( this.normalAttribute !== undefined ) {
 
-				_face.a.fromBufferAttribute( this.normalAttribute, faceIndex * 3 );
-				_face.b.fromBufferAttribute( this.normalAttribute, faceIndex * 3 + 1 );
-				_face.c.fromBufferAttribute( this.normalAttribute, faceIndex * 3 + 2 );
+				_face.a.fromBufferAttribute( this.normalAttribute, i0 );
+				_face.b.fromBufferAttribute( this.normalAttribute, i1 );
+				_face.c.fromBufferAttribute( this.normalAttribute, i2 );
 				targetNormal.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) ).normalize();
 
 			} else {
 
 				_face.getNormal( targetNormal );
-				
+
 			}
 
 		}
 
 		if ( targetColor !== undefined && this.colorAttribute !== undefined ) {
 
-			_face.a.fromBufferAttribute( this.colorAttribute, faceIndex * 3 );
-			_face.b.fromBufferAttribute( this.colorAttribute, faceIndex * 3 + 1 );
-			_face.c.fromBufferAttribute( this.colorAttribute, faceIndex * 3 + 2 );
+			_face.a.fromBufferAttribute( this.colorAttribute, i0 );
+			_face.b.fromBufferAttribute( this.colorAttribute, i1 );
+			_face.c.fromBufferAttribute( this.colorAttribute, i2 );
 
 			_color
 				.set( 0, 0, 0 )
@@ -217,9 +234,9 @@ class MeshSurfaceSampler {
 
 		if ( targetUV !== undefined && this.uvAttribute !== undefined ) {
 
-			_uva.fromBufferAttribute( this.uvAttribute, faceIndex * 3 );
-			_uvb.fromBufferAttribute( this.uvAttribute, faceIndex * 3 + 1 );
-			_uvc.fromBufferAttribute( this.uvAttribute, faceIndex * 3 + 2 );
+			_uva.fromBufferAttribute( this.uvAttribute, i0 );
+			_uvb.fromBufferAttribute( this.uvAttribute, i1 );
+			_uvc.fromBufferAttribute( this.uvAttribute, i2 );
 			targetUV.set( 0, 0 ).addScaledVector( _uva, u ).addScaledVector( _uvb, v ).addScaledVector( _uvc, 1 - ( u + v ) );
 
 		}