Geometry.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. * @author kile / http://kile.stravaganza.org/
  4. * @author alteredq / http://alteredqualia.com/
  5. * @author mikael emtinger / http://gomo.se/
  6. * @author zz85 / http://www.lab4games.net/zz85/blog
  7. * @author bhouston / http://exocortex.com
  8. */
  9. THREE.Geometry = function () {
  10. THREE.EventDispatcher.call( this );
  11. this.id = THREE.GeometryIdCount ++;
  12. this.name = '';
  13. this.vertices = [];
  14. this.colors = []; // one-to-one vertex colors, used in ParticleSystem, Line and Ribbon
  15. this.normals = []; // one-to-one vertex normals, used in Ribbon
  16. this.faces = [];
  17. this.faceUvs = [[]];
  18. this.faceVertexUvs = [[]];
  19. this.morphTargets = [];
  20. this.morphColors = [];
  21. this.morphNormals = [];
  22. this.skinWeights = [];
  23. this.skinIndices = [];
  24. this.lineDistances = [];
  25. this.boundingBox = null;
  26. this.boundingSphere = null;
  27. this.hasTangents = false;
  28. this.dynamic = true; // the intermediate typed arrays will be deleted when set to false
  29. // update flags
  30. this.verticesNeedUpdate = false;
  31. this.elementsNeedUpdate = false;
  32. this.uvsNeedUpdate = false;
  33. this.normalsNeedUpdate = false;
  34. this.tangentsNeedUpdate = false;
  35. this.colorsNeedUpdate = false;
  36. this.lineDistancesNeedUpdate = false;
  37. this.buffersNeedUpdate = false;
  38. };
  39. THREE.Geometry.prototype = {
  40. constructor: THREE.Geometry,
  41. applyMatrix: function ( matrix ) {
  42. var normalMatrix = new THREE.Matrix3();
  43. normalMatrix.getInverse( matrix ).transpose();
  44. for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
  45. var vertex = this.vertices[ i ];
  46. matrix.multiplyVector3( vertex );
  47. }
  48. for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
  49. var face = this.faces[ i ];
  50. normalMatrix.multiplyVector3( face.normal ).normalize();
  51. for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
  52. normalMatrix.multiplyVector3( face.vertexNormals[ j ] ).normalize();
  53. }
  54. matrix.multiplyVector3( face.centroid );
  55. }
  56. },
  57. computeCentroids: function () {
  58. var f, fl, face;
  59. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  60. face = this.faces[ f ];
  61. face.centroid.set( 0, 0, 0 );
  62. if ( face instanceof THREE.Face3 ) {
  63. face.centroid.addSelf( this.vertices[ face.a ] );
  64. face.centroid.addSelf( this.vertices[ face.b ] );
  65. face.centroid.addSelf( this.vertices[ face.c ] );
  66. face.centroid.divideScalar( 3 );
  67. } else if ( face instanceof THREE.Face4 ) {
  68. face.centroid.addSelf( this.vertices[ face.a ] );
  69. face.centroid.addSelf( this.vertices[ face.b ] );
  70. face.centroid.addSelf( this.vertices[ face.c ] );
  71. face.centroid.addSelf( this.vertices[ face.d ] );
  72. face.centroid.divideScalar( 4 );
  73. }
  74. }
  75. },
  76. computeFaceNormals: function () {
  77. var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
  78. cb = new THREE.Vector3(), ab = new THREE.Vector3();
  79. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  80. face = this.faces[ f ];
  81. vA = this.vertices[ face.a ];
  82. vB = this.vertices[ face.b ];
  83. vC = this.vertices[ face.c ];
  84. cb.sub( vC, vB );
  85. ab.sub( vA, vB );
  86. cb.crossSelf( ab );
  87. cb.normalize();
  88. face.normal.copy( cb );
  89. }
  90. },
  91. computeVertexNormals: function ( areaWeighted ) {
  92. var v, vl, f, fl, face, vertices;
  93. // create internal buffers for reuse when calling this method repeatedly
  94. // (otherwise memory allocation / deallocation every frame is big resource hog)
  95. if ( this.__tmpVertices === undefined ) {
  96. this.__tmpVertices = new Array( this.vertices.length );
  97. vertices = this.__tmpVertices;
  98. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  99. vertices[ v ] = new THREE.Vector3();
  100. }
  101. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  102. face = this.faces[ f ];
  103. if ( face instanceof THREE.Face3 ) {
  104. face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  105. } else if ( face instanceof THREE.Face4 ) {
  106. face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  107. }
  108. }
  109. } else {
  110. vertices = this.__tmpVertices;
  111. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  112. vertices[ v ].set( 0, 0, 0 );
  113. }
  114. }
  115. if ( areaWeighted ) {
  116. // vertex normals weighted by triangle areas
  117. // http://www.iquilezles.org/www/articles/normals/normals.htm
  118. var vA, vB, vC, vD;
  119. var cb = new THREE.Vector3(), ab = new THREE.Vector3(),
  120. db = new THREE.Vector3(), dc = new THREE.Vector3(), bc = new THREE.Vector3();
  121. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  122. face = this.faces[ f ];
  123. if ( face instanceof THREE.Face3 ) {
  124. vA = this.vertices[ face.a ];
  125. vB = this.vertices[ face.b ];
  126. vC = this.vertices[ face.c ];
  127. cb.sub( vC, vB );
  128. ab.sub( vA, vB );
  129. cb.crossSelf( ab );
  130. vertices[ face.a ].addSelf( cb );
  131. vertices[ face.b ].addSelf( cb );
  132. vertices[ face.c ].addSelf( cb );
  133. } else if ( face instanceof THREE.Face4 ) {
  134. vA = this.vertices[ face.a ];
  135. vB = this.vertices[ face.b ];
  136. vC = this.vertices[ face.c ];
  137. vD = this.vertices[ face.d ];
  138. // abd
  139. db.sub( vD, vB );
  140. ab.sub( vA, vB );
  141. db.crossSelf( ab );
  142. vertices[ face.a ].addSelf( db );
  143. vertices[ face.b ].addSelf( db );
  144. vertices[ face.d ].addSelf( db );
  145. // bcd
  146. dc.sub( vD, vC );
  147. bc.sub( vB, vC );
  148. dc.crossSelf( bc );
  149. vertices[ face.b ].addSelf( dc );
  150. vertices[ face.c ].addSelf( dc );
  151. vertices[ face.d ].addSelf( dc );
  152. }
  153. }
  154. } else {
  155. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  156. face = this.faces[ f ];
  157. if ( face instanceof THREE.Face3 ) {
  158. vertices[ face.a ].addSelf( face.normal );
  159. vertices[ face.b ].addSelf( face.normal );
  160. vertices[ face.c ].addSelf( face.normal );
  161. } else if ( face instanceof THREE.Face4 ) {
  162. vertices[ face.a ].addSelf( face.normal );
  163. vertices[ face.b ].addSelf( face.normal );
  164. vertices[ face.c ].addSelf( face.normal );
  165. vertices[ face.d ].addSelf( face.normal );
  166. }
  167. }
  168. }
  169. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  170. vertices[ v ].normalize();
  171. }
  172. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  173. face = this.faces[ f ];
  174. if ( face instanceof THREE.Face3 ) {
  175. face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
  176. face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
  177. face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
  178. } else if ( face instanceof THREE.Face4 ) {
  179. face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
  180. face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
  181. face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
  182. face.vertexNormals[ 3 ].copy( vertices[ face.d ] );
  183. }
  184. }
  185. },
  186. computeMorphNormals: function () {
  187. var i, il, f, fl, face;
  188. // save original normals
  189. // - create temp variables on first access
  190. // otherwise just copy (for faster repeated calls)
  191. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  192. face = this.faces[ f ];
  193. if ( ! face.__originalFaceNormal ) {
  194. face.__originalFaceNormal = face.normal.clone();
  195. } else {
  196. face.__originalFaceNormal.copy( face.normal );
  197. }
  198. if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
  199. for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
  200. if ( ! face.__originalVertexNormals[ i ] ) {
  201. face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
  202. } else {
  203. face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
  204. }
  205. }
  206. }
  207. // use temp geometry to compute face and vertex normals for each morph
  208. var tmpGeo = new THREE.Geometry();
  209. tmpGeo.faces = this.faces;
  210. for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
  211. // create on first access
  212. if ( ! this.morphNormals[ i ] ) {
  213. this.morphNormals[ i ] = {};
  214. this.morphNormals[ i ].faceNormals = [];
  215. this.morphNormals[ i ].vertexNormals = [];
  216. var dstNormalsFace = this.morphNormals[ i ].faceNormals;
  217. var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
  218. var faceNormal, vertexNormals;
  219. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  220. face = this.faces[ f ];
  221. faceNormal = new THREE.Vector3();
  222. if ( face instanceof THREE.Face3 ) {
  223. vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
  224. } else {
  225. vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3(), d: new THREE.Vector3() };
  226. }
  227. dstNormalsFace.push( faceNormal );
  228. dstNormalsVertex.push( vertexNormals );
  229. }
  230. }
  231. var morphNormals = this.morphNormals[ i ];
  232. // set vertices to morph target
  233. tmpGeo.vertices = this.morphTargets[ i ].vertices;
  234. // compute morph normals
  235. tmpGeo.computeFaceNormals();
  236. tmpGeo.computeVertexNormals();
  237. // store morph normals
  238. var faceNormal, vertexNormals;
  239. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  240. face = this.faces[ f ];
  241. faceNormal = morphNormals.faceNormals[ f ];
  242. vertexNormals = morphNormals.vertexNormals[ f ];
  243. faceNormal.copy( face.normal );
  244. if ( face instanceof THREE.Face3 ) {
  245. vertexNormals.a.copy( face.vertexNormals[ 0 ] );
  246. vertexNormals.b.copy( face.vertexNormals[ 1 ] );
  247. vertexNormals.c.copy( face.vertexNormals[ 2 ] );
  248. } else {
  249. vertexNormals.a.copy( face.vertexNormals[ 0 ] );
  250. vertexNormals.b.copy( face.vertexNormals[ 1 ] );
  251. vertexNormals.c.copy( face.vertexNormals[ 2 ] );
  252. vertexNormals.d.copy( face.vertexNormals[ 3 ] );
  253. }
  254. }
  255. }
  256. // restore original normals
  257. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  258. face = this.faces[ f ];
  259. face.normal = face.__originalFaceNormal;
  260. face.vertexNormals = face.__originalVertexNormals;
  261. }
  262. },
  263. computeTangents: function () {
  264. // based on http://www.terathon.com/code/tangent.html
  265. // tangents go to vertices
  266. var f, fl, v, vl, i, il, vertexIndex,
  267. face, uv, vA, vB, vC, uvA, uvB, uvC,
  268. x1, x2, y1, y2, z1, z2,
  269. s1, s2, t1, t2, r, t, test,
  270. tan1 = [], tan2 = [],
  271. sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
  272. tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
  273. n = new THREE.Vector3(), w;
  274. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  275. tan1[ v ] = new THREE.Vector3();
  276. tan2[ v ] = new THREE.Vector3();
  277. }
  278. function handleTriangle( context, a, b, c, ua, ub, uc ) {
  279. vA = context.vertices[ a ];
  280. vB = context.vertices[ b ];
  281. vC = context.vertices[ c ];
  282. uvA = uv[ ua ];
  283. uvB = uv[ ub ];
  284. uvC = uv[ uc ];
  285. x1 = vB.x - vA.x;
  286. x2 = vC.x - vA.x;
  287. y1 = vB.y - vA.y;
  288. y2 = vC.y - vA.y;
  289. z1 = vB.z - vA.z;
  290. z2 = vC.z - vA.z;
  291. s1 = uvB.x - uvA.x;
  292. s2 = uvC.x - uvA.x;
  293. t1 = uvB.y - uvA.y;
  294. t2 = uvC.y - uvA.y;
  295. r = 1.0 / ( s1 * t2 - s2 * t1 );
  296. sdir.set( ( t2 * x1 - t1 * x2 ) * r,
  297. ( t2 * y1 - t1 * y2 ) * r,
  298. ( t2 * z1 - t1 * z2 ) * r );
  299. tdir.set( ( s1 * x2 - s2 * x1 ) * r,
  300. ( s1 * y2 - s2 * y1 ) * r,
  301. ( s1 * z2 - s2 * z1 ) * r );
  302. tan1[ a ].addSelf( sdir );
  303. tan1[ b ].addSelf( sdir );
  304. tan1[ c ].addSelf( sdir );
  305. tan2[ a ].addSelf( tdir );
  306. tan2[ b ].addSelf( tdir );
  307. tan2[ c ].addSelf( tdir );
  308. }
  309. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  310. face = this.faces[ f ];
  311. uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
  312. if ( face instanceof THREE.Face3 ) {
  313. handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
  314. } else if ( face instanceof THREE.Face4 ) {
  315. handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
  316. handleTriangle( this, face.b, face.c, face.d, 1, 2, 3 );
  317. }
  318. }
  319. var faceIndex = [ 'a', 'b', 'c', 'd' ];
  320. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  321. face = this.faces[ f ];
  322. for ( i = 0; i < face.vertexNormals.length; i++ ) {
  323. n.copy( face.vertexNormals[ i ] );
  324. vertexIndex = face[ faceIndex[ i ] ];
  325. t = tan1[ vertexIndex ];
  326. // Gram-Schmidt orthogonalize
  327. tmp.copy( t );
  328. tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
  329. // Calculate handedness
  330. tmp2.cross( face.vertexNormals[ i ], t );
  331. test = tmp2.dot( tan2[ vertexIndex ] );
  332. w = (test < 0.0) ? -1.0 : 1.0;
  333. face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
  334. }
  335. }
  336. this.hasTangents = true;
  337. },
  338. computeLineDistances: function ( ) {
  339. var d = 0;
  340. var vertices = this.vertices;
  341. for ( var i = 0, il = vertices.length; i < il; i ++ ) {
  342. if ( i > 0 ) {
  343. d += vertices[ i ].distanceTo( vertices[ i - 1 ] );
  344. }
  345. this.lineDistances[ i ] = d;
  346. }
  347. },
  348. computeBoundingBox: function () {
  349. if ( this.boundingBox === null ) {
  350. this.boundingBox = new THREE.Box3();
  351. }
  352. this.boundingBox.setFromPoints( this.vertices );
  353. },
  354. computeBoundingSphere: function () {
  355. if ( this.boundingSphere === null ) {
  356. this.boundingSphere = new THREE.Sphere();
  357. }
  358. this.boundingSphere.setFromCenterAndPoints( this.boundingSphere.center, this.vertices );
  359. },
  360. /*
  361. * Checks for duplicate vertices with hashmap.
  362. * Duplicated vertices are removed
  363. * and faces' vertices are updated.
  364. */
  365. mergeVertices: function () {
  366. var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
  367. var unique = [], changes = [];
  368. var v, key;
  369. var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
  370. var precision = Math.pow( 10, precisionPoints );
  371. var i,il, face;
  372. var abcd = 'abcd', o, k, j, jl, u;
  373. for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
  374. v = this.vertices[ i ];
  375. key = [ Math.round( v.x * precision ), Math.round( v.y * precision ), Math.round( v.z * precision ) ].join( '_' );
  376. if ( verticesMap[ key ] === undefined ) {
  377. verticesMap[ key ] = i;
  378. unique.push( this.vertices[ i ] );
  379. changes[ i ] = unique.length - 1;
  380. } else {
  381. //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
  382. changes[ i ] = changes[ verticesMap[ key ] ];
  383. }
  384. };
  385. // Start to patch face indices
  386. for( i = 0, il = this.faces.length; i < il; i ++ ) {
  387. face = this.faces[ i ];
  388. if ( face instanceof THREE.Face3 ) {
  389. face.a = changes[ face.a ];
  390. face.b = changes[ face.b ];
  391. face.c = changes[ face.c ];
  392. } else if ( face instanceof THREE.Face4 ) {
  393. face.a = changes[ face.a ];
  394. face.b = changes[ face.b ];
  395. face.c = changes[ face.c ];
  396. face.d = changes[ face.d ];
  397. // check dups in (a, b, c, d) and convert to -> face3
  398. o = [ face.a, face.b, face.c, face.d ];
  399. for ( k = 3; k > 0; k -- ) {
  400. if ( o.indexOf( face[ abcd[ k ] ] ) !== k ) {
  401. // console.log('faces', face.a, face.b, face.c, face.d, 'dup at', k);
  402. o.splice( k, 1 );
  403. this.faces[ i ] = new THREE.Face3( o[0], o[1], o[2], face.normal, face.color, face.materialIndex );
  404. for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
  405. u = this.faceVertexUvs[ j ][ i ];
  406. if ( u ) u.splice( k, 1 );
  407. }
  408. this.faces[ i ].vertexColors = face.vertexColors;
  409. break;
  410. }
  411. }
  412. }
  413. }
  414. // Use unique set of vertices
  415. var diff = this.vertices.length - unique.length;
  416. this.vertices = unique;
  417. return diff;
  418. },
  419. clone: function () {
  420. var geometry = new THREE.Geometry();
  421. var vertices = this.vertices;
  422. for ( var i = 0, il = vertices.length; i < il; i ++ ) {
  423. geometry.vertices.push( vertices[ i ].clone() );
  424. }
  425. var faces = this.faces;
  426. for ( var i = 0, il = faces.length; i < il; i ++ ) {
  427. geometry.faces.push( faces[ i ].clone() );
  428. }
  429. var uvs = this.faceVertexUvs[ 0 ];
  430. for ( var i = 0, il = uvs.length; i < il; i ++ ) {
  431. var uv = uvs[ i ], uvCopy = [];
  432. for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
  433. uvCopy.push( new THREE.Vector2( uv[ j ].x, uv[ j ].y ) );
  434. }
  435. geometry.faceVertexUvs[ 0 ].push( uvCopy );
  436. }
  437. return geometry;
  438. },
  439. dispose: function () {
  440. this.dispatchEvent( { type: 'dispose' } );
  441. for ( var property in this ) {
  442. delete this[ property ];
  443. }
  444. }
  445. };
  446. THREE.GeometryIdCount = 0;