-
-
Notifications
You must be signed in to change notification settings - Fork 35.7k
/
Copy pathConvexGeometry.js
71 lines (49 loc) · 1.58 KB
/
ConvexGeometry.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import {
BufferGeometry,
Float32BufferAttribute
} from 'three';
import { ConvexHull } from '../math/ConvexHull.js';
/**
* This class can be used to generate a convex hull for a given array of 3D points.
* The average time complexity for this task is considered to be O(nlog(n)).
*
* ```js
* const geometry = new ConvexGeometry( points );
* const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
* const mesh = new THREE.Mesh( geometry, material );
* scene.add( mesh );
* ```
*
* @augments BufferGeometry
*/
class ConvexGeometry extends BufferGeometry {
/**
* Constructs a new convex geometry.
*
* @param {Array<Vector3>} points - An array of points in 3D space which should be enclosed by the convex hull.
*/
constructor( points = [] ) {
super();
// buffers
const vertices = [];
const normals = [];
const convexHull = new ConvexHull().setFromPoints( points );
// generate vertices and normals
const faces = convexHull.faces;
for ( let i = 0; i < faces.length; i ++ ) {
const face = faces[ i ];
let edge = face.edge;
// we move along a doubly-connected edge list to access all face points (see HalfEdge docs)
do {
const 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.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
}
}
export { ConvexGeometry };