JSONLoader.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. * @author alteredq / http://alteredqualia.com/
  4. */
  5. THREE.JSONLoader = function ( showStatus ) {
  6. THREE.Loader.call( this, showStatus );
  7. this.withCredentials = false;
  8. };
  9. THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );
  10. THREE.JSONLoader.prototype.constructor = THREE.JSONLoader;
  11. THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
  12. // todo: unify load API to for easier SceneLoader use
  13. texturePath = texturePath && ( typeof texturePath === 'string' ) ? texturePath : this.extractUrlBase( url );
  14. this.onLoadStart();
  15. this.loadAjaxJSON( this, url, callback, texturePath );
  16. };
  17. THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {
  18. var xhr = new XMLHttpRequest();
  19. var length = 0;
  20. xhr.onreadystatechange = function () {
  21. if ( xhr.readyState === xhr.DONE ) {
  22. if ( xhr.status === 200 || xhr.status === 0 ) {
  23. if ( xhr.responseText ) {
  24. var json = JSON.parse( xhr.responseText );
  25. var metadata = json.metadata;
  26. if ( metadata !== undefined ) {
  27. if ( metadata.type === 'object' ) {
  28. console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
  29. return;
  30. }
  31. if ( metadata.type === 'scene' ) {
  32. console.error( 'THREE.JSONLoader: ' + url + ' seems to be a Scene. Use THREE.SceneLoader instead.' );
  33. return;
  34. }
  35. }
  36. var result = context.parse( json, texturePath );
  37. callback( result.geometry, result.materials );
  38. } else {
  39. console.error( 'THREE.JSONLoader: ' + url + ' seems to be unreachable or the file is empty.' );
  40. }
  41. // in context of more complex asset initialization
  42. // do not block on single failed file
  43. // maybe should go even one more level up
  44. context.onLoadComplete();
  45. } else {
  46. console.error( 'THREE.JSONLoader: Couldn\'t load ' + url + ' (' + xhr.status + ')' );
  47. }
  48. } else if ( xhr.readyState === xhr.LOADING ) {
  49. if ( callbackProgress ) {
  50. if ( length === 0 ) {
  51. length = xhr.getResponseHeader( 'Content-Length' );
  52. }
  53. callbackProgress( { total: length, loaded: xhr.responseText.length } );
  54. }
  55. } else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {
  56. if ( callbackProgress !== undefined ) {
  57. length = xhr.getResponseHeader( 'Content-Length' );
  58. }
  59. }
  60. };
  61. xhr.open( 'GET', url, true );
  62. xhr.withCredentials = this.withCredentials;
  63. xhr.send( null );
  64. };
  65. THREE.JSONLoader.prototype.parse = function ( json, texturePath ) {
  66. var geometry = new THREE.Geometry(),
  67. scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
  68. parseModel( scale );
  69. parseSkin();
  70. parseMorphing( scale );
  71. geometry.computeFaceNormals();
  72. geometry.computeBoundingSphere();
  73. function parseModel( scale ) {
  74. function isBitSet( value, position ) {
  75. return value & ( 1 << position );
  76. }
  77. var i, j, fi,
  78. offset, zLength,
  79. colorIndex, normalIndex, uvIndex,
  80. type,
  81. isQuad,
  82. hasMaterial,
  83. hasFaceVertexUv,
  84. hasFaceNormal, hasFaceVertexNormal,
  85. hasFaceColor, hasFaceVertexColor,
  86. vertex, face, faceA, faceB, hex, normal,
  87. uvLayer, uv, u, v,
  88. faces = json.faces,
  89. vertices = json.vertices,
  90. normals = json.normals,
  91. colors = json.colors,
  92. nUvLayers = 0;
  93. if ( json.uvs !== undefined ) {
  94. // disregard empty arrays
  95. for ( i = 0; i < json.uvs.length; i ++ ) {
  96. if ( json.uvs[ i ].length ) nUvLayers ++;
  97. }
  98. for ( i = 0; i < nUvLayers; i ++ ) {
  99. geometry.faceVertexUvs[ i ] = [];
  100. }
  101. }
  102. offset = 0;
  103. zLength = vertices.length;
  104. while ( offset < zLength ) {
  105. vertex = new THREE.Vector3();
  106. vertex.x = vertices[ offset ++ ] * scale;
  107. vertex.y = vertices[ offset ++ ] * scale;
  108. vertex.z = vertices[ offset ++ ] * scale;
  109. geometry.vertices.push( vertex );
  110. }
  111. offset = 0;
  112. zLength = faces.length;
  113. while ( offset < zLength ) {
  114. type = faces[ offset ++ ];
  115. isQuad = isBitSet( type, 0 );
  116. hasMaterial = isBitSet( type, 1 );
  117. hasFaceVertexUv = isBitSet( type, 3 );
  118. hasFaceNormal = isBitSet( type, 4 );
  119. hasFaceVertexNormal = isBitSet( type, 5 );
  120. hasFaceColor = isBitSet( type, 6 );
  121. hasFaceVertexColor = isBitSet( type, 7 );
  122. // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
  123. if ( isQuad ) {
  124. faceA = new THREE.Face3();
  125. faceA.a = faces[ offset ];
  126. faceA.b = faces[ offset + 1 ];
  127. faceA.c = faces[ offset + 3 ];
  128. faceB = new THREE.Face3();
  129. faceB.a = faces[ offset + 1 ];
  130. faceB.b = faces[ offset + 2 ];
  131. faceB.c = faces[ offset + 3 ];
  132. offset += 4;
  133. if ( hasMaterial ) {
  134. offset ++;
  135. }
  136. // to get face <=> uv index correspondence
  137. fi = geometry.faces.length;
  138. if ( hasFaceVertexUv ) {
  139. for ( i = 0; i < nUvLayers; i ++ ) {
  140. uvLayer = json.uvs[ i ];
  141. geometry.faceVertexUvs[ i ][ fi ] = [];
  142. geometry.faceVertexUvs[ i ][ fi + 1 ] = [];
  143. for ( j = 0; j < 4; j ++ ) {
  144. uvIndex = faces[ offset ++ ];
  145. u = uvLayer[ uvIndex * 2 ];
  146. v = uvLayer[ uvIndex * 2 + 1 ];
  147. uv = new THREE.Vector2( u, v );
  148. if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
  149. if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
  150. }
  151. }
  152. }
  153. if ( hasFaceNormal ) {
  154. normalIndex = faces[ offset ++ ] * 3;
  155. faceA.normal.set(
  156. normals[ normalIndex ++ ],
  157. normals[ normalIndex ++ ],
  158. normals[ normalIndex ]
  159. );
  160. faceB.normal.copy( faceA.normal );
  161. }
  162. if ( hasFaceVertexNormal ) {
  163. for ( i = 0; i < 4; i ++ ) {
  164. normalIndex = faces[ offset ++ ] * 3;
  165. normal = new THREE.Vector3(
  166. normals[ normalIndex ++ ],
  167. normals[ normalIndex ++ ],
  168. normals[ normalIndex ]
  169. );
  170. if ( i !== 2 ) faceA.vertexNormals.push( normal );
  171. if ( i !== 0 ) faceB.vertexNormals.push( normal );
  172. }
  173. }
  174. if ( hasFaceColor ) {
  175. colorIndex = faces[ offset ++ ];
  176. hex = colors[ colorIndex ];
  177. faceA.color.setHex( hex );
  178. faceB.color.setHex( hex );
  179. }
  180. if ( hasFaceVertexColor ) {
  181. for ( i = 0; i < 4; i ++ ) {
  182. colorIndex = faces[ offset ++ ];
  183. hex = colors[ colorIndex ];
  184. if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
  185. if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );
  186. }
  187. }
  188. geometry.faces.push( faceA );
  189. geometry.faces.push( faceB );
  190. } else {
  191. face = new THREE.Face3();
  192. face.a = faces[ offset ++ ];
  193. face.b = faces[ offset ++ ];
  194. face.c = faces[ offset ++ ];
  195. if ( hasMaterial ) {
  196. offset ++;
  197. }
  198. // to get face <=> uv index correspondence
  199. fi = geometry.faces.length;
  200. if ( hasFaceVertexUv ) {
  201. for ( i = 0; i < nUvLayers; i ++ ) {
  202. uvLayer = json.uvs[ i ];
  203. geometry.faceVertexUvs[ i ][ fi ] = [];
  204. for ( j = 0; j < 3; j ++ ) {
  205. uvIndex = faces[ offset ++ ];
  206. u = uvLayer[ uvIndex * 2 ];
  207. v = uvLayer[ uvIndex * 2 + 1 ];
  208. uv = new THREE.Vector2( u, v );
  209. geometry.faceVertexUvs[ i ][ fi ].push( uv );
  210. }
  211. }
  212. }
  213. if ( hasFaceNormal ) {
  214. normalIndex = faces[ offset ++ ] * 3;
  215. face.normal.set(
  216. normals[ normalIndex ++ ],
  217. normals[ normalIndex ++ ],
  218. normals[ normalIndex ]
  219. );
  220. }
  221. if ( hasFaceVertexNormal ) {
  222. for ( i = 0; i < 3; i ++ ) {
  223. normalIndex = faces[ offset ++ ] * 3;
  224. normal = new THREE.Vector3(
  225. normals[ normalIndex ++ ],
  226. normals[ normalIndex ++ ],
  227. normals[ normalIndex ]
  228. );
  229. face.vertexNormals.push( normal );
  230. }
  231. }
  232. if ( hasFaceColor ) {
  233. colorIndex = faces[ offset ++ ];
  234. face.color.setHex( colors[ colorIndex ] );
  235. }
  236. if ( hasFaceVertexColor ) {
  237. for ( i = 0; i < 3; i ++ ) {
  238. colorIndex = faces[ offset ++ ];
  239. face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
  240. }
  241. }
  242. geometry.faces.push( face );
  243. }
  244. }
  245. }
  246. function parseSkin() {
  247. var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
  248. if ( json.skinWeights ) {
  249. for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
  250. var x = json.skinWeights[ i ];
  251. var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
  252. var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
  253. var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
  254. geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
  255. }
  256. }
  257. if ( json.skinIndices ) {
  258. for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
  259. var a = json.skinIndices[ i ];
  260. var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
  261. var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
  262. var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
  263. geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
  264. }
  265. }
  266. geometry.bones = json.bones;
  267. if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
  268. console.warn( 'THREE.JSONLoader: When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
  269. geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
  270. }
  271. // could change this to json.animations[0] or remove completely
  272. geometry.animation = json.animation;
  273. geometry.animations = json.animations;
  274. }
  275. function parseMorphing( scale ) {
  276. if ( json.morphTargets !== undefined ) {
  277. var i, l, v, vl, dstVertices, srcVertices;
  278. for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
  279. geometry.morphTargets[ i ] = {};
  280. geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
  281. geometry.morphTargets[ i ].vertices = [];
  282. dstVertices = geometry.morphTargets[ i ].vertices;
  283. srcVertices = json.morphTargets [ i ].vertices;
  284. for ( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
  285. var vertex = new THREE.Vector3();
  286. vertex.x = srcVertices[ v ] * scale;
  287. vertex.y = srcVertices[ v + 1 ] * scale;
  288. vertex.z = srcVertices[ v + 2 ] * scale;
  289. dstVertices.push( vertex );
  290. }
  291. }
  292. }
  293. if ( json.morphColors !== undefined ) {
  294. var i, l, c, cl, dstColors, srcColors, color;
  295. for ( i = 0, l = json.morphColors.length; i < l; i ++ ) {
  296. geometry.morphColors[ i ] = {};
  297. geometry.morphColors[ i ].name = json.morphColors[ i ].name;
  298. geometry.morphColors[ i ].colors = [];
  299. dstColors = geometry.morphColors[ i ].colors;
  300. srcColors = json.morphColors [ i ].colors;
  301. for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
  302. color = new THREE.Color( 0xffaa00 );
  303. color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
  304. dstColors.push( color );
  305. }
  306. }
  307. }
  308. }
  309. if ( json.materials === undefined || json.materials.length === 0 ) {
  310. return { geometry: geometry };
  311. } else {
  312. var materials = this.initMaterials( json.materials, texturePath );
  313. if ( this.needsTangents( materials ) ) {
  314. geometry.computeTangents();
  315. }
  316. return { geometry: geometry, materials: materials };
  317. }
  318. };
粤ICP备19079148号