12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055 |
- /**
- * @author mrdoob / http://mrdoob.com/
- * @author alteredq / http://alteredqualia.com/
- */
- THREE.GeometryUtils = {
- // Merge two geometries or geometry and geometry from object (using object's transform)
- merge: function ( geometry1, object2 /* mesh | geometry */ ) {
- var matrix, matrixRotation,
- vertexOffset = geometry1.vertices.length,
- uvPosition = geometry1.faceVertexUvs[ 0 ].length,
- geometry2 = object2 instanceof THREE.Mesh ? object2.geometry : object2,
- vertices1 = geometry1.vertices,
- vertices2 = geometry2.vertices,
- faces1 = geometry1.faces,
- faces2 = geometry2.faces,
- uvs1 = geometry1.faceVertexUvs[ 0 ],
- uvs2 = geometry2.faceVertexUvs[ 0 ];
- if ( object2 instanceof THREE.Mesh ) {
- object2.matrixAutoUpdate && object2.updateMatrix();
- matrix = object2.matrix;
- matrixRotation = new THREE.Matrix4();
- matrixRotation.extractRotation( matrix, object2.scale );
- }
- // vertices
- for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
- var vertex = vertices2[ i ];
- var vertexCopy = vertex.clone();
- if ( matrix ) vertexCopy.multiplyMatrix4( matrix );
- vertices1.push( vertexCopy );
- }
- // faces
- for ( i = 0, il = faces2.length; i < il; i ++ ) {
- var face = faces2[ i ], faceCopy, normal, color,
- faceVertexNormals = face.vertexNormals,
- faceVertexColors = face.vertexColors;
- if ( face instanceof THREE.Face3 ) {
- faceCopy = new THREE.Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
- } else if ( face instanceof THREE.Face4 ) {
- faceCopy = new THREE.Face4( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset, face.d + vertexOffset );
- }
- faceCopy.normal.copy( face.normal );
- if ( matrixRotation ) faceCopy.normal.multiplyMatrix4( matrixRotation );
- for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
- normal = faceVertexNormals[ j ].clone();
- if ( matrixRotation ) normal.multiplyMatrix4( matrixRotation );
- faceCopy.vertexNormals.push( normal );
- }
- faceCopy.color.copy( face.color );
- for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
- color = faceVertexColors[ j ];
- faceCopy.vertexColors.push( color.clone() );
- }
- faceCopy.materialIndex = face.materialIndex;
- faceCopy.centroid.copy( face.centroid );
- if ( matrix ) faceCopy.centroid.multiplyMatrix4( matrix );
- faces1.push( faceCopy );
- }
- // uvs
- for ( i = 0, il = uvs2.length; i < il; i ++ ) {
- var uv = uvs2[ i ], uvCopy = [];
- for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
- uvCopy.push( new THREE.Vector2( uv[ j ].x, uv[ j ].y ) );
- }
- uvs1.push( uvCopy );
- }
- },
- removeMaterials: function ( geometry, materialIndexArray ) {
- var materialIndexMap = {};
- for ( var i = 0, il = materialIndexArray.length; i < il; i ++ ) {
- materialIndexMap[ materialIndexArray[i] ] = true;
- }
- var face, newFaces = [];
- for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
- face = geometry.faces[ i ];
- if ( ! ( face.materialIndex in materialIndexMap ) ) newFaces.push( face );
- }
- geometry.faces = newFaces;
- },
- // Get random point in triangle (via barycentric coordinates)
- // (uniform distribution)
- // http://www.cgafaq.info/wiki/Random_Point_In_Triangle
- randomPointInTriangle: function ( vectorA, vectorB, vectorC ) {
- var a, b, c,
- point = new THREE.Vector3(),
- tmp = THREE.GeometryUtils.__v1;
- a = THREE.GeometryUtils.random();
- b = THREE.GeometryUtils.random();
- if ( ( a + b ) > 1 ) {
- a = 1 - a;
- b = 1 - b;
- }
- c = 1 - a - b;
- point.copy( vectorA );
- point.multiplyScalar( a );
- tmp.copy( vectorB );
- tmp.multiplyScalar( b );
- point.addSelf( tmp );
- tmp.copy( vectorC );
- tmp.multiplyScalar( c );
- point.addSelf( tmp );
- return point;
- },
- // Get random point in face (triangle / quad)
- // (uniform distribution)
- randomPointInFace: function ( face, geometry, useCachedAreas ) {
- var vA, vB, vC, vD;
- if ( face instanceof THREE.Face3 ) {
- vA = geometry.vertices[ face.a ];
- vB = geometry.vertices[ face.b ];
- vC = geometry.vertices[ face.c ];
- return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC );
- } else if ( face instanceof THREE.Face4 ) {
- vA = geometry.vertices[ face.a ];
- vB = geometry.vertices[ face.b ];
- vC = geometry.vertices[ face.c ];
- vD = geometry.vertices[ face.d ];
- var area1, area2;
- if ( useCachedAreas ) {
- if ( face._area1 && face._area2 ) {
- area1 = face._area1;
- area2 = face._area2;
- } else {
- area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
- area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
- face._area1 = area1;
- face._area2 = area2;
- }
- } else {
- area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD ),
- area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
- }
- var r = THREE.GeometryUtils.random() * ( area1 + area2 );
- if ( r < area1 ) {
- return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vD );
- } else {
- return THREE.GeometryUtils.randomPointInTriangle( vB, vC, vD );
- }
- }
- },
- // Get uniformly distributed random points in mesh
- // - create array with cumulative sums of face areas
- // - pick random number from 0 to total area
- // - find corresponding place in area array by binary search
- // - get random point in face
- randomPointsInGeometry: function ( geometry, n ) {
- var face, i,
- faces = geometry.faces,
- vertices = geometry.vertices,
- il = faces.length,
- totalArea = 0,
- cumulativeAreas = [],
- vA, vB, vC, vD;
- // precompute face areas
- for ( i = 0; i < il; i ++ ) {
- face = faces[ i ];
- if ( face instanceof THREE.Face3 ) {
- vA = vertices[ face.a ];
- vB = vertices[ face.b ];
- vC = vertices[ face.c ];
- face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC );
- } else if ( face instanceof THREE.Face4 ) {
- vA = vertices[ face.a ];
- vB = vertices[ face.b ];
- vC = vertices[ face.c ];
- vD = vertices[ face.d ];
- face._area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
- face._area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
- face._area = face._area1 + face._area2;
- }
- totalArea += face._area;
- cumulativeAreas[ i ] = totalArea;
- }
- // binary search cumulative areas array
- function binarySearchIndices( value ) {
- function binarySearch( start, end ) {
- // return closest larger index
- // if exact number is not found
- if ( end < start )
- return start;
- var mid = start + Math.floor( ( end - start ) / 2 );
- if ( cumulativeAreas[ mid ] > value ) {
- return binarySearch( start, mid - 1 );
- } else if ( cumulativeAreas[ mid ] < value ) {
- return binarySearch( mid + 1, end );
- } else {
- return mid;
- }
- }
- var result = binarySearch( 0, cumulativeAreas.length - 1 )
- return result;
- }
- // pick random face weighted by face area
- var r, index,
- result = [];
- var stats = {};
- for ( i = 0; i < n; i ++ ) {
- r = THREE.GeometryUtils.random() * totalArea;
- index = binarySearchIndices( r );
- result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry, true );
- if ( ! stats[ index ] ) {
- stats[ index ] = 1;
- } else {
- stats[ index ] += 1;
- }
- }
- return result;
- },
- // Get triangle area (half of parallelogram)
- // http://mathworld.wolfram.com/TriangleArea.html
- triangleArea: function ( vectorA, vectorB, vectorC ) {
- var tmp1 = THREE.GeometryUtils.__v1,
- tmp2 = THREE.GeometryUtils.__v2;
- tmp1.sub( vectorB, vectorA );
- tmp2.sub( vectorC, vectorA );
- tmp1.crossSelf( tmp2 );
- return 0.5 * tmp1.length();
- },
- // Center geometry so that 0,0,0 is in center of bounding box
- center: function ( geometry ) {
- geometry.computeBoundingBox();
- var bb = geometry.boundingBox;
- var offset = new THREE.Vector3();
- offset.add( bb.min, bb.max );
- offset.multiplyScalar( -0.5 );
- geometry.applyMatrix( new THREE.Matrix4().makeTranslation( offset ) );
- geometry.computeBoundingBox();
- return offset;
- },
- // Normalize UVs to be from <0,1>
- // (for now just the first set of UVs)
- normalizeUVs: function ( geometry ) {
- var uvSet = geometry.faceVertexUvs[ 0 ];
- for ( var i = 0, il = uvSet.length; i < il; i ++ ) {
- var uvs = uvSet[ i ];
- for ( var j = 0, jl = uvs.length; j < jl; j ++ ) {
- // texture repeat
- if( uvs[ j ].x !== 1.0 ) uvs[ j ].x = uvs[ j ].x - Math.floor( uvs[ j ].x );
- if( uvs[ j ].y !== 1.0 ) uvs[ j ].y = uvs[ j ].y - Math.floor( uvs[ j ].y );
- }
- }
- },
- triangulateQuads: function ( geometry ) {
- var i, il, j, jl;
- var faces = [];
- var faceUvs = [];
- var faceVertexUvs = [];
- for ( i = 0, il = geometry.faceUvs.length; i < il; i ++ ) {
- faceUvs[ i ] = [];
- }
- for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
- faceVertexUvs[ i ] = [];
- }
- for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
- var face = geometry.faces[ i ];
- if ( face instanceof THREE.Face4 ) {
- var a = face.a;
- var b = face.b;
- var c = face.c;
- var d = face.d;
- var triA = new THREE.Face3();
- var triB = new THREE.Face3();
- triA.color.copy( face.color );
- triB.color.copy( face.color );
- triA.materialIndex = face.materialIndex;
- triB.materialIndex = face.materialIndex;
- triA.a = a;
- triA.b = b;
- triA.c = d;
- triB.a = b;
- triB.b = c;
- triB.c = d;
- if ( face.vertexColors.length === 4 ) {
- triA.vertexColors[ 0 ] = face.vertexColors[ 0 ].clone();
- triA.vertexColors[ 1 ] = face.vertexColors[ 1 ].clone();
- triA.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
- triB.vertexColors[ 0 ] = face.vertexColors[ 1 ].clone();
- triB.vertexColors[ 1 ] = face.vertexColors[ 2 ].clone();
- triB.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
- }
- faces.push( triA, triB );
- for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- if ( geometry.faceVertexUvs[ j ].length ) {
- var uvs = geometry.faceVertexUvs[ j ][ i ];
- var uvA = uvs[ 0 ];
- var uvB = uvs[ 1 ];
- var uvC = uvs[ 2 ];
- var uvD = uvs[ 3 ];
- var uvsTriA = [ uvA.clone(), uvB.clone(), uvD.clone() ];
- var uvsTriB = [ uvB.clone(), uvC.clone(), uvD.clone() ];
- faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
- }
- }
- for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
- if ( geometry.faceUvs[ j ].length ) {
- var faceUv = geometry.faceUvs[ j ][ i ];
- faceUvs[ j ].push( faceUv, faceUv );
- }
- }
- } else {
- faces.push( face );
- for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
- faceUvs[ j ].push( geometry.faceUvs[ j ][ i ] );
- }
- for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
- faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
- }
- }
- }
- geometry.faces = faces;
- geometry.faceUvs = faceUvs;
- geometry.faceVertexUvs = faceVertexUvs;
- geometry.computeCentroids();
- geometry.computeFaceNormals();
- geometry.computeVertexNormals();
- if ( geometry.hasTangents ) geometry.computeTangents();
- },
- // Make all faces use unique vertices
- // so that each face can be separated from others
- explode: function( geometry ) {
- var vertices = [];
- for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
- var n = vertices.length;
- var face = geometry.faces[ i ];
- if ( face instanceof THREE.Face4 ) {
- var a = face.a;
- var b = face.b;
- var c = face.c;
- var d = face.d;
- var va = geometry.vertices[ a ];
- var vb = geometry.vertices[ b ];
- var vc = geometry.vertices[ c ];
- var vd = geometry.vertices[ d ];
- vertices.push( va.clone() );
- vertices.push( vb.clone() );
- vertices.push( vc.clone() );
- vertices.push( vd.clone() );
- face.a = n;
- face.b = n + 1;
- face.c = n + 2;
- face.d = n + 3;
- } else {
- var a = face.a;
- var b = face.b;
- var c = face.c;
- var va = geometry.vertices[ a ];
- var vb = geometry.vertices[ b ];
- var vc = geometry.vertices[ c ];
- vertices.push( va.clone() );
- vertices.push( vb.clone() );
- vertices.push( vc.clone() );
- face.a = n;
- face.b = n + 1;
- face.c = n + 2;
- }
- }
- geometry.vertices = vertices;
- delete geometry.__tmpVertices;
- },
- // Break faces with edges longer than maxEdgeLength
- // - not recursive
- tessellate: function ( geometry, maxEdgeLength ) {
- 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 = [];
- 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( 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.lerpSelf( uvC, 0.5 );
- uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
- uvsTriB = [ uvM.clone(), uvC.clone(), uvA.clone() ];
- // AC
- } else {
- uvM = uvA.clone();
- uvM.lerpSelf( 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.lerpSelf( vb, 0.5 );
- vm2 = vc.clone();
- vm2.lerpSelf( 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.lerpSelf( face.vertexNormals[ 1 ], 0.5 );
- vnm2 = face.vertexNormals[ 2 ].clone();
- vnm2.lerpSelf( 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.lerpSelf( face.vertexColors[ 1 ], 0.5 );
- vcm2 = face.vertexColors[ 2 ].clone();
- vcm2.lerpSelf( 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.lerpSelf( vc, 0.5 );
- vm2 = vd.clone();
- vm2.lerpSelf( 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.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
- vnm2 = face.vertexNormals[ 3 ].clone();
- vnm2.lerpSelf( 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.lerpSelf( face.vertexColors[ 2 ], 0.5 );
- vcm2 = face.vertexColors[ 3 ].clone();
- vcm2.lerpSelf( 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.lerpSelf( uvB, 0.5 );
- uvM2 = uvC.clone();
- uvM2.lerpSelf( 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.lerpSelf( uvC, 0.5 );
- uvM2 = uvD.clone();
- uvM2.lerpSelf( 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;
- },
-
- setMaterialIndex: function ( geometry, index, startFace, endFace ){
-
- var faces = geometry.faces;
- var start = startFace || 0;
- var end = endFace || faces.length - 1;
-
- for ( var i = start; i <= end; i ++ ) {
-
- faces[i].materialIndex = index;
- }
-
- }
- };
- THREE.GeometryUtils.random = THREE.Math.random16;
- THREE.GeometryUtils.__v1 = new THREE.Vector3();
- THREE.GeometryUtils.__v2 = new THREE.Vector3();
|