diff --git a/src/extras/geometries/SubdivisionGeometry.js b/src/extras/geometries/SubdivisionGeometry.js new file mode 100644 index 00000000..8c6a5807 --- /dev/null +++ b/src/extras/geometries/SubdivisionGeometry.js @@ -0,0 +1,413 @@ +/* + * @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