/* * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog * * Subdivision Geometry Modifier * using Catmull-Clark Subdivision Surfaces * for creating smooth geometry meshes * * Note: a modifier modifies vertices and faces of geometry, * so use THREE.GeometryUtils.clone() if orignal geoemtry needs to be retained * * Readings: * http://en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface * http://www.rorydriscoll.com/2008/08/01/catmull-clark-subdivision-the-basics/ * http://xrt.wikidot.com/blog:31 * "Subdivision Surfaces in Character Animation" * * Supports: * Closed and Open geometries. * * TODO: * crease vertex and "semi-sharp" features * selective subdivision */ THREE.SubdivisionModifier = function( subdivisions ) { this.subdivisions = (subdivisions === undefined ) ? 1 : subdivisions; // Settings this.useOldVertexColors = false; this.supportUVs = true; }; //THREE.SubdivisionModifier.prototype = new THREE.Modifier(); THREE.SubdivisionModifier.prototype.constructor = THREE.SubdivisionModifier; // Applies the "modify" pattern THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { var repeats = this.subdivisions; while ( repeats-- > 0 ) { this.smooth( geometry ); } }; // Performs an iteration of Catmull-Clark Subdivision THREE.SubdivisionModifier.prototype.smooth = function ( oldGeometry ) { //console.log( 'running smooth' ); // New set of vertices, faces and uvs var newVertices = [], newFaces = [], newUVs = []; function v( x, y, z ) { newVertices.push( new THREE.Vertex( new THREE.Vector3( x, y, z ) ) ); } var scope = this; function f4( a, b, c, d, oldFace, orders ) { // TODO move vertex selection over here! var newFace = new THREE.Face4( a, b, c, d, null, oldFace.color, oldFace.material ); if (scope.useOldVertexColors) { newFace.vertexColors = []; var color, tmpColor, order; for (var i=0;i<4;i++) { order = orders[i]; color = new THREE.Color(), color.setRGB(0,0,0); for (var j=0, jl=0; j 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 ) { 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 // var edges = []; // // var numOfEdges = 0; // for (i in vfMap) { // numOfEdges++; // // edge = vfMap[i]; // edges.push(edge); // // } //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 sharpEdges = {}, sharpVertices = [], sharpFaces = []; var uvForVertices = []; // 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; i2) { // TODO } */ F.divideScalar(f); for (j=0; j