BufferGeometry.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. */
  4. THREE.BufferGeometry = function () {
  5. THREE.GeometryLibrary.push( this );
  6. this.id = THREE.GeometryIdCount ++;
  7. // attributes
  8. this.attributes = {};
  9. // attributes typed arrays are kept only if dynamic flag is set
  10. this.dynamic = false;
  11. // boundings
  12. this.boundingBox = null;
  13. this.boundingSphere = null;
  14. this.hasTangents = false;
  15. // for compatibility
  16. this.morphTargets = [];
  17. };
  18. THREE.BufferGeometry.prototype = {
  19. constructor : THREE.BufferGeometry,
  20. applyMatrix: function ( matrix ) {
  21. var positionArray;
  22. var normalArray;
  23. if ( this.attributes[ "position" ] ) positionArray = this.attributes[ "position" ].array;
  24. if ( this.attributes[ "normal" ] ) normalArray = this.attributes[ "normal" ].array;
  25. if ( positionArray !== undefined ) {
  26. matrix.multiplyVector3Array( positionArray );
  27. this.verticesNeedUpdate = true;
  28. }
  29. if ( normalArray !== undefined ) {
  30. var matrixRotation = new THREE.Matrix4();
  31. matrixRotation.extractRotation( matrix );
  32. matrixRotation.multiplyVector3Array( normalArray );
  33. this.normalsNeedUpdate = true;
  34. }
  35. },
  36. computeBoundingBox: function () {
  37. if ( ! this.boundingBox ) {
  38. this.boundingBox = {
  39. min: new THREE.Vector3( Infinity, Infinity, Infinity ),
  40. max: new THREE.Vector3( -Infinity, -Infinity, -Infinity )
  41. };
  42. }
  43. var positions = this.attributes[ "position" ].array;
  44. if ( positions ) {
  45. var bb = this.boundingBox;
  46. var x, y, z;
  47. for ( var i = 0, il = positions.length; i < il; i += 3 ) {
  48. x = positions[ i ];
  49. y = positions[ i + 1 ];
  50. z = positions[ i + 2 ];
  51. // bounding box
  52. if ( x < bb.min.x ) {
  53. bb.min.x = x;
  54. } else if ( x > bb.max.x ) {
  55. bb.max.x = x;
  56. }
  57. if ( y < bb.min.y ) {
  58. bb.min.y = y;
  59. } else if ( y > bb.max.y ) {
  60. bb.max.y = y;
  61. }
  62. if ( z < bb.min.z ) {
  63. bb.min.z = z;
  64. } else if ( z > bb.max.z ) {
  65. bb.max.z = z;
  66. }
  67. }
  68. }
  69. if ( positions === undefined || positions.length === 0 ) {
  70. this.boundingBox.min.set( 0, 0, 0 );
  71. this.boundingBox.max.set( 0, 0, 0 );
  72. }
  73. },
  74. computeBoundingSphere: function () {
  75. if ( ! this.boundingSphere ) this.boundingSphere = { radius: 0 };
  76. var positions = this.attributes[ "position" ].array;
  77. if ( positions ) {
  78. var radiusSq, maxRadiusSq = 0;
  79. var x, y, z;
  80. for ( var i = 0, il = positions.length; i < il; i += 3 ) {
  81. x = positions[ i ];
  82. y = positions[ i + 1 ];
  83. z = positions[ i + 2 ];
  84. radiusSq = x * x + y * y + z * z;
  85. if ( radiusSq > maxRadiusSq ) maxRadiusSq = radiusSq;
  86. }
  87. this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
  88. }
  89. },
  90. computeVertexNormals: function () {
  91. if ( this.attributes[ "position" ] && this.attributes[ "index" ] ) {
  92. var i, il;
  93. var j, jl;
  94. var nVertexElements = this.attributes[ "position" ].array.length;
  95. if ( this.attributes[ "normal" ] === undefined ) {
  96. this.attributes[ "normal" ] = {
  97. itemSize: 3,
  98. array: new Float32Array( nVertexElements ),
  99. numItems: nVertexElements
  100. };
  101. } else {
  102. // reset existing normals to zero
  103. for ( i = 0, il = this.attributes[ "normal" ].array.length; i < il; i ++ ) {
  104. this.attributes[ "normal" ].array[ i ] = 0;
  105. }
  106. }
  107. var offsets = this.offsets;
  108. var indices = this.attributes[ "index" ].array;
  109. var positions = this.attributes[ "position" ].array;
  110. var normals = this.attributes[ "normal" ].array;
  111. var vA, vB, vC, x, y, z,
  112. pA = new THREE.Vector3(),
  113. pB = new THREE.Vector3(),
  114. pC = new THREE.Vector3(),
  115. cb = new THREE.Vector3(),
  116. ab = new THREE.Vector3();
  117. for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
  118. var start = offsets[ j ].start;
  119. var count = offsets[ j ].count;
  120. var index = offsets[ j ].index;
  121. for ( i = start, il = start + count; i < il; i += 3 ) {
  122. vA = index + indices[ i ];
  123. vB = index + indices[ i + 1 ];
  124. vC = index + indices[ i + 2 ];
  125. x = positions[ vA * 3 ];
  126. y = positions[ vA * 3 + 1 ];
  127. z = positions[ vA * 3 + 2 ];
  128. pA.set( x, y, z );
  129. x = positions[ vB * 3 ];
  130. y = positions[ vB * 3 + 1 ];
  131. z = positions[ vB * 3 + 2 ];
  132. pB.set( x, y, z );
  133. x = positions[ vC * 3 ];
  134. y = positions[ vC * 3 + 1 ];
  135. z = positions[ vC * 3 + 2 ];
  136. pC.set( x, y, z );
  137. cb.sub( pC, pB );
  138. ab.sub( pA, pB );
  139. cb.crossSelf( ab );
  140. normals[ vA * 3 ] += cb.x;
  141. normals[ vA * 3 + 1 ] += cb.y;
  142. normals[ vA * 3 + 2 ] += cb.z;
  143. normals[ vB * 3 ] += cb.x;
  144. normals[ vB * 3 + 1 ] += cb.y;
  145. normals[ vB * 3 + 2 ] += cb.z;
  146. normals[ vC * 3 ] += cb.x;
  147. normals[ vC * 3 + 1 ] += cb.y;
  148. normals[ vC * 3 + 2 ] += cb.z;
  149. }
  150. }
  151. // normalize normals
  152. for ( i = 0, il = normals.length; i < il; i += 3 ) {
  153. x = normals[ i ];
  154. y = normals[ i + 1 ];
  155. z = normals[ i + 2 ];
  156. var n = 1.0 / Math.sqrt( x * x + y * y + z * z );
  157. normals[ i ] *= n;
  158. normals[ i + 1 ] *= n;
  159. normals[ i + 2 ] *= n;
  160. }
  161. this.normalsNeedUpdate = true;
  162. }
  163. },
  164. computeTangents: function () {
  165. // based on http://www.terathon.com/code/tangent.html
  166. // (per vertex tangents)
  167. if ( this.attributes[ "index" ] === undefined ||
  168. this.attributes[ "position" ] === undefined ||
  169. this.attributes[ "normal" ] === undefined ||
  170. this.attributes[ "uv" ] === undefined ) {
  171. console.warn( "Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()" );
  172. return;
  173. }
  174. var indices = this.attributes[ "index" ].array;
  175. var positions = this.attributes[ "position" ].array;
  176. var normals = this.attributes[ "normal" ].array;
  177. var uvs = this.attributes[ "uv" ].array;
  178. var nVertices = positions.length / 3;
  179. if ( this.attributes[ "tangent" ] === undefined ) {
  180. var nTangentElements = 4 * nVertices;
  181. this.attributes[ "tangent" ] = {
  182. itemSize: 4,
  183. array: new Float32Array( nTangentElements ),
  184. numItems: nTangentElements
  185. };
  186. }
  187. var tangents = this.attributes[ "tangent" ].array;
  188. var tan1 = [], tan2 = [];
  189. for ( var k = 0; k < nVertices; k ++ ) {
  190. tan1[ k ] = new THREE.Vector3();
  191. tan2[ k ] = new THREE.Vector3();
  192. }
  193. var xA, yA, zA,
  194. xB, yB, zB,
  195. xC, yC, zC,
  196. uA, vA,
  197. uB, vB,
  198. uC, vC,
  199. x1, x2, y1, y2, z1, z2,
  200. s1, s2, t1, t2, r;
  201. var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
  202. function handleTriangle( a, b, c ) {
  203. xA = positions[ a * 3 ];
  204. yA = positions[ a * 3 + 1 ];
  205. zA = positions[ a * 3 + 2 ];
  206. xB = positions[ b * 3 ];
  207. yB = positions[ b * 3 + 1 ];
  208. zB = positions[ b * 3 + 2 ];
  209. xC = positions[ c * 3 ];
  210. yC = positions[ c * 3 + 1 ];
  211. zC = positions[ c * 3 + 2 ];
  212. uA = uvs[ a * 2 ];
  213. vA = uvs[ a * 2 + 1 ];
  214. uB = uvs[ b * 2 ];
  215. vB = uvs[ b * 2 + 1 ];
  216. uC = uvs[ c * 2 ];
  217. vC = uvs[ c * 2 + 1 ];
  218. x1 = xB - xA;
  219. x2 = xC - xA;
  220. y1 = yB - yA;
  221. y2 = yC - yA;
  222. z1 = zB - zA;
  223. z2 = zC - zA;
  224. s1 = uB - uA;
  225. s2 = uC - uA;
  226. t1 = vB - vA;
  227. t2 = vC - vA;
  228. r = 1.0 / ( s1 * t2 - s2 * t1 );
  229. sdir.set(
  230. ( t2 * x1 - t1 * x2 ) * r,
  231. ( t2 * y1 - t1 * y2 ) * r,
  232. ( t2 * z1 - t1 * z2 ) * r
  233. );
  234. tdir.set(
  235. ( s1 * x2 - s2 * x1 ) * r,
  236. ( s1 * y2 - s2 * y1 ) * r,
  237. ( s1 * z2 - s2 * z1 ) * r
  238. );
  239. tan1[ a ].addSelf( sdir );
  240. tan1[ b ].addSelf( sdir );
  241. tan1[ c ].addSelf( sdir );
  242. tan2[ a ].addSelf( tdir );
  243. tan2[ b ].addSelf( tdir );
  244. tan2[ c ].addSelf( tdir );
  245. }
  246. var i, il;
  247. var j, jl;
  248. var iA, iB, iC;
  249. var offsets = this.offsets;
  250. for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
  251. var start = offsets[ j ].start;
  252. var count = offsets[ j ].count;
  253. var index = offsets[ j ].index;
  254. for ( i = start, il = start + count; i < il; i += 3 ) {
  255. iA = index + indices[ i ];
  256. iB = index + indices[ i + 1 ];
  257. iC = index + indices[ i + 2 ];
  258. handleTriangle( iA, iB, iC );
  259. }
  260. }
  261. var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
  262. var n = new THREE.Vector3(), n2 = new THREE.Vector3();
  263. var w, t, test;
  264. var nx, ny, nz;
  265. function handleVertex( v ) {
  266. n.x = normals[ v * 3 ];
  267. n.y = normals[ v * 3 + 1 ];
  268. n.z = normals[ v * 3 + 2 ];
  269. n2.copy( n );
  270. t = tan1[ v ];
  271. // Gram-Schmidt orthogonalize
  272. tmp.copy( t );
  273. tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
  274. // Calculate handedness
  275. tmp2.cross( n2, t );
  276. test = tmp2.dot( tan2[ v ] );
  277. w = ( test < 0.0 ) ? -1.0 : 1.0;
  278. tangents[ v * 4 ] = tmp.x;
  279. tangents[ v * 4 + 1 ] = tmp.y;
  280. tangents[ v * 4 + 2 ] = tmp.z;
  281. tangents[ v * 4 + 3 ] = w;
  282. }
  283. for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
  284. var start = offsets[ j ].start;
  285. var count = offsets[ j ].count;
  286. var index = offsets[ j ].index;
  287. for ( i = start, il = start + count; i < il; i += 3 ) {
  288. iA = index + indices[ i ];
  289. iB = index + indices[ i + 1 ];
  290. iC = index + indices[ i + 2 ];
  291. handleVertex( iA );
  292. handleVertex( iB );
  293. handleVertex( iC );
  294. }
  295. }
  296. this.hasTangents = true;
  297. this.tangentsNeedUpdate = true;
  298. }
  299. };
粤ICP备19079148号