Loop Subdivision
subdivision :Subdivse function :
function subdivise(geometry, sub){ geometry.faceVertexUvs = []; sub = Math.min(Math.max(sub,0),7); for(var boucle = 0; boucle < sub; boucle++){ var oldVertices = geometry.vertices; // { x, y, z} var oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 } // Generate edges Lookup var edges = {}; // edge oldVertex1_oldVertex2 = { oldVertex1, oldVertex2, faces[] } var metaVertices = []; generateLookups(oldVertices, oldFaces, metaVertices, edges); // new edges vertex /* 2 6 6 2 */ var newEdgeVertices = []; for(var k in edges){ var edge = edges[k]; //R2, R3, R4 var vertexWeight = 6/16; var adjVertexWeight = 2/16; var newVertex = new THREE.Vector3(); newVertex.add(edge.a).multiplyScalar(vertexWeight); newVertex.add(edge.b.clone().multiplyScalar(vertexWeight)); for(var l in edge.faces){ var face = edge.faces[l]; // each vertex var letters = ['a','b','c']; for(var m in letters){ var vertex = oldVertices[face[letters[m]]]; if(vertex != edge.a && vertex != edge.b){ newVertex.add(vertex.clone().multiplyScalar(adjVertexWeight)); } } } edge.newIndex = newEdgeVertices.length+oldVertices.length; newEdgeVertices.push(newVertex); } //console.assert(newEdgeVertices.length == 18, "Edges vertex should count to 18"); // Reposition already created vertex /* 1 1 1 10 1 1 1 */ var newSourceVertices = []; for(var i = 0; i < oldVertices.length; i++){ var oldVertex = oldVertices[i]; let edges = metaVertices[i].edges; var n = edges.length; var alpha_n = Math.pow(3/8 + Math.cos(2*Math.PI/n)/4, 2)+3/8; var alpha = 1.7*alpha_n - 1; var beta = (1-alpha)/n; let newVertex = oldVertex.clone().multiplyScalar(alpha); for(var k in edges){ newVertex.add(edges[k].clone().multiplyScalar(beta)); } newSourceVertices.push(newVertex); } //link source and edge -> 1 face = 4 new faces var newFaces = []; var newVertices = newSourceVertices.concat(newEdgeVertices); for(var i = 0; i<oldFaces.length; i++){ var face = oldFaces[i]; var d = getEdge( face.a, face.b, edges ).newIndex; var e = getEdge( face.b, face.c, edges ).newIndex; var f = getEdge( face.c, face.a, edges ).newIndex; /* a / \ d---f / \ / \ b---e---c */ newFaces.push(new THREE.Face3(d, e, f)); newFaces.push(new THREE.Face3(face.a, d, f)); newFaces.push(new THREE.Face3(face.b, e, d)); newFaces.push(new THREE.Face3(face.c, f, e)); } geometry.faces = newFaces; geometry.vertices = newVertices; } geometry.computeVertexNormals(); return geometry; }