|
@@ -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 ) );
|
|
|
|
|
|
}
|