GLTFLoader.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.GLTFLoader = function ( manager ) {
  5. this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
  6. };
  7. THREE.GLTFLoader.prototype = {
  8. constructor: THREE.GLTFLoader,
  9. load: function ( url, onLoad, onProgress, onError ) {
  10. var scope = this;
  11. var loader = new THREE.XHRLoader( scope.manager );
  12. loader.load( url, function ( text ) {
  13. onLoad( scope.parse( JSON.parse( text ) ) );
  14. }, onProgress, onError );
  15. },
  16. setCrossOrigin: function ( value ) {
  17. this.crossOrigin = value;
  18. },
  19. parse: function ( json ) {
  20. function stringToArrayBuffer( string ) {
  21. var bytes = atob( string );
  22. var buffer = new ArrayBuffer( bytes.length );
  23. var bufferView = new Uint8Array( buffer );
  24. for ( var i = 0; i < bytes.length; i ++ ) {
  25. bufferView[ i ] = bytes.charCodeAt( i );
  26. }
  27. return buffer;
  28. }
  29. console.time( 'GLTFLoader' );
  30. var library = {
  31. buffers: {},
  32. bufferViews: {},
  33. accessors: {},
  34. textures: {},
  35. materials: {},
  36. meshes: {},
  37. nodes: {},
  38. scenes: {}
  39. };
  40. // buffers
  41. var buffers = json.buffers;
  42. for ( var bufferId in buffers ) {
  43. var buffer = buffers[ bufferId ];
  44. if ( buffer.type === 'arraybuffer' ) {
  45. var header = 'data:application/octet-stream;base64,';
  46. if ( buffer.uri.indexOf( header ) === 0 ) {
  47. library.buffers[ bufferId ] = stringToArrayBuffer( buffer.uri.substr( header.length ) );
  48. }
  49. }
  50. }
  51. // buffer views
  52. var bufferViews = json.bufferViews;
  53. for ( var bufferViewId in bufferViews ) {
  54. var bufferView = bufferViews[ bufferViewId ];
  55. var arraybuffer = library.buffers[ bufferView.buffer ];
  56. library.bufferViews[ bufferViewId ] = arraybuffer.slice( bufferView.byteOffset, bufferView.byteOffset + bufferView.byteLength );
  57. }
  58. // accessors
  59. var COMPONENT_TYPES = {
  60. 5120: Int8Array,
  61. 5121: Uint8Array,
  62. 5122: Int16Array,
  63. 5123: Uint16Array,
  64. 5125: Uint32Array,
  65. 5126: Float32Array,
  66. };
  67. var TYPE_SIZES = {
  68. 'SCALAR': 1, 'VEC2': 2, 'VEC3': 3, 'VEC4': 4,
  69. 'MAT2': 4, 'MAT3': 9, 'MAT4': 16
  70. };
  71. var accessors = json.accessors;
  72. for ( var accessorId in accessors ) {
  73. var accessor = accessors[ accessorId ];
  74. var arraybuffer = library.bufferViews[ accessor.bufferView ];
  75. var itemSize = TYPE_SIZES[ accessor.type ];
  76. var TypedArray = COMPONENT_TYPES[ accessor.componentType ];
  77. var array = new TypedArray( arraybuffer, accessor.byteOffset, accessor.count * itemSize );
  78. library.accessors[ accessorId ] = new THREE.BufferAttribute( array, itemSize );
  79. }
  80. // textures
  81. var FILTERS = {
  82. 9728: THREE.NearestFilter,
  83. 9729: THREE.LinearFilter,
  84. 9984: THREE.NearestMipMapNearestFilter,
  85. 9985: THREE.LinearMipMapNearestFilter,
  86. 9986: THREE.NearestMipMapLinearFilter,
  87. 9987: THREE.LinearMipMapLinearFilter
  88. };
  89. var WRAPPINGS = {
  90. 33071: THREE.ClampToEdgeWrapping,
  91. 33648: THREE.MirroredRepeatWrapping,
  92. 10497: THREE.RepeatWrapping
  93. };
  94. var textures = json.textures;
  95. for ( var textureId in textures ) {
  96. var texture = textures[ textureId ];
  97. var _texture = new THREE.Texture();
  98. _texture.flipY = false;
  99. if ( texture.source ) {
  100. var source = json.images[ texture.source ];
  101. _texture.image = new Image();
  102. _texture.image.src = source.uri;
  103. _texture.needsUpdate = true;
  104. }
  105. if ( texture.sampler ) {
  106. var sampler = json.samplers[ texture.sampler ];
  107. _texture.magFilter = FILTERS[ sampler.magFilter ];
  108. _texture.minFilter = FILTERS[ sampler.minFilter ];
  109. _texture.wrapS = WRAPPINGS[ sampler.wrapS ];
  110. _texture.wrapT = WRAPPINGS[ sampler.wrapT ];
  111. }
  112. library.textures[ textureId ] = _texture;
  113. }
  114. // materials
  115. var materials = json.materials;
  116. for ( var materialId in materials ) {
  117. var material = materials[ materialId ];
  118. var _material = new THREE.MeshPhongMaterial();
  119. _material.name = material.name;
  120. var values = material.values;
  121. if ( Array.isArray( values.diffuse ) ) {
  122. _material.color.fromArray( values.diffuse );
  123. } else if ( typeof( values.diffuse ) === 'string' ) {
  124. _material.map = library.textures[ values.diffuse ];
  125. }
  126. if ( Array.isArray( values.emission ) ) _material.emissive.fromArray( values.emission );
  127. if ( Array.isArray( values.specular ) ) _material.specular.fromArray( values.specular );
  128. if ( values.shininess !== undefined ) _material.shininess = values.shininess;
  129. library.materials[ materialId ] = _material;
  130. }
  131. // meshes
  132. var meshes = json.meshes;
  133. for ( var meshId in meshes ) {
  134. var mesh = meshes[ meshId ];
  135. var group = new THREE.Group();
  136. group.name = mesh.name;
  137. var primitives = mesh.primitives;
  138. for ( var i = 0; i < primitives.length; i ++ ) {
  139. var primitive = primitives[ i ];
  140. var attributes = primitive.attributes;
  141. var geometry = new THREE.BufferGeometry();
  142. if ( primitive.indices ) {
  143. geometry.setIndex( library.accessors[ primitive.indices ] );
  144. }
  145. for ( var attributeId in attributes ) {
  146. var attribute = attributes[ attributeId ];
  147. var bufferAttribute = library.accessors[ attribute ];
  148. switch ( attributeId ) {
  149. case 'POSITION':
  150. geometry.addAttribute( 'position', bufferAttribute );
  151. break;
  152. case 'NORMAL':
  153. geometry.addAttribute( 'normal', bufferAttribute );
  154. break;
  155. case 'TEXCOORD_0':
  156. geometry.addAttribute( 'uv', bufferAttribute );
  157. break;
  158. }
  159. }
  160. var material = library.materials[ primitive.material ];
  161. group.add( new THREE.Mesh( geometry, material ) );
  162. }
  163. library.meshes[ meshId ] = group;
  164. }
  165. // nodes
  166. var nodes = json.nodes;
  167. var matrix = new THREE.Matrix4();
  168. for ( var nodeId in nodes ) {
  169. var node = nodes[ nodeId ];
  170. var object = new THREE.Group();
  171. object.name = node.name;
  172. if ( node.translation !== undefined ) {
  173. object.position.fromArray( node.translation );
  174. }
  175. if ( node.rotation !== undefined ) {
  176. object.quaternion.fromArray( node.rotation );
  177. }
  178. if ( node.scale !== undefined ) {
  179. object.scale.fromArray( node.scale );
  180. }
  181. if ( node.matrix !== undefined ) {
  182. matrix.fromArray( node.matrix );
  183. matrix.decompose( object.position, object.quaternion, object.scale );
  184. }
  185. if ( node.meshes !== undefined ) {
  186. for ( var i = 0; i < node.meshes.length; i ++ ) {
  187. var meshId = node.meshes[ i ];
  188. var group = library.meshes[ meshId ];
  189. object.add( group.clone() );
  190. }
  191. }
  192. library.nodes[ nodeId ] = object;
  193. }
  194. for ( var nodeId in nodes ) {
  195. var node = nodes[ nodeId ];
  196. for ( var i = 0; i < node.children.length; i ++ ) {
  197. var child = node.children[ i ];
  198. library.nodes[ nodeId ].add( library.nodes[ child ] );
  199. }
  200. }
  201. // scenes
  202. var scenes = json.scenes;
  203. for ( var sceneId in scenes ) {
  204. var scene = scenes[ sceneId ];
  205. var container = new THREE.Scene();
  206. for ( var i = 0; i < scene.nodes.length; i ++ ) {
  207. var node = scene.nodes[ i ];
  208. container.add( library.nodes[ node ] );
  209. }
  210. library.scenes[ sceneId ] = container;
  211. }
  212. console.timeEnd( 'GLTFLoader' );
  213. return {
  214. scene: library.scenes[ json.scene ]
  215. };
  216. }
  217. };