super-three 0.144.0 → 0.147.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (450) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +735 -387
  3. package/build/three.js +735 -387
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +910 -408
  6. package/examples/js/animation/AnimationClipCreator.js +0 -8
  7. package/examples/js/animation/CCDIKSolver.js +50 -67
  8. package/examples/js/animation/MMDAnimationHelper.js +66 -137
  9. package/examples/js/animation/MMDPhysics.js +70 -134
  10. package/examples/js/cameras/CinematicCamera.js +33 -22
  11. package/examples/js/controls/ArcballControls.js +138 -405
  12. package/examples/js/controls/DragControls.js +8 -33
  13. package/examples/js/controls/FirstPersonControls.js +32 -54
  14. package/examples/js/controls/FlyControls.js +29 -55
  15. package/examples/js/controls/OrbitControls.js +125 -99
  16. package/examples/js/controls/PointerLockControls.js +5 -14
  17. package/examples/js/controls/TrackballControls.js +33 -86
  18. package/examples/js/controls/TransformControls.js +85 -170
  19. package/examples/js/csm/CSM.js +4 -39
  20. package/examples/js/csm/CSMFrustum.js +3 -9
  21. package/examples/js/csm/CSMHelper.js +24 -4
  22. package/examples/js/csm/CSMShader.js +2 -6
  23. package/examples/js/curves/CurveExtras.js +27 -27
  24. package/examples/js/curves/NURBSCurve.js +4 -16
  25. package/examples/js/curves/NURBSSurface.js +3 -9
  26. package/examples/js/curves/NURBSUtils.js +8 -45
  27. package/examples/js/effects/AnaglyphEffect.js +4 -18
  28. package/examples/js/effects/AsciiEffect.js +32 -31
  29. package/examples/js/effects/OutlineEffect.js +26 -30
  30. package/examples/js/effects/ParallaxBarrierEffect.js +0 -13
  31. package/examples/js/effects/PeppersGhostEffect.js +12 -39
  32. package/examples/js/effects/StereoEffect.js +0 -4
  33. package/examples/js/environments/RoomEnvironment.js +12 -10
  34. package/examples/js/exporters/ColladaExporter.js +48 -65
  35. package/examples/js/exporters/DRACOExporter.js +22 -22
  36. package/examples/js/exporters/EXRExporter.js +15 -18
  37. package/examples/js/exporters/GLTFExporter.js +141 -317
  38. package/examples/js/exporters/MMDExporter.js +5 -12
  39. package/examples/js/exporters/OBJExporter.js +42 -33
  40. package/examples/js/exporters/PLYExporter.js +38 -33
  41. package/examples/js/exporters/STLExporter.js +5 -7
  42. package/examples/js/exporters/USDZExporter.js +113 -27
  43. package/examples/js/geometries/BoxLineGeometry.js +0 -1
  44. package/examples/js/geometries/ConvexGeometry.js +11 -6
  45. package/examples/js/geometries/DecalGeometry.js +53 -20
  46. package/examples/js/geometries/LightningStrike.js +54 -67
  47. package/examples/js/geometries/ParametricGeometries.js +8 -7
  48. package/examples/js/geometries/ParametricGeometry.js +25 -12
  49. package/examples/js/geometries/RoundedBoxGeometry.js +21 -19
  50. package/examples/js/geometries/TeapotGeometry.js +54 -50
  51. package/examples/js/geometries/TextGeometry.js +6 -4
  52. package/examples/js/helpers/LightProbeHelper.js +1 -2
  53. package/examples/js/helpers/OctreeHelper.js +22 -20
  54. package/examples/js/helpers/PositionalAudioHelper.js +8 -6
  55. package/examples/js/helpers/RectAreaLightHelper.js +6 -7
  56. package/examples/js/helpers/VertexNormalsHelper.js +15 -13
  57. package/examples/js/helpers/VertexTangentsHelper.js +15 -9
  58. package/examples/js/helpers/ViewHelper.js +31 -16
  59. package/examples/js/interactive/HTMLMesh.js +25 -39
  60. package/examples/js/interactive/InteractiveGroup.js +9 -14
  61. package/examples/js/interactive/SelectionBox.js +3 -70
  62. package/examples/js/interactive/SelectionHelper.js +0 -8
  63. package/examples/js/lights/LightProbeGenerator.js +32 -39
  64. package/examples/js/lights/RectAreaLightUniformsLib.js +5 -1
  65. package/examples/js/lines/LineGeometry.js +3 -5
  66. package/examples/js/lines/LineMaterial.js +4 -11
  67. package/examples/js/lines/LineSegments2.js +40 -89
  68. package/examples/js/lines/LineSegmentsGeometry.js +7 -28
  69. package/examples/js/lines/Wireframe.js +2 -7
  70. package/examples/js/lines/WireframeGeometry2.js +3 -1
  71. package/examples/js/loaders/3DMLoader.js +58 -155
  72. package/examples/js/loaders/3MFLoader.js +72 -106
  73. package/examples/js/loaders/AMFLoader.js +0 -25
  74. package/examples/js/loaders/BVHLoader.js +44 -43
  75. package/examples/js/loaders/BasisTextureLoader.js +16 -46
  76. package/examples/js/loaders/ColladaLoader.js +228 -359
  77. package/examples/js/loaders/DDSLoader.js +24 -25
  78. package/examples/js/loaders/DRACOLoader.js +29 -66
  79. package/examples/js/loaders/EXRLoader.js +67 -164
  80. package/examples/js/loaders/FBXLoader.js +287 -441
  81. package/examples/js/loaders/FontLoader.js +6 -15
  82. package/examples/js/loaders/GCodeLoader.js +15 -16
  83. package/examples/js/loaders/GLTFLoader.js +409 -706
  84. package/examples/js/loaders/HDRCubeTextureLoader.js +0 -6
  85. package/examples/js/loaders/KMZLoader.js +3 -7
  86. package/examples/js/loaders/KTXLoader.js +12 -30
  87. package/examples/js/loaders/LDrawLoader.js +178 -289
  88. package/examples/js/loaders/LUT3dlLoader.js +7 -11
  89. package/examples/js/loaders/LUTCubeLoader.js +0 -8
  90. package/examples/js/loaders/LWOLoader.js +59 -124
  91. package/examples/js/loaders/LogLuvLoader.js +27 -77
  92. package/examples/js/loaders/LottieLoader.js +4 -4
  93. package/examples/js/loaders/MD2Loader.js +26 -27
  94. package/examples/js/loaders/MDDLoader.js +6 -10
  95. package/examples/js/loaders/MMDLoader.js +180 -189
  96. package/examples/js/loaders/MTLLoader.js +18 -47
  97. package/examples/js/loaders/NRRDLoader.js +44 -84
  98. package/examples/js/loaders/OBJLoader.js +50 -65
  99. package/examples/js/loaders/PCDLoader.js +34 -29
  100. package/examples/js/loaders/PDBLoader.js +17 -13
  101. package/examples/js/loaders/PLYLoader.js +62 -48
  102. package/examples/js/loaders/PRWMLoader.js +11 -22
  103. package/examples/js/loaders/PVRLoader.js +7 -16
  104. package/examples/js/loaders/RGBELoader.js +36 -61
  105. package/examples/js/loaders/RGBMLoader.js +26 -87
  106. package/examples/js/loaders/STLLoader.js +20 -27
  107. package/examples/js/loaders/SVGLoader.js +361 -233
  108. package/examples/js/loaders/TDSLoader.js +81 -118
  109. package/examples/js/loaders/TGALoader.js +39 -41
  110. package/examples/js/loaders/TIFFLoader.js +0 -1
  111. package/examples/js/loaders/TTFLoader.js +0 -8
  112. package/examples/js/loaders/TiltLoader.js +14 -15
  113. package/examples/js/loaders/VOXLoader.js +8 -16
  114. package/examples/js/loaders/VRMLLoader.js +243 -340
  115. package/examples/js/loaders/VTKLoader.js +101 -118
  116. package/examples/js/loaders/XYZLoader.js +2 -4
  117. package/examples/js/loaders/lwo/IFFParser.js +55 -136
  118. package/examples/js/loaders/lwo/LWO2Parser.js +32 -83
  119. package/examples/js/loaders/lwo/LWO3Parser.js +31 -73
  120. package/examples/js/materials/MeshGouraudMaterial.js +15 -13
  121. package/examples/js/math/Capsule.js +0 -17
  122. package/examples/js/math/ColorConverter.js +3 -3
  123. package/examples/js/math/ConvexHull.js +185 -141
  124. package/examples/js/math/ImprovedNoise.js +1 -1
  125. package/examples/js/math/Lut.js +8 -15
  126. package/examples/js/math/MeshSurfaceSampler.js +6 -28
  127. package/examples/js/math/OBB.js +90 -49
  128. package/examples/js/math/Octree.js +2 -57
  129. package/examples/js/math/SimplexNoise.js +74 -88
  130. package/examples/js/misc/ConvexObjectBreaker.js +37 -48
  131. package/examples/js/misc/GPUComputationRenderer.js +26 -16
  132. package/examples/js/misc/Gyroscope.js +5 -9
  133. package/examples/js/misc/MD2Character.js +14 -23
  134. package/examples/js/misc/MD2CharacterComplex.js +73 -54
  135. package/examples/js/misc/MorphAnimMesh.js +0 -6
  136. package/examples/js/misc/MorphBlendMesh.js +3 -30
  137. package/examples/js/misc/ProgressiveLightMap.js +47 -43
  138. package/examples/js/misc/RollerCoaster.js +17 -24
  139. package/examples/js/misc/TubePainter.js +18 -12
  140. package/examples/js/misc/Volume.js +16 -45
  141. package/examples/js/misc/VolumeSlice.js +14 -24
  142. package/examples/js/modifiers/CurveModifier.js +19 -21
  143. package/examples/js/modifiers/EdgeSplitModifier.js +0 -30
  144. package/examples/js/modifiers/SimplifyModifier.js +56 -59
  145. package/examples/js/modifiers/TessellateModifier.js +2 -9
  146. package/examples/js/objects/GroundProjectedEnv.js +2 -14
  147. package/examples/js/objects/Lensflare.js +47 -38
  148. package/examples/js/objects/LightningStorm.js +10 -13
  149. package/examples/js/objects/MarchingCubes.js +80 -59
  150. package/examples/js/objects/Reflector.js +22 -20
  151. package/examples/js/objects/ReflectorForSSRPass.js +19 -23
  152. package/examples/js/objects/Refractor.js +52 -30
  153. package/examples/js/objects/ShadowMesh.js +1 -2
  154. package/examples/js/objects/Sky.js +2 -7
  155. package/examples/js/objects/Water.js +23 -18
  156. package/examples/js/objects/Water2.js +20 -19
  157. package/examples/js/physics/AmmoPhysics.js +23 -20
  158. package/examples/js/physics/OimoPhysics.js +19 -17
  159. package/examples/js/postprocessing/AdaptiveToneMappingPass.js +13 -20
  160. package/examples/js/postprocessing/AfterimagePass.js +19 -12
  161. package/examples/js/postprocessing/BloomPass.js +38 -17
  162. package/examples/js/postprocessing/BokehPass.js +29 -12
  163. package/examples/js/postprocessing/ClearPass.js +1 -6
  164. package/examples/js/postprocessing/CubeTexturePass.js +12 -9
  165. package/examples/js/postprocessing/DotScreenPass.js +7 -5
  166. package/examples/js/postprocessing/EffectComposer.js +25 -32
  167. package/examples/js/postprocessing/FilmPass.js +7 -5
  168. package/examples/js/postprocessing/GlitchPass.js +10 -11
  169. package/examples/js/postprocessing/HalftonePass.js +9 -9
  170. package/examples/js/postprocessing/LUTPass.js +2 -15
  171. package/examples/js/postprocessing/MaskPass.js +20 -17
  172. package/examples/js/postprocessing/OutlinePass.js +45 -36
  173. package/examples/js/postprocessing/Pass.js +11 -14
  174. package/examples/js/postprocessing/RenderPass.js +3 -7
  175. package/examples/js/postprocessing/RenderPixelatedPass.js +215 -0
  176. package/examples/js/postprocessing/SAOPass.js +40 -32
  177. package/examples/js/postprocessing/SMAAPass.js +34 -17
  178. package/examples/js/postprocessing/SSAARenderPass.js +14 -14
  179. package/examples/js/postprocessing/SSAOPass.js +56 -42
  180. package/examples/js/postprocessing/SSRPass.js +78 -61
  181. package/examples/js/postprocessing/SavePass.js +14 -6
  182. package/examples/js/postprocessing/ShaderPass.js +9 -8
  183. package/examples/js/postprocessing/TAARenderPass.js +11 -9
  184. package/examples/js/postprocessing/TexturePass.js +7 -4
  185. package/examples/js/postprocessing/UnrealBloomPass.js +43 -25
  186. package/examples/js/renderers/CSS2DRenderer.js +2 -21
  187. package/examples/js/renderers/CSS3DRenderer.js +3 -24
  188. package/examples/js/renderers/Projector.js +29 -85
  189. package/examples/js/renderers/SVGRenderer.js +4 -50
  190. package/examples/js/shaders/ACESFilmicToneMappingShader.js +3 -6
  191. package/examples/js/shaders/AfterimageShader.js +3 -6
  192. package/examples/js/shaders/BasicShader.js +3 -6
  193. package/examples/js/shaders/BleachBypassShader.js +3 -6
  194. package/examples/js/shaders/BlendShader.js +3 -6
  195. package/examples/js/shaders/BokehShader.js +3 -6
  196. package/examples/js/shaders/BokehShader2.js +4 -13
  197. package/examples/js/shaders/BrightnessContrastShader.js +3 -6
  198. package/examples/js/shaders/ColorCorrectionShader.js +2 -6
  199. package/examples/js/shaders/ColorifyShader.js +2 -6
  200. package/examples/js/shaders/ConvolutionShader.js +5 -10
  201. package/examples/js/shaders/CopyShader.js +3 -6
  202. package/examples/js/shaders/DOFMipMapShader.js +3 -6
  203. package/examples/js/shaders/DepthLimitedBlurShader.js +2 -9
  204. package/examples/js/shaders/DigitalGlitch.js +3 -6
  205. package/examples/js/shaders/DotScreenShader.js +2 -6
  206. package/examples/js/shaders/FXAAShader.js +1 -3
  207. package/examples/js/shaders/FilmShader.js +3 -6
  208. package/examples/js/shaders/FocusShader.js +3 -6
  209. package/examples/js/shaders/FreiChenShader.js +2 -6
  210. package/examples/js/shaders/GammaCorrectionShader.js +3 -6
  211. package/examples/js/shaders/GodRaysShader.js +11 -24
  212. package/examples/js/shaders/HalftoneShader.js +3 -6
  213. package/examples/js/shaders/HorizontalBlurShader.js +3 -6
  214. package/examples/js/shaders/HorizontalTiltShiftShader.js +3 -6
  215. package/examples/js/shaders/HueSaturationShader.js +3 -6
  216. package/examples/js/shaders/KaleidoShader.js +3 -6
  217. package/examples/js/shaders/LuminosityHighPassShader.js +2 -6
  218. package/examples/js/shaders/LuminosityShader.js +3 -6
  219. package/examples/js/shaders/MMDToonShader.js +2 -8
  220. package/examples/js/shaders/MirrorShader.js +3 -6
  221. package/examples/js/shaders/NormalMapShader.js +2 -6
  222. package/examples/js/shaders/RGBShiftShader.js +3 -6
  223. package/examples/js/shaders/SAOShader.js +2 -6
  224. package/examples/js/shaders/SMAAShader.js +6 -18
  225. package/examples/js/shaders/SSAOShader.js +2 -6
  226. package/examples/js/shaders/SSRShader.js +6 -18
  227. package/examples/js/shaders/SepiaShader.js +3 -6
  228. package/examples/js/shaders/SobelOperatorShader.js +2 -6
  229. package/examples/js/shaders/TechnicolorShader.js +3 -6
  230. package/examples/js/shaders/ToneMapShader.js +3 -6
  231. package/examples/js/shaders/ToonShader.js +8 -24
  232. package/examples/js/shaders/TriangleBlurShader.js +2 -6
  233. package/examples/js/shaders/UnpackDepthRGBAShader.js +3 -6
  234. package/examples/js/shaders/VelocityShader.js +126 -0
  235. package/examples/js/shaders/VerticalBlurShader.js +3 -6
  236. package/examples/js/shaders/VerticalTiltShiftShader.js +3 -6
  237. package/examples/js/shaders/VignetteShader.js +3 -6
  238. package/examples/js/shaders/VolumeShader.js +2 -6
  239. package/examples/js/shaders/WaterRefractionShader.js +2 -6
  240. package/examples/js/textures/FlakesTexture.js +0 -1
  241. package/examples/js/utils/BufferGeometryUtils.js +236 -170
  242. package/examples/js/utils/CameraUtils.js +5 -20
  243. package/examples/js/utils/GPUStatsPanel.js +3 -12
  244. package/examples/js/utils/GeometryCompressionUtils.js +19 -44
  245. package/examples/js/utils/GeometryUtils.js +13 -18
  246. package/examples/js/utils/LDrawUtils.js +8 -11
  247. package/examples/js/utils/PackedPhongMaterial.js +6 -4
  248. package/examples/js/utils/SceneUtils.js +117 -6
  249. package/examples/js/utils/ShadowMapViewer.js +17 -14
  250. package/examples/js/utils/SkeletonUtils.js +13 -27
  251. package/examples/js/utils/UVsDebug.js +20 -12
  252. package/examples/js/utils/WorkerPool.js +1 -11
  253. package/examples/jsm/animation/CCDIKSolver.js +27 -3
  254. package/examples/jsm/animation/MMDPhysics.js +25 -0
  255. package/examples/jsm/capabilities/WebGPU.js +3 -1
  256. package/examples/jsm/controls/FirstPersonControls.js +20 -20
  257. package/examples/jsm/controls/FlyControls.js +16 -17
  258. package/examples/jsm/controls/OrbitControls.js +44 -4
  259. package/examples/jsm/controls/TrackballControls.js +14 -2
  260. package/examples/jsm/controls/TransformControls.js +1 -1
  261. package/examples/jsm/csm/CSM.js +1 -0
  262. package/examples/jsm/csm/CSMHelper.js +30 -0
  263. package/examples/jsm/exporters/GLTFExporter.js +0 -79
  264. package/examples/jsm/exporters/USDZExporter.js +93 -1
  265. package/examples/jsm/helpers/OctreeHelper.js +22 -8
  266. package/examples/jsm/helpers/VertexNormalsHelper.js +7 -1
  267. package/examples/jsm/helpers/VertexTangentsHelper.js +7 -0
  268. package/examples/jsm/helpers/ViewHelper.js +24 -0
  269. package/examples/jsm/interactive/HTMLMesh.js +5 -6
  270. package/examples/jsm/interactive/InteractiveGroup.js +4 -2
  271. package/examples/jsm/libs/flow.module.js +610 -160
  272. package/examples/jsm/libs/lottie_canvas.module.js +14844 -0
  273. package/examples/jsm/lines/LineSegments2.js +4 -0
  274. package/examples/jsm/loaders/3DMLoader.js +1 -2
  275. package/examples/jsm/loaders/ColladaLoader.js +28 -0
  276. package/examples/jsm/loaders/FBXLoader.js +18 -2
  277. package/examples/jsm/loaders/GLTFLoader.js +269 -428
  278. package/examples/jsm/loaders/KTX2Loader.js +68 -29
  279. package/examples/jsm/loaders/LDrawLoader.js +14 -13
  280. package/examples/jsm/loaders/LottieLoader.js +4 -2
  281. package/examples/jsm/loaders/MaterialXLoader.js +728 -0
  282. package/examples/jsm/loaders/PCDLoader.js +1 -1
  283. package/examples/jsm/loaders/PLYLoader.js +68 -16
  284. package/examples/jsm/loaders/SVGLoader.js +227 -14
  285. package/examples/jsm/loaders/USDZLoader.js +351 -111
  286. package/examples/jsm/loaders/VRMLLoader.js +13 -1
  287. package/examples/jsm/math/ConvexHull.js +4 -4
  288. package/examples/jsm/math/Octree.js +1 -1
  289. package/examples/jsm/node-editor/NodeEditor.js +91 -12
  290. package/examples/jsm/node-editor/core/BaseNode.js +10 -3
  291. package/examples/jsm/node-editor/materials/BasicMaterialEditor.js +6 -9
  292. package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +6 -9
  293. package/examples/jsm/node-editor/math/AngleEditor.js +3 -3
  294. package/examples/jsm/node-editor/math/InvertEditor.js +2 -2
  295. package/examples/jsm/node-editor/scene/MeshEditor.js +11 -8
  296. package/examples/jsm/node-editor/utils/PreviewEditor.js +4 -0
  297. package/examples/jsm/nodes/Nodes.js +30 -3
  298. package/examples/jsm/nodes/accessors/BitangentNode.js +62 -0
  299. package/examples/jsm/nodes/accessors/NormalNode.js +6 -6
  300. package/examples/jsm/nodes/accessors/Object3DNode.js +1 -1
  301. package/examples/jsm/nodes/accessors/PositionNode.js +6 -0
  302. package/examples/jsm/nodes/accessors/ReferenceNode.js +1 -1
  303. package/examples/jsm/nodes/accessors/SkinningNode.js +8 -1
  304. package/examples/jsm/nodes/accessors/TangentNode.js +95 -0
  305. package/examples/jsm/nodes/core/AttributeNode.js +31 -8
  306. package/examples/jsm/nodes/core/Node.js +1 -1
  307. package/examples/jsm/nodes/core/NodeBuilder.js +55 -6
  308. package/examples/jsm/nodes/core/NodeFrame.js +2 -2
  309. package/examples/jsm/nodes/core/NodeVarying.js +7 -4
  310. package/examples/jsm/nodes/core/VaryingNode.js +6 -4
  311. package/examples/jsm/nodes/core/constants.js +13 -13
  312. package/examples/jsm/nodes/display/BlendModeNode.js +85 -0
  313. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +2 -12
  314. package/examples/jsm/nodes/display/NormalMapNode.js +19 -12
  315. package/examples/jsm/nodes/display/PosterizeNode.js +25 -0
  316. package/examples/jsm/nodes/display/ViewportNode.js +106 -0
  317. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +5 -5
  318. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +3 -3
  319. package/examples/jsm/nodes/functions/light/getDistanceAttenuation.js +2 -2
  320. package/examples/jsm/nodes/gpgpu/ComputeNode.js +1 -1
  321. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +1 -1
  322. package/examples/jsm/nodes/loaders/NodeMaterialLoader.js +3 -1
  323. package/examples/jsm/nodes/materials/Materials.js +9 -7
  324. package/examples/jsm/nodes/materials/NodeMaterial.js +9 -1
  325. package/examples/jsm/nodes/materialx/{Disclaimer.md → DISCLAIMER.md} +1 -1
  326. package/examples/jsm/nodes/materialx/MaterialXNodes.js +59 -0
  327. package/examples/jsm/nodes/materialx/{functions/lib → lib}/mx_hsv.js +1 -1
  328. package/examples/jsm/nodes/materialx/{functions/lib → lib}/mx_noise.js +13 -3
  329. package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +18 -0
  330. package/examples/jsm/nodes/math/MathNode.js +5 -5
  331. package/examples/jsm/nodes/math/OperatorNode.js +16 -3
  332. package/examples/jsm/nodes/shadernode/ShaderNode.js +35 -20
  333. package/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js +87 -63
  334. package/examples/jsm/nodes/shadernode/ShaderNodeElements.js +29 -0
  335. package/examples/jsm/nodes/utils/ConvertNode.js +15 -14
  336. package/examples/jsm/nodes/utils/EquirectUVNode.js +27 -0
  337. package/examples/jsm/nodes/utils/JoinNode.js +8 -2
  338. package/examples/jsm/nodes/utils/MatcapUVNode.js +2 -4
  339. package/examples/jsm/nodes/utils/MaxMipLevelNode.js +1 -1
  340. package/examples/jsm/nodes/utils/OscNode.js +2 -2
  341. package/examples/jsm/nodes/utils/RemapNode.js +34 -0
  342. package/examples/jsm/nodes/utils/SpriteSheetUVNode.js +8 -10
  343. package/examples/jsm/nodes/utils/TimerNode.js +21 -1
  344. package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +51 -0
  345. package/examples/jsm/postprocessing/AfterimagePass.js +17 -4
  346. package/examples/jsm/postprocessing/BloomPass.js +22 -3
  347. package/examples/jsm/postprocessing/BokehPass.js +18 -4
  348. package/examples/jsm/postprocessing/CubeTexturePass.js +12 -5
  349. package/examples/jsm/postprocessing/DotScreenPass.js +8 -0
  350. package/examples/jsm/postprocessing/EffectComposer.js +9 -0
  351. package/examples/jsm/postprocessing/FilmPass.js +8 -0
  352. package/examples/jsm/postprocessing/GlitchPass.js +13 -1
  353. package/examples/jsm/postprocessing/HalftonePass.js +8 -0
  354. package/examples/jsm/postprocessing/OutlinePass.js +21 -1
  355. package/examples/jsm/postprocessing/Pass.js +2 -0
  356. package/examples/jsm/postprocessing/RenderPixelatedPass.js +234 -0
  357. package/examples/jsm/postprocessing/SAOPass.js +20 -0
  358. package/examples/jsm/postprocessing/SMAAPass.js +16 -0
  359. package/examples/jsm/postprocessing/SSAARenderPass.js +4 -0
  360. package/examples/jsm/postprocessing/SavePass.js +17 -1
  361. package/examples/jsm/postprocessing/ShaderPass.js +8 -0
  362. package/examples/jsm/postprocessing/TAARenderPass.js +9 -0
  363. package/examples/jsm/postprocessing/TexturePass.js +8 -0
  364. package/examples/jsm/postprocessing/UnrealBloomPass.js +16 -0
  365. package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +56 -35
  366. package/examples/jsm/renderers/webgpu/WebGPUAnimation.js +58 -0
  367. package/examples/jsm/renderers/webgpu/WebGPUAttributes.js +63 -5
  368. package/examples/jsm/renderers/webgpu/WebGPUBackground.js +36 -7
  369. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +47 -12
  370. package/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js +41 -9
  371. package/examples/jsm/shaders/MMDToonShader.js +0 -2
  372. package/examples/jsm/shaders/VelocityShader.js +128 -0
  373. package/examples/jsm/utils/BufferGeometryUtils.js +174 -42
  374. package/examples/jsm/utils/SceneUtils.js +129 -4
  375. package/examples/jsm/webxr/OculusHandModel.js +3 -2
  376. package/examples/jsm/webxr/XRHandMeshModel.js +8 -3
  377. package/package.json +13 -13
  378. package/src/Three.js +1 -0
  379. package/src/animation/PropertyBinding.js +7 -0
  380. package/src/audio/AudioContext.js +5 -5
  381. package/src/cameras/CubeCamera.js +14 -14
  382. package/src/constants.js +1 -1
  383. package/src/core/InstancedBufferGeometry.js +1 -7
  384. package/src/core/InterleavedBufferAttribute.js +4 -4
  385. package/src/extras/Earcut.js +67 -67
  386. package/src/geometries/PolyhedronGeometry.js +1 -1
  387. package/src/geometries/ShapeGeometry.js +1 -1
  388. package/src/helpers/ArrowHelper.js +9 -0
  389. package/src/helpers/Box3Helper.js +7 -0
  390. package/src/helpers/BoxHelper.js +7 -1
  391. package/src/helpers/DirectionalLightHelper.js +5 -1
  392. package/src/helpers/GridHelper.js +7 -0
  393. package/src/helpers/HemisphereLightHelper.js +4 -1
  394. package/src/helpers/PlaneHelper.js +9 -0
  395. package/src/helpers/PointLightHelper.js +2 -1
  396. package/src/helpers/PolarGridHelper.js +7 -0
  397. package/src/helpers/SkeletonHelper.js +7 -0
  398. package/src/helpers/SpotLightHelper.js +4 -2
  399. package/src/lights/LightShadow.js +1 -2
  400. package/src/lights/PointLight.js +2 -2
  401. package/src/lights/SpotLight.js +2 -2
  402. package/src/loaders/FileLoader.js +4 -1
  403. package/src/loaders/ObjectLoader.js +5 -1
  404. package/src/materials/Material.js +1 -1
  405. package/src/materials/MeshPhysicalMaterial.js +1 -1
  406. package/src/math/Color.js +5 -5
  407. package/src/math/Matrix3.js +53 -18
  408. package/src/math/Ray.js +2 -5
  409. package/src/math/Sphere.js +36 -21
  410. package/src/objects/InstancedMesh.js +7 -0
  411. package/src/objects/LOD.js +25 -6
  412. package/src/renderers/WebGL3DRenderTarget.js +1 -1
  413. package/src/renderers/WebGLArrayRenderTarget.js +1 -1
  414. package/src/renderers/WebGLCubeRenderTarget.js +1 -1
  415. package/src/renderers/WebGLMultipleRenderTargets.js +1 -1
  416. package/src/renderers/WebGLRenderTarget.js +1 -1
  417. package/src/renderers/WebGLRenderer.js +36 -62
  418. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +0 -4
  419. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +0 -1
  420. package/src/renderers/shaders/ShaderChunk/lights_lambert_pars_fragment.glsl.js +0 -2
  421. package/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js +0 -2
  422. package/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js +0 -2
  423. package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -4
  424. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +8 -0
  425. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +2 -2
  426. package/src/renderers/shaders/ShaderChunk.js +3 -0
  427. package/src/renderers/shaders/ShaderLib/background.glsl.js +7 -2
  428. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +62 -0
  429. package/src/renderers/shaders/ShaderLib/cube.glsl.js +4 -6
  430. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +0 -3
  431. package/src/renderers/shaders/ShaderLib.js +20 -6
  432. package/src/renderers/shaders/UniformsLib.js +1 -1
  433. package/src/renderers/shaders/UniformsUtils.js +15 -0
  434. package/src/renderers/webgl/WebGLAttributes.js +2 -0
  435. package/src/renderers/webgl/WebGLBackground.js +15 -7
  436. package/src/renderers/webgl/WebGLLights.js +0 -4
  437. package/src/renderers/webgl/WebGLMaterials.js +2 -1
  438. package/src/renderers/webgl/WebGLShadowMap.js +3 -1
  439. package/src/renderers/webgl/WebGLState.js +78 -41
  440. package/src/renderers/webgl/WebGLTextures.js +94 -39
  441. package/src/renderers/webgl/WebGLUniforms.js +152 -24
  442. package/src/renderers/webgl/WebGLUtils.js +1 -1
  443. package/src/renderers/webxr/WebXRController.js +46 -13
  444. package/src/renderers/webxr/WebXRManager.js +70 -2
  445. package/src/scenes/Scene.js +8 -0
  446. package/src/textures/CompressedArrayTexture.js +18 -0
  447. package/src/textures/Texture.js +2 -1
  448. package/examples/js/libs/lottie_canvas.js +0 -12751
  449. package/examples/js/shaders/PixelShader.js +0 -51
  450. package/examples/jsm/shaders/PixelShader.js +0 -44
