|
@@ -5,24 +5,96 @@ var OrbitControls = require("three-orbit-controls")(THREE);
|
5
|
5
|
const scene = new THREE.Scene();
|
6
|
6
|
var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
|
7
|
7
|
|
8
|
|
-var geometry = new THREE.IcosahedronBufferGeometry(5, 7);
|
9
|
|
-
|
10
|
|
-var position = geometry.getAttribute("position");
|
11
|
|
-var colors = [];
|
12
|
|
-var color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
13
|
|
-for (var i = 0; i < position.count / 3; i += 1) {
|
14
|
|
- color.setRGB(i / (position.count / 3), i / (position.count / 3), i / (position.count / 3));
|
15
|
|
- colors.push(color.r, color.g, color.b);
|
16
|
|
- colors.push(color.r, color.g, color.b);
|
17
|
|
- colors.push(color.r, color.g, color.b);
|
|
8
|
+var geometry = new THREE.IcosahedronGeometry(10, 2);
|
|
9
|
+
|
|
10
|
+var vertToFaces = {};
|
|
11
|
+var newVertices = geometry.vertices;
|
|
12
|
+var newFaces = [];
|
|
13
|
+
|
|
14
|
+for (var i = 0; i < geometry.faces.length; i += 1) {
|
|
15
|
+ var face = geometry.faces[i];
|
|
16
|
+
|
|
17
|
+ if (vertToFaces[face.a]) {
|
|
18
|
+ vertToFaces[face.a].push(i);
|
|
19
|
+ } else {
|
|
20
|
+ vertToFaces[face.a] = [i];
|
|
21
|
+ }
|
|
22
|
+
|
|
23
|
+ if (vertToFaces[face.b]) {
|
|
24
|
+ vertToFaces[face.b].push(i);
|
|
25
|
+ } else {
|
|
26
|
+ vertToFaces[face.b] = [i];
|
|
27
|
+ }
|
|
28
|
+
|
|
29
|
+ if (vertToFaces[face.c]) {
|
|
30
|
+ vertToFaces[face.c].push(i);
|
|
31
|
+ } else {
|
|
32
|
+ vertToFaces[face.c] = [i];
|
|
33
|
+ }
|
|
34
|
+}
|
|
35
|
+
|
|
36
|
+var originalVertCount = geometry.vertices.length;
|
|
37
|
+
|
|
38
|
+var faceCentroids = {};
|
|
39
|
+for (var i = 0; i < geometry.faces.length; i += 1) {
|
|
40
|
+ var face = geometry.faces[i];
|
|
41
|
+ var vertexA = geometry.vertices[face.a];
|
|
42
|
+ var vertexB = geometry.vertices[face.b];
|
|
43
|
+ var vertexC = geometry.vertices[face.c];
|
|
44
|
+ var centroid = new THREE.Vector3(
|
|
45
|
+ (vertexA.x + vertexB.x + vertexC.x) / 3,
|
|
46
|
+ (vertexA.y + vertexB.y + vertexC.y) / 3,
|
|
47
|
+ (vertexA.z + vertexB.z + vertexC.z) / 3,
|
|
48
|
+ );
|
|
49
|
+
|
|
50
|
+ var centroidIndex = newVertices.push(centroid) - 1;
|
|
51
|
+ faceCentroids[i] = centroidIndex;
|
|
52
|
+}
|
|
53
|
+
|
|
54
|
+for (var i = 0; i < originalVertCount; i += 1) {
|
|
55
|
+ var faces = vertToFaces[i];
|
|
56
|
+ var color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
|
57
|
+ for (var j = 0; j < faces.length; j += 1) {
|
|
58
|
+ var faceIndex = faces[j];
|
|
59
|
+ var face = geometry.faces[faceIndex];
|
|
60
|
+ var nonCenterVerts = [face.a, face.b, face.c].filter(vert => vert !== i);
|
|
61
|
+ var sortedFace = new THREE.Face3(i, nonCenterVerts[0], nonCenterVerts[1]);
|
|
62
|
+
|
|
63
|
+ var vertexA = geometry.vertices[sortedFace.a];
|
|
64
|
+ var vertexB = geometry.vertices[sortedFace.b];
|
|
65
|
+ var vertexC = geometry.vertices[sortedFace.c];
|
|
66
|
+ var halfAB = vertexA.clone().lerp(vertexB, 0.5);
|
|
67
|
+ var halfAC = vertexA.clone().lerp(vertexC, 0.5);
|
|
68
|
+ var halfBC = vertexB.clone().lerp(vertexC, 0.5);
|
|
69
|
+
|
|
70
|
+ // TODO: cache these and retrieve in future iteration (use .toFixed(3) in hash)
|
|
71
|
+ var centroidIndex = faceCentroids[faceIndex];
|
|
72
|
+ var halfABIndex = newVertices.push(halfAB) - 1;
|
|
73
|
+ var halfACIndex = newVertices.push(halfAC) - 1;
|
|
74
|
+ var halfBCIndex = newVertices.push(halfBC) - 1;
|
|
75
|
+
|
|
76
|
+ var face1 = new THREE.Face3(sortedFace.a, centroidIndex, halfABIndex);
|
|
77
|
+ face1.color = color;
|
|
78
|
+ var face2 = new THREE.Face3(sortedFace.a, centroidIndex, halfACIndex);
|
|
79
|
+ face2.color = color;
|
|
80
|
+
|
|
81
|
+ newFaces.push(face1, face2);
|
|
82
|
+ }
|
18
|
83
|
}
|
19
|
84
|
|
20
|
85
|
function disposeArray() {
|
21
|
86
|
this.array = null;
|
22
|
87
|
}
|
23
|
|
-geometry.addAttribute("color", new THREE.Float32BufferAttribute(colors, 3).onUpload(disposeArray));
|
24
|
|
-var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors });
|
25
|
|
-var sphere = new THREE.Mesh(geometry, material);
|
|
88
|
+
|
|
89
|
+var newGeometry = new THREE.Geometry();
|
|
90
|
+newGeometry.vertices = newVertices;
|
|
91
|
+newGeometry.faces = newFaces;
|
|
92
|
+newGeometry.computeFaceNormals();
|
|
93
|
+newGeometry.computeVertexNormals();
|
|
94
|
+newGeometry.normalize();
|
|
95
|
+
|
|
96
|
+var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, side: THREE.DoubleSide });
|
|
97
|
+var sphere = new THREE.Mesh(newGeometry, material);
|
26
|
98
|
scene.add(sphere);
|
27
|
99
|
|
28
|
100
|
var controls = new OrbitControls(camera);
|