Create more efficient BufferGeometry

And, cache midpoint vertices.
This commit is contained in:
Tyler Hallada 2019-02-04 23:17:57 -05:00
parent 113de04cbe
commit ec1a200aaf

View File

@ -5,11 +5,15 @@ 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.IcosahedronGeometry(10, 2); console.time("IcosahedronGeometry");
var geometry = new THREE.IcosahedronGeometry(10, 6);
console.log(geometry);
console.timeEnd("IcosahedronGeometry");
console.time("Hexsphere");
var vertToFaces = {}; var vertToFaces = {};
var newVertices = geometry.vertices; var newVertices = [];
var newFaces = []; var colors = [];
for (var i = 0; i < geometry.faces.length; i += 1) { for (var i = 0; i < geometry.faces.length; i += 1) {
var face = geometry.faces[i]; var face = geometry.faces[i];
@ -47,10 +51,12 @@ for (var i = 0; i < geometry.faces.length; i += 1) {
(vertexA.z + vertexB.z + vertexC.z) / 3, (vertexA.z + vertexB.z + vertexC.z) / 3,
); );
var centroidIndex = newVertices.push(centroid) - 1; // var centroidIndex = (newVertices.push(centroid.x, centroid.y, centroid.z) / 3) - 1;
faceCentroids[i] = centroidIndex; faceCentroids[i] = centroid;
} }
console.time("find dual");
var midVertCache = {};
for (var i = 0; i < originalVertCount; i += 1) { for (var i = 0; i < originalVertCount; i += 1) {
var faces = vertToFaces[i]; 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());
@ -59,41 +65,62 @@ for (var i = 0; i < originalVertCount; i += 1) {
var face = geometry.faces[faceIndex]; var face = geometry.faces[faceIndex];
var nonCenterVerts = [face.a, face.b, face.c].filter(vert => vert !== i); var nonCenterVerts = [face.a, face.b, face.c].filter(vert => vert !== i);
var sortedFace = new THREE.Face3(i, nonCenterVerts[0], nonCenterVerts[1]); var sortedFace = new THREE.Face3(i, nonCenterVerts[0], nonCenterVerts[1]);
// var sortedFace = face;
var vertexA = geometry.vertices[sortedFace.a]; var vertexA = geometry.vertices[sortedFace.a];
var vertexB = geometry.vertices[sortedFace.b]; var vertexB = geometry.vertices[sortedFace.b];
var vertexC = geometry.vertices[sortedFace.c]; 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 midABKey = sortedFace.a + "," + sortedFace.b
var centroidIndex = faceCentroids[faceIndex]; var midAB = midVertCache[midABKey];
var halfABIndex = newVertices.push(halfAB) - 1; if (!midAB) {
var halfACIndex = newVertices.push(halfAC) - 1; midAB = vertexA.clone().lerp(vertexB, 0.5);
var halfBCIndex = newVertices.push(halfBC) - 1; midVertCache[midABKey] = midAB;
}
var midACKey = sortedFace.a + "," + sortedFace.c
var midAC = midVertCache[midACKey];
if (!midAC) {
midAC = vertexA.clone().lerp(vertexC, 0.5);
midVertCache[midACKey] = midAC;
}
var centroid = faceCentroids[faceIndex];
var face1 = new THREE.Face3(sortedFace.a, centroidIndex, halfABIndex); newVertices.push(
face1.color = color; vertexA.x, vertexA.y, vertexA.z,
var face2 = new THREE.Face3(sortedFace.a, centroidIndex, halfACIndex); centroid.x, centroid.y, centroid.z,
face2.color = color; midAB.x, midAB.y, midAB.z,
newFaces.push(face1, face2); vertexA.x, vertexA.y, vertexA.z,
centroid.x, centroid.y, centroid.z,
midAC.x, midAC.y, midAC.z,
);
colors.push(
color.r, color.g, color.b,
color.r, color.g, color.b,
color.r, color.g, color.b,
color.r, color.g, color.b,
color.r, color.g, color.b,
color.r, color.g, color.b,
);
} }
} }
console.timeEnd("find dual");
function disposeArray() { function disposeArray() {
this.array = null; this.array = null;
} }
var newGeometry = new THREE.Geometry(); var newGeometry = new THREE.BufferGeometry();
newGeometry.vertices = newVertices; newGeometry.addAttribute("position", new THREE.Float32BufferAttribute(newVertices, 3));
newGeometry.faces = newFaces; newGeometry.addAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
newGeometry.computeFaceNormals(); // newGeometry.computeFaceNormals();
newGeometry.computeVertexNormals(); // newGeometry.computeVertexNormals();
newGeometry.normalize(); // newGeometry.normalize();
var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, side: THREE.DoubleSide });
var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, side: THREE.DoubleSide });
var sphere = new THREE.Mesh(newGeometry, material); var sphere = new THREE.Mesh(newGeometry, material);
scene.add(sphere); scene.add(sphere);
@ -105,6 +132,7 @@ controls.update()
var renderer = new THREE.WebGLRenderer(); var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement ); document.body.appendChild( renderer.domElement );
console.timeEnd("Hexsphere");
window.addEventListener('resize', onWindowResize, false); window.addEventListener('resize', onWindowResize, false);