@@ -69,14 +69,17 @@
69
69
  return new GLTFMeshoptCompression( parser );
70
70
 
71
71
  } );
72
+ this.register( function ( parser ) {
72
73
 
73
- }
74
+ return new GLTFMeshGpuInstancing( parser );
75
+
76
+ } );
74
77
 
78
+ }
75
79
  load( url, onLoad, onProgress, onError ) {
76
80
 
77
81
  const scope = this;
78
82
  let resourcePath;
79
-
80
83
  if ( this.resourcePath !== '' ) {
81
84
 
82
85
  resourcePath = this.resourcePath;
@@ -89,13 +92,12 @@
89
92
 
90
93
  resourcePath = THREE.LoaderUtils.extractUrlBase( url );
91
94
 
92
- } // Tells the LoadingManager to track an extra item, which resolves after
95
+ }
96
+
97
+ // Tells the LoadingManager to track an extra item, which resolves after
93
98
  // the model is fully loaded. This means the count of items loaded will
94
99
  // be incorrect, but ensures manager.onLoad() does not fire early.
95
-
96
-
97
100
  this.manager.itemStart( url );
98
-
99
101
  const _onError = function ( e ) {
100
102
 
101
103
  if ( onError ) {
@@ -138,34 +140,29 @@
138
140
  }, onProgress, _onError );
139
141
 
140
142
  }
141
-
142
143
  setDRACOLoader( dracoLoader ) {
143
144
 
144
145
  this.dracoLoader = dracoLoader;
145
146
  return this;
146
147
 
147
148
  }
148
-
149
149
  setDDSLoader() {
150
150
 
151
151
  throw new Error( 'THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".' );
152
152
 
153
153
  }
154
-
155
154
  setKTX2Loader( ktx2Loader ) {
156
155
 
157
156
  this.ktx2Loader = ktx2Loader;
158
157
  return this;
159
158
 
160
159
  }
161
-
162
160
  setMeshoptDecoder( meshoptDecoder ) {
163
161
 
164
162
  this.meshoptDecoder = meshoptDecoder;
165
163
  return this;
166
164
 
167
165
  }
168
-
169
166
  register( callback ) {
170
167
 
171
168
  if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {
@@ -177,7 +174,6 @@
177
174
  return this;
178
175
 
179
176
  }
180
-
181
177
  unregister( callback ) {
182
178
 
183
179
  if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {
@@ -189,21 +185,18 @@
189
185
  return this;
190
186
 
191
187
  }
192
-
193
188
  parse( data, path, onLoad, onError ) {
194
189
 
195
- let content;
190
+ let json;
196
191
  const extensions = {};
197
192
  const plugins = {};
198
-
199
193
  if ( typeof data === 'string' ) {
200
194
 
201
- content = data;
195
+ json = JSON.parse( data );
202
196
 
203
- } else {
197
+ } else if ( data instanceof ArrayBuffer ) {
204
198
 
205
199
  const magic = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) );
206
-
207
200
  if ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {
208
201
 
209
202
  try {
@@ -217,17 +210,19 @@
217
210
 
218
211
  }
219
212
 
220
- content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content;
213
+ json = JSON.parse( extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content );
221
214
 
222
215
  } else {
223
216
 
224
- content = THREE.LoaderUtils.decodeText( new Uint8Array( data ) );
217
+ json = JSON.parse( THREE.LoaderUtils.decodeText( new Uint8Array( data ) ) );
225
218
 
226
219
  }
227
220
 
228
- }
221
+ } else {
222
+
223
+ json = data;
229
224
 
230
- const json = JSON.parse( content );
225
+ }
231
226
 
232
227
  if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {
233
228
 
@@ -245,15 +240,15 @@
245
240
  meshoptDecoder: this.meshoptDecoder
246
241
  } );
247
242
  parser.fileLoader.setRequestHeader( this.requestHeader );
248
-
249
243
  for ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {
250
244
 
251
245
  const plugin = this.pluginCallbacks[ i ]( parser );
252
- plugins[ plugin.name ] = plugin; // Workaround to avoid determining as unknown extension
246
+ plugins[ plugin.name ] = plugin;
247
+
248
+ // Workaround to avoid determining as unknown extension
253
249
  // in addUnknownExtensionsToUserData().
254
250
  // Remove this workaround if we move all the existing
255
251
  // extension handlers to plugin system
256
-
257
252
  extensions[ plugin.name ] = true;
258
253
 
259
254
  }
@@ -264,29 +259,20 @@
264
259
 
265
260
  const extensionName = json.extensionsUsed[ i ];
266
261
  const extensionsRequired = json.extensionsRequired || [];
267
-
268
262
  switch ( extensionName ) {
269
263
 
270
264
  case EXTENSIONS.KHR_MATERIALS_UNLIT:
271
265
  extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
272
266
  break;
273
-
274
- case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
275
- extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
276
- break;
277
-
278
267
  case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
279
268
  extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );
