| |
| |
| |
| |
|
|
| THREE.GeometryUtils = { |
|
|
| |
|
|
| merge: function ( geometry1, geometry2, materialIndexOffset ) { |
|
|
| console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); |
|
|
| var matrix; |
|
|
| if ( geometry2 instanceof THREE.Mesh ) { |
|
|
| geometry2.matrixAutoUpdate && geometry2.updateMatrix(); |
|
|
| matrix = geometry2.matrix; |
| geometry2 = geometry2.geometry; |
|
|
| } |
|
|
| geometry1.merge( geometry2, matrix, materialIndexOffset ); |
|
|
| }, |
|
|
| |
| |
| |
|
|
| randomPointInTriangle: function () { |
|
|
| var vector = new THREE.Vector3(); |
|
|
| return function ( vectorA, vectorB, vectorC ) { |
|
|
| var point = new THREE.Vector3(); |
|
|
| var a = Math.random(); |
| var b = Math.random(); |
|
|
| if ( ( a + b ) > 1 ) { |
|
|
| a = 1 - a; |
| b = 1 - b; |
|
|
| } |
|
|
| var c = 1 - a - b; |
|
|
| point.copy( vectorA ); |
| point.multiplyScalar( a ); |
|
|
| vector.copy( vectorB ); |
| vector.multiplyScalar( b ); |
|
|
| point.add( vector ); |
|
|
| vector.copy( vectorC ); |
| vector.multiplyScalar( c ); |
|
|
| point.add( vector ); |
|
|
| return point; |
|
|
| }; |
|
|
| }(), |
|
|
| |
| |
|
|
| randomPointInFace: function ( face, geometry ) { |
|
|
| var vA, vB, vC; |
|
|
| vA = geometry.vertices[ face.a ]; |
| vB = geometry.vertices[ face.b ]; |
| vC = geometry.vertices[ face.c ]; |
|
|
| return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC ); |
|
|
| }, |
|
|
| |
| |
| |
| |
| |
|
|
| randomPointsInGeometry: function ( geometry, n ) { |
|
|
| var face, i, |
| faces = geometry.faces, |
| vertices = geometry.vertices, |
| il = faces.length, |
| totalArea = 0, |
| cumulativeAreas = [], |
| vA, vB, vC; |
|
|
| |
|
|
| for ( i = 0; i < il; i ++ ) { |
|
|
| face = faces[ i ]; |
|
|
| vA = vertices[ face.a ]; |
| vB = vertices[ face.b ]; |
| vC = vertices[ face.c ]; |
|
|
| face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC ); |
|
|
| totalArea += face._area; |
|
|
| cumulativeAreas[ i ] = totalArea; |
|
|
| } |
|
|
| |
|
|
| function binarySearchIndices( value ) { |
|
|
| function binarySearch( start, end ) { |
|
|
| |
| |
|
|
| if ( end < start ) |
| return start; |
|
|
| var mid = start + Math.floor( ( end - start ) / 2 ); |
|
|
| if ( cumulativeAreas[ mid ] > value ) { |
|
|
| return binarySearch( start, mid - 1 ); |
|
|
| } else if ( cumulativeAreas[ mid ] < value ) { |
|
|
| return binarySearch( mid + 1, end ); |
|
|
| } else { |
|
|
| return mid; |
|
|
| } |
|
|
| } |
|
|
| var result = binarySearch( 0, cumulativeAreas.length - 1 ); |
| return result; |
|
|
| } |
|
|
| |
|
|
| var r, index, |
| result = []; |
|
|
| var stats = {}; |
|
|
| for ( i = 0; i < n; i ++ ) { |
|
|
| r = Math.random() * totalArea; |
|
|
| index = binarySearchIndices( r ); |
|
|
| result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry ); |
|
|
| if ( ! stats[ index ] ) { |
|
|
| stats[ index ] = 1; |
|
|
| } else { |
|
|
| stats[ index ] += 1; |
|
|
| } |
|
|
| } |
|
|
| return result; |
|
|
| }, |
|
|
| randomPointsInBufferGeometry: function ( geometry, n ) { |
|
|
| var i, |
| vertices = geometry.attributes.position.array, |
| totalArea = 0, |
| cumulativeAreas = [], |
| vA, vB, vC; |
|
|
| |
| vA = new THREE.Vector3(); |
| vB = new THREE.Vector3(); |
| vC = new THREE.Vector3(); |
|
|
| |
| var il = vertices.length / 9; |
|
|
| for ( i = 0; i < il; i ++ ) { |
|
|
| vA.set( vertices[ i * 9 + 0 ], vertices[ i * 9 + 1 ], vertices[ i * 9 + 2 ] ); |
| vB.set( vertices[ i * 9 + 3 ], vertices[ i * 9 + 4 ], vertices[ i * 9 + 5 ] ); |
| vC.set( vertices[ i * 9 + 6 ], vertices[ i * 9 + 7 ], vertices[ i * 9 + 8 ] ); |
|
|
| totalArea += THREE.GeometryUtils.triangleArea( vA, vB, vC ); |
|
|
| cumulativeAreas.push( totalArea ); |
|
|
| } |
|
|
| |
|
|
| function binarySearchIndices( value ) { |
|
|
| function binarySearch( start, end ) { |
|
|
| |
| |
|
|
| if ( end < start ) |
| return start; |
|
|
| var mid = start + Math.floor( ( end - start ) / 2 ); |
|
|
| if ( cumulativeAreas[ mid ] > value ) { |
|
|
| return binarySearch( start, mid - 1 ); |
|
|
| } else if ( cumulativeAreas[ mid ] < value ) { |
|
|
| return binarySearch( mid + 1, end ); |
|
|
| } else { |
|
|
| return mid; |
|
|
| } |
|
|
| } |
|
|
| var result = binarySearch( 0, cumulativeAreas.length - 1 ); |
| return result; |
|
|
| } |
|
|
| |
|
|
| var r, index, |
| result = []; |
|
|
| for ( i = 0; i < n; i ++ ) { |
|
|
| r = Math.random() * totalArea; |
|
|
| index = binarySearchIndices( r ); |
|
|
| |
| vA.set( vertices[ index * 9 + 0 ], vertices[ index * 9 + 1 ], vertices[ index * 9 + 2 ] ); |
| vB.set( vertices[ index * 9 + 3 ], vertices[ index * 9 + 4 ], vertices[ index * 9 + 5 ] ); |
| vC.set( vertices[ index * 9 + 6 ], vertices[ index * 9 + 7 ], vertices[ index * 9 + 8 ] ); |
| result[ i ] = THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC ); |
|
|
| } |
|
|
| return result; |
|
|
| }, |
|
|
| |
| |
|
|
| triangleArea: function () { |
|
|
| var vector1 = new THREE.Vector3(); |
| var vector2 = new THREE.Vector3(); |
|
|
| return function ( vectorA, vectorB, vectorC ) { |
|
|
| vector1.subVectors( vectorB, vectorA ); |
| vector2.subVectors( vectorC, vectorA ); |
| vector1.cross( vector2 ); |
|
|
| return 0.5 * vector1.length(); |
|
|
| }; |
|
|
| }(), |
|
|
| center: function ( geometry ) { |
|
|
| console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); |
| return geometry.center(); |
|
|
| } |
|
|
| }; |
|
|