BinaryLoader.js 20 KB

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