280
269
  break;
281
-
282
270
  case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
283
271
  extensions[ extensionName ] = new GLTFTextureTransformExtension();
284
272
  break;
285
-
286
273
  case EXTENSIONS.KHR_MESH_QUANTIZATION:
287
274
  extensions[ extensionName ] = new GLTFMeshQuantizationExtension();
288
275
  break;
289
-
290
276
  default:
291
277
  if ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {
292
278
 
@@ -305,7 +291,6 @@
305
291
  parser.parse( onLoad, onError );
306
292
 
307
293
  }
308
-
309
294
  parseAsync( data, path ) {
310
295
 
311
296
  const scope = this;
@@ -318,8 +303,8 @@
318
303
  }
319
304
 
320
305
  }
321
- /* GLTFREGISTRY */
322
306
 
307
+ /* GLTFREGISTRY */
323
308
 
324
309
  function GLTFRegistry() {
325
310
 
@@ -348,20 +333,17 @@
348
333
  };
349
334
 
350
335
  }
351
- /*********************************/
352
336
 
337
+ /*********************************/
353
338
  /********** EXTENSIONS ***********/
354
-
355
339
  /*********************************/
356
340
 
357
-
358
341
  const EXTENSIONS = {
359
342
  KHR_BINARY_GLTF: 'KHR_binary_glTF',
360
343
  KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
361
344
  KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
362
345
  KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
363
346
  KHR_MATERIALS_IOR: 'KHR_materials_ior',
364
- KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
365
347
  KHR_MATERIALS_SHEEN: 'KHR_materials_sheen',
366
348
  KHR_MATERIALS_SPECULAR: 'KHR_materials_specular',
367
349
  KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',
@@ -373,37 +355,36 @@
373
355
  KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
374
356
  KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
375
357
  EXT_TEXTURE_WEBP: 'EXT_texture_webp',
376
- EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression'
358
+ EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
359
+ EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'
377
360
  };
361
+
378
362
  /**
379
363
  * Punctual Lights Extension
380
364
  *
381
365
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
382
366
  */
383
-
384
367
  class GLTFLightsExtension {
385
368
 
386
369
  constructor( parser ) {
387
370
 
388
371
  this.parser = parser;
389
- this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL; // THREE.Object3D instance caches
372
+ this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;
390
373
 
374
+ // THREE.Object3D instance caches
391
375
  this.cache = {
392
376
  refs: {},
393
377
  uses: {}
394
378
  };
395
379
 
396
380
  }
397
-
398
381
  _markDefs() {
399
382
 
400
383
  const parser = this.parser;
401
384
  const nodeDefs = this.parser.json.nodes || [];
402
-
403
385
  for ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {
404
386
 
405
387
  const nodeDef = nodeDefs[ nodeIndex ];
406
-
407
388
  if ( nodeDef.extensions && nodeDef.extensions[ this.name ] && nodeDef.extensions[ this.name ].light !== undefined ) {
408
389
 
409
390
  parser._addNodeRef( this.cache, nodeDef.extensions[ this.name ].light );
@@ -413,7 +394,6 @@
413
394
  }
414
395
 
415
396
  }
416
-
417
397
  _loadLight( lightIndex ) {
418
398
 
419
399
  const parser = this.parser;
@@ -428,7 +408,6 @@
428
408
  const color = new THREE.Color( 0xffffff );
429
409
  if ( lightDef.color !== undefined ) color.fromArray( lightDef.color );
430
410
  const range = lightDef.range !== undefined ? lightDef.range : 0;
431
-
432
411
  switch ( lightDef.type ) {
433
412
 
434
413
  case 'directional':
@@ -436,16 +415,14 @@
436
415
  lightNode.target.position.set( 0, 0, - 1 );
437
416
  lightNode.add( lightNode.target );
438
417
  break;
439
-
440
418
  case 'point':
441
419
  lightNode = new THREE.PointLight( color );
442
420
  lightNode.distance = range;
443
421
  break;
444
-
445
422
  case 'spot':
446
423
  lightNode = new THREE.SpotLight( color );
447
- lightNode.distance = range; // Handle spotlight properties.
448
-
424
+ lightNode.distance = range;
425
+ // Handle spotlight properties.
449
426
  lightDef.spot = lightDef.spot || {};
450
427
  lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;
451
428
  lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;
@@ -454,16 +431,16 @@
454
431
  lightNode.target.position.set( 0, 0, - 1 );
455
432
  lightNode.add( lightNode.target );
456
433
  break;
457
-
458
434
  default:
459
435
  throw new Error( 'THREE.GLTFLoader: Unexpected light type: ' + lightDef.type );
460
436
 
461
- } // Some lights (e.g. spot) default to a position other than the origin. Reset the position
462
- // here, because node-level parsing will only override position if explicitly specified.
463
-
437
+ }
464
438
 
439
+ // Some lights (e.g. spot) default to a position other than the origin. Reset the position
440
+ // here, because node-level parsing will only override position if explicitly specified.
465
441
  lightNode.position.set( 0, 0, 0 );
466
442
  lightNode.decay = 2;
443
+ assignExtrasToUserData( lightNode, lightDef );
467
444
  if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
468
445
  lightNode.name = parser.createUniqueName( lightDef.name || 'light_' + lightIndex );
469
446
  dependency = Promise.resolve( lightNode );
@@ -471,7 +448,12 @@
471
448
  return dependency;
472
449
 
473
450
  }
451
+ getDependency( type, index ) {
452
+
453
+ if ( type !== 'light' ) return;
454
+ return this._loadLight( index );
474
455
 
456
+ }
475
457
  createNodeAttachment( nodeIndex ) {
476
458
 
477
459
  const self = this;
@@ -490,13 +472,12 @@
490
472
  }
491
473
 
492
474
  }
475
+
493
476
  /**
494
477
  * Unlit Materials Extension
495
478
  *
496
479
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
497
480
  */
