GeometryUtils.js 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. * @author alteredq / http://alteredqualia.com/
  4. */
  5. THREE.GeometryUtils = {
  6. // Merge two geometries or geometry and geometry from object (using object's transform)
  7. merge: function ( geometry1, object2 /* mesh | geometry */ ) {
  8. var matrix, matrixRotation,
  9. vertexOffset = geometry1.vertices.length,
  10. uvPosition = geometry1.faceVertexUvs[ 0 ].length,
  11. geometry2 = object2 instanceof THREE.Mesh ? object2.geometry : object2,
  12. vertices1 = geometry1.vertices,
  13. vertices2 = geometry2.vertices,
  14. faces1 = geometry1.faces,
  15. faces2 = geometry2.faces,
  16. uvs1 = geometry1.faceVertexUvs[ 0 ],
  17. uvs2 = geometry2.faceVertexUvs[ 0 ];
  18. if ( object2 instanceof THREE.Mesh ) {
  19. object2.matrixAutoUpdate && object2.updateMatrix();
  20. matrix = object2.matrix;
  21. matrixRotation = new THREE.Matrix4();
  22. matrixRotation.extractRotation( matrix, object2.scale );
  23. }
  24. // vertices
  25. for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
  26. var vertex = vertices2[ i ];
  27. var vertexCopy = vertex.clone();
  28. if ( matrix ) vertexCopy.multiplyMatrix4( matrix );
  29. vertices1.push( vertexCopy );
  30. }
  31. // faces
  32. for ( i = 0, il = faces2.length; i < il; i ++ ) {
  33. var face = faces2[ i ], faceCopy, normal, color,
  34. faceVertexNormals = face.vertexNormals,
  35. faceVertexColors = face.vertexColors;
  36. if ( face instanceof THREE.Face3 ) {
  37. faceCopy = new THREE.Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
  38. } else if ( face instanceof THREE.Face4 ) {
  39. faceCopy = new THREE.Face4( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset, face.d + vertexOffset );
  40. }
  41. faceCopy.normal.copy( face.normal );
  42. if ( matrixRotation ) faceCopy.normal.multiplyMatrix4( matrixRotation );
  43. for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
  44. normal = faceVertexNormals[ j ].clone();
  45. if ( matrixRotation ) normal.multiplyMatrix4( matrixRotation );
  46. faceCopy.vertexNormals.push( normal );
  47. }
  48. faceCopy.color.copy( face.color );
  49. for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
  50. color = faceVertexColors[ j ];
  51. faceCopy.vertexColors.push( color.clone() );
  52. }
  53. faceCopy.materialIndex = face.materialIndex;
  54. faceCopy.centroid.copy( face.centroid );
  55. if ( matrix ) faceCopy.centroid.multiplyMatrix4( matrix );
  56. faces1.push( faceCopy );
  57. }
  58. // uvs
  59. for ( i = 0, il = uvs2.length; i < il; i ++ ) {
  60. var uv = uvs2[ i ], uvCopy = [];
  61. for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
  62. uvCopy.push( new THREE.Vector2( uv[ j ].x, uv[ j ].y ) );
  63. }
  64. uvs1.push( uvCopy );
  65. }
  66. },
  67. removeMaterials: function ( geometry, materialIndexArray ) {
  68. var materialIndexMap = {};
  69. for ( var i = 0, il = materialIndexArray.length; i < il; i ++ ) {
  70. materialIndexMap[ materialIndexArray[i] ] = true;
  71. }
  72. var face, newFaces = [];
  73. for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
  74. face = geometry.faces[ i ];
  75. if ( ! ( face.materialIndex in materialIndexMap ) ) newFaces.push( face );
  76. }
  77. geometry.faces = newFaces;
  78. },
  79. // Get random point in triangle (via barycentric coordinates)
  80. // (uniform distribution)
  81. // http://www.cgafaq.info/wiki/Random_Point_In_Triangle
  82. randomPointInTriangle: function ( vectorA, vectorB, vectorC ) {
  83. var a, b, c,
  84. point = new THREE.Vector3(),
  85. tmp = THREE.GeometryUtils.__v1;
  86. a = THREE.GeometryUtils.random();
  87. b = THREE.GeometryUtils.random();
  88. if ( ( a + b ) > 1 ) {
  89. a = 1 - a;
  90. b = 1 - b;
  91. }
  92. c = 1 - a - b;
  93. point.copy( vectorA );
  94. point.multiplyScalar( a );
  95. tmp.copy( vectorB );
  96. tmp.multiplyScalar( b );
  97. point.addSelf( tmp );
  98. tmp.copy( vectorC );
  99. tmp.multiplyScalar( c );
  100. point.addSelf( tmp );
  101. return point;
  102. },
  103. // Get random point in face (triangle / quad)
  104. // (uniform distribution)
  105. randomPointInFace: function ( face, geometry, useCachedAreas ) {
  106. var vA, vB, vC, vD;
  107. if ( face instanceof THREE.Face3 ) {
  108. vA = geometry.vertices[ face.a ];
  109. vB = geometry.vertices[ face.b ];
  110. vC = geometry.vertices[ face.c ];
  111. return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC );
  112. } else if ( face instanceof THREE.Face4 ) {
  113. vA = geometry.vertices[ face.a ];
  114. vB = geometry.vertices[ face.b ];
  115. vC = geometry.vertices[ face.c ];
  116. vD = geometry.vertices[ face.d ];
  117. var area1, area2;
  118. if ( useCachedAreas ) {
  119. if ( face._area1 && face._area2 ) {
  120. area1 = face._area1;
  121. area2 = face._area2;
  122. } else {
  123. area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
  124. area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
  125. face._area1 = area1;
  126. face._area2 = area2;
  127. }
  128. } else {
  129. area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD ),
  130. area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
  131. }
  132. var r = THREE.GeometryUtils.random() * ( area1 + area2 );
  133. if ( r < area1 ) {
  134. return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vD );
  135. } else {
  136. return THREE.GeometryUtils.randomPointInTriangle( vB, vC, vD );
  137. }
  138. }
  139. },
  140. // Get uniformly distributed random points in mesh
  141. // - create array with cumulative sums of face areas
  142. // - pick random number from 0 to total area
  143. // - find corresponding place in area array by binary search
  144. // - get random point in face
  145. randomPointsInGeometry: function ( geometry, n ) {
  146. var face, i,
  147. faces = geometry.faces,
  148. vertices = geometry.vertices,
  149. il = faces.length,
  150. totalArea = 0,
  151. cumulativeAreas = [],
  152. vA, vB, vC, vD;
  153. // precompute face areas
  154. for ( i = 0; i < il; i ++ ) {
  155. face = faces[ i ];
  156. if ( face instanceof THREE.Face3 ) {
  157. vA = vertices[ face.a ];
  158. vB = vertices[ face.b ];
  159. vC = vertices[ face.c ];
  160. face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC );
  161. } else if ( face instanceof THREE.Face4 ) {
  162. vA = vertices[ face.a ];
  163. vB = vertices[ face.b ];
  164. vC = vertices[ face.c ];
  165. vD = vertices[ face.d ];
  166. face._area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
  167. face._area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
  168. face._area = face._area1 + face._area2;
  169. }
  170. totalArea += face._area;
  171. cumulativeAreas[ i ] = totalArea;
  172. }
  173. // binary search cumulative areas array
  174. function binarySearchIndices( value ) {
  175. function binarySearch( start, end ) {
  176. // return closest larger index
  177. // if exact number is not found
  178. if ( end < start )
  179. return start;
  180. var mid = start + Math.floor( ( end - start ) / 2 );
  181. if ( cumulativeAreas[ mid ] > value ) {
  182. return binarySearch( start, mid - 1 );
  183. } else if ( cumulativeAreas[ mid ] < value ) {
  184. return binarySearch( mid + 1, end );
  185. } else {
  186. return mid;
  187. }
  188. }
  189. var result = binarySearch( 0, cumulativeAreas.length - 1 )
  190. return result;
  191. }
  192. // pick random face weighted by face area
  193. var r, index,
  194. result = [];
  195. var stats = {};
  196. for ( i = 0; i < n; i ++ ) {
  197. r = THREE.GeometryUtils.random() * totalArea;
  198. index = binarySearchIndices( r );
  199. result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry, true );
  200. if ( ! stats[ index ] ) {
  201. stats[ index ] = 1;
  202. } else {
  203. stats[ index ] += 1;
  204. }
  205. }
  206. return result;
  207. },
  208. // Get triangle area (half of parallelogram)
  209. // http://mathworld.wolfram.com/TriangleArea.html
  210. triangleArea: function ( vectorA, vectorB, vectorC ) {
  211. var tmp1 = THREE.GeometryUtils.__v1,
  212. tmp2 = THREE.GeometryUtils.__v2;
  213. tmp1.sub( vectorB, vectorA );
  214. tmp2.sub( vectorC, vectorA );
  215. tmp1.crossSelf( tmp2 );
  216. return 0.5 * tmp1.length();
  217. },
  218. // Center geometry so that 0,0,0 is in center of bounding box
  219. center: function ( geometry ) {
  220. geometry.computeBoundingBox();
  221. var bb = geometry.boundingBox;
  222. var offset = new THREE.Vector3();
  223. offset.add( bb.min, bb.max );
  224. offset.multiplyScalar( -0.5 );
  225. geometry.applyMatrix( new THREE.Matrix4().makeTranslation( offset ) );
  226. geometry.computeBoundingBox();
  227. return offset;
  228. },
  229. // Normalize UVs to be from <0,1>
  230. // (for now just the first set of UVs)
  231. normalizeUVs: function ( geometry ) {
  232. var uvSet = geometry.faceVertexUvs[ 0 ];
  233. for ( var i = 0, il = uvSet.length; i < il; i ++ ) {
  234. var uvs = uvSet[ i ];
  235. for ( var j = 0, jl = uvs.length; j < jl; j ++ ) {
  236. // texture repeat
  237. if( uvs[ j ].x !== 1.0 ) uvs[ j ].x = uvs[ j ].x - Math.floor( uvs[ j ].x );
  238. if( uvs[ j ].y !== 1.0 ) uvs[ j ].y = uvs[ j ].y - Math.floor( uvs[ j ].y );
  239. }
  240. }
  241. },
  242. triangulateQuads: function ( geometry ) {
  243. var i, il, j, jl;
  244. var faces = [];
  245. var faceUvs = [];
  246. var faceVertexUvs = [];
  247. for ( i = 0, il = geometry.faceUvs.length; i < il; i ++ ) {
  248. faceUvs[ i ] = [];
  249. }
  250. for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
  251. faceVertexUvs[ i ] = [];
  252. }
  253. for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
  254. var face = geometry.faces[ i ];
  255. if ( face instanceof THREE.Face4 ) {
  256. var a = face.a;
  257. var b = face.b;
  258. var c = face.c;
  259. var d = face.d;
  260. var triA = new THREE.Face3();
  261. var triB = new THREE.Face3();
  262. triA.color.copy( face.color );
  263. triB.color.copy( face.color );
  264. triA.materialIndex = face.materialIndex;
  265. triB.materialIndex = face.materialIndex;
  266. triA.a = a;
  267. triA.b = b;
  268. triA.c = d;
  269. triB.a = b;
  270. triB.b = c;
  271. triB.c = d;
  272. if ( face.vertexColors.length === 4 ) {
  273. triA.vertexColors[ 0 ] = face.vertexColors[ 0 ].clone();
  274. triA.vertexColors[ 1 ] = face.vertexColors[ 1 ].clone();
  275. triA.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
  276. triB.vertexColors[ 0 ] = face.vertexColors[ 1 ].clone();
  277. triB.vertexColors[ 1 ] = face.vertexColors[ 2 ].clone();
  278. triB.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
  279. }
  280. faces.push( triA, triB );
  281. for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
  282. if ( geometry.faceVertexUvs[ j ].length ) {
  283. var uvs = geometry.faceVertexUvs[ j ][ i ];
  284. var uvA = uvs[ 0 ];
  285. var uvB = uvs[ 1 ];
  286. var uvC = uvs[ 2 ];
  287. var uvD = uvs[ 3 ];
  288. var uvsTriA = [ uvA.clone(), uvB.clone(), uvD.clone() ];
  289. var uvsTriB = [ uvB.clone(), uvC.clone(), uvD.clone() ];
  290. faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
  291. }
  292. }
  293. for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
  294. if ( geometry.faceUvs[ j ].length ) {
  295. var faceUv = geometry.faceUvs[ j ][ i ];
  296. faceUvs[ j ].push( faceUv, faceUv );
  297. }
  298. }
  299. } else {
  300. faces.push( face );
  301. for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
  302. faceUvs[ j ].push( geometry.faceUvs[ j ][ i ] );
  303. }
  304. for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
  305. faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
  306. }
  307. }
  308. }
  309. geometry.faces = faces;
  310. geometry.faceUvs = faceUvs;
  311. geometry.faceVertexUvs = faceVertexUvs;
  312. geometry.computeCentroids();
  313. geometry.computeFaceNormals();
  314. geometry.computeVertexNormals();
  315. if ( geometry.hasTangents ) geometry.computeTangents();
  316. },
  317. // Make all faces use unique vertices
  318. // so that each face can be separated from others
  319. explode: function( geometry ) {
  320. var vertices = [];
  321. for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
  322. var n = vertices.length;
  323. var face = geometry.faces[ i ];
  324. if ( face instanceof THREE.Face4 ) {
  325. var a = face.a;
  326. var b = face.b;
  327. var c = face.c;
  328. var d = face.d;
  329. var va = geometry.vertices[ a ];
  330. var vb = geometry.vertices[ b ];
  331. var vc = geometry.vertices[ c ];
  332. var vd = geometry.vertices[ d ];
  333. vertices.push( va.clone() );
  334. vertices.push( vb.clone() );
  335. vertices.push( vc.clone() );
  336. vertices.push( vd.clone() );
  337. face.a = n;
  338. face.b = n + 1;
  339. face.c = n + 2;
  340. face.d = n + 3;
  341. } else {
  342. var a = face.a;
  343. var b = face.b;
  344. var c = face.c;
  345. var va = geometry.vertices[ a ];
  346. var vb = geometry.vertices[ b ];
  347. var vc = geometry.vertices[ c ];
  348. vertices.push( va.clone() );
  349. vertices.push( vb.clone() );
  350. vertices.push( vc.clone() );
  351. face.a = n;
  352. face.b = n + 1;
  353. face.c = n + 2;
  354. }
  355. }
  356. geometry.vertices = vertices;
  357. delete geometry.__tmpVertices;
  358. },
  359. // Break faces with edges longer than maxEdgeLength
  360. // - not recursive
  361. tessellate: function ( geometry, maxEdgeLength ) {
  362. var i, il, face,
  363. a, b, c, d,
  364. va, vb, vc, vd,
  365. dab, dbc, dac, dcd, dad,
  366. m, m1, m2,
  367. vm, vm1, vm2,
  368. vnm, vnm1, vnm2,
  369. vcm, vcm1, vcm2,
  370. triA, triB,
  371. quadA, quadB,
  372. edge;
  373. var faces = [];
  374. var faceVertexUvs = [];
  375. for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
  376. faceVertexUvs[ i ] = [];
  377. }
  378. for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
  379. face = geometry.faces[ i ];
  380. if ( face instanceof THREE.Face3 ) {
  381. a = face.a;
  382. b = face.b;
  383. c = face.c;
  384. va = geometry.vertices[ a ];
  385. vb = geometry.vertices[ b ];
  386. vc = geometry.vertices[ c ];
  387. dab = va.distanceTo( vb );
  388. dbc = vb.distanceTo( vc );
  389. dac = va.distanceTo( vc );
  390. if ( dab > maxEdgeLength || dbc > maxEdgeLength || dac > maxEdgeLength ) {
  391. m = geometry.vertices.length;
  392. triA = face.clone();
  393. triB = face.clone();
  394. if ( dab >= dbc && dab >= dac ) {
  395. vm = va.clone();
  396. vm.lerpSelf( vb, 0.5 );
  397. triA.a = a;
  398. triA.b = m;
  399. triA.c = c;
  400. triB.a = m;
  401. triB.b = b;
  402. triB.c = c;
  403. if ( face.vertexNormals.length === 3 ) {
  404. vnm = face.vertexNormals[ 0 ].clone();
  405. vnm.lerpSelf( face.vertexNormals[ 1 ], 0.5 );
  406. triA.vertexNormals[ 1 ].copy( vnm );
  407. triB.vertexNormals[ 0 ].copy( vnm );
  408. }
  409. if ( face.vertexColors.length === 3 ) {
  410. vcm = face.vertexColors[ 0 ].clone();
  411. vcm.lerpSelf( face.vertexColors[ 1 ], 0.5 );
  412. triA.vertexColors[ 1 ].copy( vcm );
  413. triB.vertexColors[ 0 ].copy( vcm );
  414. }
  415. edge = 0;
  416. } else if ( dbc >= dab && dbc >= dac ) {
  417. vm = vb.clone();
  418. vm.lerpSelf( vc, 0.5 );
  419. triA.a = a;
  420. triA.b = b;
  421. triA.c = m;
  422. triB.a = m;
  423. triB.b = c;
  424. triB.c = a;
  425. if ( face.vertexNormals.length === 3 ) {
  426. vnm = face.vertexNormals[ 1 ].clone();
  427. vnm.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
  428. triA.vertexNormals[ 2 ].copy( vnm );
  429. triB.vertexNormals[ 0 ].copy( vnm );
  430. triB.vertexNormals[ 1 ].copy( face.vertexNormals[ 2 ] );
  431. triB.vertexNormals[ 2 ].copy( face.vertexNormals[ 0 ] );
  432. }
  433. if ( face.vertexColors.length === 3 ) {
  434. vcm = face.vertexColors[ 1 ].clone();
  435. vcm.lerpSelf( face.vertexColors[ 2 ], 0.5 );
  436. triA.vertexColors[ 2 ].copy( vcm );
  437. triB.vertexColors[ 0 ].copy( vcm );
  438. triB.vertexColors[ 1 ].copy( face.vertexColors[ 2 ] );
  439. triB.vertexColors[ 2 ].copy( face.vertexColors[ 0 ] );
  440. }
  441. edge = 1;
  442. } else {
  443. vm = va.clone();
  444. vm.lerpSelf( vc, 0.5 );
  445. triA.a = a;
  446. triA.b = b;
  447. triA.c = m;
  448. triB.a = m;
  449. triB.b = b;
  450. triB.c = c;
  451. if ( face.vertexNormals.length === 3 ) {
  452. vnm = face.vertexNormals[ 0 ].clone();
  453. vnm.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
  454. triA.vertexNormals[ 2 ].copy( vnm );
  455. triB.vertexNormals[ 0 ].copy( vnm );
  456. }
  457. if ( face.vertexColors.length === 3 ) {
  458. vcm = face.vertexColors[ 0 ].clone();
  459. vcm.lerpSelf( face.vertexColors[ 2 ], 0.5 );
  460. triA.vertexColors[ 2 ].copy( vcm );
  461. triB.vertexColors[ 0 ].copy( vcm );
  462. }
  463. edge = 2;
  464. }
  465. faces.push( triA, triB );
  466. geometry.vertices.push( vm );
  467. var j, jl, uvs, uvA, uvB, uvC, uvM, uvsTriA, uvsTriB;
  468. for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
  469. if ( geometry.faceVertexUvs[ j ].length ) {
  470. uvs = geometry.faceVertexUvs[ j ][ i ];
  471. uvA = uvs[ 0 ];
  472. uvB = uvs[ 1 ];
  473. uvC = uvs[ 2 ];
  474. // AB
  475. if ( edge === 0 ) {
  476. uvM = uvA.clone();
  477. uvM.lerpSelf( uvB, 0.5 );
  478. uvsTriA = [ uvA.clone(), uvM.clone(), uvC.clone() ];
  479. uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
  480. // BC
  481. } else if ( edge === 1 ) {
  482. uvM = uvB.clone();
  483. uvM.lerpSelf( uvC, 0.5 );
  484. uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
  485. uvsTriB = [ uvM.clone(), uvC.clone(), uvA.clone() ];
  486. // AC
  487. } else {
  488. uvM = uvA.clone();
  489. uvM.lerpSelf( uvC, 0.5 );
  490. uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
  491. uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
  492. }
  493. faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
  494. }
  495. }
  496. } else {
  497. faces.push( face );
  498. for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
  499. faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
  500. }
  501. }
  502. } else {
  503. a = face.a;
  504. b = face.b;
  505. c = face.c;
  506. d = face.d;
  507. va = geometry.vertices[ a ];
  508. vb = geometry.vertices[ b ];
  509. vc = geometry.vertices[ c ];
  510. vd = geometry.vertices[ d ];
  511. dab = va.distanceTo( vb );
  512. dbc = vb.distanceTo( vc );
  513. dcd = vc.distanceTo( vd );
  514. dad = va.distanceTo( vd );
  515. if ( dab > maxEdgeLength || dbc > maxEdgeLength || dcd > maxEdgeLength || dad > maxEdgeLength ) {
  516. m1 = geometry.vertices.length;
  517. m2 = geometry.vertices.length + 1;
  518. quadA = face.clone();
  519. quadB = face.clone();
  520. if ( ( dab >= dbc && dab >= dcd && dab >= dad ) || ( dcd >= dbc && dcd >= dab && dcd >= dad ) ) {
  521. vm1 = va.clone();
  522. vm1.lerpSelf( vb, 0.5 );
  523. vm2 = vc.clone();
  524. vm2.lerpSelf( vd, 0.5 );
  525. quadA.a = a;
  526. quadA.b = m1;
  527. quadA.c = m2;
  528. quadA.d = d;
  529. quadB.a = m1;
  530. quadB.b = b;
  531. quadB.c = c;
  532. quadB.d = m2;
  533. if ( face.vertexNormals.length === 4 ) {
  534. vnm1 = face.vertexNormals[ 0 ].clone();
  535. vnm1.lerpSelf( face.vertexNormals[ 1 ], 0.5 );
  536. vnm2 = face.vertexNormals[ 2 ].clone();
  537. vnm2.lerpSelf( face.vertexNormals[ 3 ], 0.5 );
  538. quadA.vertexNormals[ 1 ].copy( vnm1 );
  539. quadA.vertexNormals[ 2 ].copy( vnm2 );
  540. quadB.vertexNormals[ 0 ].copy( vnm1 );
  541. quadB.vertexNormals[ 3 ].copy( vnm2 );
  542. }
  543. if ( face.vertexColors.length === 4 ) {
  544. vcm1 = face.vertexColors[ 0 ].clone();
  545. vcm1.lerpSelf( face.vertexColors[ 1 ], 0.5 );
  546. vcm2 = face.vertexColors[ 2 ].clone();
  547. vcm2.lerpSelf( face.vertexColors[ 3 ], 0.5 );
  548. quadA.vertexColors[ 1 ].copy( vcm1 );
  549. quadA.vertexColors[ 2 ].copy( vcm2 );
  550. quadB.vertexColors[ 0 ].copy( vcm1 );
  551. quadB.vertexColors[ 3 ].copy( vcm2 );
  552. }
  553. edge = 0;
  554. } else {
  555. vm1 = vb.clone();
  556. vm1.lerpSelf( vc, 0.5 );
  557. vm2 = vd.clone();
  558. vm2.lerpSelf( va, 0.5 );
  559. quadA.a = a;
  560. quadA.b = b;
  561. quadA.c = m1;
  562. quadA.d = m2;
  563. quadB.a = m2;
  564. quadB.b = m1;
  565. quadB.c = c;
  566. quadB.d = d;
  567. if ( face.vertexNormals.length === 4 ) {
  568. vnm1 = face.vertexNormals[ 1 ].clone();
  569. vnm1.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
  570. vnm2 = face.vertexNormals[ 3 ].clone();
  571. vnm2.lerpSelf( face.vertexNormals[ 0 ], 0.5 );
  572. quadA.vertexNormals[ 2 ].copy( vnm1 );
  573. quadA.vertexNormals[ 3 ].copy( vnm2 );
  574. quadB.vertexNormals[ 0 ].copy( vnm2 );
  575. quadB.vertexNormals[ 1 ].copy( vnm1 );
  576. }
  577. if ( face.vertexColors.length === 4 ) {
  578. vcm1 = face.vertexColors[ 1 ].clone();
  579. vcm1.lerpSelf( face.vertexColors[ 2 ], 0.5 );
  580. vcm2 = face.vertexColors[ 3 ].clone();
  581. vcm2.lerpSelf( face.vertexColors[ 0 ], 0.5 );
  582. quadA.vertexColors[ 2 ].copy( vcm1 );
  583. quadA.vertexColors[ 3 ].copy( vcm2 );
  584. quadB.vertexColors[ 0 ].copy( vcm2 );
  585. quadB.vertexColors[ 1 ].copy( vcm1 );
  586. }
  587. edge = 1;
  588. }
  589. faces.push( quadA, quadB );
  590. geometry.vertices.push( vm1, vm2 );
  591. var j, jl, uvs, uvA, uvB, uvC, uvD, uvM1, uvM2, uvsQuadA, uvsQuadB;
  592. for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
  593. if ( geometry.faceVertexUvs[ j ].length ) {
  594. uvs = geometry.faceVertexUvs[ j ][ i ];
  595. uvA = uvs[ 0 ];
  596. uvB = uvs[ 1 ];
  597. uvC = uvs[ 2 ];
  598. uvD = uvs[ 3 ];
  599. // AB + CD
  600. if ( edge === 0 ) {
  601. uvM1 = uvA.clone();
  602. uvM1.lerpSelf( uvB, 0.5 );
  603. uvM2 = uvC.clone();
  604. uvM2.lerpSelf( uvD, 0.5 );
  605. uvsQuadA = [ uvA.clone(), uvM1.clone(), uvM2.clone(), uvD.clone() ];
  606. uvsQuadB = [ uvM1.clone(), uvB.clone(), uvC.clone(), uvM2.clone() ];
  607. // BC + AD
  608. } else {
  609. uvM1 = uvB.clone();
  610. uvM1.lerpSelf( uvC, 0.5 );
  611. uvM2 = uvD.clone();
  612. uvM2.lerpSelf( uvA, 0.5 );
  613. uvsQuadA = [ uvA.clone(), uvB.clone(), uvM1.clone(), uvM2.clone() ];
  614. uvsQuadB = [ uvM2.clone(), uvM1.clone(), uvC.clone(), uvD.clone() ];
  615. }
  616. faceVertexUvs[ j ].push( uvsQuadA, uvsQuadB );
  617. }
  618. }
  619. } else {
  620. faces.push( face );
  621. for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
  622. faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
  623. }
  624. }
  625. }
  626. }
  627. geometry.faces = faces;
  628. geometry.faceVertexUvs = faceVertexUvs;
  629. },
  630. setMaterialIndex: function ( geometry, index, startFace, endFace ){
  631. var faces = geometry.faces;
  632. var start = startFace || 0;
  633. var end = endFace || faces.length - 1;
  634. for ( var i = start; i <= end; i ++ ) {
  635. faces[i].materialIndex = index;
  636. }
  637. }
  638. };
  639. THREE.GeometryUtils.random = THREE.Math.random16;
  640. THREE.GeometryUtils.__v1 = new THREE.Vector3();
  641. THREE.GeometryUtils.__v2 = new THREE.Vector3();