diff --git a/lib/ConvexHull.d.ts b/lib/ConvexHull.d.ts index f2521d2..1495fd8 100644 --- a/lib/ConvexHull.d.ts +++ b/lib/ConvexHull.d.ts @@ -10,7 +10,14 @@ declare class Face { normal: Vector3; } +declare class VertexNode { + point: Vector3; +} + declare class ConvexHull { public faces: Face[]; + public vertices: VertexNode[]; setFromObject(mesh: Mesh): this; + collectFaces(): number[][]; + collectFacesAndVertices(): { faces: number[][]; vertices: Vector3[]; } } diff --git a/lib/ConvexHull.js b/lib/ConvexHull.js index fe37696..90b48ec 100644 --- a/lib/ConvexHull.js +++ b/lib/ConvexHull.js @@ -1,5 +1,4 @@ import { - BufferGeometry, Line3, Plane, Triangle, @@ -42,6 +41,41 @@ var ConvexHull = ( function () { Object.assign( ConvexHull.prototype, { + collectFacesAndVertices: function () { + // Get face indices. + // These are the indices of all input vertices, including vertices inside the convex hull. + const faceIndices = this.faces.map((f) => f.collectIndices()); + + // Get distinct vertex indices referenced by convex hull faces. + const referencedFaceIndices = Array.from( + new Set(faceIndices.flatMap((f) => f)).values() + ).sort((a, b) => a - b); + + // Create a mapping between original vertex indices to new vertex indices. + const originalToNewIndex = new Map(); + for (let i = 0; i < referencedFaceIndices.length; i++) { + originalToNewIndex.set(referencedFaceIndices[i], i); + } + + // Get faces with remapped vertex indices. + const faces = []; + for (let i = 0; i < faceIndices.length; i++) { + const indices = faceIndices[i]; + const a = originalToNewIndex.get(indices[0]); + const b = originalToNewIndex.get(indices[1]); + const c = originalToNewIndex.get(indices[2]); + faces.push([a, b, c]); + } + + // Get vertices referenced by faces. + const vertices = []; + for (let i = 0; i < referencedFaceIndices.length; i++) { + vertices.push(this.vertices[referencedFaceIndices[i]].point); + } + + return { faces, vertices }; + }, + setFromPoints: function ( points ) { if ( Array.isArray( points ) !== true ) { @@ -60,7 +94,7 @@ var ConvexHull = ( function () { for ( var i = 0, l = points.length; i < l; i ++ ) { - this.vertices.push( new VertexNode( points[ i ] ) ); + this.vertices.push( new VertexNode( points[ i ], i ) ); } @@ -980,6 +1014,16 @@ var ConvexHull = ( function () { Object.assign( Face.prototype, { + collectIndices: function () { + const indices = []; + let edge = this.edge; + do { + indices.push(edge.head().index); + edge = edge.next; + } while (edge !== this.edge); + return indices; + }, + getEdge: function ( i ) { var edge = this.edge; @@ -1105,12 +1149,15 @@ var ConvexHull = ( function () { // A vertex as a double linked list node. - function VertexNode( point ) { + function VertexNode( point, index ) { this.point = point; + // index in the input array + this.index = index; this.prev = null; this.next = null; - this.face = null; // the face that is able to see this vertex + // the face that is able to see this vertex + this.face = null; } diff --git a/src/index.ts b/src/index.ts index 8527579..e8c4b0e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ -import { Box, Quaternion as CQuaternion, ConvexPolyhedron, Cylinder, Shape, Sphere, Trimesh, Vec3 } from 'cannon-es'; +import { Box, ConvexPolyhedron, Cylinder, Quaternion as CQuaternion, Shape, Sphere, Trimesh, Vec3 } from 'cannon-es'; import { Box3, BufferGeometry, CylinderGeometry, MathUtils, Mesh, Object3D, SphereGeometry, Vector3 } from 'three'; -import { ConvexHull } from '../lib/ConvexHull.js'; +import { ConvexHull } from '../lib/ConvexHull'; import { getComponent, getGeometry, getVertices } from './utils'; const PI_2 = Math.PI / 2; @@ -254,34 +254,23 @@ function getConvexPolyhedronParameters (object: Object3D): ShapeParameters