@needle-tools/three 0.145.4 → 0.146.2

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