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