topical media & game development

talk show tell print

mobile-query-three-vendor-three.js-modifiers-TessellateModifier.js / js



  
Break faces with edges longer than maxEdgeLength - not recursive
author: alteredq / 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;
  
  }
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.