BinaryLoader.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. */
  4. THREE.BinaryLoader = function ( showStatus ) {
  5. THREE.Loader.call( this, showStatus );
  6. };
  7. THREE.BinaryLoader.prototype = Object.create( THREE.Loader.prototype );
  8. // Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
  9. // - binary models consist of two files: JS and BIN
  10. // - parameters
  11. // - url (required)
  12. // - callback (required)
  13. // - texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
  14. // - binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
  15. THREE.BinaryLoader.prototype.load = function( url, callback, texturePath, binaryPath ) {
  16. texturePath = texturePath ? texturePath : this.extractUrlBase( url );
  17. binaryPath = binaryPath ? binaryPath : this.extractUrlBase( url );
  18. var callbackProgress = this.showProgress ? THREE.Loader.prototype.updateProgress : null;
  19. this.onLoadStart();
  20. // #1 load JS part via web worker
  21. this.loadAjaxJSON( this, url, callback, texturePath, binaryPath, callbackProgress );
  22. };
  23. THREE.BinaryLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, binaryPath, callbackProgress ) {
  24. var xhr = new XMLHttpRequest();
  25. xhr.onreadystatechange = function () {
  26. if ( xhr.readyState == 4 ) {
  27. if ( xhr.status == 200 || xhr.status == 0 ) {
  28. var json = JSON.parse( xhr.responseText );
  29. context.loadAjaxBuffers( json, callback, binaryPath, texturePath, callbackProgress );
  30. } else {
  31. console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
  32. }
  33. }
  34. };
  35. xhr.open( "GET", url, true );
  36. if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
  37. xhr.setRequestHeader( "Content-Type", "text/plain" );
  38. xhr.send( null );
  39. };
  40. THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binaryPath, texturePath, callbackProgress ) {
  41. var xhr = new XMLHttpRequest(),
  42. url = binaryPath + "/" + json.buffers;
  43. var length = 0;
  44. xhr.onreadystatechange = function () {
  45. if ( xhr.readyState == 4 ) {
  46. if ( xhr.status == 200 || xhr.status == 0 ) {
  47. THREE.BinaryLoader.prototype.createBinModel( xhr.response, callback, texturePath, json.materials );
  48. } else {
  49. console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
  50. }
  51. } else if ( xhr.readyState == 3 ) {
  52. if ( callbackProgress ) {
  53. if ( length == 0 ) {
  54. length = xhr.getResponseHeader( "Content-Length" );
  55. }
  56. callbackProgress( { total: length, loaded: xhr.responseText.length } );
  57. }
  58. } else if ( xhr.readyState == 2 ) {
  59. length = xhr.getResponseHeader( "Content-Length" );
  60. }
  61. };
  62. xhr.open( "GET", url, true );
  63. xhr.responseType = "arraybuffer";
  64. xhr.send( null );
  65. };
  66. // Binary AJAX parser
  67. THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texturePath, materials ) {
  68. var Model = function ( texturePath ) {
  69. var scope = this,
  70. currentOffset = 0,
  71. md,
  72. normals = [],
  73. uvs = [],
  74. start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
  75. start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
  76. tri_size, quad_size,
  77. len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
  78. len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
  79. THREE.Geometry.call( this );
  80. THREE.Loader.prototype.initMaterials( scope, materials, texturePath );
  81. md = parseMetaData( data, currentOffset );
  82. currentOffset += md.header_bytes;
  83. /*
  84. md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
  85. md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
  86. md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
  87. md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
  88. */
  89. // buffers sizes
  90. tri_size = md.vertex_index_bytes * 3 + md.material_index_bytes;
  91. quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
  92. len_tri_flat = md.ntri_flat * ( tri_size );
  93. len_tri_smooth = md.ntri_smooth * ( tri_size + md.normal_index_bytes * 3 );
  94. len_tri_flat_uv = md.ntri_flat_uv * ( tri_size + md.uv_index_bytes * 3 );
  95. len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
  96. len_quad_flat = md.nquad_flat * ( quad_size );
  97. len_quad_smooth = md.nquad_smooth * ( quad_size + md.normal_index_bytes * 4 );
  98. len_quad_flat_uv = md.nquad_flat_uv * ( quad_size + md.uv_index_bytes * 4 );
  99. len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
  100. // read buffers
  101. currentOffset += init_vertices( currentOffset );
  102. currentOffset += init_normals( currentOffset );
  103. currentOffset += handlePadding( md.nnormals * 3 );
  104. currentOffset += init_uvs( currentOffset );
  105. start_tri_flat = currentOffset;
  106. start_tri_smooth = start_tri_flat + len_tri_flat + handlePadding( md.ntri_flat * 2 );
  107. start_tri_flat_uv = start_tri_smooth + len_tri_smooth + handlePadding( md.ntri_smooth * 2 );
  108. start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
  109. start_quad_flat = start_tri_smooth_uv + len_tri_smooth_uv + handlePadding( md.ntri_smooth_uv * 2 );
  110. start_quad_smooth = start_quad_flat + len_quad_flat + handlePadding( md.nquad_flat * 2 );
  111. start_quad_flat_uv = start_quad_smooth + len_quad_smooth + handlePadding( md.nquad_smooth * 2 );
  112. start_quad_smooth_uv= start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 );
  113. // have to first process faces with uvs
  114. // so that face and uv indices match
  115. init_triangles_flat_uv( start_tri_flat_uv );
  116. init_triangles_smooth_uv( start_tri_smooth_uv );
  117. init_quads_flat_uv( start_quad_flat_uv );
  118. init_quads_smooth_uv( start_quad_smooth_uv );
  119. // now we can process untextured faces
  120. init_triangles_flat( start_tri_flat );
  121. init_triangles_smooth( start_tri_smooth );
  122. init_quads_flat( start_quad_flat );
  123. init_quads_smooth( start_quad_smooth );
  124. this.computeCentroids();
  125. this.computeFaceNormals();
  126. if ( THREE.Loader.prototype.hasNormals( this ) ) this.computeTangents();
  127. function handlePadding( n ) {
  128. return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
  129. };
  130. function parseMetaData( data, offset ) {
  131. var metaData = {
  132. 'signature' :parseString( data, offset, 12 ),
  133. 'header_bytes' :parseUChar8( data, offset + 12 ),
  134. 'vertex_coordinate_bytes' :parseUChar8( data, offset + 13 ),
  135. 'normal_coordinate_bytes' :parseUChar8( data, offset + 14 ),
  136. 'uv_coordinate_bytes' :parseUChar8( data, offset + 15 ),
  137. 'vertex_index_bytes' :parseUChar8( data, offset + 16 ),
  138. 'normal_index_bytes' :parseUChar8( data, offset + 17 ),
  139. 'uv_index_bytes' :parseUChar8( data, offset + 18 ),
  140. 'material_index_bytes' :parseUChar8( data, offset + 19 ),
  141. 'nvertices' :parseUInt32( data, offset + 20 ),
  142. 'nnormals' :parseUInt32( data, offset + 20 + 4*1 ),
  143. 'nuvs' :parseUInt32( data, offset + 20 + 4*2 ),
  144. 'ntri_flat' :parseUInt32( data, offset + 20 + 4*3 ),
  145. 'ntri_smooth' :parseUInt32( data, offset + 20 + 4*4 ),
  146. 'ntri_flat_uv' :parseUInt32( data, offset + 20 + 4*5 ),
  147. 'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ),
  148. 'nquad_flat' :parseUInt32( data, offset + 20 + 4*7 ),
  149. 'nquad_smooth' :parseUInt32( data, offset + 20 + 4*8 ),
  150. 'nquad_flat_uv' :parseUInt32( data, offset + 20 + 4*9 ),
  151. 'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 )
  152. };
  153. /*
  154. console.log( "signature: " + metaData.signature );
  155. console.log( "header_bytes: " + metaData.header_bytes );
  156. console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
  157. console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
  158. console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
  159. console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
  160. console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
  161. console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
  162. console.log( "material_index_bytes: " + metaData.material_index_bytes );
  163. console.log( "nvertices: " + metaData.nvertices );
  164. console.log( "nnormals: " + metaData.nnormals );
  165. console.log( "nuvs: " + metaData.nuvs );
  166. console.log( "ntri_flat: " + metaData.ntri_flat );
  167. console.log( "ntri_smooth: " + metaData.ntri_smooth );
  168. console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
  169. console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
  170. console.log( "nquad_flat: " + metaData.nquad_flat );
  171. console.log( "nquad_smooth: " + metaData.nquad_smooth );
  172. console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
  173. console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
  174. var total = metaData.header_bytes
  175. + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
  176. + metaData.nnormals * metaData.normal_coordinate_bytes * 3
  177. + metaData.nuvs * metaData.uv_coordinate_bytes * 2
  178. + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
  179. + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
  180. + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
  181. + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
  182. + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
  183. + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
  184. + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
  185. + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
  186. console.log( "total bytes: " + total );
  187. */
  188. return metaData;
  189. };
  190. function parseString( data, offset, length ) {
  191. var charArray = new Uint8Array( data, offset, length );
  192. var text = "";
  193. for ( var i = 0; i < length; i ++ ) {
  194. text += String.fromCharCode( charArray[ offset + i ] );
  195. }
  196. return text;
  197. };
  198. function parseUChar8( data, offset ) {
  199. var charArray = new Uint8Array( data, offset, 1 );
  200. return charArray[ 0 ];
  201. };
  202. function parseUInt32( data, offset ) {
  203. var intArray = new Uint32Array( data, offset, 1 );
  204. return intArray[ 0 ];
  205. };
  206. function init_vertices( start ) {
  207. var nElements = md.nvertices;
  208. var coordArray = new Float32Array( data, start, nElements * 3 );
  209. var i, x, y, z;
  210. for( i = 0; i < nElements; i ++ ) {
  211. x = coordArray[ i * 3 ];
  212. y = coordArray[ i * 3 + 1 ];
  213. z = coordArray[ i * 3 + 2 ];
  214. vertex( scope, x, y, z );
  215. }
  216. return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
  217. };
  218. function init_normals( start ) {
  219. var nElements = md.nnormals;
  220. if ( nElements ) {
  221. var normalArray = new Int8Array( data, start, nElements * 3 );
  222. var i, x, y, z;
  223. for( i = 0; i < nElements; i ++ ) {
  224. x = normalArray[ i * 3 ];
  225. y = normalArray[ i * 3 + 1 ];
  226. z = normalArray[ i * 3 + 2 ];
  227. normals.push( x/127, y/127, z/127 );
  228. }
  229. }
  230. return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
  231. };
  232. function init_uvs( start ) {
  233. var nElements = md.nuvs;
  234. if ( nElements ) {
  235. var uvArray = new Float32Array( data, start, nElements * 2 );
  236. var i, u, v;
  237. for( i = 0; i < nElements; i ++ ) {
  238. u = uvArray[ i * 2 ];
  239. v = uvArray[ i * 2 + 1 ];
  240. uvs.push( u, v );
  241. }
  242. }
  243. return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
  244. };
  245. function init_uvs3( nElements, offset ) {
  246. var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
  247. var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
  248. for( i = 0; i < nElements; i ++ ) {
  249. uva = uvIndexBuffer[ i * 3 ];
  250. uvb = uvIndexBuffer[ i * 3 + 1 ];
  251. uvc = uvIndexBuffer[ i * 3 + 2 ];
  252. u1 = uvs[ uva*2 ];
  253. v1 = uvs[ uva*2 + 1 ];
  254. u2 = uvs[ uvb*2 ];
  255. v2 = uvs[ uvb*2 + 1 ];
  256. u3 = uvs[ uvc*2 ];
  257. v3 = uvs[ uvc*2 + 1 ];
  258. uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 );
  259. }
  260. };
  261. function init_uvs4( nElements, offset ) {
  262. var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
  263. var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
  264. for( i = 0; i < nElements; i ++ ) {
  265. uva = uvIndexBuffer[ i * 4 ];
  266. uvb = uvIndexBuffer[ i * 4 + 1 ];
  267. uvc = uvIndexBuffer[ i * 4 + 2 ];
  268. uvd = uvIndexBuffer[ i * 4 + 3 ];
  269. u1 = uvs[ uva*2 ];
  270. v1 = uvs[ uva*2 + 1 ];
  271. u2 = uvs[ uvb*2 ];
  272. v2 = uvs[ uvb*2 + 1 ];
  273. u3 = uvs[ uvc*2 ];
  274. v3 = uvs[ uvc*2 + 1 ];
  275. u4 = uvs[ uvd*2 ];
  276. v4 = uvs[ uvd*2 + 1 ];
  277. uv4( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3, u4, v4 );
  278. }
  279. };
  280. function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
  281. var i, a, b, c, m;
  282. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
  283. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  284. for( i = 0; i < nElements; i ++ ) {
  285. a = vertexIndexBuffer[ i * 3 ];
  286. b = vertexIndexBuffer[ i * 3 + 1 ];
  287. c = vertexIndexBuffer[ i * 3 + 2 ];
  288. m = materialIndexBuffer[ i ];
  289. f3( scope, a, b, c, m );
  290. }
  291. };
  292. function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
  293. var i, a, b, c, d, m;
  294. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
  295. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  296. for( i = 0; i < nElements; i ++ ) {
  297. a = vertexIndexBuffer[ i * 4 ];
  298. b = vertexIndexBuffer[ i * 4 + 1 ];
  299. c = vertexIndexBuffer[ i * 4 + 2 ];
  300. d = vertexIndexBuffer[ i * 4 + 3 ];
  301. m = materialIndexBuffer[ i ];
  302. f4( scope, a, b, c, d, m );
  303. }
  304. };
  305. function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
  306. var i, a, b, c, m;
  307. var na, nb, nc;
  308. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
  309. var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
  310. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  311. for( i = 0; i < nElements; i ++ ) {
  312. a = vertexIndexBuffer[ i * 3 ];
  313. b = vertexIndexBuffer[ i * 3 + 1 ];
  314. c = vertexIndexBuffer[ i * 3 + 2 ];
  315. na = normalIndexBuffer[ i * 3 ];
  316. nb = normalIndexBuffer[ i * 3 + 1 ];
  317. nc = normalIndexBuffer[ i * 3 + 2 ];
  318. m = materialIndexBuffer[ i ];
  319. f3n( scope, normals, a, b, c, m, na, nb, nc );
  320. }
  321. };
  322. function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
  323. var i, a, b, c, d, m;
  324. var na, nb, nc, nd;
  325. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
  326. var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
  327. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  328. for( i = 0; i < nElements; i ++ ) {
  329. a = vertexIndexBuffer[ i * 4 ];
  330. b = vertexIndexBuffer[ i * 4 + 1 ];
  331. c = vertexIndexBuffer[ i * 4 + 2 ];
  332. d = vertexIndexBuffer[ i * 4 + 3 ];
  333. na = normalIndexBuffer[ i * 4 ];
  334. nb = normalIndexBuffer[ i * 4 + 1 ];
  335. nc = normalIndexBuffer[ i * 4 + 2 ];
  336. nd = normalIndexBuffer[ i * 4 + 3 ];
  337. m = materialIndexBuffer[ i ];
  338. f4n( scope, normals, a, b, c, d, m, na, nb, nc, nd );
  339. }
  340. };
  341. function init_triangles_flat( start ) {
  342. var nElements = md.ntri_flat;
  343. if ( nElements ) {
  344. var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  345. init_faces3_flat( nElements, start, offsetMaterials );
  346. }
  347. };
  348. function init_triangles_flat_uv( start ) {
  349. var nElements = md.ntri_flat_uv;
  350. if ( nElements ) {
  351. var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  352. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  353. init_faces3_flat( nElements, start, offsetMaterials );
  354. init_uvs3( nElements, offsetUvs );
  355. }
  356. };
  357. function init_triangles_smooth( start ) {
  358. var nElements = md.ntri_smooth;
  359. if ( nElements ) {
  360. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  361. var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  362. init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
  363. }
  364. };
  365. function init_triangles_smooth_uv( start ) {
  366. var nElements = md.ntri_smooth_uv;
  367. if ( nElements ) {
  368. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  369. var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  370. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  371. init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
  372. init_uvs3( nElements, offsetUvs );
  373. }
  374. };
  375. function init_quads_flat( start ) {
  376. var nElements = md.nquad_flat;
  377. if ( nElements ) {
  378. var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  379. init_faces4_flat( nElements, start, offsetMaterials );
  380. }
  381. };
  382. function init_quads_flat_uv( start ) {
  383. var nElements = md.nquad_flat_uv;
  384. if ( nElements ) {
  385. var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  386. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  387. init_faces4_flat( nElements, start, offsetMaterials );
  388. init_uvs4( nElements, offsetUvs );
  389. }
  390. };
  391. function init_quads_smooth( start ) {
  392. var nElements = md.nquad_smooth;
  393. if ( nElements ) {
  394. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  395. var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  396. init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
  397. }
  398. };
  399. function init_quads_smooth_uv( start ) {
  400. var nElements = md.nquad_smooth_uv;
  401. if ( nElements ) {
  402. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  403. var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  404. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  405. init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
  406. init_uvs4( nElements, offsetUvs );
  407. }
  408. };
  409. };
  410. function vertex ( scope, x, y, z ) {
  411. scope.vertices.push( new THREE.Vector3( x, y, z ) );
  412. };
  413. function f3 ( scope, a, b, c, mi ) {
  414. scope.faces.push( new THREE.Face3( a, b, c, null, null, mi ) );
  415. };
  416. function f4 ( scope, a, b, c, d, mi ) {
  417. scope.faces.push( new THREE.Face4( a, b, c, d, null, null, mi ) );
  418. };
  419. function f3n ( scope, normals, a, b, c, mi, na, nb, nc ) {
  420. var nax = normals[ na*3 ],
  421. nay = normals[ na*3 + 1 ],
  422. naz = normals[ na*3 + 2 ],
  423. nbx = normals[ nb*3 ],
  424. nby = normals[ nb*3 + 1 ],
  425. nbz = normals[ nb*3 + 2 ],
  426. ncx = normals[ nc*3 ],
  427. ncy = normals[ nc*3 + 1 ],
  428. ncz = normals[ nc*3 + 2 ];
  429. scope.faces.push( new THREE.Face3( a, b, c,
  430. [new THREE.Vector3( nax, nay, naz ),
  431. new THREE.Vector3( nbx, nby, nbz ),
  432. new THREE.Vector3( ncx, ncy, ncz )],
  433. null,
  434. mi ) );
  435. };
  436. function f4n ( scope, normals, a, b, c, d, mi, na, nb, nc, nd ) {
  437. var nax = normals[ na*3 ],
  438. nay = normals[ na*3 + 1 ],
  439. naz = normals[ na*3 + 2 ],
  440. nbx = normals[ nb*3 ],
  441. nby = normals[ nb*3 + 1 ],
  442. nbz = normals[ nb*3 + 2 ],
  443. ncx = normals[ nc*3 ],
  444. ncy = normals[ nc*3 + 1 ],
  445. ncz = normals[ nc*3 + 2 ],
  446. ndx = normals[ nd*3 ],
  447. ndy = normals[ nd*3 + 1 ],
  448. ndz = normals[ nd*3 + 2 ];
  449. scope.faces.push( new THREE.Face4( a, b, c, d,
  450. [new THREE.Vector3( nax, nay, naz ),
  451. new THREE.Vector3( nbx, nby, nbz ),
  452. new THREE.Vector3( ncx, ncy, ncz ),
  453. new THREE.Vector3( ndx, ndy, ndz )],
  454. null,
  455. mi ) );
  456. };
  457. function uv3 ( where, u1, v1, u2, v2, u3, v3 ) {
  458. var uv = [];
  459. uv.push( new THREE.UV( u1, v1 ) );
  460. uv.push( new THREE.UV( u2, v2 ) );
  461. uv.push( new THREE.UV( u3, v3 ) );
  462. where.push( uv );
  463. };
  464. function uv4 ( where, u1, v1, u2, v2, u3, v3, u4, v4 ) {
  465. var uv = [];
  466. uv.push( new THREE.UV( u1, v1 ) );
  467. uv.push( new THREE.UV( u2, v2 ) );
  468. uv.push( new THREE.UV( u3, v3 ) );
  469. uv.push( new THREE.UV( u4, v4 ) );
  470. where.push( uv );
  471. };
  472. Model.prototype = Object.create( THREE.Geometry.prototype );
  473. callback( new Model( texturePath ) );
  474. };