浏览代码

QuickHull3: New ConvexGeometry

Mugen87 8 年之前
父节点
当前提交
2cb2054d25
共有 3 个文件被更改,包括 87 次插入14 次删除
  1. 75 0
      src/geometries/ConvexGeometry.js
  2. 1 0
      src/geometries/Geometries.js
  3. 11 14
      src/math/convexhull/QuickHull3.js

+ 75 - 0
src/geometries/ConvexGeometry.js

@@ -0,0 +1,75 @@
+/**
+ * @author Mugen87 / https://github.com/Mugen87
+ */
+
+import { Geometry } from '../core/Geometry';
+import { BufferGeometry } from '../core/BufferGeometry';
+import { Float32BufferAttribute } from '../core/BufferAttribute';
+import { QuickHull3 } from '../math/convexhull/QuickHull3';
+
+function ConvexGeometry( points ) {
+
+	Geometry.call( this );
+
+	this.type = 'ConvexGeometry';
+
+	this.fromBufferGeometry( new ConvexBufferGeometry( points ) );
+	this.mergeVertices();
+
+}
+
+ConvexGeometry.prototype = Object.create( Geometry.prototype );
+ConvexGeometry.prototype.constructor = ConvexGeometry;
+
+
+function ConvexBufferGeometry( points ) {
+
+  BufferGeometry.call( this );
+
+	this.type = 'ConvexBufferGeometry';
+
+  // buffers
+
+  var vertices = [];
+  var normals = [];
+
+  // execute QuickHull
+
+  var quickHull = new THREE.QuickHull3().setFromPoints( points );
+
+  // generate vertices and normals
+
+  var faces = quickHull.faces;
+
+  for ( let i = 0; i < faces.length; i ++ ) {
+
+    var face = faces[ i ];
+    var edge = face.edge;
+
+    // we move along a doubly-connected edge list to access all face points (see HalfEdge docs)
+
+    do {
+
+      var point = edge.head().point;
+
+      vertices.push( point.x, point.y, point.z );
+      normals.push( face.normal.x, face.normal.y, face.normal.z );
+
+      edge = edge.next;
+
+    } while ( edge !== face.edge );
+
+  }
+
+  // build geometry
+
+  this.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+  this.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
+
+}
+
+ConvexBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
+ConvexBufferGeometry.prototype.constructor = ConvexBufferGeometry;
+
+
+export { ConvexGeometry, ConvexBufferGeometry };

+ 1 - 0
src/geometries/Geometries.js

@@ -20,3 +20,4 @@ export { ConeGeometry, ConeBufferGeometry } from './ConeGeometry.js';
 export { CylinderGeometry, CylinderBufferGeometry } from './CylinderGeometry.js';
 export { CircleGeometry, CircleBufferGeometry } from './CircleGeometry.js';
 export { BoxGeometry, BoxBufferGeometry } from './BoxGeometry.js';
+export { ConvexGeometry, ConvexBufferGeometry } from './ConvexGeometry.js';

+ 11 - 14
src/math/convexhull/QuickHull3.js

@@ -15,13 +15,13 @@ function QuickHull3() {
 
 	this.tolerance = - 1;
 
-	this.faces = [];
-	this.newFaces = [];
+	this.faces = []; // the generated faces of the convex hull
+	this.newFaces = []; // this array holds the faces that are generated in a single iteration
 
 	this.assigned = new VertexList();
 	this.unassigned = new VertexList();
 
-	this.vertices = []; // vertices of the hull (internal representation of given points)
+	this.vertices = []; 	// vertices of the hull (internal representation of given geometry data)
 
 }
 
@@ -57,9 +57,7 @@ Object.assign( QuickHull3.prototype, {
 
 	setFromObject: function ( object ) {
 
-		var scope = this;
-
-		this.makeEmpty();
+		var points = [];
 
 		object.updateMatrixWorld( true );
 
@@ -80,7 +78,7 @@ Object.assign( QuickHull3.prototype, {
 						point = vertices[ i ].clone();
 						point.applyMatrix4( node.matrixWorld );
 
-						scope.vertices.push( new Vertex( point ) );
+						points.push( point );
 
 					}
 
@@ -96,7 +94,7 @@ Object.assign( QuickHull3.prototype, {
 
 							point.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );
 
-							scope.vertices.push( new Vertex( point ) );
+							points.push( point );
 
 						}
 
@@ -108,9 +106,7 @@ Object.assign( QuickHull3.prototype, {
 
 		} );
 
-		this.compute();
-
-		return this;
+		return this.setFromPoints( points );
 
 	},
 
@@ -375,7 +371,7 @@ Object.assign( QuickHull3.prototype, {
 
 		}
 
-		// use min/max vectors to compute epsilon
+		// use min/max vectors to compute an optimal epsilon
 
 		this.tolerance = 3 * Number.EPSILON * (
 			Math.max( Math.abs( min.x ), Math.abs( max.x ) ) +
@@ -387,7 +383,8 @@ Object.assign( QuickHull3.prototype, {
 
 	},
 
-	// Computes the initial tetrahedron assigning to its faces all the points that are candidates to form part of the hull
+	// Computes the initial simplex assigning to its faces all the points
+	// that are candidates to form part of the hull
 
 	computeInitialHull: function () {
 
@@ -611,7 +608,7 @@ Object.assign( QuickHull3.prototype, {
 
 	},
 
-	// Finds the next vertex to make faces with the current hull
+	// Finds the next vertex to create faces with the current hull
 
 	nextVertexToAdd: function () {