498
-
499
-
500
481
  class GLTFMaterialsUnlitExtension {
501
482
 
502
483
  constructor() {
@@ -504,20 +485,17 @@
504
485
  this.name = EXTENSIONS.KHR_MATERIALS_UNLIT;
505
486
 
506
487
  }
507
-
508
488
  getMaterialType() {
509
489
 
510
490
  return THREE.MeshBasicMaterial;
511
491
 
512
492
  }
513
-
514
493
  extendParams( materialParams, materialDef, parser ) {
515
494
 
516
495
  const pending = [];
517
496
  materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
518
497
  materialParams.opacity = 1.0;
519
498
  const metallicRoughness = materialDef.pbrMetallicRoughness;
520
-
521
499
  if ( metallicRoughness ) {
522
500
 
523
501
  if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {
@@ -541,13 +519,12 @@
541
519
  }
542
520
 
543
521
  }
522
+
544
523
  /**
545
524
  * Materials Emissive Strength Extension
546
525
  *
547
526
  * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
548
527
  */
549
-
550
-
551
528
  class GLTFMaterialsEmissiveStrengthExtension {
552
529
 
553
530
  constructor( parser ) {
@@ -556,12 +533,10 @@
556
533
  this.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;
557
534
 
558
535
  }
559
-
560
536
  extendMaterialParams( materialIndex, materialParams ) {
561
537
 
562
538
  const parser = this.parser;
563
539
  const materialDef = parser.json.materials[ materialIndex ];
564
-
565
540
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
566
541
 
567
542
  return Promise.resolve();
@@ -569,7 +544,6 @@
569
544
  }
570
545
 
571
546
  const emissiveStrength = materialDef.extensions[ this.name ].emissiveStrength;
572
-
573
547
  if ( emissiveStrength !== undefined ) {
574
548
 
575
549
  materialParams.emissiveIntensity = emissiveStrength;
@@ -581,13 +555,12 @@
581
555
  }
582
556
 
583
557
  }
558
+
584
559
  /**
585
560
  * Clearcoat Materials Extension
586
561
  *
587
562
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
588
563
  */
589
-
590
-
591
564
  class GLTFMaterialsClearcoatExtension {
592
565
 
593
566
  constructor( parser ) {
@@ -596,7 +569,6 @@
596
569
  this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
597
570
 
598
571
  }
599
-
600
572
  getMaterialType( materialIndex ) {
601
573
 
602
574
  const parser = this.parser;
@@ -605,12 +577,10 @@
605
577
  return THREE.MeshPhysicalMaterial;
606
578
 
607
579
  }
608
-
609
580
  extendMaterialParams( materialIndex, materialParams ) {
610
581
 
611
582
  const parser = this.parser;
612
583
  const materialDef = parser.json.materials[ materialIndex ];
613
-
614
584
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
615
585
 
616
586
  return Promise.resolve();
@@ -619,7 +589,6 @@
619
589
 
620
590
  const pending = [];
621
591
  const extension = materialDef.extensions[ this.name ];
622
-
623
592
  if ( extension.clearcoatFactor !== undefined ) {
624
593
 
625
594
  materialParams.clearcoat = extension.clearcoatFactor;
@@ -647,7 +616,6 @@
647
616
  if ( extension.clearcoatNormalTexture !== undefined ) {
648
617
 
649
618
  pending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );
650
-
651
619
  if ( extension.clearcoatNormalTexture.scale !== undefined ) {
652
620
 
653
621
  const scale = extension.clearcoatNormalTexture.scale;
@@ -662,13 +630,12 @@
662
630
  }
663
631
 
664
632
  }
633
+
665
634
  /**
666
635
  * Iridescence Materials Extension
667
636
  *
668
637
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
669
638
  */
670
-
671
-
672
639
  class GLTFMaterialsIridescenceExtension {
673
640
 
674
641
  constructor( parser ) {
@@ -677,7 +644,6 @@
677
644
  this.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;
678
645
 
679
646
  }
680
-
681
647
  getMaterialType( materialIndex ) {
682
648
 
683
649
  const parser = this.parser;
@@ -686,12 +652,10 @@
686
652
  return THREE.MeshPhysicalMaterial;
687
653
 
688
654
  }
689
-
690
655
  extendMaterialParams( materialIndex, materialParams ) {
691
656
 
692
657
  const parser = this.parser;
693
658
  const materialDef = parser.json.materials[ materialIndex ];
694
-
695
659
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
696
660
 
697
661
  return Promise.resolve();
@@ -700,7 +664,6 @@
700
664
 
701
665
  const pending = [];
702
666
  const extension = materialDef.extensions[ this.name ];
703
-
704
667
  if ( extension.iridescenceFactor !== undefined ) {
705
668
 
706
669
  materialParams.iridescence = extension.iridescenceFactor;
@@ -748,13 +711,12 @@
748
711
  }
749
712
 
750
713
  }
714
+
751
715
  /**
752
716
  * Sheen Materials Extension
753
717
  *
754
718
  * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen
755
719
  */
756
-
757
-
758
720
  class GLTFMaterialsSheenExtension {
759
721
 
760
722
  constructor( parser ) {
@@ -763,7 +725,6 @@
763
725
  this.name = EXTENSIONS.KHR_MATERIALS_SHEEN;
764
726
 
765
727
  }
766
-
767
728
  getMaterialType( materialIndex ) {
768
729
 
769
730
  const parser = this.parser;
@@ -772,12 +733,10 @@
772
733
  return THREE.MeshPhysicalMaterial;
773
734
 
774
735
  }
775
-
776
736
  extendMaterialParams( materialIndex, materialParams ) {
777
737
 
778
738
  const parser = this.parser;
779
739
  const materialDef = parser.json.materials[ materialIndex ];
780
-
781
740
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
782
741
 
783
742
  return Promise.resolve();
@@ -789,7 +748,6 @@
789
748
  materialParams.sheenRoughness = 0;
790
749
  materialParams.sheen = 1;
791
750
  const extension = materialDef.extensions[ this.name ];
792
-
793
751
  if ( extension.sheenColorFactor !== undefined ) {
794
752
 
795
753
  materialParams.sheenColor.fromArray( extension.sheenColorFactor );
@@ -819,14 +777,13 @@
819
777
  }
820
778
 
821
779
  }
780
+
822
781
  /**
823
782
  * Transmission Materials Extension
824
783
  *
825
784
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
826
785
  * Draft: https://github.com/KhronosGroup/glTF/pull/1698
827
786
  */
828
-
829
-
830
787
  class GLTFMaterialsTransmissionExtension {
831
788
 
832
789
  constructor( parser ) {
@@ -835,7 +792,6 @@
835
792
  this.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;
836
793
 
837
794
  }
838
-
839
795
  getMaterialType( materialIndex ) {
840
796
 
841
797
  const parser = this.parser;
@@ -844,12 +800,10 @@
844
800
  return THREE.MeshPhysicalMaterial;
845
801
 
846
802
  }
847
-
848
803
  extendMaterialParams( materialIndex, materialParams ) {
849
804
 
850
805
  const parser = this.parser;
851
806
  const materialDef = parser.json.materials[ materialIndex ];
852
-
853
807
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
854
808
 
855
809
  return Promise.resolve();
@@ -858,7 +812,6 @@
858
812
 
859
813
  const pending = [];
860
814
  const extension = materialDef.extensions[ this.name ];
861
-
862
815
  if ( extension.transmissionFactor !== undefined ) {
863
816
 
864
817
  materialParams.transmission = extension.transmissionFactor;
@@ -876,13 +829,12 @@
876
829
  }
877
830
 
878
831
  }
832
+
879
833
  /**
880
834
  * Materials Volume Extension
881
835
  *
882
836
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
883
837
  */
884
-
885
-
886
838
  class GLTFMaterialsVolumeExtension {
887
839
 
888
840
  constructor( parser ) {
@@ -891,7 +843,6 @@
891
843
  this.name = EXTENSIONS.KHR_MATERIALS_VOLUME;
892
844
 
893
845
  }
894
-
895
846
  getMaterialType( materialIndex ) {
896
847
 
897
848
  const parser = this.parser;
@@ -900,12 +851,10 @@
900
851
  return THREE.MeshPhysicalMaterial;
901
852
 
902
853
  }
903
-
904
854
  extendMaterialParams( materialIndex, materialParams ) {
905
855
 
906
856
  const parser = this.parser;
907
857
  const materialDef = parser.json.materials[ materialIndex ];
908
-
909
858
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
910
859
 
911
860
  return Promise.resolve();
@@ -915,14 +864,13 @@
915
864
  const pending = [];
916
865
  const extension = materialDef.extensions[ this.name ];
917
866
  materialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0;
918
-
919
867
  if ( extension.thicknessTexture !== undefined ) {
920
868
 
921
869
  pending.push( parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) );
922
870
 
923
871
  }
924
872
 
925
- materialParams.attenuationDistance = extension.attenuationDistance || 0;
873
+ materialParams.attenuationDistance = extension.attenuationDistance || Infinity;
926
874
  const colorArray = extension.attenuationColor || [ 1, 1, 1 ];
927
875
  materialParams.attenuationColor = new THREE.Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] );
928
876
  return Promise.all( pending );
@@ -930,13 +878,12 @@
930
878
  }
931
879
 
932
880
  }
881
+
933
882
  /**
934
883
  * Materials ior Extension
935
884
  *
936
885
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior
937
886
  */
938
-
939
-
940
887
  class GLTFMaterialsIorExtension {
941
888
 
942
889
  constructor( parser ) {
@@ -945,7 +892,6 @@
945
892
  this.name = EXTENSIONS.KHR_MATERIALS_IOR;
946
893
 
947
894
  }
948
-
949
895
  getMaterialType( materialIndex ) {
950
896
 
951
897
  const parser = this.parser;
@@ -954,12 +900,10 @@
954
900
  return THREE.MeshPhysicalMaterial;
955
901
 
956
902
  }
957
-
958
903
  extendMaterialParams( materialIndex, materialParams ) {
959
904
 
960
905
  const parser = this.parser;
961
906
  const materialDef = parser.json.materials[ materialIndex ];
962
-
963
907
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
964
908
 
965
909
  return Promise.resolve();
@@ -973,13 +917,12 @@
973
917
  }
974
918
 
975
919
  }
920
+
976
921
  /**
977
922
  * Materials specular Extension
978
923
  *
979
924
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular
980
925
  */
981
-
982
-
983
926
  class GLTFMaterialsSpecularExtension {
984
927
 
985
928
  constructor( parser ) {
@@ -988,7 +931,6 @@
988
931
  this.name = EXTENSIONS.KHR_MATERIALS_SPECULAR;
989
932
 
990
933
  }
991
-
992
934
  getMaterialType( materialIndex ) {
993
935
 
994
936
  const parser = this.parser;
@@ -997,12 +939,10 @@
997
939
  return THREE.MeshPhysicalMaterial;
998
940
 
999
941
  }
1000
-
1001
942
  extendMaterialParams( materialIndex, materialParams ) {
1002
943
 
1003
944
  const parser = this.parser;
1004
945
  const materialDef = parser.json.materials[ materialIndex ];
1005
-
1006
946
  if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
1007
947
 
1008
948
  return Promise.resolve();
@@ -1012,7 +952,6 @@
1012
952
  const pending = [];
1013
953
  const extension = materialDef.extensions[ this.name ];
1014
954
  materialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0;
1015
-
1016
955
  if ( extension.specularTexture !== undefined ) {
1017
956
 
1018
957
  pending.push( parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) );
@@ -1021,7 +960,6 @@
1021
960
 
1022
961
  const colorArray = extension.specularColorFactor || [ 1, 1, 1 ];
1023
962
  materialParams.specularColor = new THREE.Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] );
1024
-
1025
963
  if ( extension.specularColorTexture !== undefined ) {
1026
964
 
1027
965
  pending.push( parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, THREE.sRGBEncoding ) );
@@ -1033,13 +971,12 @@
1033
971
  }
1034
972
 
1035
973
  }
974
+
1036
975
  /**
1037
976
  * BasisU THREE.Texture Extension
1038
977
  *
1039
978
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu
1040
979
  */
1041
-
1042
-
1043
980
  class GLTFTextureBasisUExtension {
1044
981
 
1045
982
  constructor( parser ) {
@@ -1048,13 +985,11 @@
1048
985
  this.name = EXTENSIONS.KHR_TEXTURE_BASISU;
1049
986
 
1050
987
  }
1051
-
1052
988
  loadTexture( textureIndex ) {
1053
989
 
1054
990
  const parser = this.parser;
1055
991
  const json = parser.json;
1056
992
  const textureDef = json.textures[ textureIndex ];
1057
-
1058
993
  if ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) {
1059
994
 
1060
995
  return null;
@@ -1063,7 +998,6 @@
1063
998
 
1064
999
  const extension = textureDef.extensions[ this.name ];
1065
1000
  const loader = parser.options.ktx2Loader;
1066
-
1067
1001
  if ( ! loader ) {
1068
1002
 
1069
1003
  if ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {
@@ -1084,13 +1018,12 @@
1084
1018
  }
1085
1019
 
1086
1020
  }
1021
+
1087
1022
  /**
1088
1023
  * WebP THREE.Texture Extension
1089
1024
  *
1090
1025
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp
1091
1026
  */
1092
-
1093
-
1094
1027
  class GLTFTextureWebPExtension {
1095
1028
 
1096
1029
  constructor( parser ) {
@@ -1100,14 +1033,12 @@
1100
1033
  this.isSupported = null;
1101
1034
 
1102
1035
  }
1103
-
1104
1036
  loadTexture( textureIndex ) {
1105
1037
 
1106
1038
  const name = this.name;
1107
1039
  const parser = this.parser;
1108
1040
  const json = parser.json;
1109
1041
  const textureDef = json.textures[ textureIndex ];
1110
-
1111
1042
  if ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {
1112
1043
 
1113
1044
  return null;
@@ -1117,7 +1048,6 @@
1117
1048
  const extension = textureDef.extensions[ name ];
1118
1049
  const source = json.images[ extension.source ];
1119
1050
  let loader = parser.textureLoader;
1120
-
1121
1051
  if ( source.uri ) {
1122
1052
 
1123
1053
  const handler = parser.options.manager.getHandler( source.uri );
@@ -1128,31 +1058,29 @@
1128
1058
  return this.detectSupport().then( function ( isSupported ) {
1129
1059
 
1130
1060
  if ( isSupported ) return parser.loadTextureImage( textureIndex, extension.source, loader );
1131
-
1132
1061
  if ( json.extensionsRequired && json.extensionsRequired.indexOf( name ) >= 0 ) {
1133
1062
 
1134
1063
  throw new Error( 'THREE.GLTFLoader: WebP required by asset but unsupported.' );
1135
1064
 
1136
- } // Fall back to PNG or JPEG.
1137
-
1065
+ }
1138
1066
 
1067
+ // Fall back to PNG or JPEG.
1139
1068
  return parser.loadTexture( textureIndex );
1140
1069
 
1141
1070
  } );
1142
1071
 
1143
1072
  }
1144
-
1145
1073
  detectSupport() {
1146
1074
 
1147
1075
  if ( ! this.isSupported ) {
1148
1076
 
1149
1077
  this.isSupported = new Promise( function ( resolve ) {
1150
1078
 
1151
- const image = new Image(); // Lossy test image. Support for lossy images doesn't guarantee support for all
1152
- // WebP images, unfortunately.
1079
+ const image = new Image();
1153
1080
 
1081
+ // Lossy test image. Support for lossy images doesn't guarantee support for all
1082
+ // WebP images, unfortunately.
1154
1083
  image.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';
1155
-
1156
1084
  image.onload = image.onerror = function () {
1157
1085
 
1158
1086
  resolve( image.height === 1 );
@@ -1168,13 +1096,12 @@
1168
1096
  }
1169
1097
 
1170
1098
  }
1099
+
1171
1100
  /**
1172
1101
  * meshopt BufferView Compression Extension
1173
1102
  *
1174
1103
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression
1175
1104
  */
1176
-
1177
-
1178
1105
  class GLTFMeshoptCompression {
1179
1106
 
1180
1107
  constructor( parser ) {
@@ -1183,18 +1110,15 @@
1183
1110
  this.parser = parser;
1184
1111
 
1185
1112
  }
1186
-
1187
1113
  loadBufferView( index ) {
1188
1114
 
1189
1115
  const json = this.parser.json;
1190
1116
  const bufferView = json.bufferViews[ index ];
1191
-
1192
1117
  if ( bufferView.extensions && bufferView.extensions[ this.name ] ) {
1193
1118
 
1194
1119
  const extensionDef = bufferView.extensions[ this.name ];
1195
1120
  const buffer = this.parser.getDependency( 'buffer', extensionDef.buffer );
1196
1121
  const decoder = this.parser.options.meshoptDecoder;
1197
-
1198
1122
  if ( ! decoder || ! decoder.supported ) {
1199
1123
 
1200
1124
  if ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {
@@ -1217,7 +1141,6 @@
1217
1141
  const count = extensionDef.count;
1218
1142
  const stride = extensionDef.byteStride;
1219
1143
  const source = new Uint8Array( res, byteOffset, byteLength );
1220
-
1221
1144
  if ( decoder.decodeGltfBufferAsync ) {
1222
1145
 
1223
1146
  return decoder.decodeGltfBufferAsync( count, stride, source, extensionDef.mode, extensionDef.filter ).then( function ( res ) {
@@ -1250,16 +1173,152 @@
1250
1173
  }
1251
1174
 
1252
1175
  }
1253
- /* BINARY EXTENSION */
1254
1176
 
1177
+ /**
1178
+ * GPU Instancing Extension
1179
+ *
1180
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing
1181
+ *
1182
+ */
1183
+ class GLTFMeshGpuInstancing {
1184
+
1185
+ constructor( parser ) {
1255
1186
 
1187
+ this.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING;
1188
+ this.parser = parser;
1189
+
1190
+ }
1191
+ createNodeMesh( nodeIndex ) {
1192
+
1193
+ const json = this.parser.json;
1194
+ const nodeDef = json.nodes[ nodeIndex ];
1195
+ if ( ! nodeDef.extensions || ! nodeDef.extensions[ this.name ] || nodeDef.mesh === undefined ) {
1196
+
1197
+ return null;
1198
+
1199
+ }
1200
+
1201
+ const meshDef = json.meshes[ nodeDef.mesh ];
1202
+
1203
+ // No THREE.Points or Lines + Instancing support yet
1204
+
1205
+ for ( const primitive of meshDef.primitives ) {
1206
+
1207
+ if ( primitive.mode !== WEBGL_CONSTANTS.TRIANGLES && primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP && primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN && primitive.mode !== undefined ) {
1208
+
1209
+ return null;
1210
+
1211
+ }
1212
+
1213
+ }
1214
+
1215
+ const extensionDef = nodeDef.extensions[ this.name ];
1216
+ const attributesDef = extensionDef.attributes;
1217
+
1218
+ // @TODO: Can we support THREE.InstancedMesh + THREE.SkinnedMesh?
1219
+
1220
+ const pending = [];
1221
+ const attributes = {};
1222
+ for ( const key in attributesDef ) {
1223
+
1224
+ pending.push( this.parser.getDependency( 'accessor', attributesDef[ key ] ).then( accessor => {
1225
+
1226
+ attributes[ key ] = accessor;
1227
+ return attributes[ key ];
1228
+
1229
+ } ) );
1230
+
1231
+ }
1232
+
1233
+ if ( pending.length < 1 ) {
1234
+
1235
+ return null;
1236
+
1237
+ }
1238
+
1239
+ pending.push( this.parser.createNodeMesh( nodeIndex ) );
1240
+ return Promise.all( pending ).then( results => {
1241
+
1242
+ const nodeObject = results.pop();
1243
+ const meshes = nodeObject.isGroup ? nodeObject.children : [ nodeObject ];
1244
+ const count = results[ 0 ].count; // All attribute counts should be same
1245
+ const instancedMeshes = [];
1246
+ for ( const mesh of meshes ) {
1247
+
1248
+ // Temporal variables
1249
+ const m = new THREE.Matrix4();
1250
+ const p = new THREE.Vector3();
1251
+ const q = new THREE.Quaternion();
1252
+ const s = new THREE.Vector3( 1, 1, 1 );
1253
+ const instancedMesh = new THREE.InstancedMesh( mesh.geometry, mesh.material, count );
1254
+ for ( let i = 0; i < count; i ++ ) {
1255
+
1256
+ if ( attributes.TRANSLATION ) {
1257
+
1258
+ p.fromBufferAttribute( attributes.TRANSLATION, i );
1259
+
1260
+ }
1261
+
1262
+ if ( attributes.ROTATION ) {
1263
+
1264
+ q.fromBufferAttribute( attributes.ROTATION, i );
1265
+
1266
+ }
1267
+
1268
+ if ( attributes.SCALE ) {
1269
+
1270
+ s.fromBufferAttribute( attributes.SCALE, i );
1271
+
1272
+ }
1273
+
1274
+ instancedMesh.setMatrixAt( i, m.compose( p, q, s ) );
1275
+
1276
+ }
1277
+
1278
+ // Add instance attributes to the geometry, excluding TRS.
1279
+ for ( const attributeName in attributes ) {
1280
+
1281
+ if ( attributeName !== 'TRANSLATION' && attributeName !== 'ROTATION' && attributeName !== 'SCALE' ) {
1282
+
1283
+ mesh.geometry.setAttribute( attributeName, attributes[ attributeName ] );
1284
+
1285
+ }
1286
+
1287
+ }
1288
+
1289
+ // Just in case
1290
+ THREE.Object3D.prototype.copy.call( instancedMesh, mesh );
1291
+
1292
+ // https://github.com/mrdoob/three.js/issues/18334
1293
+ instancedMesh.frustumCulled = false;
1294
+ this.parser.assignFinalMaterial( instancedMesh );
1295
+ instancedMeshes.push( instancedMesh );
1296
+
1297
+ }
1298
+
1299
+ if ( nodeObject.isGroup ) {
1300
+
1301
+ nodeObject.clear();
1302
+ nodeObject.add( ...instancedMeshes );
1303
+ return nodeObject;
1304
+
1305
+ }
1306
+
1307
+ return instancedMeshes[ 0 ];
1308
+
1309
+ } );
1310
+
1311
+ }
1312
+
1313
+ }
1314
+
1315
+ /* BINARY EXTENSION */
1256
1316
  const BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
1257
1317
  const BINARY_EXTENSION_HEADER_LENGTH = 12;
1258
1318
  const BINARY_EXTENSION_CHUNK_TYPES = {
1259
1319
  JSON: 0x4E4F534A,
1260
1320
  BIN: 0x004E4942
1261
1321
  };
1262
-
1263
1322
  class GLTFBinaryExtension {
1264
1323
 
1265
1324
  constructor( data ) {
@@ -1273,7 +1332,6 @@
1273
1332
  version: headerView.getUint32( 4, true ),
1274
1333
  length: headerView.getUint32( 8, true )
1275
1334
  };
1276
-
1277
1335
  if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {
1278
1336
 
1279
1337
  throw new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' );
@@ -1287,14 +1345,12 @@
1287
1345
  const chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;
1288
1346
  const chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );
1289
1347
  let chunkIndex = 0;
1290
-
1291
1348
  while ( chunkIndex < chunkContentsLength ) {
1292
1349
 
1293
1350
  const chunkLength = chunkView.getUint32( chunkIndex, true );
1294
1351
  chunkIndex += 4;
1295
1352
  const chunkType = chunkView.getUint32( chunkIndex, true );
1296
1353
  chunkIndex += 4;
1297
-
1298
1354
  if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {
1299
1355
 
1300
1356
  const contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );
@@ -1305,8 +1361,9 @@
1305
1361
  const byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;
1306
1362
  this.body = data.slice( byteOffset, byteOffset + chunkLength );
1307
1363
 
1308
- } // Clients must ignore chunks with unknown types.
1364
+ }
1309
1365
 
1366
+ // Clients must ignore chunks with unknown types.
1310
1367
 
1311
1368
  chunkIndex += chunkLength;
1312
1369
 
@@ -1321,13 +1378,12 @@
1321
1378
  }
1322
1379
 
1323
1380
  }
1381
+
1324
1382
  /**
1325
1383
  * DRACO THREE.Mesh Compression Extension
1326
1384
  *
1327
1385
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
1328
1386
  */
1329
-
1330
-
1331
1387
  class GLTFDracoMeshCompressionExtension {
1332
1388
 
1333
1389
  constructor( json, dracoLoader ) {
@@ -1344,7 +1400,6 @@
1344
1400
  this.dracoLoader.preload();
1345
1401
 
1346
1402
  }
1347
-
1348
1403
  decodePrimitive( primitive, parser ) {
1349
1404
 
1350
1405
  const json = this.json;
@@ -1354,7 +1409,6 @@
1354
1409
  const threeAttributeMap = {};
1355
1410
  const attributeNormalizedMap = {};
1356
1411
  const attributeTypeMap = {};
1357
-
1358
1412
  for ( const attributeName in gltfAttributeMap ) {
1359
1413
 
1360
1414
  const threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
@@ -1365,7 +1419,6 @@
1365
1419
  for ( const attributeName in primitive.attributes ) {
1366
1420
 
1367
1421
  const threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
1368
-
1369
1422
  if ( gltfAttributeMap[ attributeName ] !== undefined ) {
1370
1423
 
1371
1424
  const accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
@@ -1402,13 +1455,12 @@
1402
1455
  }
1403
1456
 
1404
1457
  }
1458
+
1405
1459
  /**
1406
1460
  * THREE.Texture Transform Extension
1407
1461
  *
1408
1462
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform
1409
1463
  */
1410
-
1411
-
1412
1464
  class GLTFTextureTransformExtension {
1413
1465
 
1414
1466
  constructor() {
@@ -1416,7 +1468,6 @@
1416
1468
  this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;
1417
1469
 
1418
1470
  }
1419
-
1420
1471
  extendTexture( texture, transform ) {
1421
1472
 
1422
1473
  if ( transform.texCoord !== undefined ) {
@@ -1433,7 +1484,6 @@
1433
1484
  }
1434
1485
 
1435
1486
  texture = texture.clone();
1436
-
1437
1487
  if ( transform.offset !== undefined ) {
1438
1488
 
1439
1489
  texture.offset.fromArray( transform.offset );
@@ -1458,254 +1508,12 @@
1458
1508
  }
1459
1509
 
1460
1510
  }
1461
- /**
1462
- * Specular-Glossiness Extension
1463
- *
1464
- * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness
1465
- */
1466
-
1467
- /**
1468
- * A sub class of StandardMaterial with some of the functionality
1469
- * changed via the `onBeforeCompile` callback
1470
- * @pailhead
1471
- */
1472
-
1473
-
1474
- class GLTFMeshStandardSGMaterial extends THREE.MeshStandardMaterial {
1475
-
1476
- constructor( params ) {
1477
-
1478
- super();
1479
- this.isGLTFSpecularGlossinessMaterial = true; //various chunks that need replacing
1480
-
1481
- const specularMapParsFragmentChunk = [ '#ifdef USE_SPECULARMAP', ' uniform sampler2D specularMap;', '#endif' ].join( '\n' );
1482
- const glossinessMapParsFragmentChunk = [ '#ifdef USE_GLOSSINESSMAP', ' uniform sampler2D glossinessMap;', '#endif' ].join( '\n' );
1483
- const specularMapFragmentChunk = [ 'vec3 specularFactor = specular;', '#ifdef USE_SPECULARMAP', ' vec4 texelSpecular = texture2D( specularMap, vUv );', ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', ' specularFactor *= texelSpecular.rgb;', '#endif' ].join( '\n' );
1484
- 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' );
1485
- const lightPhysicalFragmentChunk = [ 'PhysicalMaterial material;', 'material.diffuseColor = diffuseColor.rgb * ( 1. - max( specularFactor.r, max( specularFactor.g, specularFactor.b ) ) );', 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );', 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );', 'material.roughness = max( 1.0 - glossinessFactor, 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.', 'material.roughness += geometryRoughness;', 'material.roughness = min( material.roughness, 1.0 );', 'material.specularColor = specularFactor;' ].join( '\n' );
1486
- const uniforms = {
1487
- specular: {
1488
- value: new THREE.Color().setHex( 0xffffff )
1489
- },
1490
- glossiness: {
1491
- value: 1
1492
- },
1493
- specularMap: {
1494
- value: null
1495
- },
1496
- glossinessMap: {
1497
- value: null
1498
- }
1499
- };
1500
- this._extraUniforms = uniforms;
1501
-
1502
- this.onBeforeCompile = function ( shader ) {
1503
-
1504
- for ( const uniformName in uniforms ) {
1505
-
1506
- shader.uniforms[ uniformName ] = uniforms[ uniformName ];
1507
-
1508
- }
1509
-
1510
- shader.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 ).replace( '#include <roughnessmap_fragment>', specularMapFragmentChunk ).replace( '#include <metalnessmap_fragment>', glossinessMapFragmentChunk ).replace( '#include <lights_physical_fragment>', lightPhysicalFragmentChunk );
1511
-
1512
- };
1513
-
1514
- Object.defineProperties( this, {
1515
- specular: {
1516
- get: function () {
1517
-
1518
- return uniforms.specular.value;
1519
-
1520
- },
1521
- set: function ( v ) {
1522
-
1523
- uniforms.specular.value = v;
1524
-
1525
- }
1526
- },
1527
- specularMap: {
1528
- get: function () {
1529
-
1530
- return uniforms.specularMap.value;
1531
-
1532
- },
1533
- set: function ( v ) {
1534
-
1535
- uniforms.specularMap.value = v;
1536
-
1537
- if ( v ) {
1538
-
1539
- this.defines.USE_SPECULARMAP = ''; // USE_UV is set by the renderer for specular maps
1540
-
1541
- } else {
1542
-
1543
- delete this.defines.USE_SPECULARMAP;
1544
-
1545
- }
1546
-
1547
- }
1548
- },
1549
- glossiness: {
1550
- get: function () {
1551
-
1552
- return uniforms.glossiness.value;
1553
-
1554
- },
1555
- set: function ( v ) {
1556
-
1557
- uniforms.glossiness.value = v;
1558
-
1559
- }
1560
- },
1561
- glossinessMap: {
1562
- get: function () {
1563
-
1564
- return uniforms.glossinessMap.value;
1565
-
1566
- },
1567
- set: function ( v ) {
1568
-
1569
- uniforms.glossinessMap.value = v;
1570
-
1571
- if ( v ) {
1572
-
1573
- this.defines.USE_GLOSSINESSMAP = '';
1574
- this.defines.USE_UV = '';
1575
-
1576
- } else {
1577
-
1578
- delete this.defines.USE_GLOSSINESSMAP;
1579
- delete this.defines.USE_UV;
1580
-
1581
- }
1582
-
1583
- }
1584
- }
1585
- } );
1586
- delete this.metalness;
1587
- delete this.roughness;
1588
- delete this.metalnessMap;
1589
- delete this.roughnessMap;
1590
- this.setValues( params );
1591
-
1592
- }
1593
-
1594
- copy( source ) {
1595
-
1596
- super.copy( source );
1597
- this.specularMap = source.specularMap;
1598
- this.specular.copy( source.specular );
1599
- this.glossinessMap = source.glossinessMap;
1600
- this.glossiness = source.glossiness;
1601
- delete this.metalness;
1602
- delete this.roughness;
1603
- delete this.metalnessMap;
1604
- delete this.roughnessMap;
1605
- return this;
1606
-
1607
- }
1608
-
1609
- }
1610
-
1611
- class GLTFMaterialsPbrSpecularGlossinessExtension {
1612
-
1613
- constructor() {
1614
-
1615
- this.name = EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS;
1616
- this.specularGlossinessParams = [ 'color', 'map', 'lightMap', 'lightMapIntensity', 'aoMap', 'aoMapIntensity', 'emissive', 'emissiveIntensity', 'emissiveMap', 'bumpMap', 'bumpScale', 'normalMap', 'normalMapType', 'displacementMap', 'displacementScale', 'displacementBias', 'specularMap', 'specular', 'glossinessMap', 'glossiness', 'alphaMap', 'envMap', 'envMapIntensity' ];
1617
-
1618
- }
1619
-
1620
- getMaterialType() {
1621
-
1622
- return GLTFMeshStandardSGMaterial;
1623
-
1624
- }
1625
1511
 
1626
- extendParams( materialParams, materialDef, parser ) {
1627
-
1628
- const pbrSpecularGlossiness = materialDef.extensions[ this.name ];
1629
- materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
1630
- materialParams.opacity = 1.0;
1631
- const pending = [];
1632
-
1633
- if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) {
1634
-
1635
- const array = pbrSpecularGlossiness.diffuseFactor;
1636
- materialParams.color.fromArray( array );
1637
- materialParams.opacity = array[ 3 ];
1638
-
1639
- }
1640
-
1641
- if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) {
1642
-
1643
- pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, THREE.sRGBEncoding ) );
1644
-
1645
- }
1646
-
1647
- materialParams.emissive = new THREE.Color( 0.0, 0.0, 0.0 );
1648
- materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0;
1649
- materialParams.specular = new THREE.Color( 1.0, 1.0, 1.0 );
1650
-
1651
- if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) {
1652
-
1653
- materialParams.specular.fromArray( pbrSpecularGlossiness.specularFactor );
1654
-
1655
- }
1656
-
1657
- if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) {
1658
-
1659
- const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture;
1660
- pending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) );
1661
- pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef, THREE.sRGBEncoding ) );
1662
-
1663
- }
1664
-
1665
- return Promise.all( pending );
1666
-
1667
- }
1668
-
1669
- createMaterial( materialParams ) {
1670
-
1671
- const material = new GLTFMeshStandardSGMaterial( materialParams );
1672
- material.fog = true;
1673
- material.color = materialParams.color;
1674
- material.map = materialParams.map === undefined ? null : materialParams.map;
1675
- material.lightMap = null;
1676
- material.lightMapIntensity = 1.0;
1677
- material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap;
1678
- material.aoMapIntensity = 1.0;
1679
- material.emissive = materialParams.emissive;
1680
- material.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity;
1681
- material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap;
1682
- material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap;
1683
- material.bumpScale = 1;
1684
- material.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap;
1685
- material.normalMapType = THREE.TangentSpaceNormalMap;
1686
- if ( materialParams.normalScale ) material.normalScale = materialParams.normalScale;
1687
- material.displacementMap = null;
1688
- material.displacementScale = 1;
1689
- material.displacementBias = 0;
1690
- material.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap;
1691
- material.specular = materialParams.specular;
1692
- material.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap;
1693
- material.glossiness = materialParams.glossiness;
1694
- material.alphaMap = null;
1695
- material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap;
1696
- material.envMapIntensity = 1.0;
1697
- return material;
1698
-
1699
- }
1700
-
1701
- }
1702
1512
  /**
1703
1513
  * THREE.Mesh Quantization Extension
1704
1514
  *
1705
1515
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization
1706
1516
  */
1707
-
1708
-
1709
1517
  class GLTFMeshQuantizationExtension {
1710
1518
 
1711
1519
  constructor() {
@@ -1715,15 +1523,13 @@
1715
1523
  }
1716
1524
 
1717
1525
  }
1718
- /*********************************/
1719
1526
 
1527
+ /*********************************/
1720
1528
  /********** INTERPOLATION ********/
1721
-
1722
1529
  /*********************************/
1530
+
1723
1531
  // Spline Interpolation
1724
1532
  // Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation
1725
-
1726
-
1727
1533
  class GLTFCubicSplineInterpolant extends THREE.Interpolant {
1728
1534
 
1729
1535
  constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
@@ -1731,16 +1537,15 @@
1731
1537
  super( parameterPositions, sampleValues, sampleSize, resultBuffer );
1732
1538
 
1733
1539
  }
1734
-
1735
1540
  copySampleValue_( index ) {
1736
1541
 
1737
1542
  // Copies a sample value to the result buffer. See description of glTF
1738
1543
  // CUBICSPLINE values layout in interpolate_() function below.
1544
+
1739
1545
  const result = this.resultBuffer,
1740
1546
  values = this.sampleValues,
1741
1547
  valueSize = this.valueSize,
1742
1548
  offset = index * valueSize * 3 + valueSize;
1743
-
1744
1549
  for ( let i = 0; i !== valueSize; i ++ ) {
1745
1550
 
1746
1551
  result[ i ] = values[ offset + i ];
@@ -1750,7 +1555,6 @@
1750
1555
  return result;
1751
1556
 
1752
1557
  }
1753
-
1754
1558
  interpolate_( i1, t0, t, t1 ) {
1755
1559
 
1756
1560
  const result = this.resultBuffer;
@@ -1767,17 +1571,15 @@
1767
1571
  const s2 = - 2 * ppp + 3 * pp;
1768
1572
  const s3 = ppp - pp;
1769
1573
  const s0 = 1 - s2;
1770
- const s1 = s3 - pp + p; // Layout of keyframe output values for CUBICSPLINE animations:
1771
- // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
1574
+ const s1 = s3 - pp + p;
1772
1575
 
1576
+ // Layout of keyframe output values for CUBICSPLINE animations:
1577
+ // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
1773
1578
  for ( let i = 0; i !== stride; i ++ ) {
1774
1579
 
1775
1580
  const p0 = values[ offset0 + i + stride ]; // splineVertex_k
1776
-
1777
1581
  const m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)
1778
-
1779
1582
  const p1 = values[ offset1 + i + stride ]; // splineVertex_k+1
1780
-
1781
1583
  const m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)
1782
1584
 
1783
1585
  result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
@@ -1789,31 +1591,25 @@
1789
1591
  }
1790
1592
 
1791
1593
  }
1792
-
1793
1594
  const _q = new THREE.Quaternion();
1794
-
1795
1595
  class GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant {
1796
1596
 
1797
1597
  interpolate_( i1, t0, t, t1 ) {
1798
1598
 
1799
1599
  const result = super.interpolate_( i1, t0, t, t1 );
1800
-
1801
1600
  _q.fromArray( result ).normalize().toArray( result );
1802
-
1803
1601
  return result;
1804
1602
 
1805
1603
  }
1806
1604
 
1807
1605
  }
1808
- /*********************************/
1809
1606
 
1607
+ /*********************************/
1810
1608
  /********** INTERNALS ************/
1811
-
1812
1609
  /*********************************/
1813
1610
 
1814
1611
  /* CONSTANTS */
1815
1612
 
1816
-
1817
1613
  const WEBGL_CONSTANTS = {
1818
1614
  FLOAT: 5126,
1819
1615
  //FLOAT_MAT2: 35674,
@@ -1893,10 +1689,10 @@
1893
1689
  MASK: 'MASK',
1894
1690
  BLEND: 'BLEND'
1895
1691
  };
1692
+
1896
1693
  /**
1897
1694
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
1898
1695
  */
1899
-
1900
1696
  function createDefaultMaterial( cache ) {
1901
1697
 
1902
1698
  if ( cache[ 'DefaultMaterial' ] === undefined ) {
@@ -1920,6 +1716,7 @@
1920
1716
  function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {
1921
1717
 
1922
1718
  // Add unknown glTF extensions to an object's userData.
1719
+
1923
1720
  for ( const name in objectDef.extensions ) {
1924
1721
 
1925
1722
  if ( knownExtensions[ name ] === undefined ) {
@@ -1932,12 +1729,11 @@
1932
1729
  }
1933
1730
 
1934
1731
  }
1732
+
1935
1733
  /**
1936
1734
  * @param {Object3D|Material|BufferGeometry} object
1937
1735
  * @param {GLTF.definition} gltfDef
1938
1736
  */
1939
-
1940
-
1941
1737
  function assignExtrasToUserData( object, gltfDef ) {
1942
1738
 
1943
1739
  if ( gltfDef.extras !== undefined ) {
@@ -1955,6 +1751,7 @@
1955
1751
  }
1956
1752
 
1957
1753
  }
1754
+
1958
1755
  /**
1959
1756
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
1960
1757
  *
@@ -1963,14 +1760,11 @@
1963
1760
  * @param {GLTFParser} parser
1964
1761
  * @return {Promise<BufferGeometry>}
1965
1762
  */
1966
-
1967
-
1968
1763
  function addMorphTargets( geometry, targets, parser ) {
1969
1764
 
1970
1765
  let hasMorphPosition = false;
1971
1766
  let hasMorphNormal = false;
1972
1767
  let hasMorphColor = false;
1973
-
1974
1768
  for ( let i = 0, il = targets.length; i < il; i ++ ) {
1975
1769
 
1976
1770
  const target = targets[ i ];
@@ -1985,11 +1779,9 @@
1985
1779
  const pendingPositionAccessors = [];
1986
1780
  const pendingNormalAccessors = [];
1987
1781
  const pendingColorAccessors = [];
1988
-
1989
1782
  for ( let i = 0, il = targets.length; i < il; i ++ ) {
1990
1783
 
1991
1784
  const target = targets[ i ];
1992
-
1993
1785
  if ( hasMorphPosition ) {
1994
1786
 
1995
1787
  const pendingAccessor = target.POSITION !== undefined ? parser.getDependency( 'accessor', target.POSITION ) : geometry.attributes.position;
@@ -2027,16 +1819,14 @@
2027
1819
  } );
2028
1820
 
2029
1821
  }
1822
+
2030
1823
  /**
2031
1824
  * @param {Mesh} mesh
2032
1825
  * @param {GLTF.Mesh} meshDef
2033
1826
  */
2034
-
2035
-
2036
1827
  function updateMorphTargets( mesh, meshDef ) {
2037
1828
 
2038
1829
  mesh.updateMorphTargets();
2039
-
2040
1830
  if ( meshDef.weights !== undefined ) {
2041
1831
 
2042
1832
  for ( let i = 0, il = meshDef.weights.length; i < il; i ++ ) {
@@ -2045,17 +1835,15 @@
2045
1835
 
2046
1836
  }
2047
1837
 
2048
- } // .extras has user-defined data, so check that .extras.targetNames is an array.
2049
-
1838
+ }
2050
1839
 
1840
+ // .extras has user-defined data, so check that .extras.targetNames is an array.
2051
1841
  if ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {
2052
1842
 
2053
1843
  const targetNames = meshDef.extras.targetNames;
2054
-
2055
1844
  if ( mesh.morphTargetInfluences.length === targetNames.length ) {
2056
1845
 
2057
1846
  mesh.morphTargetDictionary = {};
2058
-
2059
1847
  for ( let i = 0, il = targetNames.length; i < il; i ++ ) {
2060
1848
 
2061
1849
  mesh.morphTargetDictionary[ targetNames[ i ] ] = i;
@@ -2076,7 +1864,6 @@
2076
1864
 
2077
1865
  const dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];
2078
1866
  let geometryKey;
2079
-
2080
1867
  if ( dracoExtension ) {
2081
1868
 
2082
1869
  geometryKey = 'draco:' + dracoExtension.bufferView + ':' + dracoExtension.indices + ':' + createAttributesKey( dracoExtension.attributes );
@@ -2095,7 +1882,6 @@
2095
1882
 
2096
1883
  let attributesKey = '';
2097
1884
  const keys = Object.keys( attributes ).sort();
2098
-
2099
1885
  for ( let i = 0, il = keys.length; i < il; i ++ ) {
2100
1886
 
2101
1887
  attributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';
@@ -2110,20 +1896,17 @@
2110
1896
 
2111
1897
  // Reference:
2112
1898
  // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data
1899
+
2113
1900
  switch ( constructor ) {
2114
1901
 
2115
1902
  case Int8Array:
2116
1903
  return 1 / 127;
2117
-
2118
1904
  case Uint8Array:
2119
1905
  return 1 / 255;
2120
-
2121
1906
  case Int16Array:
2122
1907
  return 1 / 32767;
2123
-
2124
1908
  case Uint16Array:
2125
1909
  return 1 / 65535;
2126
-
2127
1910
  default:
2128
1911
  throw new Error( 'THREE.GLTFLoader: Unsupported normalized accessor component type.' );
2129
1912
 
@@ -2138,8 +1921,8 @@
2138
1921
  return 'image/png';
2139
1922
 
2140
1923
  }
2141
- /* GLTF PARSER */
2142
1924
 
1925
+ /* GLTF PARSER */
2143
1926
 
2144
1927
  class GLTFParser {
2145
1928
 
@@ -2148,14 +1931,18 @@
2148
1931
  this.json = json;
2149
1932
  this.extensions = {};
2150
1933
  this.plugins = {};
2151
- this.options = options; // loader object cache
1934
+ this.options = options;
2152
1935
 
2153
- this.cache = new GLTFRegistry(); // associations between Three.js objects and glTF elements
1936
+ // loader object cache
1937
+ this.cache = new GLTFRegistry();
2154
1938
 
2155
- this.associations = new Map(); // THREE.BufferGeometry caching
1939
+ // associations between Three.js objects and glTF elements
1940
+ this.associations = new Map();
2156
1941
 
2157
- this.primitiveCache = {}; // THREE.Object3D instance caches
1942
+ // THREE.BufferGeometry caching
1943
+ this.primitiveCache = {};
2158
1944
 
1945
+ // THREE.Object3D instance caches
2159
1946
  this.meshCache = {
2160
1947
  refs: {},
2161
1948
  uses: {}
@@ -2169,14 +1956,24 @@
2169
1956
  uses: {}
2170
1957
  };
2171
1958
  this.sourceCache = {};
2172
- this.textureCache = {}; // Track node names, to ensure no duplicates
1959
+ this.textureCache = {};
2173
1960
 
2174
- this.nodeNamesUsed = {}; // Use an THREE.ImageBitmapLoader if imageBitmaps are supported. Moves much of the
1961
+ // Track node names, to ensure no duplicates
1962
+ this.nodeNamesUsed = {};
1963
+
1964
+ // Use an THREE.ImageBitmapLoader if imageBitmaps are supported. Moves much of the
2175
1965
  // expensive work of uploading a texture to the GPU off the main thread.
2176
1966
 
2177
- const isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true;
2178
- const isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1;
2179
- const firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1;
1967
+ let isSafari = false;
1968
+ let isFirefox = false;
1969
+ let firefoxVersion = - 1;
1970
+ if ( typeof navigator !== 'undefined' ) {
1971
+
1972
+ isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true;
1973
+ isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1;
1974
+ firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1;
1975
+
1976
+ }
2180
1977
 
2181
1978
  if ( typeof createImageBitmap === 'undefined' || isSafari || isFirefox && firefoxVersion < 98 ) {
2182
1979
 
@@ -2192,7 +1989,6 @@
2192
1989
  this.textureLoader.setRequestHeader( this.options.requestHeader );
2193
1990
  this.fileLoader = new THREE.FileLoader( this.options.manager );
2194
1991
  this.fileLoader.setResponseType( 'arraybuffer' );
2195
-
2196
1992
  if ( this.options.crossOrigin === 'use-credentials' ) {
2197
1993
 
2198
1994
  this.fileLoader.setWithCredentials( true );
@@ -2200,33 +1996,31 @@
2200
1996
  }
2201
1997
 
2202
1998
  }
2203
-
2204
1999
  setExtensions( extensions ) {
2205
2000
 
2206
2001
  this.extensions = extensions;
2207
2002
 
2208
2003
  }
2209
-
2210
2004
  setPlugins( plugins ) {
2211
2005
 
2212
2006
  this.plugins = plugins;
2213
2007
 
2214
2008
  }
2215
-
2216
2009
  parse( onLoad, onError ) {
2217
2010
 
2218
2011
  const parser = this;
2219
2012
  const json = this.json;
2220
- const extensions = this.extensions; // Clear the loader cache
2013
+ const extensions = this.extensions;
2221
2014
 
2222
- this.cache.removeAll(); // Mark the special nodes/meshes in json for efficient parse
2015
+ // Clear the loader cache
2016
+ this.cache.removeAll();
2223
2017
 
2018
+ // Mark the special nodes/meshes in json for efficient parse
2224
2019
  this._invokeAll( function ( ext ) {
2225
2020
 
2226
2021
  return ext._markDefs && ext._markDefs();
2227
2022
 
2228
2023
  } );
2229
-
2230
2024
  Promise.all( this._invokeAll( function ( ext ) {
2231
2025
 
2232
2026
  return ext.beforeRoot && ext.beforeRoot();
@@ -2261,43 +2055,41 @@
2261
2055
  } ).catch( onError );
2262
2056
 
2263
2057
  }
2058
+
2264
2059
  /**
2265
2060
  * Marks the special nodes/meshes in json for efficient parse.
2266
2061
  */
2267
-
2268
-
2269
2062
  _markDefs() {
2270
2063
 
2271
2064
  const nodeDefs = this.json.nodes || [];
2272
2065
  const skinDefs = this.json.skins || [];
2273
- const meshDefs = this.json.meshes || []; // Nothing in the node definition indicates whether it is a THREE.Bone or an
2274
- // THREE.Object3D. Use the skins' joint references to mark bones.
2066
+ const meshDefs = this.json.meshes || [];
2275
2067
 
2068
+ // Nothing in the node definition indicates whether it is a THREE.Bone or an
2069
+ // THREE.Object3D. Use the skins' joint references to mark bones.
2276
2070
  for ( let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) {
2277
2071
 
2278
2072
  const joints = skinDefs[ skinIndex ].joints;
2279
-
2280
2073
  for ( let i = 0, il = joints.length; i < il; i ++ ) {
2281
2074
 
2282
2075
  nodeDefs[ joints[ i ] ].isBone = true;
2283
2076
 
2284
2077
  }
2285
2078
 
2286
- } // Iterate over all nodes, marking references to shared resources,
2287
- // as well as skeleton joints.
2288
-
2079
+ }
2289
2080
 
2081
+ // Iterate over all nodes, marking references to shared resources,
2082
+ // as well as skeleton joints.
2290
2083
  for ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {
2291
2084
 
2292
2085
  const nodeDef = nodeDefs[ nodeIndex ];
2293
-
2294
2086
  if ( nodeDef.mesh !== undefined ) {
2295
2087
 
2296
- this._addNodeRef( this.meshCache, nodeDef.mesh ); // Nothing in the mesh definition indicates whether it is
2088
+ this._addNodeRef( this.meshCache, nodeDef.mesh );
2089
+
2090
+ // Nothing in the mesh definition indicates whether it is
2297
2091
  // a THREE.SkinnedMesh or THREE.Mesh. Use the node's mesh reference
2298
2092
  // to mark THREE.SkinnedMesh if node has skin.
2299
-
2300
-
2301
2093
  if ( nodeDef.skin !== undefined ) {
2302
2094
 
2303
2095
  meshDefs[ nodeDef.mesh ].isSkinnedMesh = true;
@@ -2315,6 +2107,7 @@
2315
2107
  }
2316
2108
 
2317
2109
  }
2110
+
2318
2111
  /**
2319
2112
  * Counts references to shared node / THREE.Object3D resources. These resources
2320
2113
  * can be reused, or "instantiated", at multiple nodes in the scene
@@ -2324,12 +2117,9 @@
2324
2117
  *
2325
2118
  * Example: CesiumMilkTruck sample model reuses "Wheel" meshes.
2326
2119
  */
2327
-
2328
-
2329
2120
  _addNodeRef( cache, index ) {
2330
2121
 
2331
2122
  if ( index === undefined ) return;
2332
-
2333
2123
  if ( cache.refs[ index ] === undefined ) {
2334
2124
 
2335
2125
  cache.refs[ index ] = cache.uses[ index ] = 0;
@@ -2339,19 +2129,18 @@
2339
2129
  cache.refs[ index ] ++;
2340
2130
 
2341
2131
  }
2342
- /** Returns a reference to a shared resource, cloning it if necessary. */
2343
-
2344
2132
 
2133
+ /** Returns a reference to a shared resource, cloning it if necessary. */
2345
2134
  _getNodeRef( cache, index, object ) {
2346
2135
 
2347
2136
  if ( cache.refs[ index ] <= 1 ) return object;
2348
- const ref = object.clone(); // Propagates mappings to the cloned object, prevents mappings on the
2349
- // original object from being lost.
2137
+ const ref = object.clone();
2350
2138
 
2139
+ // Propagates mappings to the cloned object, prevents mappings on the
2140
+ // original object from being lost.
2351
2141
  const updateMappings = ( original, clone ) => {
2352
2142
 
2353
2143
  const mappings = this.associations.get( original );
2354
-
2355
2144
  if ( mappings != null ) {
2356
2145
 
2357
2146
  this.associations.set( clone, mappings );
@@ -2371,12 +2160,10 @@
2371
2160
  return ref;
2372
2161
 
2373
2162
  }
2374
-
2375
2163
  _invokeOne( func ) {
2376
2164
 
2377
2165
  const extensions = Object.values( this.plugins );
2378
2166
  extensions.push( this );
2379
-
2380
2167
  for ( let i = 0; i < extensions.length; i ++ ) {
2381
2168
 
2382
2169
  const result = func( extensions[ i ] );
@@ -2387,13 +2174,11 @@
2387
2174
  return null;
2388
2175
 
2389
2176
  }
2390
-
2391
2177
  _invokeAll( func ) {
2392
2178
 
2393
2179
  const extensions = Object.values( this.plugins );
2394
2180
  extensions.unshift( this );
2395
2181
  const pending = [];
2396
-
2397
2182
  for ( let i = 0; i < extensions.length; i ++ ) {
2398
2183
 
2399
2184
  const result = func( extensions[ i ] );
@@ -2404,19 +2189,17 @@
2404
2189
  return pending;
2405
2190
 
2406
2191
  }
2192
+
2407
2193
  /**
2408
2194
  * Requests the specified dependency asynchronously, with caching.
2409
2195
  * @param {string} type
2410
2196
  * @param {number} index
2411
2197
  * @return {Promise<Object3D|Material|THREE.Texture|AnimationClip|ArrayBuffer|Object>}
2412
2198
  */
2413
-
2414
-
2415
2199
  getDependency( type, index ) {
2416
2200
 
2417
2201
  const cacheKey = type + ':' + index;
2418
2202
  let dependency = this.cache.get( cacheKey );
2419
-
2420
2203
  if ( ! dependency ) {
2421
2204
 
2422
2205
  switch ( type ) {
@@ -2424,11 +2207,9 @@
2424
2207
  case 'scene':
2425
2208
  dependency = this.loadScene( index );
2426
2209
  break;
2427
-
2428
2210
  case 'node':
2429
2211
  dependency = this.loadNode( index );
2430
2212
  break;
2431
-
2432
2213
  case 'mesh':
2433
2214
  dependency = this._invokeOne( function ( ext ) {
2434
2215
 
@@ -2436,11 +2217,9 @@
2436
2217
 
2437
2218
  } );
2438
2219
  break;
2439
-
2440
2220
  case 'accessor':
2441
2221
  dependency = this.loadAccessor( index );
2442
2222
  break;
2443
-
2444
2223
  case 'bufferView':
2445
2224
  dependency = this._invokeOne( function ( ext ) {
2446
2225
 
@@ -2448,11 +2227,9 @@
2448
2227
 
2449
2228
  } );
2450
2229
  break;
2451
-
2452
2230
  case 'buffer':
2453
2231
  dependency = this.loadBuffer( index );
2454
2232
  break;
2455
-
2456
2233
  case 'material':
2457
2234
  dependency = this._invokeOne( function ( ext ) {
2458
2235
 
@@ -2460,7 +2237,6 @@
2460
2237
 
2461
2238
  } );
2462
2239
  break;
2463
-
2464
2240
  case 'texture':
2465
2241
  dependency = this._invokeOne( function ( ext ) {
2466
2242
 
@@ -2468,11 +2244,9 @@
2468
2244
 
2469
2245
  } );
2470
2246
  break;
2471
-
2472
2247
  case 'skin':
2473
2248
  dependency = this.loadSkin( index );
2474
2249
  break;
2475
-
2476
2250
  case 'animation':
2477
2251
  dependency = this._invokeOne( function ( ext ) {
2478
2252
 
@@ -2480,13 +2254,22 @@
2480
2254
 
2481
2255
  } );
2482
2256
  break;
2483
-
2484
2257
  case 'camera':
2485
2258
  dependency = this.loadCamera( index );
2486
2259
  break;
2487
-
2488
2260
  default:
2489
- throw new Error( 'Unknown type: ' + type );
2261
+ dependency = this._invokeOne( function ( ext ) {
2262
+
2263
+ return ext != this && ext.getDependency && ext.getDependency( type, index );
2264
+
2265
+ } );
2266
+ if ( ! dependency ) {
2267
+
2268
+ throw new Error( 'Unknown type: ' + type );
2269
+
2270
+ }
2271
+
2272
+ break;
2490
2273
 
2491
2274
  }
2492
2275
 
@@ -2497,17 +2280,15 @@
2497
2280
  return dependency;
2498
2281
 
2499
2282
  }
2283
+
2500
2284
  /**
2501
2285
  * Requests all dependencies of the specified type asynchronously, with caching.
2502
2286
  * @param {string} type
2503
2287
  * @return {Promise<Array<Object>>}
2504
2288
  */
2505
-
2506
-
2507
2289
  getDependencies( type ) {
2508
2290
 
2509
2291
  let dependencies = this.cache.get( type );
2510
-
2511
2292
  if ( ! dependencies ) {
2512
2293
 
2513
2294
  const parser = this;
@@ -2524,25 +2305,23 @@
2524
2305
  return dependencies;
2525
2306
 
2526
2307
  }
2308
+
2527
2309
  /**
2528
2310
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
2529
2311
  * @param {number} bufferIndex
2530
2312
  * @return {Promise<ArrayBuffer>}
2531
2313
  */
2532
-
2533
-
2534
2314
  loadBuffer( bufferIndex ) {
2535
2315
 
2536
2316
  const bufferDef = this.json.buffers[ bufferIndex ];
2537
2317
  const loader = this.fileLoader;
2538
-
2539
2318
  if ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) {
2540
2319
 
2541
2320
  throw new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' );
2542
2321
 
2543
- } // If present, GLB container is required to be the first buffer.
2544
-
2322
+ }
2545
2323
 
2324
+ // If present, GLB container is required to be the first buffer.
2546
2325
  if ( bufferDef.uri === undefined && bufferIndex === 0 ) {
2547
2326
 
2548
2327
  return Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body );
@@ -2561,13 +2340,12 @@
2561
2340
  } );
2562
2341
 
2563
2342
  }
2343
+
2564
2344
  /**
2565
2345
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
2566
2346
  * @param {number} bufferViewIndex
2567
2347
  * @return {Promise<ArrayBuffer>}
2568
2348
  */
2569
-
2570
-
2571
2349
  loadBufferView( bufferViewIndex ) {
2572
2350
 
2573
2351
  const bufferViewDef = this.json.bufferViews[ bufferViewIndex ];
@@ -2580,30 +2358,28 @@
2580
2358
  } );
2581
2359
 
2582
2360
  }
2361
+
2583
2362
  /**
2584
2363
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors
2585
2364
  * @param {number} accessorIndex
2586
2365
  * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}
2587
2366
  */
2588
-
2589
-
2590
2367
  loadAccessor( accessorIndex ) {
2591
2368
 
2592
2369
  const parser = this;
2593
2370
  const json = this.json;
2594
2371
  const accessorDef = this.json.accessors[ accessorIndex ];
2595
-
2596
2372
  if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {
2597
2373
 
2598
- // Ignore empty accessors, which may be used to declare runtime
2599
- // information about attributes coming from another source (e.g. Draco
2600
- // compression extension).
2601
- return Promise.resolve( null );
2374
+ const itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];
2375
+ const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
2376
+ const normalized = accessorDef.normalized === true;
2377
+ const array = new TypedArray( accessorDef.count * itemSize );
2378
+ return Promise.resolve( new THREE.BufferAttribute( array, itemSize, normalized ) );
2602
2379
 
2603
2380
  }
2604
2381
 
2605
2382
  const pendingBufferViews = [];
2606
-
2607
2383
  if ( accessorDef.bufferView !== undefined ) {
2608
2384
 
2609
2385
  pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) );
@@ -2625,15 +2401,17 @@
2625
2401
 
2626
2402
  const bufferView = bufferViews[ 0 ];
2627
2403
  const itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];
2628
- const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
2404
+ const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
2629
2405
 
2406
+ // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
2630
2407
  const elementBytes = TypedArray.BYTES_PER_ELEMENT;
2631
2408
  const itemBytes = elementBytes * itemSize;
2632
2409
  const byteOffset = accessorDef.byteOffset || 0;
2633
2410
  const byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined;
2634
2411
  const normalized = accessorDef.normalized === true;
2635
- let array, bufferAttribute; // The buffer is not interleaved if the stride is the item size in bytes.
2412
+ let array, bufferAttribute;
2636
2413
 
2414
+ // The buffer is not interleaved if the stride is the item size in bytes.
2637
2415
  if ( byteStride && byteStride !== itemBytes ) {
2638
2416
 
2639
2417
  // Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own THREE.InterleavedBuffer
@@ -2641,11 +2419,11 @@
2641
2419
  const ibSlice = Math.floor( byteOffset / byteStride );
2642
2420
  const ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;
2643
2421
  let ib = parser.cache.get( ibCacheKey );
2644
-
2645
2422
  if ( ! ib ) {
2646
2423
 
2647
- array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes ); // Integer parameters to IB/IBA are in array elements, not bytes.
2424
+ array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );
2648
2425
 
2426
+ // Integer parameters to IB/IBA are in array elements, not bytes.
2649
2427
  ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes );
2650
2428
  parser.cache.add( ibCacheKey, ib );
2651
2429
 
@@ -2667,9 +2445,9 @@
2667
2445
 
2668
2446
  bufferAttribute = new THREE.BufferAttribute( array, itemSize, normalized );
2669
2447
 
2670
- } // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors
2671
-
2448
+ }
2672
2449
 
2450
+ // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors
2673
2451
  if ( accessorDef.sparse !== undefined ) {
2674
2452
 
2675
2453
  const itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;
@@ -2678,7 +2456,6 @@
2678
2456
  const byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;
2679
2457
  const sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices );
2680
2458
  const sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize );
2681
-
2682
2459
  if ( bufferView !== null ) {
2683
2460
 
2684
2461
  // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.
@@ -2704,13 +2481,12 @@
2704
2481
  } );
2705
2482
 
2706
2483
  }
2484
+
2707
2485
  /**
2708
2486
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
2709
2487
  * @param {number} textureIndex
2710
- * @return {Promise<THREE.Texture>}
2488
+ * @return {Promise<THREE.Texture|null>}
2711
2489
  */
2712
-
2713
-
2714
2490
  loadTexture( textureIndex ) {
2715
2491
 
2716
2492
  const json = this.json;
@@ -2719,7 +2495,6 @@
2719
2495
  const sourceIndex = textureDef.source;
2720
2496
  const sourceDef = json.images[ sourceIndex ];
2721
2497
  let loader = this.textureLoader;
2722
-
2723
2498
  if ( sourceDef.uri ) {
2724
2499
 
2725
2500
  const handler = options.manager.getHandler( sourceDef.uri );
@@ -2730,7 +2505,6 @@
2730
2505
  return this.loadTextureImage( textureIndex, sourceIndex, loader );
2731
2506
 
2732
2507
  }
2733
-
2734
2508
  loadTextureImage( textureIndex, sourceIndex, loader ) {
2735
2509
 
2736
2510
  const parser = this;
@@ -2738,7 +2512,6 @@
2738
2512
  const textureDef = json.textures[ textureIndex ];
2739
2513
  const sourceDef = json.images[ sourceIndex ];
2740
2514
  const cacheKey = ( sourceDef.uri || sourceDef.bufferView ) + ':' + textureDef.sampler;
2741
-
2742
2515
  if ( this.textureCache[ cacheKey ] ) {
2743
2516
 
2744
2517
  // See https://github.com/mrdoob/three.js/issues/21559.
@@ -2749,7 +2522,7 @@
2749
2522
  const promise = this.loadImageSource( sourceIndex, loader ).then( function ( texture ) {
2750
2523
 
2751
2524
  texture.flipY = false;
2752
- if ( textureDef.name ) texture.name = textureDef.name;
2525
+ texture.name = textureDef.name || sourceDef.name || '';
2753
2526
  const samplers = json.samplers || {};
2754
2527
  const sampler = samplers[ textureDef.sampler ] || {};
2755
2528
  texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter;
@@ -2770,13 +2543,11 @@
2770
2543
  return promise;
2771
2544
 
2772
2545
  }
2773
-
2774
2546
  loadImageSource( sourceIndex, loader ) {
2775
2547
 
2776
2548
  const parser = this;
2777
2549
  const json = this.json;
2778
2550
  const options = this.options;
2779
-
2780
2551
  if ( this.sourceCache[ sourceIndex ] !== undefined ) {
2781
2552
 
2782
2553
  return this.sourceCache[ sourceIndex ].then( texture => texture.clone() );
@@ -2787,10 +2558,10 @@
2787
2558
  const URL = self.URL || self.webkitURL;
2788
2559
  let sourceURI = sourceDef.uri || '';
2789
2560
  let isObjectURL = false;
2790
-
2791
2561
  if ( sourceDef.bufferView !== undefined ) {
2792
2562
 
2793
2563
  // Load binary image data from bufferView, if provided.
2564
+
2794
2565
  sourceURI = parser.getDependency( 'bufferView', sourceDef.bufferView ).then( function ( bufferView ) {
2795
2566
 
2796
2567
  isObjectURL = true;
@@ -2813,7 +2584,6 @@
2813
2584
  return new Promise( function ( resolve, reject ) {
2814
2585
 
2815
2586
  let onLoad = resolve;
2816
-
2817
2587
  if ( loader.isImageBitmapLoader === true ) {
2818
2588
 
2819
2589
  onLoad = function ( imageBitmap ) {
@@ -2833,6 +2603,7 @@
2833
2603
  } ).then( function ( texture ) {
2834
2604
 
2835
2605
  // Clean up resources and configure THREE.Texture.
2606
+
2836
2607
  if ( isObjectURL === true ) {
2837
2608
 
2838
2609
  URL.revokeObjectURL( sourceURI );
@@ -2852,6 +2623,7 @@
2852
2623
  return promise;
2853
2624
 
2854
2625
  }
2626
+
2855
2627
  /**
2856
2628
  * Asynchronously assigns a texture to the given material parameters.
2857
2629
  * @param {Object} materialParams
@@ -2859,13 +2631,13 @@
2859
2631
  * @param {Object} mapDef
2860
2632
  * @return {Promise<Texture>}
2861
2633
  */
2862
-
2863
-
2864
2634
  assignTexture( materialParams, mapName, mapDef, encoding ) {
2865
2635
 
2866
2636
  const parser = this;
2867
2637
  return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
2868
2638
 
2639
+ if ( ! texture ) return null;
2640
+
2869
2641
  // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured
2870
2642
  // However, we will copy UV set 0 to UV set 1 on demand for aoMap
2871
2643
  if ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) {
@@ -2877,7 +2649,6 @@
2877
2649
  if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {
2878
2650
 
2879
2651
  const transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;
2880
-
2881
2652
  if ( transform ) {
2882
2653
 
2883
2654
  const gltfReference = parser.associations.get( texture );
@@ -2900,6 +2671,7 @@
2900
2671
  } );
2901
2672
 
2902
2673
  }
2674
+
2903
2675
  /**
2904
2676
  * Assigns final material to a THREE.Mesh, THREE.Line, or THREE.Points instance. The instance
2905
2677
  * already has a material (generated from the glTF material options alone)
@@ -2908,8 +2680,6 @@
2908
2680
  * be created if necessary, and reused from a cache.
2909
2681
  * @param {Object3D} mesh THREE.Mesh, THREE.Line, or THREE.Points instance.
2910
2682
  */
2911
-
2912
-
2913
2683
  assignFinalMaterial( mesh ) {
2914
2684
 
2915
2685
  const geometry = mesh.geometry;
@@ -2917,12 +2687,10 @@
2917
2687
  const useDerivativeTangents = geometry.attributes.tangent === undefined;
2918
2688
  const useVertexColors = geometry.attributes.color !== undefined;
2919
2689
  const useFlatShading = geometry.attributes.normal === undefined;
2920
-
2921
2690
  if ( mesh.isPoints ) {
2922
2691
 
2923
2692
  const cacheKey = 'PointsMaterial:' + material.uuid;
2924
2693
  let pointsMaterial = this.cache.get( cacheKey );
2925
-
2926
2694
  if ( ! pointsMaterial ) {
2927
2695
 
2928
2696
  pointsMaterial = new THREE.PointsMaterial();
@@ -2941,7 +2709,6 @@
2941
2709
 
2942
2710
  const cacheKey = 'LineBasicMaterial:' + material.uuid;
2943
2711
  let lineMaterial = this.cache.get( cacheKey );
2944
-
2945
2712
  if ( ! lineMaterial ) {
2946
2713
 
2947
2714
  lineMaterial = new THREE.LineBasicMaterial();
@@ -2953,24 +2720,21 @@
2953
2720
 
2954
2721
  material = lineMaterial;
2955
2722
 
2956
- } // Clone the material if it will be modified
2957
-
2723
+ }
2958
2724
 
2725
+ // Clone the material if it will be modified
2959
2726
  if ( useDerivativeTangents || useVertexColors || useFlatShading ) {
2960
2727
 
2961
2728
  let cacheKey = 'ClonedMaterial:' + material.uuid + ':';
2962
- if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
2963
2729
  if ( useDerivativeTangents ) cacheKey += 'derivative-tangents:';
2964
2730
  if ( useVertexColors ) cacheKey += 'vertex-colors:';
2965
2731
  if ( useFlatShading ) cacheKey += 'flat-shading:';
2966
2732
  let cachedMaterial = this.cache.get( cacheKey );
2967
-
2968
2733
  if ( ! cachedMaterial ) {
2969
2734
 
2970
2735
  cachedMaterial = material.clone();
2971
2736
  if ( useVertexColors ) cachedMaterial.vertexColors = true;
2972
2737
  if ( useFlatShading ) cachedMaterial.flatShading = true;
2973
-
2974
2738
  if ( useDerivativeTangents ) {
2975
2739
 
2976
2740
  // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
@@ -2986,8 +2750,9 @@
2986
2750
 
2987
2751
  material = cachedMaterial;
2988
2752
 
2989
- } // workarounds for mesh and geometry
2753
+ }
2990
2754
 
2755
+ // workarounds for mesh and geometry
2991
2756
 
2992
2757
  if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
2993
2758
 
@@ -2998,19 +2763,17 @@
2998
2763
  mesh.material = material;
2999
2764
 
3000
2765
  }
3001
-
3002
2766
  getMaterialType() {
3003
2767
 
3004
2768
  return THREE.MeshStandardMaterial;
3005
2769
 
3006
2770
  }
2771
+
3007
2772
  /**
3008
2773
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
3009
2774
  * @param {number} materialIndex
3010
2775
  * @return {Promise<Material>}
3011
2776
  */
3012
-
3013
-
3014
2777
  loadMaterial( materialIndex ) {
3015
2778
 
3016
2779
  const parser = this;
@@ -3021,14 +2784,7 @@
3021
2784
  const materialParams = {};
3022
2785
  const materialExtensions = materialDef.extensions || {};
3023
2786
  const pending = [];
3024
-
3025
- if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) {
3026
-
3027
- const sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ];
3028
- materialType = sgExtension.getMaterialType();
3029
- pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) );
3030
-
3031
- } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {
2787
+ if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {
3032
2788
 
3033
2789
  const kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];
3034
2790
  materialType = kmuExtension.getMaterialType();
@@ -3038,10 +2794,10 @@
3038
2794
 
3039
2795
  // Specification:
3040
2796
  // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
2797
+
3041
2798
  const metallicRoughness = materialDef.pbrMetallicRoughness || {};
3042
2799
  materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
3043
2800
  materialParams.opacity = 1.0;
3044
-
3045
2801
  if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {
3046
2802
 
3047
2803
  const array = metallicRoughness.baseColorFactor;
@@ -3058,7 +2814,6 @@
3058
2814
 
3059
2815
  materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
3060
2816
  materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;
3061
-
3062
2817
  if ( metallicRoughness.metallicRoughnessTexture !== undefined ) {
3063
2818
 
3064
2819
  pending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );
@@ -3086,17 +2841,16 @@
3086
2841
  }
3087
2842
 
3088
2843
  const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;
3089
-
3090
2844
  if ( alphaMode === ALPHA_MODES.BLEND ) {
3091
2845
 
3092
- materialParams.transparent = true; // See: https://github.com/mrdoob/three.js/issues/17706
2846
+ materialParams.transparent = true;
3093
2847
 
2848
+ // See: https://github.com/mrdoob/three.js/issues/17706
3094
2849
  materialParams.depthWrite = false;
3095
2850
 
3096
2851
  } else {
3097
2852
 
3098
2853
  materialParams.transparent = false;
3099
-
3100
2854
  if ( alphaMode === ALPHA_MODES.MASK ) {
3101
2855
 
3102
2856
  materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;
@@ -3109,7 +2863,6 @@
3109
2863
 
3110
2864
  pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) );
3111
2865
  materialParams.normalScale = new THREE.Vector2( 1, 1 );
3112
-
3113
2866
  if ( materialDef.normalTexture.scale !== undefined ) {
3114
2867
 
3115
2868
  const scale = materialDef.normalTexture.scale;
@@ -3122,7 +2875,6 @@
3122
2875
  if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
3123
2876
 
3124
2877
  pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );
3125
-
3126
2878
  if ( materialDef.occlusionTexture.strength !== undefined ) {
3127
2879
 
3128
2880
  materialParams.aoMapIntensity = materialDef.occlusionTexture.strength;
@@ -3145,18 +2897,7 @@
3145
2897
 
3146
2898
  return Promise.all( pending ).then( function () {
3147
2899
 
3148
- let material;
3149
-
3150
- if ( materialType === GLTFMeshStandardSGMaterial ) {
3151
-
3152
- material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams );
3153
-
3154
- } else {
3155
-
3156
- material = new materialType( materialParams );
3157
-
3158
- }
3159
-
2900
+ const material = new materialType( materialParams );
3160
2901
  if ( materialDef.name ) material.name = materialDef.name;
3161
2902
  assignExtrasToUserData( material, materialDef );
3162
2903
  parser.associations.set( material, {
@@ -3168,14 +2909,12 @@
3168
2909
  } );
3169
2910
 
3170
2911
  }
3171
- /** When THREE.Object3D instances are targeted by animation, they need unique names. */
3172
-
3173
2912
 
2913
+ /** When THREE.Object3D instances are targeted by animation, they need unique names. */
3174
2914
  createUniqueName( originalName ) {
3175
2915
 
3176
2916
  const sanitizedName = THREE.PropertyBinding.sanitizeNodeName( originalName || '' );
3177
2917
  let name = sanitizedName;
3178
-
3179
2918
  for ( let i = 1; this.nodeNamesUsed[ name ]; ++ i ) {
3180
2919
 
3181
2920
  name = sanitizedName + '_' + i;
@@ -3186,6 +2925,7 @@
3186
2925
  return name;
3187
2926
 
3188
2927
  }
2928
+
3189
2929
  /**
3190
2930
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
3191
2931
  *
@@ -3194,14 +2934,11 @@
3194
2934
  * @param {Array<GLTF.Primitive>} primitives
3195
2935
  * @return {Promise<Array<BufferGeometry>>}
3196
2936
  */
3197
-
3198
-
3199
2937
  loadGeometries( primitives ) {
3200
2938
 
3201
2939
  const parser = this;
3202
2940
  const extensions = this.extensions;
3203
2941
  const cache = this.primitiveCache;
3204
-
3205
2942
  function createDracoPrimitive( primitive ) {
3206
2943
 
3207
2944
  return extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ].decodePrimitive( primitive, parser ).then( function ( geometry ) {
@@ -3213,14 +2950,13 @@
3213
2950
  }
3214
2951
 
3215
2952
  const pending = [];
3216
-
3217
2953
  for ( let i = 0, il = primitives.length; i < il; i ++ ) {
3218
2954
 
3219
2955
  const primitive = primitives[ i ];
3220
- const cacheKey = createPrimitiveKey( primitive ); // See if we've already created this geometry
2956
+ const cacheKey = createPrimitiveKey( primitive );
3221
2957
 
2958
+ // See if we've already created this geometry
3222
2959
  const cached = cache[ cacheKey ];
3223
-
3224
2960
  if ( cached ) {
3225
2961
 
3226
2962
  // Use the cached geometry if it exists
@@ -3229,7 +2965,6 @@
3229
2965
  } else {
3230
2966
 
3231
2967
  let geometryPromise;
3232
-
3233
2968
  if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) {
3234
2969
 
3235
2970
  // Use DRACO geometry if available
@@ -3240,9 +2975,9 @@
3240
2975
  // Otherwise create a new geometry
3241
2976
  geometryPromise = addPrimitiveAttributes( new THREE.BufferGeometry(), primitive, parser );
3242
2977
 
3243
- } // Cache this geometry
3244
-
2978
+ }
3245
2979
 
2980
+ // Cache this geometry
3246
2981
  cache[ cacheKey ] = {
3247
2982
  primitive: primitive,
3248
2983
  promise: geometryPromise
@@ -3256,13 +2991,12 @@
3256
2991
  return Promise.all( pending );
3257
2992
 
3258
2993
  }
2994
+
3259
2995
  /**
3260
2996
  * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes
3261
2997
  * @param {number} meshIndex
3262
2998
  * @return {Promise<Group|Mesh|SkinnedMesh>}
3263
2999
  */
3264
-
3265
-
3266
3000
  loadMesh( meshIndex ) {
3267
3001
 
3268
3002
  const parser = this;
@@ -3271,7 +3005,6 @@
3271
3005
  const meshDef = json.meshes[ meshIndex ];
3272
3006
  const primitives = meshDef.primitives;
3273
3007
  const pending = [];
3274
-
3275
3008
  for ( let i = 0, il = primitives.length; i < il; i ++ ) {
3276
3009
 
3277
3010
  const material = primitives[ i ].material === undefined ? createDefaultMaterial( this.cache ) : this.getDependency( 'material', primitives[ i ].material );
@@ -3285,20 +3018,19 @@
3285
3018
  const materials = results.slice( 0, results.length - 1 );
3286
3019
  const geometries = results[ results.length - 1 ];
3287
3020
  const meshes = [];
3288
-
3289
3021
  for ( let i = 0, il = geometries.length; i < il; i ++ ) {
3290
3022
 
3291
3023
  const geometry = geometries[ i ];
3292
- const primitive = primitives[ i ]; // 1. create THREE.Mesh
3024
+ const primitive = primitives[ i ];
3025
+
3026
+ // 1. create THREE.Mesh
3293
3027
 
3294
3028
  let mesh;
3295
3029
  const material = materials[ i ];
3296
-
3297
3030
  if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || primitive.mode === undefined ) {
3298
3031
 
3299
3032
  // .isSkinnedMesh isn't in glTF spec. See ._markDefs()
3300
3033
  mesh = meshDef.isSkinnedMesh === true ? new THREE.SkinnedMesh( geometry, material ) : new THREE.Mesh( geometry, material );
3301
-
3302
3034
  if ( mesh.isSkinnedMesh === true && ! mesh.geometry.attributes.skinWeight.normalized ) {
3303
3035
 
3304
3036
  // we normalize floating point skin weight array to fix malformed assets (see #15319)
@@ -3372,7 +3104,6 @@
3372
3104
  parser.associations.set( group, {
3373
3105
  meshes: meshIndex
3374
3106
  } );
3375
-
3376
3107
  for ( let i = 0, il = meshes.length; i < il; i ++ ) {
3377
3108
 
3378
3109
  group.add( meshes[ i ] );
@@ -3384,19 +3115,17 @@
3384
3115
  } );
3385
3116
 
3386
3117
  }
3118
+
3387
3119
  /**
3388
3120
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
3389
3121
  * @param {number} cameraIndex
3390
3122
  * @return {Promise<THREE.Camera>}
3391
3123
  */
3392
-
3393
-
3394
3124
  loadCamera( cameraIndex ) {
3395
3125
 
3396
3126
  let camera;
3397
3127
  const cameraDef = this.json.cameras[ cameraIndex ];
3398
3128
  const params = cameraDef[ cameraDef.type ];
3399
-
3400
3129
  if ( ! params ) {
3401
3130
 
3402
3131
  console.warn( 'THREE.GLTFLoader: Missing camera parameters.' );
@@ -3419,41 +3148,72 @@
3419
3148
  return Promise.resolve( camera );
3420
3149
 
3421
3150
  }
3151
+
3422
3152
  /**
3423
3153
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
3424
3154
  * @param {number} skinIndex
3425
- * @return {Promise<Object>}
3155
+ * @return {Promise<Skeleton>}
3426
3156
  */
3427
-
3428
-
3429
3157
  loadSkin( skinIndex ) {
3430
3158
 
3431
3159
  const skinDef = this.json.skins[ skinIndex ];
3432
- const skinEntry = {
3433
- joints: skinDef.joints
3434
- };
3160
+ const pending = [];
3161
+ for ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) {
3162
+
3163
+ pending.push( this.getDependency( 'node', skinDef.joints[ i ] ) );
3164
+
3165
+ }
3435
3166
 
3436
- if ( skinDef.inverseBindMatrices === undefined ) {
3167
+ if ( skinDef.inverseBindMatrices !== undefined ) {
3437
3168
 
3438
- return Promise.resolve( skinEntry );
3169
+ pending.push( this.getDependency( 'accessor', skinDef.inverseBindMatrices ) );
3170
+
3171
+ } else {
3172
+
3173
+ pending.push( null );
3439
3174
 
3440
3175
  }
3441
3176
 
3442
- return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) {
3177
+ return Promise.all( pending ).then( function ( results ) {
3178
+
3179
+ const inverseBindMatrices = results.pop();
3180
+ const jointNodes = results;
3181
+ const bones = [];
3182
+ const boneInverses = [];
3183
+ for ( let i = 0, il = jointNodes.length; i < il; i ++ ) {
3184
+
3185
+ const jointNode = jointNodes[ i ];
3186
+ if ( jointNode ) {
3187
+
3188
+ bones.push( jointNode );
3189
+ const mat = new THREE.Matrix4();
3190
+ if ( inverseBindMatrices !== null ) {
3191
+
3192
+ mat.fromArray( inverseBindMatrices.array, i * 16 );
3193
+
3194
+ }
3195
+
3196
+ boneInverses.push( mat );
3197
+
3198
+ } else {
3199
+
3200
+ console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinDef.joints[ i ] );
3201
+
3202
+ }
3443
3203
 
3444
- skinEntry.inverseBindMatrices = accessor;
3445
- return skinEntry;
3204
+ }
3205
+
3206
+ return new THREE.Skeleton( bones, boneInverses );
3446
3207
 
3447
3208
  } );
3448
3209
 
3449
3210
  }
3211
+
3450
3212
  /**
3451
3213
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
3452
3214
  * @param {number} animationIndex
3453
3215
  * @return {Promise<AnimationClip>}
3454
3216
  */
3455
-
3456
-
3457
3217
  loadAnimation( animationIndex ) {
3458
3218
 
3459
3219
  const json = this.json;
@@ -3463,7 +3223,6 @@
3463
3223
  const pendingOutputAccessors = [];
3464
3224
  const pendingSamplers = [];
3465
3225
  const pendingTargets = [];
3466
-
3467
3226
  for ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) {
3468
3227
 
3469
3228
  const channel = animationDef.channels[ i ];
@@ -3488,7 +3247,6 @@
3488
3247
  const samplers = dependencies[ 3 ];
3489
3248
  const targets = dependencies[ 4 ];
3490
3249
  const tracks = [];
3491
-
3492
3250
  for ( let i = 0, il = nodes.length; i < il; i ++ ) {
3493
3251
 
3494
3252
  const node = nodes[ i ];
@@ -3499,17 +3257,14 @@
3499
3257
  if ( node === undefined ) continue;
3500
3258
  node.updateMatrix();
3501
3259
  let TypedKeyframeTrack;
3502
-
3503
3260
  switch ( PATH_PROPERTIES[ target.path ] ) {
3504
3261
 
3505
3262
  case PATH_PROPERTIES.weights:
3506
3263
  TypedKeyframeTrack = THREE.NumberKeyframeTrack;
3507
3264
  break;
3508
-
3509
3265
  case PATH_PROPERTIES.rotation:
3510
3266
  TypedKeyframeTrack = THREE.QuaternionKeyframeTrack;
3511
3267
  break;
3512
-
3513
3268
  case PATH_PROPERTIES.position:
3514
3269
  case PATH_PROPERTIES.scale:
3515
3270
  default:
@@ -3521,7 +3276,6 @@
3521
3276
  const targetName = node.name ? node.name : node.uuid;
3522
3277
  const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear;
3523
3278
  const targetNames = [];
3524
-
3525
3279
  if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {
3526
3280
 
3527
3281
  node.traverse( function ( object ) {
@@ -3541,12 +3295,10 @@
3541
3295
  }
3542
3296
 
3543
3297
  let outputArray = outputAccessor.array;
3544
-
3545
3298
  if ( outputAccessor.normalized ) {
3546
3299
 
3547
3300
  const scale = getNormalizedComponentScale( outputArray.constructor );
3548
3301
  const scaled = new Float32Array( outputArray.length );
3549
-
3550
3302
  for ( let j = 0, jl = outputArray.length; j < jl; j ++ ) {
3551
3303
 
3552
3304
  scaled[ j ] = outputArray[ j ] * scale;
@@ -3559,8 +3311,9 @@
3559
3311
 
3560
3312
  for ( let j = 0, jl = targetNames.length; j < jl; j ++ ) {
3561
3313
 
3562
- const track = new TypedKeyframeTrack( targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], inputAccessor.array, outputArray, interpolation ); // Override interpolation with custom factory method.
3314
+ const track = new TypedKeyframeTrack( targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], inputAccessor.array, outputArray, interpolation );
3563
3315
 
3316
+ // Override interpolation with custom factory method.
3564
3317
  if ( sampler.interpolation === 'CUBICSPLINE' ) {
3565
3318
 
3566
3319
  track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {
@@ -3568,12 +3321,13 @@
3568
3321
  // A CUBICSPLINE keyframe in glTF has three output values for each input value,
3569
3322
  // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()
3570
3323
  // must be divided by three to get the interpolant's sampleSize argument.
3324
+
3571
3325
  const interpolantType = this instanceof THREE.QuaternionKeyframeTrack ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;
3572
3326
  return new interpolantType( this.times, this.values, this.getValueSize() / 3, result );
3573
3327
 
3574
- }; // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
3575
-
3328
+ };
3576
3329
 
3330
+ // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
3577
3331
  track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
3578
3332
 
3579
3333
  }
@@ -3590,7 +3344,6 @@
3590
3344
  } );
3591
3345
 
3592
3346
  }
3593
-
3594
3347
  createNodeMesh( nodeIndex ) {
3595
3348
 
3596
3349
  const json = this.json;
@@ -3599,15 +3352,14 @@
3599
3352
  if ( nodeDef.mesh === undefined ) return null;
3600
3353
  return parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
3601
3354
 
3602
- const node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh ); // if weights are provided on the node, override weights on the mesh.
3603
-
3355
+ const node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh );
3604
3356
 
3357
+ // if weights are provided on the node, override weights on the mesh.
3605
3358
  if ( nodeDef.weights !== undefined ) {
3606
3359
 
3607
3360
  node.traverse( function ( o ) {
3608
3361
 
3609
3362
  if ( ! o.isMesh ) return;
3610
-
3611
3363
  for ( let i = 0, il = nodeDef.weights.length; i < il; i ++ ) {
3612
3364
 
3613
3365
  o.morphTargetInfluences[ i ] = nodeDef.weights[ i ];
@@ -3623,31 +3375,29 @@
3623
3375
  } );
3624
3376
 
3625
3377
  }
3378
+
3626
3379
  /**
3627
3380
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy
3628
3381
  * @param {number} nodeIndex
3629
3382
  * @return {Promise<Object3D>}
3630
3383
  */
3631
-
3632
-
3633
3384
  loadNode( nodeIndex ) {
3634
3385
 
3635
3386
  const json = this.json;
3636
3387
  const extensions = this.extensions;
3637
3388
  const parser = this;
3638
- const nodeDef = json.nodes[ nodeIndex ]; // reserve node's name before its dependencies, so the root has the intended name.
3389
+ const nodeDef = json.nodes[ nodeIndex ];
3639
3390
 
3391
+ // reserve node's name before its dependencies, so the root has the intended name.
3640
3392
  const nodeName = nodeDef.name ? parser.createUniqueName( nodeDef.name ) : '';
3641
3393
  return function () {
3642
3394
 
3643
3395
  const pending = [];
3644
-
3645
3396
  const meshPromise = parser._invokeOne( function ( ext ) {
3646
3397
 
3647
3398
  return ext.createNodeMesh && ext.createNodeMesh( nodeIndex );
3648
3399
 
3649
3400
  } );
3650
-
3651
3401
  if ( meshPromise ) {
3652
3402
 
3653
3403
  pending.push( meshPromise );
@@ -3673,13 +3423,13 @@
3673
3423
  pending.push( promise );
3674
3424
 
3675
3425
  } );
3676
-
3677
3426
  return Promise.all( pending );
3678
3427
 
3679
3428
  }().then( function ( objects ) {
3680
3429
 
3681
- let node; // .isBone isn't in glTF spec. See ._markDefs
3430
+ let node;
3682
3431
 
3432
+ // .isBone isn't in glTF spec. See ._markDefs
3683
3433
  if ( nodeDef.isBone === true ) {
3684
3434
 
3685
3435
  node = new THREE.Bone();
@@ -3717,7 +3467,6 @@
3717
3467
 
3718
3468
  assignExtrasToUserData( node, nodeDef );
3719
3469
  if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );
3720
-
3721
3470
  if ( nodeDef.matrix !== undefined ) {
3722
3471
 
3723
3472
  const matrix = new THREE.Matrix4();
@@ -3758,28 +3507,27 @@
3758
3507
  } );
3759
3508
 
3760
3509
  }
3510
+
3761
3511
  /**
3762
3512
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes
3763
3513
  * @param {number} sceneIndex
3764
3514
  * @return {Promise<Group>}
3765
3515
  */
3766
-
3767
-
3768
3516
  loadScene( sceneIndex ) {
3769
3517
 
3770
3518
  const json = this.json;
3771
3519
  const extensions = this.extensions;
3772
3520
  const sceneDef = this.json.scenes[ sceneIndex ];
3773
- const parser = this; // THREE.Loader returns THREE.Group, not Scene.
3774
- // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172
3521
+ const parser = this;
3775
3522
 
3523
+ // THREE.Loader returns THREE.Group, not Scene.
3524
+ // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172
3776
3525
  const scene = new THREE.Group();
3777
3526
  if ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );
3778
3527
  assignExtrasToUserData( scene, sceneDef );
3779
3528
  if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );
3780
3529
  const nodeIds = sceneDef.nodes || [];
3781
3530
  const pending = [];
3782
-
3783
3531
  for ( let i = 0, il = nodeIds.length; i < il; i ++ ) {
3784
3532
 
3785
3533
  pending.push( buildNodeHierarchy( nodeIds[ i ], scene, json, parser ) );
@@ -3793,7 +3541,6 @@
3793
3541
  const reduceAssociations = node => {
3794
3542
 
3795
3543
  const reducedAssociations = new Map();
3796
-
3797
3544
  for ( const [ key, value ] of parser.associations ) {
3798
3545
 
3799
3546
  if ( key instanceof THREE.Material || key instanceof THREE.Texture ) {
@@ -3807,7 +3554,6 @@
3807
3554
  node.traverse( node => {
3808
3555
 
3809
3556
  const mappings = parser.associations.get( node );
3810
-
3811
3557
  if ( mappings != null ) {
3812
3558
 
3813
3559
  reducedAssociations.set( node, mappings );
@@ -3827,62 +3573,21 @@
3827
3573
  }
3828
3574
 
3829
3575
  }
3830
-
3831
3576
  function buildNodeHierarchy( nodeId, parentObject, json, parser ) {
3832
3577
 
3833
3578
  const nodeDef = json.nodes[ nodeId ];
3834
3579
  return parser.getDependency( 'node', nodeId ).then( function ( node ) {
3835
3580
 
3836
- if ( nodeDef.skin === undefined ) return node; // build skeleton here as well
3581
+ if ( nodeDef.skin === undefined ) return node;
3837
3582
 
3838
- let skinEntry;
3839
- return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) {
3583
+ // build skeleton here as well
3840
3584
 
3841
- skinEntry = skin;
3842
- const pendingJoints = [];
3843
-
3844
- for ( let i = 0, il = skinEntry.joints.length; i < il; i ++ ) {
3845
-
3846
- pendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) );
3847
-
3848
- }
3849
-
3850
- return Promise.all( pendingJoints );
3851
-
3852
- } ).then( function ( jointNodes ) {
3585
+ return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skeleton ) {
3853
3586
 
3854
3587
  node.traverse( function ( mesh ) {
3855
3588
 
3856
- if ( ! mesh.isMesh ) return;
3857
- const bones = [];
3858
- const boneInverses = [];
3859
-
3860
- for ( let j = 0, jl = jointNodes.length; j < jl; j ++ ) {
3861
-
3862
- const jointNode = jointNodes[ j ];
3863
-
3864
- if ( jointNode ) {
3865
-
3866
- bones.push( jointNode );
3867
- const mat = new THREE.Matrix4();
3868
-
3869
- if ( skinEntry.inverseBindMatrices !== undefined ) {
3870
-
3871
- mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 );
3872
-
3873
- }
3874
-
3875
- boneInverses.push( mat );
3876
-
3877
- } else {
3878
-
3879
- console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[ j ] );
3880
-
3881
- }
3882
-
3883
- }
3884
-
3885
- mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld );
3589
+ if ( ! mesh.isSkinnedMesh ) return;
3590
+ mesh.bind( skeleton, mesh.matrixWorld );
3886
3591
 
3887
3592
  } );
3888
3593
  return node;
@@ -3892,13 +3597,12 @@
3892
3597
  } ).then( function ( node ) {
3893
3598
 
3894
3599
  // build node hierachy
3600
+
3895
3601
  parentObject.add( node );
3896
3602
  const pending = [];
3897
-
3898
3603
  if ( nodeDef.children ) {
3899
3604
 
3900
3605
  const children = nodeDef.children;
3901
-
3902
3606
  for ( let i = 0, il = children.length; i < il; i ++ ) {
3903
3607
 
3904
3608
  const child = children[ i ];
@@ -3913,28 +3617,27 @@
3913
3617
  } );
3914
3618
 
3915
3619
  }
3620
+
3916
3621
  /**
3917
3622
  * @param {BufferGeometry} geometry
3918
3623
  * @param {GLTF.Primitive} primitiveDef
3919
3624
  * @param {GLTFParser} parser
3920
3625
  */
3921
-
3922
-
3923
3626
  function computeBounds( geometry, primitiveDef, parser ) {
3924
3627
 
3925
3628
  const attributes = primitiveDef.attributes;
3926
3629
  const box = new THREE.Box3();
3927
-
3928
3630
  if ( attributes.POSITION !== undefined ) {
3929
3631
 
3930
3632
  const accessor = parser.json.accessors[ attributes.POSITION ];
3931
3633
  const min = accessor.min;
3932
- const max = accessor.max; // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
3634
+ const max = accessor.max;
3635
+
3636
+ // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
3933
3637
 
3934
3638
  if ( min !== undefined && max !== undefined ) {
3935
3639
 
3936
3640
  box.set( new THREE.Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ), new THREE.Vector3( max[ 0 ], max[ 1 ], max[ 2 ] ) );
3937
-
3938
3641
  if ( accessor.normalized ) {
3939
3642
 
3940
3643
  const boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );
@@ -3957,21 +3660,20 @@
3957
3660
  }
3958
3661
 
3959
3662
  const targets = primitiveDef.targets;
3960
-
3961
3663
  if ( targets !== undefined ) {
3962
3664
 
3963
3665
  const maxDisplacement = new THREE.Vector3();
3964
3666
  const vector = new THREE.Vector3();
3965
-
3966
3667
  for ( let i = 0, il = targets.length; i < il; i ++ ) {
3967
3668
 
3968
3669
  const target = targets[ i ];
3969
-
3970
3670
  if ( target.POSITION !== undefined ) {
3971
3671
 
3972
3672
  const accessor = parser.json.accessors[ target.POSITION ];
3973
3673
  const min = accessor.min;
3974
- const max = accessor.max; // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
3674
+ const max = accessor.max;
3675
+
3676
+ // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
3975
3677
 
3976
3678
  if ( min !== undefined && max !== undefined ) {
3977
3679
 
@@ -3979,18 +3681,17 @@
3979
3681
  vector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) );
3980
3682
  vector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) );
3981
3683
  vector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) );
3982
-
3983
3684
  if ( accessor.normalized ) {
3984
3685
 
3985
3686
  const boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );
3986
3687
  vector.multiplyScalar( boxScale );
3987
3688
 
3988
- } // Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative
3689
+ }
3690
+
3691
+ // Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative
3989
3692
  // to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets
3990
3693
  // are used to implement key-frame animations and as such only two are active at a time - this results in very large
3991
3694
  // boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.
3992
-
3993
-
3994
3695
  maxDisplacement.max( vector );
3995
3696
 
3996
3697
  } else {
@@ -4001,9 +3702,9 @@
4001
3702
 
4002
3703
  }
4003
3704
 
4004
- } // As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.
4005
-
3705
+ }
4006
3706
 
3707
+ // As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.
4007
3708
  box.expandByVector( maxDisplacement );
4008
3709
 
4009
3710
  }
@@ -4015,19 +3716,17 @@
4015
3716
  geometry.boundingSphere = sphere;
4016
3717
 
4017
3718
  }
3719
+
4018
3720
  /**
4019
3721
  * @param {BufferGeometry} geometry
4020
3722
  * @param {GLTF.Primitive} primitiveDef
4021
3723
  * @param {GLTFParser} parser
4022
3724
  * @return {Promise<BufferGeometry>}
4023
3725
  */
4024
-
4025
-
4026
3726
  function addPrimitiveAttributes( geometry, primitiveDef, parser ) {
4027
3727
 
4028
3728
  const attributes = primitiveDef.attributes;
4029
3729
  const pending = [];
4030
-
4031
3730
  function assignAttributeAccessor( accessorIndex, attributeName ) {
4032
3731
 
4033
3732
  return parser.getDependency( 'accessor', accessorIndex ).then( function ( accessor ) {
@@ -4040,8 +3739,9 @@
4040
3739
 
4041
3740
  for ( const gltfAttributeName in attributes ) {
4042
3741
 
4043
- const threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase(); // Skip attributes already provided by e.g. Draco extension.
3742
+ const threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();
4044
3743
 
3744
+ // Skip attributes already provided by e.g. Draco extension.
4045
3745
  if ( threeAttributeName in geometry.attributes ) continue;
4046
3746
  pending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) );
4047
3747
 
@@ -4067,22 +3767,22 @@
4067
3767
  } );
4068
3768
 
4069
3769
  }
3770
+
4070
3771
  /**
4071
3772
  * @param {BufferGeometry} geometry
4072
3773
  * @param {Number} drawMode
4073
3774
  * @return {BufferGeometry}
4074
3775
  */
4075
-
4076
-
4077
3776
  function toTrianglesDrawMode( geometry, drawMode ) {
4078
3777
 
4079
- let index = geometry.getIndex(); // generate index if not present
3778
+ let index = geometry.getIndex();
3779
+
3780
+ // generate index if not present
4080
3781
 
4081
3782
  if ( index === null ) {
4082
3783
 
4083
3784
  const indices = [];
4084
3785
  const position = geometry.getAttribute( 'position' );
4085
-
4086
3786
  if ( position !== undefined ) {
4087
3787
 
4088
3788
  for ( let i = 0; i < position.count; i ++ ) {
@@ -4101,15 +3801,16 @@
4101
3801
 
4102
3802
  }
4103
3803
 
4104
- } //
3804
+ }
4105
3805
 
3806
+ //
4106
3807
 
4107
3808
  const numberOfTriangles = index.count - 2;
4108
3809
  const newIndices = [];
4109
-
4110
3810
  if ( drawMode === THREE.TriangleFanDrawMode ) {
4111
3811
 
4112
3812
  // gl.TRIANGLE_FAN
3813
+
4113
3814
  for ( let i = 1; i <= numberOfTriangles; i ++ ) {
4114
3815
 
4115
3816
  newIndices.push( index.getX( 0 ) );
@@ -4121,6 +3822,7 @@
4121
3822
  } else {
4122
3823
 
4123
3824
  // gl.TRIANGLE_STRIP
3825
+
4124
3826
  for ( let i = 0; i < numberOfTriangles; i ++ ) {
4125
3827
 
4126
3828
  if ( i % 2 === 0 ) {
@@ -4145,8 +3847,9 @@
4145
3847
 
4146
3848
  console.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' );
4147
3849
 
4148
- } // build final geometry
3850
+ }
4149
3851
 
3852
+ // build final geometry
4150
3853
 
4151
3854
  const newGeometry = geometry.clone();
4152
3855
  newGeometry.setIndex( newIndices );