Finally a hex sphere, albeit pointy
I still need to flatten the hexagons and pentagons to make it a true dual polyhedron of the icosahedron. Also needs performance improvements. Like caching the vertices, switching from fan subdivision to a different method that represents hexagons and pentagons with less triangles.
This commit is contained in:
parent
ec037d219a
commit
113de04cbe
@ -5,7 +5,7 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"start": "webpack-dev-server --mode development --watch-poll --progress --hot",
|
"start": "webpack-dev-server --mode development --watch --progress --hot",
|
||||||
"build": "webpack"
|
"build": "webpack"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
|
94
src/index.js
94
src/index.js
@ -5,24 +5,96 @@ var OrbitControls = require("three-orbit-controls")(THREE);
|
|||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
|
var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||||
|
|
||||||
var geometry = new THREE.IcosahedronBufferGeometry(5, 7);
|
var geometry = new THREE.IcosahedronGeometry(10, 2);
|
||||||
|
|
||||||
var position = geometry.getAttribute("position");
|
var vertToFaces = {};
|
||||||
var colors = [];
|
var newVertices = geometry.vertices;
|
||||||
|
var newFaces = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < geometry.faces.length; i += 1) {
|
||||||
|
var face = geometry.faces[i];
|
||||||
|
|
||||||
|
if (vertToFaces[face.a]) {
|
||||||
|
vertToFaces[face.a].push(i);
|
||||||
|
} else {
|
||||||
|
vertToFaces[face.a] = [i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertToFaces[face.b]) {
|
||||||
|
vertToFaces[face.b].push(i);
|
||||||
|
} else {
|
||||||
|
vertToFaces[face.b] = [i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertToFaces[face.c]) {
|
||||||
|
vertToFaces[face.c].push(i);
|
||||||
|
} else {
|
||||||
|
vertToFaces[face.c] = [i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var originalVertCount = geometry.vertices.length;
|
||||||
|
|
||||||
|
var faceCentroids = {};
|
||||||
|
for (var i = 0; i < geometry.faces.length; i += 1) {
|
||||||
|
var face = geometry.faces[i];
|
||||||
|
var vertexA = geometry.vertices[face.a];
|
||||||
|
var vertexB = geometry.vertices[face.b];
|
||||||
|
var vertexC = geometry.vertices[face.c];
|
||||||
|
var centroid = new THREE.Vector3(
|
||||||
|
(vertexA.x + vertexB.x + vertexC.x) / 3,
|
||||||
|
(vertexA.y + vertexB.y + vertexC.y) / 3,
|
||||||
|
(vertexA.z + vertexB.z + vertexC.z) / 3,
|
||||||
|
);
|
||||||
|
|
||||||
|
var centroidIndex = newVertices.push(centroid) - 1;
|
||||||
|
faceCentroids[i] = centroidIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < originalVertCount; i += 1) {
|
||||||
|
var faces = vertToFaces[i];
|
||||||
var color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
var color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
||||||
for (var i = 0; i < position.count / 3; i += 1) {
|
for (var j = 0; j < faces.length; j += 1) {
|
||||||
color.setRGB(i / (position.count / 3), i / (position.count / 3), i / (position.count / 3));
|
var faceIndex = faces[j];
|
||||||
colors.push(color.r, color.g, color.b);
|
var face = geometry.faces[faceIndex];
|
||||||
colors.push(color.r, color.g, color.b);
|
var nonCenterVerts = [face.a, face.b, face.c].filter(vert => vert !== i);
|
||||||
colors.push(color.r, color.g, color.b);
|
var sortedFace = new THREE.Face3(i, nonCenterVerts[0], nonCenterVerts[1]);
|
||||||
|
|
||||||
|
var vertexA = geometry.vertices[sortedFace.a];
|
||||||
|
var vertexB = geometry.vertices[sortedFace.b];
|
||||||
|
var vertexC = geometry.vertices[sortedFace.c];
|
||||||
|
var halfAB = vertexA.clone().lerp(vertexB, 0.5);
|
||||||
|
var halfAC = vertexA.clone().lerp(vertexC, 0.5);
|
||||||
|
var halfBC = vertexB.clone().lerp(vertexC, 0.5);
|
||||||
|
|
||||||
|
// TODO: cache these and retrieve in future iteration (use .toFixed(3) in hash)
|
||||||
|
var centroidIndex = faceCentroids[faceIndex];
|
||||||
|
var halfABIndex = newVertices.push(halfAB) - 1;
|
||||||
|
var halfACIndex = newVertices.push(halfAC) - 1;
|
||||||
|
var halfBCIndex = newVertices.push(halfBC) - 1;
|
||||||
|
|
||||||
|
var face1 = new THREE.Face3(sortedFace.a, centroidIndex, halfABIndex);
|
||||||
|
face1.color = color;
|
||||||
|
var face2 = new THREE.Face3(sortedFace.a, centroidIndex, halfACIndex);
|
||||||
|
face2.color = color;
|
||||||
|
|
||||||
|
newFaces.push(face1, face2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function disposeArray() {
|
function disposeArray() {
|
||||||
this.array = null;
|
this.array = null;
|
||||||
}
|
}
|
||||||
geometry.addAttribute("color", new THREE.Float32BufferAttribute(colors, 3).onUpload(disposeArray));
|
|
||||||
var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors });
|
var newGeometry = new THREE.Geometry();
|
||||||
var sphere = new THREE.Mesh(geometry, material);
|
newGeometry.vertices = newVertices;
|
||||||
|
newGeometry.faces = newFaces;
|
||||||
|
newGeometry.computeFaceNormals();
|
||||||
|
newGeometry.computeVertexNormals();
|
||||||
|
newGeometry.normalize();
|
||||||
|
|
||||||
|
var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, side: THREE.DoubleSide });
|
||||||
|
var sphere = new THREE.Mesh(newGeometry, material);
|
||||||
scene.add(sphere);
|
scene.add(sphere);
|
||||||
|
|
||||||
var controls = new OrbitControls(camera);
|
var controls = new OrbitControls(camera);
|
||||||
|
Loading…
Reference in New Issue
Block a user