/* * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog * Smooth Geometry (SmoothMesh) using Catmull-Clark Subdivision Surfaces * Readings: * http://en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface * http://www.rorydriscoll.com/2008/08/01/catmull-clark-subdivision-the-basics/ */ // THREE.SubdivisionGeometry = function( oldGeometry ) { THREE.Geometry.call( this ); var scope = this; function v( x, y, z ) { scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x, y, z ) ) ); } function f4( a, b, c, d, color, material ) { scope.faces.push( new THREE.Face4( a, b, c, d, null, color, material) ); if (!supportUVs || uvForVertices.length!=0) { scope.faceVertexUvs[ 0 ].push( [ uvForVertices[a], uvForVertices[b], uvForVertices[c], uvForVertices[d] ] ); } } function edge_hash( a, b ) { return Math.min( a, b ) + "_" + Math.max( a, b ); }; function computeEdgeFaces( geometry ) { function addToMap( map, hash, i ) { if ( map[ hash ] === undefined ) { map[ hash ] = { "set": {}, "array": [] }; } map[ hash ].set[ i ] = 1; map[ hash ].array.push( i ); }; var i, il, v1, v2, j, k, face, faceIndices, faceIndex, edge, hash, vfMap = {}; // construct vertex -> face map for( i = 0, il = geometry.faces.length; i < il; i ++ ) { face = geometry.faces[ i ]; if ( face instanceof THREE.Face3 ) { hash = edge_hash( face.a, face.b ); addToMap( vfMap, hash, i ); hash = edge_hash( face.b, face.c ); addToMap( vfMap, hash, i ); hash = edge_hash( face.c, face.a ); addToMap( vfMap, hash, i ); } else if ( face instanceof THREE.Face4 ) { // in WebGLRenderer quad is tesselated // to triangles: a,b,d / b,c,d // shared edge is: b,d // add edge B-D only if you wish to slice a face4 // hash = edge_hash( face.b, face.d ); // addToMap( vfMap, hash, i ); hash = edge_hash( face.a, face.b ); addToMap( vfMap, hash, i ); hash = edge_hash( face.b, face.c ); addToMap( vfMap, hash, i ); hash = edge_hash( face.c, face.d ); addToMap( vfMap, hash, i ); hash = edge_hash( face.d, face.a ); addToMap( vfMap, hash, i ); } } // extract faces geometry.vfMap = vfMap; geometry.edges = []; var numOfEdges = 0; for (i in vfMap) { numOfEdges++; edge = vfMap[i]; geometry.edges.push(edge.array); } //console.log('vfMap', vfMap, 'geometry.edges',geometry.edges, 'numOfEdges', numOfEdges); return vfMap; }; var originalPoints = oldGeometry.vertices; var originalFaces = oldGeometry.faces; var newPoints = originalPoints.concat(); // Vertices var facePoints = [], edgePoints = {}; var uvForVertices = []; var supportUVs = true; // Step 1 // For each face, add a face point // Set each face point to be the centroid of all original points for the respective face. var i, il, j, jl, face; // For Uvs var uvs = oldGeometry.faceVertexUvs[0]; var abcd = 'abcd', vertice; for (i=0, il = uvs.length; i