123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- /**
- * Break faces with edges longer than maxEdgeLength
- * - not recursive
- *
- * @author alteredq / http://alteredqualia.com/
- */
- THREE.TessellateModifier = function ( maxEdgeLength ) {
- this.maxEdgeLength = maxEdgeLength;
- };
- THREE.TessellateModifier.prototype.modify = function ( geometry ) {
- var i, il, face,
- a, b, c, d,
- va, vb, vc, vd,
- dab, dbc, dac, dcd, dad,
- m, m1, m2,
- vm, vm1, vm2,
- vnm, vnm1, vnm2,
- vcm, vcm1, vcm2,
- triA, triB,
- quadA, quadB,
- edge;
- var faces = [];
- var faceVertexUvs = [];
- var maxEdgeLength = this.maxEdgeLength;
- for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
- faceVertexUvs[ i ] = [];
- }
- for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
- face = geometry.faces[ i ];
- if ( face instanceof THREE.Face3 ) {
- a = face.a;
- b = face.b;
- c = face.c;
- va = geometry.vertices[ a ];
- vb = geometry.vertices[ b ];
- vc = geometry.vertices[ c ];
- dab = va.distanceTo( vb );
- dbc = vb.distanceTo( vc );
- dac = va.distanceTo( vc );
- if ( dab > maxEdgeLength || dbc > maxEdgeLength || dac > maxEdgeLength ) {
- m = geometry.vertices.length;
- triA = face.clone();
- triB = face.clone();
- if ( dab >= dbc && dab >= dac ) {
- vm = va.clone();
- vm.lerp( vb, 0.5 );
- triA.a = a;
- triA.b = m;
- triA.c = c;
- triB.a = m;
- triB.b = b;
- triB.c = c;
- if ( face.vertexNormals.length === 3 ) {
- vnm = face.vertexNormals[ 0 ].clone();
- vnm.lerp( face.vertexNormals[ 1 ], 0.5 );
- triA.vertexNormals[ 1 ].copy( vnm );
- triB.vertexNormals[ 0 ].copy( vnm );
- }
- if ( face.vertexColors.length === 3 ) {
- vcm = face.vertexColors[ 0 ].clone();
- vcm.lerp( face.vertexColors[ 1 ], 0.5 );
- triA.vertexColors[ 1 ].copy( vcm );
- triB.vertexColors[ 0 ].copy( vcm );
- }
- edge = 0;
- } else if ( dbc >= dab && dbc >= dac ) {
- vm = vb.clone();
- vm.lerp( vc, 0.5 );
- triA.a = a;
- triA.b = b;
- triA.c = m;
- triB.a = m;
- triB.b = c;
- triB.c = a;
- if ( face.vertexNormals.length === 3 ) {
- vnm = face.vertexNormals[ 1 ].clone();
- vnm.lerp( face.vertexNormals[ 2 ], 0.5 );
- triA.vertexNormals[ 2 ].copy( vnm );
- triB.vertexNormals[ 0 ].copy( vnm );
- triB.vertexNormals[ 1 ].copy( face.vertexNormals[ 2 ] );
- triB.vertexNormals[ 2 ].copy( face.vertexNormals[ 0 ] );
- }
- if ( face.vertexColors.length === 3 ) {
- vcm = face.vertexColors[ 1 ].clone();
- vcm.lerp( face.vertexColors[ 2 ], 0.5 );
- triA.vertexColors[ 2 ].copy( vcm );
- triB.vertexColors[ 0 ].copy( vcm );
- triB.vertexColors[ 1 ].copy( face.vertexColors[ 2 ] );
- triB.vertexColors[ 2 ].copy( face.vertexColors[ 0 ] );
- }
- edge = 1;
- } else {
- vm = va.clone();
- vm.lerp( vc, 0.5 );
- triA.a = a;
- triA.b = b;
- triA.c = m;
- triB.a = m;
- triB.b = b;
- triB.c = c;
- if ( face.vertexNormals.length === 3 ) {
- vnm = face.vertexNormals[ 0 ].clone();
- vnm.lerp( face.vertexNormals[ 2 ], 0.5 );
- triA.vertexNormals[ 2 ].copy( vnm );
- triB.vertexNormals[ 0 ].copy( vnm );
- }
- if ( face.vertexColors.length === 3 ) {
- vcm = face.vertexColors[ 0 ].clone();
- vcm.lerp( face.vertexColors[ 2 ], 0.5 );
- triA.vertexColors[ 2 ].copy( vcm );
- triB.vertexColors[ 0 ].copy( vcm );
- }
- edge = 2;
- }
- faces.push( triA, triB );
- geometry.vertices.push( vm );
- var j, jl, uvs, uvA, uvB, uvC, uvM, uvsTriA, uvsTriB;
- for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- if ( geometry.faceVertexUvs[ j ].length ) {
- uvs = geometry.faceVertexUvs[ j ][ i ];
- uvA = uvs[ 0 ];
- uvB = uvs[ 1 ];
- uvC = uvs[ 2 ];
- // AB
- if ( edge === 0 ) {
- uvM = uvA.clone();
- uvM.lerp( uvB, 0.5 );
- uvsTriA = [ uvA.clone(), uvM.clone(), uvC.clone() ];
- uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
- // BC
- } else if ( edge === 1 ) {
- uvM = uvB.clone();
- uvM.lerp( uvC, 0.5 );
- uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
- uvsTriB = [ uvM.clone(), uvC.clone(), uvA.clone() ];
- // AC
- } else {
- uvM = uvA.clone();
- uvM.lerp( uvC, 0.5 );
- uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
- uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
- }
- faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
- }
- }
- } else {
- faces.push( face );
- for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
- }
- }
- } else {
- a = face.a;
- b = face.b;
- c = face.c;
- d = face.d;
- va = geometry.vertices[ a ];
- vb = geometry.vertices[ b ];
- vc = geometry.vertices[ c ];
- vd = geometry.vertices[ d ];
- dab = va.distanceTo( vb );
- dbc = vb.distanceTo( vc );
- dcd = vc.distanceTo( vd );
- dad = va.distanceTo( vd );
- if ( dab > maxEdgeLength || dbc > maxEdgeLength || dcd > maxEdgeLength || dad > maxEdgeLength ) {
- m1 = geometry.vertices.length;
- m2 = geometry.vertices.length + 1;
- quadA = face.clone();
- quadB = face.clone();
- if ( ( dab >= dbc && dab >= dcd && dab >= dad ) || ( dcd >= dbc && dcd >= dab && dcd >= dad ) ) {
- vm1 = va.clone();
- vm1.lerp( vb, 0.5 );
- vm2 = vc.clone();
- vm2.lerp( vd, 0.5 );
- quadA.a = a;
- quadA.b = m1;
- quadA.c = m2;
- quadA.d = d;
- quadB.a = m1;
- quadB.b = b;
- quadB.c = c;
- quadB.d = m2;
- if ( face.vertexNormals.length === 4 ) {
- vnm1 = face.vertexNormals[ 0 ].clone();
- vnm1.lerp( face.vertexNormals[ 1 ], 0.5 );
- vnm2 = face.vertexNormals[ 2 ].clone();
- vnm2.lerp( face.vertexNormals[ 3 ], 0.5 );
- quadA.vertexNormals[ 1 ].copy( vnm1 );
- quadA.vertexNormals[ 2 ].copy( vnm2 );
- quadB.vertexNormals[ 0 ].copy( vnm1 );
- quadB.vertexNormals[ 3 ].copy( vnm2 );
- }
- if ( face.vertexColors.length === 4 ) {
- vcm1 = face.vertexColors[ 0 ].clone();
- vcm1.lerp( face.vertexColors[ 1 ], 0.5 );
- vcm2 = face.vertexColors[ 2 ].clone();
- vcm2.lerp( face.vertexColors[ 3 ], 0.5 );
- quadA.vertexColors[ 1 ].copy( vcm1 );
- quadA.vertexColors[ 2 ].copy( vcm2 );
- quadB.vertexColors[ 0 ].copy( vcm1 );
- quadB.vertexColors[ 3 ].copy( vcm2 );
- }
- edge = 0;
- } else {
- vm1 = vb.clone();
- vm1.lerp( vc, 0.5 );
- vm2 = vd.clone();
- vm2.lerp( va, 0.5 );
- quadA.a = a;
- quadA.b = b;
- quadA.c = m1;
- quadA.d = m2;
- quadB.a = m2;
- quadB.b = m1;
- quadB.c = c;
- quadB.d = d;
- if ( face.vertexNormals.length === 4 ) {
- vnm1 = face.vertexNormals[ 1 ].clone();
- vnm1.lerp( face.vertexNormals[ 2 ], 0.5 );
- vnm2 = face.vertexNormals[ 3 ].clone();
- vnm2.lerp( face.vertexNormals[ 0 ], 0.5 );
- quadA.vertexNormals[ 2 ].copy( vnm1 );
- quadA.vertexNormals[ 3 ].copy( vnm2 );
- quadB.vertexNormals[ 0 ].copy( vnm2 );
- quadB.vertexNormals[ 1 ].copy( vnm1 );
- }
- if ( face.vertexColors.length === 4 ) {
- vcm1 = face.vertexColors[ 1 ].clone();
- vcm1.lerp( face.vertexColors[ 2 ], 0.5 );
- vcm2 = face.vertexColors[ 3 ].clone();
- vcm2.lerp( face.vertexColors[ 0 ], 0.5 );
- quadA.vertexColors[ 2 ].copy( vcm1 );
- quadA.vertexColors[ 3 ].copy( vcm2 );
- quadB.vertexColors[ 0 ].copy( vcm2 );
- quadB.vertexColors[ 1 ].copy( vcm1 );
- }
- edge = 1;
- }
- faces.push( quadA, quadB );
- geometry.vertices.push( vm1, vm2 );
- var j, jl, uvs, uvA, uvB, uvC, uvD, uvM1, uvM2, uvsQuadA, uvsQuadB;
- for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- if ( geometry.faceVertexUvs[ j ].length ) {
- uvs = geometry.faceVertexUvs[ j ][ i ];
- uvA = uvs[ 0 ];
- uvB = uvs[ 1 ];
- uvC = uvs[ 2 ];
- uvD = uvs[ 3 ];
- // AB + CD
- if ( edge === 0 ) {
- uvM1 = uvA.clone();
- uvM1.lerp( uvB, 0.5 );
- uvM2 = uvC.clone();
- uvM2.lerp( uvD, 0.5 );
- uvsQuadA = [ uvA.clone(), uvM1.clone(), uvM2.clone(), uvD.clone() ];
- uvsQuadB = [ uvM1.clone(), uvB.clone(), uvC.clone(), uvM2.clone() ];
- // BC + AD
- } else {
- uvM1 = uvB.clone();
- uvM1.lerp( uvC, 0.5 );
- uvM2 = uvD.clone();
- uvM2.lerp( uvA, 0.5 );
- uvsQuadA = [ uvA.clone(), uvB.clone(), uvM1.clone(), uvM2.clone() ];
- uvsQuadB = [ uvM2.clone(), uvM1.clone(), uvC.clone(), uvD.clone() ];
- }
- faceVertexUvs[ j ].push( uvsQuadA, uvsQuadB );
- }
- }
- } else {
- faces.push( face );
- for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
- }
- }
- }
- }
- geometry.faces = faces;
- geometry.faceVertexUvs = faceVertexUvs;
- }
|