123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- import {
- BufferGeometry,
- Face3,
- Geometry
- } from "../../../build/three.module.js";
- /**
- * Break faces with edges longer than maxEdgeLength
- */
- var TessellateModifier = function ( maxEdgeLength = 0.1, maxIterations = 6, maxFaces = Infinity ) {
- this.maxEdgeLength = maxEdgeLength;
- this.maxIterations = maxIterations;
- this.maxFaces = maxFaces;
- };
- // Applies the "modify" pattern
- TessellateModifier.prototype.modify = function ( geometry ) {
- const isBufferGeometry = geometry.isBufferGeometry;
- if ( isBufferGeometry ) {
- geometry = new Geometry().fromBufferGeometry( geometry );
- } else {
- geometry = geometry.clone();
- }
- geometry.mergeVertices( 6 );
- let finalized = false;
- let iteration = 0;
- const maxEdgeLengthSquared = this.maxEdgeLength * this.maxEdgeLength;
- let edge;
- while ( ! finalized && iteration < this.maxIterations && geometry.faces.length < this.maxFaces ) {
- const faces = [];
- const faceVertexUvs = [];
- finalized = true;
- iteration ++;
- for ( var i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
- faceVertexUvs[ i ] = [];
- }
- for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
- const face = geometry.faces[ i ];
- if ( face instanceof Face3 ) {
- const a = face.a;
- const b = face.b;
- const c = face.c;
- const va = geometry.vertices[ a ];
- const vb = geometry.vertices[ b ];
- const vc = geometry.vertices[ c ];
- const dab = va.distanceToSquared( vb );
- const dbc = vb.distanceToSquared( vc );
- const dac = va.distanceToSquared( vc );
- const limitReached = ( faces.length + il - i ) >= this.maxFaces;
- if ( ! limitReached && ( dab > maxEdgeLengthSquared || dbc > maxEdgeLengthSquared || dac > maxEdgeLengthSquared ) ) {
- finalized = false;
- const m = geometry.vertices.length;
- const triA = face.clone();
- const triB = face.clone();
- if ( dab >= dbc && dab >= dac ) {
- var 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 ) {
- var 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 ) {
- var 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 ) {
- var 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 ) {
- var 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 ) {
- var 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 {
- var 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 ) {
- var 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 ) {
- var 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 );
- for ( var j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- if ( geometry.faceVertexUvs[ j ].length ) {
- const uvs = geometry.faceVertexUvs[ j ][ i ];
- const uvA = uvs[ 0 ];
- const uvB = uvs[ 1 ];
- const uvC = uvs[ 2 ];
- // AB
- if ( edge === 0 ) {
- var uvM = uvA.clone();
- uvM.lerp( uvB, 0.5 );
- var uvsTriA = [ uvA.clone(), uvM.clone(), uvC.clone() ];
- var uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
- // BC
- } else if ( edge === 1 ) {
- var uvM = uvB.clone();
- uvM.lerp( uvC, 0.5 );
- var uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
- var uvsTriB = [ uvM.clone(), uvC.clone(), uvA.clone() ];
- // AC
- } else {
- var uvM = uvA.clone();
- uvM.lerp( uvC, 0.5 );
- var uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
- var uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
- }
- faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
- }
- }
- } else {
- faces.push( face );
- for ( var j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
- }
- }
- }
- }
- geometry.faces = faces;
- geometry.faceVertexUvs = faceVertexUvs;
- }
- if ( isBufferGeometry ) {
- return new BufferGeometry().fromGeometry( geometry );
- } else {
- return geometry;
- }
- };
- export { TessellateModifier };
|