gltf-loader.js 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647
  1. export function registerGLTFLoader(THREE) {
  2. THREE.GLTFLoader = (function () {
  3. function GLTFLoader() {
  4. this.manager = THREE.DefaultLoadingManager
  5. this.dracoLoader = null
  6. this.ddsLoader = null
  7. }
  8. GLTFLoader.prototype = {
  9. constructor: GLTFLoader,
  10. crossOrigin: 'anonymous',
  11. load(url, onLoad) {
  12. const scope = this
  13. let resourcePath
  14. if (this.resourcePath !== undefined) {
  15. resourcePath = this.resourcePath
  16. } else if (this.path !== undefined) {
  17. resourcePath = this.path
  18. } else {
  19. resourcePath = THREE.LoaderUtils.extractUrlBase(url)
  20. }
  21. scope.manager.itemStart(url)
  22. const _onError = function (e) {
  23. console.error(e)
  24. scope.manager.itemError(url)
  25. scope.manager.itemEnd(url)
  26. }
  27. const loader = new THREE.FileLoader(scope.manager)
  28. loader.setPath(this.path)
  29. loader.setResponseType('arraybuffer')
  30. loader.load(
  31. url,
  32. function (data) {
  33. try {
  34. scope.parse(
  35. data,
  36. resourcePath,
  37. function (gltf) {
  38. onLoad(gltf)
  39. scope.manager.itemEnd(url)
  40. },
  41. _onError
  42. )
  43. } catch (e) {
  44. _onError(e)
  45. }
  46. },
  47. null,
  48. _onError
  49. )
  50. },
  51. parse(data, path, onLoad, onError) {
  52. let content
  53. const extensions = {}
  54. if (typeof data === 'string') {
  55. content = data
  56. } else {
  57. const magic = THREE.LoaderUtils.decodeText(new Uint8Array(data, 0, 4))
  58. if (magic === BINARY_EXTENSION_HEADER_MAGIC) {
  59. try {
  60. extensions[EXTENSIONS.KHR_BINARY_GLTF] = new GLTFBinaryExtension(data)
  61. } catch (error) {
  62. if (onError) onError(error)
  63. return
  64. }
  65. content = extensions[EXTENSIONS.KHR_BINARY_GLTF].content
  66. } else {
  67. content = THREE.LoaderUtils.decodeText(new Uint8Array(data))
  68. }
  69. }
  70. const json = JSON.parse(content)
  71. if (json.asset === undefined || json.asset.version[0] < 2) {
  72. if (onError) onError(new Error('THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported. Use LegacyGLTFLoader instead.'))
  73. return
  74. }
  75. if (json.extensionsUsed) {
  76. for (let i = 0; i < json.extensionsUsed.length; ++i) {
  77. const extensionName = json.extensionsUsed[i]
  78. const extensionsRequired = json.extensionsRequired || []
  79. switch (extensionName) {
  80. case EXTENSIONS.KHR_LIGHTS_PUNCTUAL:
  81. extensions[extensionName] = new GLTFLightsExtension(json)
  82. break
  83. case EXTENSIONS.KHR_MATERIALS_UNLIT:
  84. extensions[extensionName] = new GLTFMaterialsUnlitExtension()
  85. break
  86. case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
  87. extensions[extensionName] = new GLTFMaterialsPbrSpecularGlossinessExtension()
  88. break
  89. case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
  90. extensions[extensionName] = new GLTFDracoMeshCompressionExtension(json, this.dracoLoader)
  91. break
  92. case EXTENSIONS.MSFT_TEXTURE_DDS:
  93. extensions[EXTENSIONS.MSFT_TEXTURE_DDS] = new GLTFTextureDDSExtension(this.ddsLoader)
  94. break
  95. case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
  96. extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM] = new GLTFTextureTransformExtension()
  97. break
  98. default:
  99. if (extensionsRequired.indexOf(extensionName) >= 0) {
  100. console.warn('THREE.GLTFLoader: Unknown extension "' + extensionName + '".')
  101. }
  102. }
  103. }
  104. }
  105. const parser = new GLTFParser(json, extensions, {
  106. path: path || this.resourcePath || '',
  107. crossOrigin: this.crossOrigin,
  108. manager: this.manager
  109. })
  110. parser.parse(onLoad, onError)
  111. }
  112. }
  113. function GLTFRegistry() {
  114. let objects = {}
  115. return {
  116. get(key) {
  117. return objects[key]
  118. },
  119. add(key, object) {
  120. objects[key] = object
  121. },
  122. remove(key) {
  123. delete objects[key]
  124. },
  125. removeAll() {
  126. objects = {}
  127. }
  128. }
  129. }
  130. var EXTENSIONS = {
  131. KHR_BINARY_GLTF: 'KHR_binary_glTF',
  132. KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
  133. KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
  134. KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
  135. KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
  136. KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
  137. MSFT_TEXTURE_DDS: 'MSFT_texture_dds'
  138. }
  139. function GLTFTextureDDSExtension(ddsLoader) {
  140. if (!ddsLoader) {
  141. throw new Error('THREE.GLTFLoader: Attempting to load .dds texture without importing THREE.DDSLoader')
  142. }
  143. this.name = EXTENSIONS.MSFT_TEXTURE_DDS
  144. this.ddsLoader = ddsLoader
  145. }
  146. function GLTFLightsExtension(json) {
  147. this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL
  148. const extension = (json.extensions && json.extensions[EXTENSIONS.KHR_LIGHTS_PUNCTUAL]) || {}
  149. this.lightDefs = extension.lights || []
  150. }
  151. GLTFLightsExtension.prototype.loadLight = function (lightIndex) {
  152. const lightDef = this.lightDefs[lightIndex]
  153. let lightNode
  154. const color = new THREE.Color(0xffffff)
  155. if (lightDef.color !== undefined) color.fromArray(lightDef.color)
  156. const range = lightDef.range !== undefined ? lightDef.range : 0
  157. switch (lightDef.type) {
  158. case 'directional':
  159. lightNode = new THREE.DirectionalLight(color)
  160. lightNode.target.position.set(0, 0, -1)
  161. lightNode.add(lightNode.target)
  162. break
  163. case 'point':
  164. lightNode = new THREE.PointLight(color)
  165. lightNode.distance = range
  166. break
  167. case 'spot':
  168. lightNode = new THREE.SpotLight(color)
  169. lightNode.distance = range
  170. lightDef.spot = lightDef.spot || {}
  171. lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0
  172. lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0
  173. lightNode.angle = lightDef.spot.outerConeAngle
  174. lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle
  175. lightNode.target.position.set(0, 0, -1)
  176. lightNode.add(lightNode.target)
  177. break
  178. default:
  179. throw new Error('THREE.GLTFLoader: Unexpected light type, "' + lightDef.type + '".')
  180. }
  181. lightNode.position.set(0, 0, 0)
  182. lightNode.decay = 2
  183. if (lightDef.intensity !== undefined) lightNode.intensity = lightDef.intensity
  184. lightNode.name = lightDef.name || ('light_' + lightIndex)
  185. return Promise.resolve(lightNode)
  186. }
  187. function GLTFMaterialsUnlitExtension() {
  188. this.name = EXTENSIONS.KHR_MATERIALS_UNLIT
  189. }
  190. GLTFMaterialsUnlitExtension.prototype.getMaterialType = function () {
  191. return THREE.MeshBasicMaterial
  192. }
  193. GLTFMaterialsUnlitExtension.prototype.extendParams = function (materialParams, materialDef, parser) {
  194. const pending = []
  195. materialParams.color = new THREE.Color(1.0, 1.0, 1.0)
  196. materialParams.opacity = 1.0
  197. const metallicRoughness = materialDef.pbrMetallicRoughness
  198. if (metallicRoughness) {
  199. if (Array.isArray(metallicRoughness.baseColorFactor)) {
  200. const array = metallicRoughness.baseColorFactor
  201. materialParams.color.fromArray(array)
  202. materialParams.opacity = array[3]
  203. }
  204. if (metallicRoughness.baseColorTexture !== undefined) {
  205. pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture))
  206. }
  207. }
  208. return Promise.all(pending)
  209. }
  210. var BINARY_EXTENSION_HEADER_MAGIC = 'glTF'
  211. const BINARY_EXTENSION_HEADER_LENGTH = 12
  212. const BINARY_EXTENSION_CHUNK_TYPES = {
  213. JSON: 0x4E4F534A,
  214. BIN: 0x004E4942
  215. }
  216. function GLTFBinaryExtension(data) {
  217. this.name = EXTENSIONS.KHR_BINARY_GLTF
  218. this.content = null
  219. this.body = null
  220. const headerView = new DataView(data, 0, BINARY_EXTENSION_HEADER_LENGTH)
  221. this.header = {
  222. magic: THREE.LoaderUtils.decodeText(new Uint8Array(data.slice(0, 4))),
  223. version: headerView.getUint32(4, true),
  224. length: headerView.getUint32(8, true)
  225. }
  226. if (this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC) {
  227. throw new Error('THREE.GLTFLoader: Unsupported glTF-Binary header.')
  228. } else if (this.header.version < 2.0) {
  229. throw new Error('THREE.GLTFLoader: Legacy binary file detected. Use LegacyGLTFLoader instead.')
  230. }
  231. const chunkView = new DataView(data, BINARY_EXTENSION_HEADER_LENGTH)
  232. let chunkIndex = 0
  233. while (chunkIndex < chunkView.byteLength) {
  234. const chunkLength = chunkView.getUint32(chunkIndex, true)
  235. chunkIndex += 4
  236. const chunkType = chunkView.getUint32(chunkIndex, true)
  237. chunkIndex += 4
  238. if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON) {
  239. const contentArray = new Uint8Array(data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength)
  240. this.content = THREE.LoaderUtils.decodeText(contentArray)
  241. } else if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN) {
  242. const byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex
  243. this.body = data.slice(byteOffset, byteOffset + chunkLength)
  244. }
  245. chunkIndex += chunkLength
  246. }
  247. if (this.content === null) {
  248. throw new Error('THREE.GLTFLoader: JSON content not found.')
  249. }
  250. }
  251. function GLTFDracoMeshCompressionExtension(json, dracoLoader) {
  252. if (!dracoLoader) {
  253. throw new Error('THREE.GLTFLoader: No DRACOLoader instance provided.')
  254. }
  255. this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION
  256. this.json = json
  257. this.dracoLoader = dracoLoader
  258. }
  259. GLTFDracoMeshCompressionExtension.prototype.decodePrimitive = function (primitive, parser) {
  260. const json = this.json
  261. const dracoLoader = this.dracoLoader
  262. const bufferViewIndex = primitive.extensions[this.name].bufferView
  263. const gltfAttributeMap = primitive.extensions[this.name].attributes
  264. const threeAttributeMap = {}
  265. const attributeNormalizedMap = {}
  266. const attributeTypeMap = {}
  267. for (var attributeName in gltfAttributeMap) {
  268. var threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase()
  269. threeAttributeMap[threeAttributeName] = gltfAttributeMap[attributeName]
  270. }
  271. for (attributeName in primitive.attributes) {
  272. var threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase()
  273. if (gltfAttributeMap[attributeName] !== undefined) {
  274. const accessorDef = json.accessors[primitive.attributes[attributeName]]
  275. const componentType = WEBGL_COMPONENT_TYPES[accessorDef.componentType]
  276. attributeTypeMap[threeAttributeName] = componentType
  277. attributeNormalizedMap[threeAttributeName] = accessorDef.normalized === true
  278. }
  279. }
  280. return parser.getDependency('bufferView', bufferViewIndex).then(function (bufferView) {
  281. return new Promise(function (resolve) {
  282. dracoLoader.decodeDracoFile(
  283. bufferView,
  284. function (geometry) {
  285. for (const attributeName in geometry.attributes) {
  286. const attribute = geometry.attributes[attributeName]
  287. const normalized = attributeNormalizedMap[attributeName]
  288. if (normalized !== undefined) attribute.normalized = normalized
  289. }
  290. resolve(geometry)
  291. },
  292. threeAttributeMap,
  293. attributeTypeMap
  294. )
  295. })
  296. })
  297. }
  298. function GLTFTextureTransformExtension() {
  299. this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM
  300. }
  301. GLTFTextureTransformExtension.prototype.extendTexture = function (texture, transform) {
  302. texture = texture.clone()
  303. if (transform.offset !== undefined) {
  304. texture.offset.fromArray(transform.offset)
  305. }
  306. if (transform.rotation !== undefined) {
  307. texture.rotation = transform.rotation
  308. }
  309. if (transform.scale !== undefined) {
  310. texture.repeat.fromArray(transform.scale)
  311. }
  312. if (transform.texCoord !== undefined) {
  313. console.warn('THREE.GLTFLoader: Custom UV sets in "' + this.name + '" extension not yet supported.')
  314. }
  315. texture.needsUpdate = true
  316. return texture
  317. }
  318. function GLTFMaterialsPbrSpecularGlossinessExtension() {
  319. return {
  320. name: EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS,
  321. specularGlossinessParams: ['color', 'map', 'lightMap', 'lightMapIntensity', 'aoMap', 'aoMapIntensity', 'emissive', 'emissiveIntensity', 'emissiveMap', 'bumpMap', 'bumpScale', 'normalMap', 'displacementMap', 'displacementScale', 'displacementBias', 'specularMap', 'specular', 'glossinessMap', 'glossiness', 'alphaMap', 'envMap', 'envMapIntensity', 'refractionRatio'],
  322. getMaterialType() {
  323. return THREE.ShaderMaterial
  324. },
  325. extendParams(materialParams, materialDef, parser) {
  326. const pbrSpecularGlossiness = materialDef.extensions[this.name]
  327. const shader = THREE.ShaderLib.standard
  328. const uniforms = THREE.UniformsUtils.clone(shader.uniforms)
  329. const specularMapParsFragmentChunk = ['#ifdef USE_SPECULARMAP', ' uniform sampler2D specularMap;', '#endif'].join('\n')
  330. const glossinessMapParsFragmentChunk = ['#ifdef USE_GLOSSINESSMAP', ' uniform sampler2D glossinessMap;', '#endif'].join('\n')
  331. const specularMapFragmentChunk = ['vec3 specularFactor = specular;', '#ifdef USE_SPECULARMAP', ' vec4 texelSpecular = texture2D( specularMap, vUv );', ' texelSpecular = sRGBToLinear( texelSpecular );', ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', ' specularFactor *= texelSpecular.rgb;', '#endif'].join('\n')
  332. const glossinessMapFragmentChunk = ['float glossinessFactor = glossiness;', '#ifdef USE_GLOSSINESSMAP', ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', ' glossinessFactor *= texelGlossiness.a;', '#endif'].join('\n')
  333. const lightPhysicalFragmentChunk = ['PhysicalMaterial material;', 'material.diffuseColor = diffuseColor.rgb;', 'material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 );', 'material.specularColor = specularFactor.rgb;'].join('\n')
  334. const fragmentShader = shader.fragmentShader.replace('uniform float roughness;', 'uniform vec3 specular;').replace('uniform float metalness;', 'uniform float glossiness;').replace('#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk).replace('#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk)
  335. .replace('#include <roughnessmap_fragment>', specularMapFragmentChunk)
  336. .replace('#include <metalnessmap_fragment>', glossinessMapFragmentChunk)
  337. .replace('#include <lights_physical_fragment>', lightPhysicalFragmentChunk)
  338. delete uniforms.roughness
  339. delete uniforms.metalness
  340. delete uniforms.roughnessMap
  341. delete uniforms.metalnessMap
  342. uniforms.specular = {
  343. value: new THREE.Color().setHex(0x111111)
  344. }
  345. uniforms.glossiness = {
  346. value: 0.5
  347. }
  348. uniforms.specularMap = {
  349. value: null
  350. }
  351. uniforms.glossinessMap = {
  352. value: null
  353. }
  354. materialParams.vertexShader = shader.vertexShader
  355. materialParams.fragmentShader = fragmentShader
  356. materialParams.uniforms = uniforms
  357. materialParams.defines = {
  358. STANDARD: ''
  359. }
  360. materialParams.color = new THREE.Color(1.0, 1.0, 1.0)
  361. materialParams.opacity = 1.0
  362. const pending = []
  363. if (Array.isArray(pbrSpecularGlossiness.diffuseFactor)) {
  364. const array = pbrSpecularGlossiness.diffuseFactor
  365. materialParams.color.fromArray(array)
  366. materialParams.opacity = array[3]
  367. }
  368. if (pbrSpecularGlossiness.diffuseTexture !== undefined) {
  369. pending.push(parser.assignTexture(materialParams, 'map', pbrSpecularGlossiness.diffuseTexture))
  370. }
  371. materialParams.emissive = new THREE.Color(0.0, 0.0, 0.0)
  372. materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0
  373. materialParams.specular = new THREE.Color(1.0, 1.0, 1.0)
  374. if (Array.isArray(pbrSpecularGlossiness.specularFactor)) {
  375. materialParams.specular.fromArray(pbrSpecularGlossiness.specularFactor)
  376. }
  377. if (pbrSpecularGlossiness.specularGlossinessTexture !== undefined) {
  378. const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture
  379. pending.push(parser.assignTexture(materialParams, 'glossinessMap', specGlossMapDef))
  380. pending.push(parser.assignTexture(materialParams, 'specularMap', specGlossMapDef))
  381. }
  382. return Promise.all(pending)
  383. },
  384. createMaterial(params) {
  385. const material = new THREE.ShaderMaterial({
  386. defines: params.defines,
  387. vertexShader: params.vertexShader,
  388. fragmentShader: params.fragmentShader,
  389. uniforms: params.uniforms,
  390. fog: true,
  391. lights: true,
  392. opacity: params.opacity,
  393. transparent: params.transparent
  394. })
  395. material.isGLTFSpecularGlossinessMaterial = true
  396. material.color = params.color
  397. material.map = params.map === undefined ? null : params.map
  398. material.lightMap = null
  399. material.lightMapIntensity = 1.0
  400. material.aoMap = params.aoMap === undefined ? null : params.aoMap
  401. material.aoMapIntensity = 1.0
  402. material.emissive = params.emissive
  403. material.emissiveIntensity = 1.0
  404. material.emissiveMap = params.emissiveMap === undefined ? null : params.emissiveMap
  405. material.bumpMap = params.bumpMap === undefined ? null : params.bumpMap
  406. material.bumpScale = 1
  407. material.normalMap = params.normalMap === undefined ? null : params.normalMap
  408. if (params.normalScale) material.normalScale = params.normalScale
  409. material.displacementMap = null
  410. material.displacementScale = 1
  411. material.displacementBias = 0
  412. material.specularMap = params.specularMap === undefined ? null : params.specularMap
  413. material.specular = params.specular
  414. material.glossinessMap = params.glossinessMap === undefined ? null : params.glossinessMap
  415. material.glossiness = params.glossiness
  416. material.alphaMap = null
  417. material.envMap = params.envMap === undefined ? null : params.envMap
  418. material.envMapIntensity = 1.0
  419. material.refractionRatio = 0.98
  420. material.extensions.derivatives = true
  421. return material
  422. },
  423. cloneMaterial(source) {
  424. const target = source.clone()
  425. target.isGLTFSpecularGlossinessMaterial = true
  426. const params = this.specularGlossinessParams
  427. for (let i = 0,
  428. il = params.length; i < il; i++) {
  429. const value = source[params[i]]
  430. target[params[i]] = (value && value.isColor) ? value.clone() : value
  431. }
  432. return target
  433. },
  434. refreshUniforms(renderer, scene, camera, geometry, material) {
  435. if (material.isGLTFSpecularGlossinessMaterial !== true) {
  436. return
  437. }
  438. const uniforms = material.uniforms
  439. const defines = material.defines
  440. uniforms.opacity.value = material.opacity
  441. uniforms.diffuse.value.copy(material.color)
  442. uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity)
  443. uniforms.map.value = material.map
  444. uniforms.specularMap.value = material.specularMap
  445. uniforms.alphaMap.value = material.alphaMap
  446. uniforms.lightMap.value = material.lightMap
  447. uniforms.lightMapIntensity.value = material.lightMapIntensity
  448. uniforms.aoMap.value = material.aoMap
  449. uniforms.aoMapIntensity.value = material.aoMapIntensity
  450. let uvScaleMap
  451. if (material.map) {
  452. uvScaleMap = material.map
  453. } else if (material.specularMap) {
  454. uvScaleMap = material.specularMap
  455. } else if (material.displacementMap) {
  456. uvScaleMap = material.displacementMap
  457. } else if (material.normalMap) {
  458. uvScaleMap = material.normalMap
  459. } else if (material.bumpMap) {
  460. uvScaleMap = material.bumpMap
  461. } else if (material.glossinessMap) {
  462. uvScaleMap = material.glossinessMap
  463. } else if (material.alphaMap) {
  464. uvScaleMap = material.alphaMap
  465. } else if (material.emissiveMap) {
  466. uvScaleMap = material.emissiveMap
  467. }
  468. if (uvScaleMap !== undefined) {
  469. if (uvScaleMap.isWebGLRenderTarget) {
  470. uvScaleMap = uvScaleMap.texture
  471. }
  472. if (uvScaleMap.matrixAutoUpdate === true) {
  473. uvScaleMap.updateMatrix()
  474. }
  475. uniforms.uvTransform.value.copy(uvScaleMap.matrix)
  476. }
  477. if (material.envMap) {
  478. uniforms.envMap.value = material.envMap
  479. uniforms.envMapIntensity.value = material.envMapIntensity
  480. uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? -1 : 1
  481. uniforms.reflectivity.value = material.reflectivity
  482. uniforms.refractionRatio.value = material.refractionRatio
  483. uniforms.maxMipLevel.value = renderer.properties.get(material.envMap).__maxMipLevel
  484. }
  485. uniforms.specular.value.copy(material.specular)
  486. uniforms.glossiness.value = material.glossiness
  487. uniforms.glossinessMap.value = material.glossinessMap
  488. uniforms.emissiveMap.value = material.emissiveMap
  489. uniforms.bumpMap.value = material.bumpMap
  490. uniforms.normalMap.value = material.normalMap
  491. uniforms.displacementMap.value = material.displacementMap
  492. uniforms.displacementScale.value = material.displacementScale
  493. uniforms.displacementBias.value = material.displacementBias
  494. if (uniforms.glossinessMap.value !== null && defines.USE_GLOSSINESSMAP === undefined) {
  495. defines.USE_GLOSSINESSMAP = ''
  496. defines.USE_ROUGHNESSMAP = ''
  497. }
  498. if (uniforms.glossinessMap.value === null && defines.USE_GLOSSINESSMAP !== undefined) {
  499. delete defines.USE_GLOSSINESSMAP
  500. delete defines.USE_ROUGHNESSMAP
  501. }
  502. }
  503. }
  504. }
  505. function GLTFCubicSplineInterpolant(parameterPositions, sampleValues, sampleSize, resultBuffer) {
  506. THREE.Interpolant.call(this, parameterPositions, sampleValues, sampleSize, resultBuffer)
  507. }
  508. GLTFCubicSplineInterpolant.prototype = Object.create(THREE.Interpolant.prototype)
  509. GLTFCubicSplineInterpolant.prototype.constructor = GLTFCubicSplineInterpolant
  510. GLTFCubicSplineInterpolant.prototype.copySampleValue_ = function (index) {
  511. const result = this.resultBuffer
  512. const values = this.sampleValues
  513. const valueSize = this.valueSize
  514. const offset = index * valueSize * 3 + valueSize
  515. for (let i = 0; i !== valueSize; i++) {
  516. result[i] = values[offset + i]
  517. }
  518. return result
  519. }
  520. GLTFCubicSplineInterpolant.prototype.beforeStart_ = GLTFCubicSplineInterpolant.prototype.copySampleValue_
  521. GLTFCubicSplineInterpolant.prototype.afterEnd_ = GLTFCubicSplineInterpolant.prototype.copySampleValue_
  522. GLTFCubicSplineInterpolant.prototype.interpolate_ = function (i1, t0, t, t1) {
  523. const result = this.resultBuffer
  524. const values = this.sampleValues
  525. const stride = this.valueSize
  526. const stride2 = stride * 2
  527. const stride3 = stride * 3
  528. const td = t1 - t0
  529. const p = (t - t0) / td
  530. const pp = p * p
  531. const ppp = pp * p
  532. const offset1 = i1 * stride3
  533. const offset0 = offset1 - stride3
  534. const s2 = -2 * ppp + 3 * pp
  535. const s3 = ppp - pp
  536. const s0 = 1 - s2
  537. const s1 = s3 - pp + p
  538. for (let i = 0; i !== stride; i++) {
  539. const p0 = values[offset0 + i + stride]
  540. const m0 = values[offset0 + i + stride2] * td
  541. const p1 = values[offset1 + i + stride]
  542. const m1 = values[offset1 + i] * td
  543. result[i] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1
  544. }
  545. return result
  546. }
  547. const WEBGL_CONSTANTS = {
  548. FLOAT: 5126,
  549. FLOAT_MAT3: 35675,
  550. FLOAT_MAT4: 35676,
  551. FLOAT_VEC2: 35664,
  552. FLOAT_VEC3: 35665,
  553. FLOAT_VEC4: 35666,
  554. LINEAR: 9729,
  555. REPEAT: 10497,
  556. SAMPLER_2D: 35678,
  557. POINTS: 0,
  558. LINES: 1,
  559. LINE_LOOP: 2,
  560. LINE_STRIP: 3,
  561. TRIANGLES: 4,
  562. TRIANGLE_STRIP: 5,
  563. TRIANGLE_FAN: 6,
  564. UNSIGNED_BYTE: 5121,
  565. UNSIGNED_SHORT: 5123
  566. }
  567. var WEBGL_COMPONENT_TYPES = {
  568. 5120: Int8Array,
  569. 5121: Uint8Array,
  570. 5122: Int16Array,
  571. 5123: Uint16Array,
  572. 5125: Uint32Array,
  573. 5126: Float32Array
  574. }
  575. const WEBGL_FILTERS = {
  576. 9728: THREE.NearestFilter,
  577. 9729: THREE.LinearFilter,
  578. 9984: THREE.NearestMipmapNearestFilter,
  579. 9985: THREE.LinearMipmapNearestFilter,
  580. 9986: THREE.NearestMipmapLinearFilter,
  581. 9987: THREE.LinearMipmapLinearFilter
  582. }
  583. const WEBGL_WRAPPINGS = {
  584. 33071: THREE.ClampToEdgeWrapping,
  585. 33648: THREE.MirroredRepeatWrapping,
  586. 10497: THREE.RepeatWrapping
  587. }
  588. const WEBGL_TYPE_SIZES = {
  589. SCALAR: 1,
  590. VEC2: 2,
  591. VEC3: 3,
  592. VEC4: 4,
  593. MAT2: 4,
  594. MAT3: 9,
  595. MAT4: 16
  596. }
  597. var ATTRIBUTES = {
  598. POSITION: 'position',
  599. NORMAL: 'normal',
  600. TANGENT: 'tangent',
  601. TEXCOORD_0: 'uv',
  602. TEXCOORD_1: 'uv2',
  603. COLOR_0: 'color',
  604. WEIGHTS_0: 'skinWeight',
  605. JOINTS_0: 'skinIndex',
  606. }
  607. const PATH_PROPERTIES = {
  608. scale: 'scale',
  609. translation: 'position',
  610. rotation: 'quaternion',
  611. weights: 'morphTargetInfluences'
  612. }
  613. const INTERPOLATION = {
  614. CUBICSPLINE: undefined,
  615. LINEAR: THREE.InterpolateLinear,
  616. STEP: THREE.InterpolateDiscrete
  617. }
  618. const ALPHA_MODES = {
  619. OPAQUE: 'OPAQUE',
  620. MASK: 'MASK',
  621. BLEND: 'BLEND'
  622. }
  623. const MIME_TYPE_FORMATS = {
  624. 'image/png': THREE.RGBAFormat,
  625. 'image/jpeg': THREE.RGBFormat
  626. }
  627. function resolveURL(url, path) {
  628. if (typeof url !== 'string' || url === '') return ''
  629. if (/^https?:\/\//i.test(path) && /^\//.test(url)) {
  630. path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1')
  631. }
  632. if (/^(https?:)?\/\//i.test(url)) return url
  633. if (/^data:.*,.*$/i.test(url)) return url
  634. if (/^blob:.*$/i.test(url)) return url
  635. return path + url
  636. }
  637. let defaultMaterial
  638. function createDefaultMaterial() {
  639. defaultMaterial = defaultMaterial || new THREE.MeshStandardMaterial({
  640. color: 0xFFFFFF,
  641. emissive: 0x000000,
  642. metalness: 1,
  643. roughness: 1,
  644. transparent: false,
  645. depthTest: true,
  646. side: THREE.FrontSide
  647. })
  648. return defaultMaterial
  649. }
  650. function addUnknownExtensionsToUserData(knownExtensions, object, objectDef) {
  651. for (const name in objectDef.extensions) {
  652. if (knownExtensions[name] === undefined) {
  653. object.userData.gltfExtensions = object.userData.gltfExtensions || {}
  654. object.userData.gltfExtensions[name] = objectDef.extensions[name]
  655. }
  656. }
  657. }
  658. function assignExtrasToUserData(object, gltfDef) {
  659. if (gltfDef.extras !== undefined) {
  660. if (typeof gltfDef.extras === 'object') {
  661. Object.assign(object.userData, gltfDef.extras)
  662. } else {
  663. console.warn('THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras)
  664. }
  665. }
  666. }
  667. function addMorphTargets(geometry, targets, parser) {
  668. let hasMorphPosition = false
  669. let hasMorphNormal = false
  670. for (var i = 0,
  671. il = targets.length; i < il; i++) {
  672. var target = targets[i]
  673. if (target.POSITION !== undefined) hasMorphPosition = true
  674. if (target.NORMAL !== undefined) hasMorphNormal = true
  675. if (hasMorphPosition && hasMorphNormal) break
  676. }
  677. if (!hasMorphPosition && !hasMorphNormal) return Promise.resolve(geometry)
  678. const pendingPositionAccessors = []
  679. const pendingNormalAccessors = []
  680. for (var i = 0,
  681. il = targets.length; i < il; i++) {
  682. var target = targets[i]
  683. if (hasMorphPosition) {
  684. var pendingAccessor = target.POSITION !== undefined ? parser.getDependency('accessor', target.POSITION) : geometry.attributes.position
  685. pendingPositionAccessors.push(pendingAccessor)
  686. }
  687. if (hasMorphNormal) {
  688. var pendingAccessor = target.NORMAL !== undefined ? parser.getDependency('accessor', target.NORMAL) : geometry.attributes.normal
  689. pendingNormalAccessors.push(pendingAccessor)
  690. }
  691. }
  692. return Promise.all([Promise.all(pendingPositionAccessors), Promise.all(pendingNormalAccessors)]).then(function (accessors) {
  693. const morphPositions = accessors[0]
  694. const morphNormals = accessors[1]
  695. for (var i = 0,
  696. il = morphPositions.length; i < il; i++) {
  697. if (geometry.attributes.position === morphPositions[i]) continue
  698. morphPositions[i] = cloneBufferAttribute(morphPositions[i])
  699. }
  700. for (var i = 0,
  701. il = morphNormals.length; i < il; i++) {
  702. if (geometry.attributes.normal === morphNormals[i]) continue
  703. morphNormals[i] = cloneBufferAttribute(morphNormals[i])
  704. }
  705. for (var i = 0,
  706. il = targets.length; i < il; i++) {
  707. const target = targets[i]
  708. const attributeName = 'morphTarget' + i
  709. if (hasMorphPosition) {
  710. if (target.POSITION !== undefined) {
  711. const positionAttribute = morphPositions[i]
  712. positionAttribute.name = attributeName
  713. const position = geometry.attributes.position
  714. for (var j = 0,
  715. jl = positionAttribute.count; j < jl; j++) {
  716. positionAttribute.setXYZ(j, positionAttribute.getX(j) + position.getX(j), positionAttribute.getY(j) + position.getY(j), positionAttribute.getZ(j) + position.getZ(j))
  717. }
  718. }
  719. }
  720. if (hasMorphNormal) {
  721. if (target.NORMAL !== undefined) {
  722. const normalAttribute = morphNormals[i]
  723. normalAttribute.name = attributeName
  724. const normal = geometry.attributes.normal
  725. for (var j = 0,
  726. jl = normalAttribute.count; j < jl; j++) {
  727. normalAttribute.setXYZ(j, normalAttribute.getX(j) + normal.getX(j), normalAttribute.getY(j) + normal.getY(j), normalAttribute.getZ(j) + normal.getZ(j))
  728. }
  729. }
  730. }
  731. }
  732. if (hasMorphPosition) geometry.morphAttributes.position = morphPositions
  733. if (hasMorphNormal) geometry.morphAttributes.normal = morphNormals
  734. return geometry
  735. })
  736. }
  737. function updateMorphTargets(mesh, meshDef) {
  738. mesh.updateMorphTargets()
  739. if (meshDef.weights !== undefined) {
  740. for (var i = 0,
  741. il = meshDef.weights.length; i < il; i++) {
  742. mesh.morphTargetInfluences[i] = meshDef.weights[i]
  743. }
  744. }
  745. if (meshDef.extras && Array.isArray(meshDef.extras.targetNames)) {
  746. const targetNames = meshDef.extras.targetNames
  747. if (mesh.morphTargetInfluences.length === targetNames.length) {
  748. mesh.morphTargetDictionary = {}
  749. for (var i = 0,
  750. il = targetNames.length; i < il; i++) {
  751. mesh.morphTargetDictionary[targetNames[i]] = i
  752. }
  753. } else {
  754. console.warn('THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.')
  755. }
  756. }
  757. }
  758. function createPrimitiveKey(primitiveDef) {
  759. const dracoExtension = primitiveDef.extensions && primitiveDef.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION]
  760. let geometryKey
  761. if (dracoExtension) {
  762. geometryKey = 'draco:' + dracoExtension.bufferView + ':' + dracoExtension.indices + ':' + createAttributesKey(dracoExtension.attributes)
  763. } else {
  764. geometryKey = primitiveDef.indices + ':' + createAttributesKey(primitiveDef.attributes) + ':' + primitiveDef.mode
  765. }
  766. return geometryKey
  767. }
  768. function createAttributesKey(attributes) {
  769. let attributesKey = ''
  770. const keys = Object.keys(attributes).sort()
  771. for (let i = 0,
  772. il = keys.length; i < il; i++) {
  773. attributesKey += keys[i] + ':' + attributes[keys[i]] + ';'
  774. }
  775. return attributesKey
  776. }
  777. function cloneBufferAttribute(attribute) {
  778. if (attribute.isInterleavedBufferAttribute) {
  779. const count = attribute.count
  780. const itemSize = attribute.itemSize
  781. const array = attribute.array.slice(0, count * itemSize)
  782. for (let i = 0,
  783. j = 0; i < count; ++i) {
  784. array[j++] = attribute.getX(i)
  785. if (itemSize >= 2) array[j++] = attribute.getY(i)
  786. if (itemSize >= 3) array[j++] = attribute.getZ(i)
  787. if (itemSize >= 4) array[j++] = attribute.getW(i)
  788. }
  789. return new THREE.BufferAttribute(array, itemSize, attribute.normalized)
  790. }
  791. return attribute.clone()
  792. }
  793. function GLTFParser(json, extensions, options) {
  794. this.json = json || {}
  795. this.extensions = extensions || {}
  796. this.options = options || {}
  797. this.cache = new GLTFRegistry()
  798. this.primitiveCache = {}
  799. this.textureLoader = new THREE.TextureLoader(this.options.manager)
  800. this.textureLoader.setCrossOrigin(this.options.crossOrigin)
  801. this.fileLoader = new THREE.FileLoader(this.options.manager)
  802. this.fileLoader.setResponseType('arraybuffer')
  803. }
  804. GLTFParser.prototype.parse = function (onLoad, onError) {
  805. const parser = this
  806. const json = this.json
  807. const extensions = this.extensions
  808. this.cache.removeAll()
  809. this.markDefs()
  810. Promise.all([this.getDependencies('scene'), this.getDependencies('animation'), this.getDependencies('camera')]).then(function (dependencies) {
  811. const result = {
  812. scene: dependencies[0][json.scene || 0],
  813. scenes: dependencies[0],
  814. animations: dependencies[1],
  815. cameras: dependencies[2],
  816. asset: json.asset,
  817. parser,
  818. userData: {}
  819. }
  820. addUnknownExtensionsToUserData(extensions, result, json)
  821. assignExtrasToUserData(result, json)
  822. onLoad(result)
  823. })
  824. .catch(onError)
  825. }
  826. GLTFParser.prototype.markDefs = function () {
  827. const nodeDefs = this.json.nodes || []
  828. const skinDefs = this.json.skins || []
  829. const meshDefs = this.json.meshes || []
  830. const meshReferences = {}
  831. const meshUses = {}
  832. for (let skinIndex = 0,
  833. skinLength = skinDefs.length; skinIndex < skinLength; skinIndex++) {
  834. const joints = skinDefs[skinIndex].joints
  835. for (let i = 0,
  836. il = joints.length; i < il; i++) {
  837. nodeDefs[joints[i]].isBone = true
  838. }
  839. }
  840. for (let nodeIndex = 0,
  841. nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex++) {
  842. const nodeDef = nodeDefs[nodeIndex]
  843. if (nodeDef.mesh !== undefined) {
  844. if (meshReferences[nodeDef.mesh] === undefined) {
  845. meshReferences[nodeDef.mesh] = meshUses[nodeDef.mesh] = 0
  846. }
  847. meshReferences[nodeDef.mesh]++
  848. if (nodeDef.skin !== undefined) {
  849. meshDefs[nodeDef.mesh].isSkinnedMesh = true
  850. }
  851. }
  852. }
  853. this.json.meshReferences = meshReferences
  854. this.json.meshUses = meshUses
  855. }
  856. GLTFParser.prototype.getDependency = function (type, index) {
  857. const cacheKey = type + ':' + index
  858. let dependency = this.cache.get(cacheKey)
  859. if (!dependency) {
  860. switch (type) {
  861. case 'scene':
  862. dependency = this.loadScene(index)
  863. break
  864. case 'node':
  865. dependency = this.loadNode(index)
  866. break
  867. case 'mesh':
  868. dependency = this.loadMesh(index)
  869. break
  870. case 'accessor':
  871. dependency = this.loadAccessor(index)
  872. break
  873. case 'bufferView':
  874. dependency = this.loadBufferView(index)
  875. break
  876. case 'buffer':
  877. dependency = this.loadBuffer(index)
  878. break
  879. case 'material':
  880. dependency = this.loadMaterial(index)
  881. break
  882. case 'texture':
  883. dependency = this.loadTexture(index)
  884. break
  885. case 'skin':
  886. dependency = this.loadSkin(index)
  887. break
  888. case 'animation':
  889. dependency = this.loadAnimation(index)
  890. break
  891. case 'camera':
  892. dependency = this.loadCamera(index)
  893. break
  894. case 'light':
  895. dependency = this.extensions[EXTENSIONS.KHR_LIGHTS_PUNCTUAL].loadLight(index)
  896. break
  897. default:
  898. throw new Error('Unknown type: ' + type)
  899. }
  900. this.cache.add(cacheKey, dependency)
  901. }
  902. return dependency
  903. }
  904. GLTFParser.prototype.getDependencies = function (type) {
  905. let dependencies = this.cache.get(type)
  906. if (!dependencies) {
  907. const parser = this
  908. const defs = this.json[type + (type === 'mesh' ? 'es' : 's')] || []
  909. dependencies = Promise.all(defs.map(function (def, index) {
  910. return parser.getDependency(type, index)
  911. }))
  912. this.cache.add(type, dependencies)
  913. }
  914. return dependencies
  915. }
  916. GLTFParser.prototype.loadBuffer = function (bufferIndex) {
  917. const bufferDef = this.json.buffers[bufferIndex]
  918. const loader = this.fileLoader
  919. if (bufferDef.type && bufferDef.type !== 'arraybuffer') {
  920. throw new Error('THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.')
  921. }
  922. if (bufferDef.uri === undefined && bufferIndex === 0) {
  923. return Promise.resolve(this.extensions[EXTENSIONS.KHR_BINARY_GLTF].body)
  924. }
  925. const options = this.options
  926. return new Promise(function (resolve, reject) {
  927. loader.load(
  928. resolveURL(bufferDef.uri, options.path),
  929. resolve,
  930. undefined,
  931. function () {
  932. reject(new Error('THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".'))
  933. }
  934. )
  935. })
  936. }
  937. GLTFParser.prototype.loadBufferView = function (bufferViewIndex) {
  938. const bufferViewDef = this.json.bufferViews[bufferViewIndex]
  939. return this.getDependency('buffer', bufferViewDef.buffer).then(function (buffer) {
  940. const byteLength = bufferViewDef.byteLength || 0
  941. const byteOffset = bufferViewDef.byteOffset || 0
  942. return buffer.slice(byteOffset, byteOffset + byteLength)
  943. })
  944. }
  945. GLTFParser.prototype.loadAccessor = function (accessorIndex) {
  946. const parser = this
  947. const json = this.json
  948. const accessorDef = this.json.accessors[accessorIndex]
  949. if (accessorDef.bufferView === undefined && accessorDef.sparse === undefined) {
  950. return Promise.resolve(null)
  951. }
  952. const pendingBufferViews = []
  953. if (accessorDef.bufferView !== undefined) {
  954. pendingBufferViews.push(this.getDependency('bufferView', accessorDef.bufferView))
  955. } else {
  956. pendingBufferViews.push(null)
  957. }
  958. if (accessorDef.sparse !== undefined) {
  959. pendingBufferViews.push(this.getDependency('bufferView', accessorDef.sparse.indices.bufferView))
  960. pendingBufferViews.push(this.getDependency('bufferView', accessorDef.sparse.values.bufferView))
  961. }
  962. return Promise.all(pendingBufferViews).then(function (bufferViews) {
  963. const bufferView = bufferViews[0]
  964. const itemSize = WEBGL_TYPE_SIZES[accessorDef.type]
  965. const TypedArray = WEBGL_COMPONENT_TYPES[accessorDef.componentType]
  966. const elementBytes = TypedArray.BYTES_PER_ELEMENT
  967. const itemBytes = elementBytes * itemSize
  968. const byteOffset = accessorDef.byteOffset || 0
  969. const byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[accessorDef.bufferView].byteStride : undefined
  970. const normalized = accessorDef.normalized === true
  971. let array; let
  972. bufferAttribute
  973. if (byteStride && byteStride !== itemBytes) {
  974. const ibSlice = Math.floor(byteOffset / byteStride)
  975. const ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count
  976. let ib = parser.cache.get(ibCacheKey)
  977. if (!ib) {
  978. array = new TypedArray(bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes)
  979. ib = new THREE.InterleavedBuffer(array, byteStride / elementBytes)
  980. parser.cache.add(ibCacheKey, ib)
  981. }
  982. bufferAttribute = new THREE.InterleavedBufferAttribute(ib, itemSize, (byteOffset % byteStride) / elementBytes, normalized)
  983. } else {
  984. if (bufferView === null) {
  985. array = new TypedArray(accessorDef.count * itemSize)
  986. } else {
  987. array = new TypedArray(bufferView, byteOffset, accessorDef.count * itemSize)
  988. }
  989. bufferAttribute = new THREE.BufferAttribute(array, itemSize, normalized)
  990. }
  991. if (accessorDef.sparse !== undefined) {
  992. const itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR
  993. const TypedArrayIndices = WEBGL_COMPONENT_TYPES[accessorDef.sparse.indices.componentType]
  994. const byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0
  995. const byteOffsetValues = accessorDef.sparse.values.byteOffset || 0
  996. const sparseIndices = new TypedArrayIndices(bufferViews[1], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices)
  997. const sparseValues = new TypedArray(bufferViews[2], byteOffsetValues, accessorDef.sparse.count * itemSize)
  998. if (bufferView !== null) {
  999. bufferAttribute.setArray(bufferAttribute.array.slice())
  1000. }
  1001. for (let i = 0,
  1002. il = sparseIndices.length; i < il; i++) {
  1003. const index = sparseIndices[i]
  1004. bufferAttribute.setX(index, sparseValues[i * itemSize])
  1005. if (itemSize >= 2) bufferAttribute.setY(index, sparseValues[i * itemSize + 1])
  1006. if (itemSize >= 3) bufferAttribute.setZ(index, sparseValues[i * itemSize + 2])
  1007. if (itemSize >= 4) bufferAttribute.setW(index, sparseValues[i * itemSize + 3])
  1008. if (itemSize >= 5) throw new Error('THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.')
  1009. }
  1010. }
  1011. return bufferAttribute
  1012. })
  1013. }
  1014. GLTFParser.prototype.loadTexture = function (textureIndex) {
  1015. const parser = this
  1016. const json = this.json
  1017. const options = this.options
  1018. const textureLoader = this.textureLoader
  1019. // var URL = global.URL;
  1020. const textureDef = json.textures[textureIndex]
  1021. const textureExtensions = textureDef.extensions || {}
  1022. let source
  1023. if (textureExtensions[EXTENSIONS.MSFT_TEXTURE_DDS]) {
  1024. source = json.images[textureExtensions[EXTENSIONS.MSFT_TEXTURE_DDS].source]
  1025. } else {
  1026. source = json.images[textureDef.source]
  1027. }
  1028. let sourceURI = source.uri
  1029. let isObjectURL = false
  1030. if (source.bufferView !== undefined) {
  1031. sourceURI = parser.getDependency('bufferView', source.bufferView).then(function (bufferView) {
  1032. isObjectURL = true
  1033. // 微信小程序不支持 Blob 对象,则使用 base64 编码的字符串来创建 data URI
  1034. const base64Str = wx.arrayBufferToBase64(bufferView)
  1035. sourceURI = `data:${source.mimeType};base64,${base64Str}`
  1036. return sourceURI
  1037. })
  1038. }
  1039. return Promise.resolve(sourceURI).then(function (sourceURI) {
  1040. let loader = THREE.Loader.Handlers.get(sourceURI)
  1041. if (!loader) {
  1042. loader = textureExtensions[EXTENSIONS.MSFT_TEXTURE_DDS] ? parser.extensions[EXTENSIONS.MSFT_TEXTURE_DDS].ddsLoader : textureLoader
  1043. }
  1044. return new Promise(function (resolve, reject) {
  1045. loader.load(resolveURL(sourceURI, options.path), resolve, undefined, reject)
  1046. })
  1047. }).then(function (texture) {
  1048. if (isObjectURL === true) {
  1049. // URL.revokeObjectURL(sourceURI)
  1050. }
  1051. texture.flipY = false
  1052. if (textureDef.name !== undefined) texture.name = textureDef.name
  1053. if (source.mimeType in MIME_TYPE_FORMATS) {
  1054. texture.format = MIME_TYPE_FORMATS[source.mimeType]
  1055. }
  1056. const samplers = json.samplers || {}
  1057. const sampler = samplers[textureDef.sampler] || {}
  1058. texture.magFilter = WEBGL_FILTERS[sampler.magFilter] || THREE.LinearFilter
  1059. texture.minFilter = WEBGL_FILTERS[sampler.minFilter] || THREE.LinearMipmapLinearFilter
  1060. texture.wrapS = WEBGL_WRAPPINGS[sampler.wrapS] || THREE.RepeatWrapping
  1061. texture.wrapT = WEBGL_WRAPPINGS[sampler.wrapT] || THREE.RepeatWrapping
  1062. return texture
  1063. })
  1064. }
  1065. GLTFParser.prototype.assignTexture = function (materialParams, mapName, mapDef) {
  1066. const parser = this
  1067. return this.getDependency('texture', mapDef.index).then(function (texture) {
  1068. if (!texture.isCompressedTexture) {
  1069. switch (mapName) {
  1070. case 'aoMap':
  1071. case 'emissiveMap':
  1072. case 'metalnessMap':
  1073. case 'normalMap':
  1074. case 'roughnessMap':
  1075. texture.format = THREE.RGBFormat
  1076. break
  1077. }
  1078. }
  1079. if (parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM]) {
  1080. const transform = mapDef.extensions !== undefined ? mapDef.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM] : undefined
  1081. if (transform) {
  1082. texture = parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM].extendTexture(texture, transform)
  1083. }
  1084. }
  1085. materialParams[mapName] = texture
  1086. })
  1087. }
  1088. GLTFParser.prototype.assignFinalMaterial = function (mesh) {
  1089. const geometry = mesh.geometry
  1090. let material = mesh.material
  1091. const extensions = this.extensions
  1092. const useVertexTangents = geometry.attributes.tangent !== undefined
  1093. const useVertexColors = geometry.attributes.color !== undefined
  1094. const useFlatShading = geometry.attributes.normal === undefined
  1095. const useSkinning = mesh.isSkinnedMesh === true
  1096. const useMorphTargets = Object.keys(geometry.morphAttributes).length > 0
  1097. const useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined
  1098. if (mesh.isPoints) {
  1099. var cacheKey = 'PointsMaterial:' + material.uuid
  1100. let pointsMaterial = this.cache.get(cacheKey)
  1101. if (!pointsMaterial) {
  1102. pointsMaterial = new THREE.PointsMaterial()
  1103. THREE.Material.prototype.copy.call(pointsMaterial, material)
  1104. pointsMaterial.color.copy(material.color)
  1105. pointsMaterial.map = material.map
  1106. pointsMaterial.lights = false
  1107. pointsMaterial.sizeAttenuation = false
  1108. this.cache.add(cacheKey, pointsMaterial)
  1109. }
  1110. material = pointsMaterial
  1111. } else if (mesh.isLine) {
  1112. var cacheKey = 'LineBasicMaterial:' + material.uuid
  1113. let lineMaterial = this.cache.get(cacheKey)
  1114. if (!lineMaterial) {
  1115. lineMaterial = new THREE.LineBasicMaterial()
  1116. THREE.Material.prototype.copy.call(lineMaterial, material)
  1117. lineMaterial.color.copy(material.color)
  1118. lineMaterial.lights = false
  1119. this.cache.add(cacheKey, lineMaterial)
  1120. }
  1121. material = lineMaterial
  1122. }
  1123. if (useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets) {
  1124. var cacheKey = 'ClonedMaterial:' + material.uuid + ':'
  1125. if (material.isGLTFSpecularGlossinessMaterial) cacheKey += 'specular-glossiness:'
  1126. if (useSkinning) cacheKey += 'skinning:'
  1127. if (useVertexTangents) cacheKey += 'vertex-tangents:'
  1128. if (useVertexColors) cacheKey += 'vertex-colors:'
  1129. if (useFlatShading) cacheKey += 'flat-shading:'
  1130. if (useMorphTargets) cacheKey += 'morph-targets:'
  1131. if (useMorphNormals) cacheKey += 'morph-normals:'
  1132. let cachedMaterial = this.cache.get(cacheKey)
  1133. if (!cachedMaterial) {
  1134. cachedMaterial = material.isGLTFSpecularGlossinessMaterial ? extensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS].cloneMaterial(material) : material.clone()
  1135. if (useSkinning) cachedMaterial.skinning = true
  1136. if (useVertexTangents) cachedMaterial.vertexTangents = true
  1137. if (useVertexColors) cachedMaterial.vertexColors = THREE.VertexColors
  1138. if (useFlatShading) cachedMaterial.flatShading = true
  1139. if (useMorphTargets) cachedMaterial.morphTargets = true
  1140. if (useMorphNormals) cachedMaterial.morphNormals = true
  1141. this.cache.add(cacheKey, cachedMaterial)
  1142. }
  1143. material = cachedMaterial
  1144. }
  1145. if (material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined) {
  1146. console.log('THREE.GLTFLoader: Duplicating UVs to support aoMap.')
  1147. geometry.addAttribute('uv2', new THREE.BufferAttribute(geometry.attributes.uv.array, 2))
  1148. }
  1149. if (material.isGLTFSpecularGlossinessMaterial) {
  1150. mesh.onBeforeRender = extensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS].refreshUniforms
  1151. }
  1152. mesh.material = material
  1153. }
  1154. GLTFParser.prototype.loadMaterial = function (materialIndex) {
  1155. const parser = this
  1156. const json = this.json
  1157. const extensions = this.extensions
  1158. const materialDef = json.materials[materialIndex]
  1159. let materialType
  1160. const materialParams = {}
  1161. const materialExtensions = materialDef.extensions || {}
  1162. const pending = []
  1163. if (materialExtensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS]) {
  1164. const sgExtension = extensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS]
  1165. materialType = sgExtension.getMaterialType()
  1166. pending.push(sgExtension.extendParams(materialParams, materialDef, parser))
  1167. } else if (materialExtensions[EXTENSIONS.KHR_MATERIALS_UNLIT]) {
  1168. const kmuExtension = extensions[EXTENSIONS.KHR_MATERIALS_UNLIT]
  1169. materialType = kmuExtension.getMaterialType()
  1170. pending.push(kmuExtension.extendParams(materialParams, materialDef, parser))
  1171. } else {
  1172. materialType = THREE.MeshStandardMaterial
  1173. const metallicRoughness = materialDef.pbrMetallicRoughness || {}
  1174. materialParams.color = new THREE.Color(1.0, 1.0, 1.0)
  1175. materialParams.opacity = 1.0
  1176. if (Array.isArray(metallicRoughness.baseColorFactor)) {
  1177. const array = metallicRoughness.baseColorFactor
  1178. materialParams.color.fromArray(array)
  1179. materialParams.opacity = array[3]
  1180. }
  1181. if (metallicRoughness.baseColorTexture !== undefined) {
  1182. pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture))
  1183. }
  1184. materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0
  1185. materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0
  1186. if (metallicRoughness.metallicRoughnessTexture !== undefined) {
  1187. pending.push(parser.assignTexture(materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture))
  1188. pending.push(parser.assignTexture(materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture))
  1189. }
  1190. }
  1191. if (materialDef.doubleSided === true) {
  1192. materialParams.side = THREE.DoubleSide
  1193. }
  1194. const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE
  1195. if (alphaMode === ALPHA_MODES.BLEND) {
  1196. materialParams.transparent = true
  1197. } else {
  1198. materialParams.transparent = false
  1199. if (alphaMode === ALPHA_MODES.MASK) {
  1200. materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5
  1201. }
  1202. }
  1203. if (materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
  1204. pending.push(parser.assignTexture(materialParams, 'normalMap', materialDef.normalTexture))
  1205. materialParams.normalScale = new THREE.Vector2(1, 1)
  1206. if (materialDef.normalTexture.scale !== undefined) {
  1207. materialParams.normalScale.set(materialDef.normalTexture.scale, materialDef.normalTexture.scale)
  1208. }
  1209. }
  1210. if (materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
  1211. pending.push(parser.assignTexture(materialParams, 'aoMap', materialDef.occlusionTexture))
  1212. if (materialDef.occlusionTexture.strength !== undefined) {
  1213. materialParams.aoMapIntensity = materialDef.occlusionTexture.strength
  1214. }
  1215. }
  1216. if (materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial) {
  1217. materialParams.emissive = new THREE.Color().fromArray(materialDef.emissiveFactor)
  1218. }
  1219. if (materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
  1220. pending.push(parser.assignTexture(materialParams, 'emissiveMap', materialDef.emissiveTexture))
  1221. }
  1222. return Promise.all(pending).then(function () {
  1223. let material
  1224. if (materialType === THREE.ShaderMaterial) {
  1225. material = extensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS].createMaterial(materialParams)
  1226. } else {
  1227. material = new materialType(materialParams)
  1228. }
  1229. if (materialDef.name !== undefined) material.name = materialDef.name
  1230. if (material.map) material.map.encoding = THREE.sRGBEncoding
  1231. if (material.emissiveMap) material.emissiveMap.encoding = THREE.sRGBEncoding
  1232. if (material.specularMap) material.specularMap.encoding = THREE.sRGBEncoding
  1233. assignExtrasToUserData(material, materialDef)
  1234. if (materialDef.extensions) addUnknownExtensionsToUserData(extensions, material, materialDef)
  1235. return material
  1236. })
  1237. }
  1238. function addPrimitiveAttributes(geometry, primitiveDef, parser) {
  1239. const attributes = primitiveDef.attributes
  1240. const pending = []
  1241. function assignAttributeAccessor(accessorIndex, attributeName) {
  1242. return parser.getDependency('accessor', accessorIndex).then(function (accessor) {
  1243. geometry.addAttribute(attributeName, accessor)
  1244. })
  1245. }
  1246. for (const gltfAttributeName in attributes) {
  1247. const threeAttributeName = ATTRIBUTES[gltfAttributeName] || gltfAttributeName.toLowerCase()
  1248. if (threeAttributeName in geometry.attributes) continue
  1249. pending.push(assignAttributeAccessor(attributes[gltfAttributeName], threeAttributeName))
  1250. }
  1251. if (primitiveDef.indices !== undefined && !geometry.index) {
  1252. const accessor = parser.getDependency('accessor', primitiveDef.indices).then(function (accessor) {
  1253. geometry.setIndex(accessor)
  1254. })
  1255. pending.push(accessor)
  1256. }
  1257. assignExtrasToUserData(geometry, primitiveDef)
  1258. return Promise.all(pending).then(function () {
  1259. return primitiveDef.targets !== undefined ? addMorphTargets(geometry, primitiveDef.targets, parser) : geometry
  1260. })
  1261. }
  1262. GLTFParser.prototype.loadGeometries = function (primitives) {
  1263. const parser = this
  1264. const extensions = this.extensions
  1265. const cache = this.primitiveCache
  1266. function createDracoPrimitive(primitive) {
  1267. return extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(primitive, parser).then(function (geometry) {
  1268. return addPrimitiveAttributes(geometry, primitive, parser)
  1269. })
  1270. }
  1271. const pending = []
  1272. for (let i = 0,
  1273. il = primitives.length; i < il; i++) {
  1274. const primitive = primitives[i]
  1275. const cacheKey = createPrimitiveKey(primitive)
  1276. const cached = cache[cacheKey]
  1277. if (cached) {
  1278. pending.push(cached.promise)
  1279. } else {
  1280. var geometryPromise
  1281. if (primitive.extensions && primitive.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION]) {
  1282. geometryPromise = createDracoPrimitive(primitive)
  1283. } else {
  1284. geometryPromise = addPrimitiveAttributes(new THREE.BufferGeometry(), primitive, parser)
  1285. }
  1286. cache[cacheKey] = {
  1287. primitive,
  1288. promise: geometryPromise
  1289. }
  1290. pending.push(geometryPromise)
  1291. }
  1292. }
  1293. return Promise.all(pending)
  1294. }
  1295. GLTFParser.prototype.loadMesh = function (meshIndex) {
  1296. const parser = this
  1297. const json = this.json
  1298. const meshDef = json.meshes[meshIndex]
  1299. const primitives = meshDef.primitives
  1300. const pending = []
  1301. for (let i = 0,
  1302. il = primitives.length; i < il; i++) {
  1303. const material = primitives[i].material === undefined ? createDefaultMaterial() : this.getDependency('material', primitives[i].material)
  1304. pending.push(material)
  1305. }
  1306. return Promise.all(pending).then(function (originalMaterials) {
  1307. return parser.loadGeometries(primitives).then(function (geometries) {
  1308. const meshes = []
  1309. for (var i = 0,
  1310. il = geometries.length; i < il; i++) {
  1311. const geometry = geometries[i]
  1312. const primitive = primitives[i]
  1313. var mesh
  1314. const material = originalMaterials[i]
  1315. if (primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || primitive.mode === undefined) {
  1316. mesh = meshDef.isSkinnedMesh === true ? new THREE.SkinnedMesh(geometry, material) : new THREE.Mesh(geometry, material)
  1317. if (mesh.isSkinnedMesh === true && !mesh.geometry.attributes.skinWeight.normalized) {
  1318. mesh.normalizeSkinWeights()
  1319. }
  1320. if (primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP) {
  1321. mesh.drawMode = THREE.TriangleStripDrawMode
  1322. } else if (primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN) {
  1323. mesh.drawMode = THREE.TriangleFanDrawMode
  1324. }
  1325. } else if (primitive.mode === WEBGL_CONSTANTS.LINES) {
  1326. mesh = new THREE.LineSegments(geometry, material)
  1327. } else if (primitive.mode === WEBGL_CONSTANTS.LINE_STRIP) {
  1328. mesh = new THREE.Line(geometry, material)
  1329. } else if (primitive.mode === WEBGL_CONSTANTS.LINE_LOOP) {
  1330. mesh = new THREE.LineLoop(geometry, material)
  1331. } else if (primitive.mode === WEBGL_CONSTANTS.POINTS) {
  1332. mesh = new THREE.Points(geometry, material)
  1333. } else {
  1334. throw new Error('THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode)
  1335. }
  1336. if (Object.keys(mesh.geometry.morphAttributes).length > 0) {
  1337. updateMorphTargets(mesh, meshDef)
  1338. }
  1339. mesh.name = meshDef.name || ('mesh_' + meshIndex)
  1340. if (geometries.length > 1) mesh.name += '_' + i
  1341. assignExtrasToUserData(mesh, meshDef)
  1342. parser.assignFinalMaterial(mesh)
  1343. meshes.push(mesh)
  1344. }
  1345. if (meshes.length === 1) {
  1346. return meshes[0]
  1347. }
  1348. const group = new THREE.Group()
  1349. for (var i = 0,
  1350. il = meshes.length; i < il; i++) {
  1351. group.add(meshes[i])
  1352. }
  1353. return group
  1354. })
  1355. })
  1356. }
  1357. GLTFParser.prototype.loadCamera = function (cameraIndex) {
  1358. let camera
  1359. const cameraDef = this.json.cameras[cameraIndex]
  1360. const params = cameraDef[cameraDef.type]
  1361. if (!params) {
  1362. console.warn('THREE.GLTFLoader: Missing camera parameters.')
  1363. return
  1364. }
  1365. if (cameraDef.type === 'perspective') {
  1366. camera = new THREE.PerspectiveCamera(THREE.Math.radToDeg(params.yfov), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6)
  1367. } else if (cameraDef.type === 'orthographic') {
  1368. camera = new THREE.OrthographicCamera(params.xmag / -2, params.xmag / 2, params.ymag / 2, params.ymag / -2, params.znear, params.zfar)
  1369. }
  1370. if (cameraDef.name !== undefined) camera.name = cameraDef.name
  1371. assignExtrasToUserData(camera, cameraDef)
  1372. return Promise.resolve(camera)
  1373. }
  1374. GLTFParser.prototype.loadSkin = function (skinIndex) {
  1375. const skinDef = this.json.skins[skinIndex]
  1376. const skinEntry = {
  1377. joints: skinDef.joints
  1378. }
  1379. if (skinDef.inverseBindMatrices === undefined) {
  1380. return Promise.resolve(skinEntry)
  1381. }
  1382. return this.getDependency('accessor', skinDef.inverseBindMatrices).then(function (accessor) {
  1383. skinEntry.inverseBindMatrices = accessor
  1384. return skinEntry
  1385. })
  1386. }
  1387. GLTFParser.prototype.loadAnimation = function (animationIndex) {
  1388. const json = this.json
  1389. const animationDef = json.animations[animationIndex]
  1390. const pendingNodes = []
  1391. const pendingInputAccessors = []
  1392. const pendingOutputAccessors = []
  1393. const pendingSamplers = []
  1394. const pendingTargets = []
  1395. for (let i = 0,
  1396. il = animationDef.channels.length; i < il; i++) {
  1397. const channel = animationDef.channels[i]
  1398. const sampler = animationDef.samplers[channel.sampler]
  1399. const target = channel.target
  1400. const name = target.node !== undefined ? target.node : target.id
  1401. const input = animationDef.parameters !== undefined ? animationDef.parameters[sampler.input] : sampler.input
  1402. const output = animationDef.parameters !== undefined ? animationDef.parameters[sampler.output] : sampler.output
  1403. pendingNodes.push(this.getDependency('node', name))
  1404. pendingInputAccessors.push(this.getDependency('accessor', input))
  1405. pendingOutputAccessors.push(this.getDependency('accessor', output))
  1406. pendingSamplers.push(sampler)
  1407. pendingTargets.push(target)
  1408. }
  1409. return Promise.all([Promise.all(pendingNodes), Promise.all(pendingInputAccessors), Promise.all(pendingOutputAccessors), Promise.all(pendingSamplers), Promise.all(pendingTargets)]).then(function (dependencies) {
  1410. const nodes = dependencies[0]
  1411. const inputAccessors = dependencies[1]
  1412. const outputAccessors = dependencies[2]
  1413. const samplers = dependencies[3]
  1414. const targets = dependencies[4]
  1415. const tracks = []
  1416. for (let i = 0,
  1417. il = nodes.length; i < il; i++) {
  1418. const node = nodes[i]
  1419. const inputAccessor = inputAccessors[i]
  1420. const outputAccessor = outputAccessors[i]
  1421. const sampler = samplers[i]
  1422. const target = targets[i]
  1423. if (node === undefined) continue
  1424. node.updateMatrix()
  1425. node.matrixAutoUpdate = true
  1426. var TypedKeyframeTrack
  1427. switch (PATH_PROPERTIES[target.path]) {
  1428. case PATH_PROPERTIES.weights:
  1429. TypedKeyframeTrack = THREE.NumberKeyframeTrack
  1430. break
  1431. case PATH_PROPERTIES.rotation:
  1432. TypedKeyframeTrack = THREE.QuaternionKeyframeTrack
  1433. break
  1434. case PATH_PROPERTIES.position:
  1435. case PATH_PROPERTIES.scale:
  1436. default:
  1437. TypedKeyframeTrack = THREE.VectorKeyframeTrack
  1438. break
  1439. }
  1440. const targetName = node.name ? node.name : node.uuid
  1441. const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[sampler.interpolation] : THREE.InterpolateLinear
  1442. var targetNames = []
  1443. if (PATH_PROPERTIES[target.path] === PATH_PROPERTIES.weights) {
  1444. node.traverse(function (object) {
  1445. if (object.isMesh === true && object.morphTargetInfluences) {
  1446. targetNames.push(object.name ? object.name : object.uuid)
  1447. }
  1448. })
  1449. } else {
  1450. targetNames.push(targetName)
  1451. }
  1452. let outputArray = outputAccessor.array
  1453. if (outputAccessor.normalized) {
  1454. var scale
  1455. if (outputArray.constructor === Int8Array) {
  1456. scale = 1 / 127
  1457. } else if (outputArray.constructor === Uint8Array) {
  1458. scale = 1 / 255
  1459. } else if (outputArray.constructor == Int16Array) {
  1460. scale = 1 / 32767
  1461. } else if (outputArray.constructor === Uint16Array) {
  1462. scale = 1 / 65535
  1463. } else {
  1464. throw new Error('THREE.GLTFLoader: Unsupported output accessor component type.')
  1465. }
  1466. const scaled = new Float32Array(outputArray.length)
  1467. for (var j = 0,
  1468. jl = outputArray.length; j < jl; j++) {
  1469. scaled[j] = outputArray[j] * scale
  1470. }
  1471. outputArray = scaled
  1472. }
  1473. for (var j = 0,
  1474. jl = targetNames.length; j < jl; j++) {
  1475. const track = new TypedKeyframeTrack(targetNames[j] + '.' + PATH_PROPERTIES[target.path], inputAccessor.array, outputArray, interpolation)
  1476. if (sampler.interpolation === 'CUBICSPLINE') {
  1477. track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline(result) {
  1478. return new GLTFCubicSplineInterpolant(this.times, this.values, this.getValueSize() / 3, result)
  1479. }
  1480. track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true
  1481. }
  1482. tracks.push(track)
  1483. }
  1484. }
  1485. const name = animationDef.name !== undefined ? animationDef.name : 'animation_' + animationIndex
  1486. return new THREE.AnimationClip(name, undefined, tracks)
  1487. })
  1488. }
  1489. GLTFParser.prototype.loadNode = function (nodeIndex) {
  1490. const json = this.json
  1491. const extensions = this.extensions
  1492. const parser = this
  1493. const meshReferences = json.meshReferences
  1494. const meshUses = json.meshUses
  1495. const nodeDef = json.nodes[nodeIndex]
  1496. return (function () {
  1497. const pending = []
  1498. if (nodeDef.mesh !== undefined) {
  1499. pending.push(parser.getDependency('mesh', nodeDef.mesh).then(function (mesh) {
  1500. let node
  1501. if (meshReferences[nodeDef.mesh] > 1) {
  1502. const instanceNum = meshUses[nodeDef.mesh]++
  1503. node = mesh.clone()
  1504. node.name += '_instance_' + instanceNum
  1505. node.onBeforeRender = mesh.onBeforeRender
  1506. for (let i = 0,
  1507. il = node.children.length; i < il; i++) {
  1508. node.children[i].name += '_instance_' + instanceNum
  1509. node.children[i].onBeforeRender = mesh.children[i].onBeforeRender
  1510. }
  1511. } else {
  1512. node = mesh
  1513. }
  1514. if (nodeDef.weights !== undefined) {
  1515. node.traverse(function (o) {
  1516. if (!o.isMesh) return
  1517. for (let i = 0,
  1518. il = nodeDef.weights.length; i < il; i++) {
  1519. o.morphTargetInfluences[i] = nodeDef.weights[i]
  1520. }
  1521. })
  1522. }
  1523. return node
  1524. }))
  1525. }
  1526. if (nodeDef.camera !== undefined) {
  1527. pending.push(parser.getDependency('camera', nodeDef.camera))
  1528. }
  1529. if (nodeDef.extensions && nodeDef.extensions[EXTENSIONS.KHR_LIGHTS_PUNCTUAL] && nodeDef.extensions[EXTENSIONS.KHR_LIGHTS_PUNCTUAL].light !== undefined) {
  1530. pending.push(parser.getDependency('light', nodeDef.extensions[EXTENSIONS.KHR_LIGHTS_PUNCTUAL].light))
  1531. }
  1532. return Promise.all(pending)
  1533. }()).then(function (objects) {
  1534. let node
  1535. if (nodeDef.isBone === true) {
  1536. node = new THREE.Bone()
  1537. } else if (objects.length > 1) {
  1538. node = new THREE.Group()
  1539. } else if (objects.length === 1) {
  1540. node = objects[0]
  1541. } else {
  1542. node = new THREE.Object3D()
  1543. }
  1544. if (node !== objects[0]) {
  1545. for (let i = 0,
  1546. il = objects.length; i < il; i++) {
  1547. node.add(objects[i])
  1548. }
  1549. }
  1550. if (nodeDef.name !== undefined) {
  1551. node.userData.name = nodeDef.name
  1552. node.name = THREE.PropertyBinding.sanitizeNodeName(nodeDef.name)
  1553. }
  1554. assignExtrasToUserData(node, nodeDef)
  1555. if (nodeDef.extensions) addUnknownExtensionsToUserData(extensions, node, nodeDef)
  1556. if (nodeDef.matrix !== undefined) {
  1557. const matrix = new THREE.Matrix4()
  1558. matrix.fromArray(nodeDef.matrix)
  1559. node.applyMatrix(matrix)
  1560. } else {
  1561. if (nodeDef.translation !== undefined) {
  1562. node.position.fromArray(nodeDef.translation)
  1563. }
  1564. if (nodeDef.rotation !== undefined) {
  1565. node.quaternion.fromArray(nodeDef.rotation)
  1566. }
  1567. if (nodeDef.scale !== undefined) {
  1568. node.scale.fromArray(nodeDef.scale)
  1569. }
  1570. }
  1571. return node
  1572. })
  1573. }
  1574. GLTFParser.prototype.loadScene = (function () {
  1575. function buildNodeHierachy(nodeId, parentObject, json, parser) {
  1576. const nodeDef = json.nodes[nodeId]
  1577. return parser.getDependency('node', nodeId).then(function (node) {
  1578. if (nodeDef.skin === undefined) return node
  1579. let skinEntry
  1580. return parser.getDependency('skin', nodeDef.skin).then(function (skin) {
  1581. skinEntry = skin
  1582. const pendingJoints = []
  1583. for (let i = 0,
  1584. il = skinEntry.joints.length; i < il; i++) {
  1585. pendingJoints.push(parser.getDependency('node', skinEntry.joints[i]))
  1586. }
  1587. return Promise.all(pendingJoints)
  1588. }).then(function (jointNodes) {
  1589. node.traverse(function (mesh) {
  1590. if (!mesh.isMesh) return
  1591. const bones = []
  1592. const boneInverses = []
  1593. for (let j = 0,
  1594. jl = jointNodes.length; j < jl; j++) {
  1595. const jointNode = jointNodes[j]
  1596. if (jointNode) {
  1597. bones.push(jointNode)
  1598. const mat = new THREE.Matrix4()
  1599. if (skinEntry.inverseBindMatrices !== undefined) {
  1600. mat.fromArray(skinEntry.inverseBindMatrices.array, j * 16)
  1601. }
  1602. boneInverses.push(mat)
  1603. } else {
  1604. console.warn('THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[j])
  1605. }
  1606. }
  1607. mesh.bind(new THREE.Skeleton(bones, boneInverses), mesh.matrixWorld)
  1608. })
  1609. return node
  1610. })
  1611. }).then(function (node) {
  1612. parentObject.add(node)
  1613. const pending = []
  1614. if (nodeDef.children) {
  1615. const children = nodeDef.children
  1616. for (let i = 0,
  1617. il = children.length; i < il; i++) {
  1618. const child = children[i]
  1619. pending.push(buildNodeHierachy(child, node, json, parser))
  1620. }
  1621. }
  1622. return Promise.all(pending)
  1623. })
  1624. }
  1625. return function loadScene(sceneIndex) {
  1626. const json = this.json
  1627. const extensions = this.extensions
  1628. const sceneDef = this.json.scenes[sceneIndex]
  1629. const parser = this
  1630. const scene = new THREE.Scene()
  1631. if (sceneDef.name !== undefined) scene.name = sceneDef.name
  1632. assignExtrasToUserData(scene, sceneDef)
  1633. if (sceneDef.extensions) addUnknownExtensionsToUserData(extensions, scene, sceneDef)
  1634. const nodeIds = sceneDef.nodes || []
  1635. const pending = []
  1636. for (let i = 0,
  1637. il = nodeIds.length; i < il; i++) {
  1638. pending.push(buildNodeHierachy(nodeIds[i], scene, json, parser))
  1639. }
  1640. return Promise.all(pending).then(function () {
  1641. return scene
  1642. })
  1643. }
  1644. }())
  1645. return GLTFLoader
  1646. }())
  1647. }