@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
@@ -42,7 +42,6 @@
42
42
  } );
43
43
 
44
44
  }
45
-
46
45
  register( callback ) {
47
46
 
48
47
  if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {
@@ -54,7 +53,6 @@
54
53
  return this;
55
54
 
56
55
  }
57
-
58
56
  unregister( callback ) {
59
57
 
60
58
  if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {
@@ -66,6 +64,7 @@
66
64
  return this;
67
65
 
68
66
  }
67
+
69
68
  /**
70
69
  * Parse scenes and generate GLTF output
71
70
  * @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes
@@ -73,13 +72,10 @@
73
72
  * @param {Function} onError Callback on errors
74
73
  * @param {Object} options options
75
74
  */
76
-
77
-
78
75
  parse( input, onDone, onError, options ) {
79
76
 
80
77
  const writer = new GLTFWriter();
81
78
  const plugins = [];
82
-
83
79
  for ( let i = 0, il = this.pluginCallbacks.length; i < il; i ++ ) {
84
80
 
85
81
  plugins.push( this.pluginCallbacks[ i ]( writer ) );
@@ -90,7 +86,6 @@
90
86
  writer.write( input, onDone, options ).catch( onError );
91
87
 
92
88
  }
93
-
94
89
  parseAsync( input, options ) {
95
90
 
96
91
  const scope = this;
@@ -102,11 +97,12 @@
102
97
 
103
98
  }
104
99
 
105
- } //------------------------------------------------------------------------------
100
+ }
101
+
102
+ //------------------------------------------------------------------------------
106
103
  // Constants
107
104
  //------------------------------------------------------------------------------
108
105
 
109
-
110
106
  const WEBGL_CONSTANTS = {
111
107
  POINTS: 0x0000,
112
108
  LINES: 0x0001,
@@ -146,7 +142,9 @@
146
142
  position: 'translation',
147
143
  quaternion: 'rotation',
148
144
  morphTargetInfluences: 'weights'
149
- }; // GLB constants
145
+ };
146
+
147
+ // GLB constants
150
148
  // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
151
149
 
152
150
  const GLB_HEADER_BYTES = 12;
@@ -154,7 +152,9 @@
154
152
  const GLB_VERSION = 2;
155
153
  const GLB_CHUNK_PREFIX_BYTES = 8;
156
154
  const GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
157
- const GLB_CHUNK_TYPE_BIN = 0x004E4942; //------------------------------------------------------------------------------
155
+ const GLB_CHUNK_TYPE_BIN = 0x004E4942;
156
+
157
+ //------------------------------------------------------------------------------
158
158
  // Utility functions
159
159
  //------------------------------------------------------------------------------
160
160
 
@@ -164,7 +164,6 @@
164
164
  * @param {Array} array2 Array 2 to compare
165
165
  * @return {Boolean} Returns true if both arrays are equal
166
166
  */
167
-
168
167
  function equalArray( array1, array2 ) {
169
168
 
170
169
  return array1.length === array2.length && array1.every( function ( element, index ) {
@@ -174,31 +173,30 @@
174
173
  } );
175
174
 
176
175
  }
176
+
177
177
  /**
178
178
  * Converts a string to an ArrayBuffer.
179
179
  * @param {string} text
180
180
  * @return {ArrayBuffer}
181
181
  */
182
-
183
-
184
182
  function stringToArrayBuffer( text ) {
185
183
 
186
184
  return new TextEncoder().encode( text ).buffer;
187
185
 
188
186
  }
187
+
189
188
  /**
190
189
  * Is identity matrix
191
190
  *
192
191
  * @param {Matrix4} matrix
193
192
  * @returns {Boolean} Returns true, if parameter is identity matrix
194
193
  */
195
-
196
-
197
194
  function isIdentityMatrix( matrix ) {
198
195
 
199
196
  return equalArray( matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] );
200
197
 
201
198
  }
199
+
202
200
  /**
203
201
  * Get the min and max vectors from the given attribute
204
202
  * @param {BufferAttribute} attribute Attribute to find the min/max in range from start to start + count
@@ -206,24 +204,21 @@
206
204
  * @param {Integer} count
207
205
  * @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components)
208
206
  */
209
-
210
-
211
207
  function getMinMax( attribute, start, count ) {
212
208
 
213
209
  const output = {
214
210
  min: new Array( attribute.itemSize ).fill( Number.POSITIVE_INFINITY ),
215
211
  max: new Array( attribute.itemSize ).fill( Number.NEGATIVE_INFINITY )
216
212
  };
217
-
218
213
  for ( let i = start; i < start + count; i ++ ) {
219
214
 
220
215
  for ( let a = 0; a < attribute.itemSize; a ++ ) {
221
216
 
222
217
  let value;
223
-
224
218
  if ( attribute.itemSize > 4 ) {
225
219
 
226
220
  // no support for interleaved data for itemSize > 4
221
+
227
222
  value = attribute.array[ i * attribute.itemSize + a ];
228
223
 
229
224
  } else {
@@ -242,6 +237,7 @@
242
237
  return output;
243
238
 
244
239
  }
240
+
245
241
  /**
246
242
  * Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
247
243
  * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
@@ -250,13 +246,12 @@
250
246
  * @returns {Integer} new buffer size with required padding.
251
247
  *
252
248
  */
253
-
254
-
255
249
  function getPaddedBufferSize( bufferSize ) {
256
250
 
257
251
  return Math.ceil( bufferSize / 4 ) * 4;
258
252
 
259
253
  }
254
+
260
255
  /**
261
256
  * Returns a buffer aligned to 4-byte boundary.
262
257
  *
@@ -264,17 +259,13 @@
264
259
  * @param {Integer} paddingByte (Optional)
265
260
  * @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer
266
261
  */
267
-
268
-
269
262
  function getPaddedArrayBuffer( arrayBuffer, paddingByte = 0 ) {
270
263
 
271
264
  const paddedLength = getPaddedBufferSize( arrayBuffer.byteLength );
272
-
273
265
  if ( paddedLength !== arrayBuffer.byteLength ) {
274
266
 
275
267
  const array = new Uint8Array( paddedLength );
276
268
  array.set( new Uint8Array( arrayBuffer ) );
277
-
278
269
  if ( paddingByte !== 0 ) {
279
270
 
280
271
  for ( let i = arrayBuffer.byteLength; i < paddedLength; i ++ ) {
@@ -313,9 +304,10 @@
313
304
 
314
305
  }
315
306
 
316
- let quality; // Blink's implementation of convertToBlob seems to default to a quality level of 100%
317
- // Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
307
+ let quality;
318
308
 
309
+ // Blink's implementation of convertToBlob seems to default to a quality level of 100%
310
+ // Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
319
311
  if ( mimeType === 'image/jpeg' ) {
320
312
 
321
313
  quality = 0.92;
@@ -332,11 +324,10 @@
332
324
  } );
333
325
 
334
326
  }
327
+
335
328
  /**
336
329
  * Writer
337
330
  */
338
-
339
-
340
331
  class GLTFWriter {
341
332
 
342
333
  constructor() {
@@ -368,20 +359,18 @@
368
359
  };
369
360
 
370
361
  }
371
-
372
362
  setPlugins( plugins ) {
373
363
 
374
364
  this.plugins = plugins;
375
365
 
376
366
  }
367
+
377
368
  /**
378
369
  * Parse scenes and generate GLTF output
379
370
  * @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes
380
371
  * @param {Function} onDone Callback on completed
381
372
  * @param {Object} options options
382
373
  */
383
-
384
-
385
374
  async write( input, onDone, options ) {
386
375
 
387
376
  this.options = Object.assign( {}, {
@@ -389,12 +378,10 @@
389
378
  binary: false,
390
379
  trs: false,
391
380
  onlyVisible: true,
392
- truncateDrawRange: true,
393
381
  maxTextureSize: Infinity,
394
382
  animations: [],
395
383
  includeCustomExtensions: false
396
384
  }, options );
397
-
398
385
  if ( this.options.animations.length > 0 ) {
399
386
 
400
387
  // Only TRS properties, and not matrices, may be targeted by animation.
@@ -408,36 +395,40 @@
408
395
  const buffers = writer.buffers;
409
396
  const json = writer.json;
410
397
  options = writer.options;
411
- const extensionsUsed = writer.extensionsUsed; // Merge buffers.
398
+ const extensionsUsed = writer.extensionsUsed;
412
399
 
400
+ // Merge buffers.
413
401
  const blob = new Blob( buffers, {
414
402
  type: 'application/octet-stream'
415
- } ); // Declare extensions.
403
+ } );
416
404
 
405
+ // Declare extensions.
417
406
  const extensionsUsedList = Object.keys( extensionsUsed );
418
- if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList; // Update bytelength of the single buffer.
407
+ if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList;
419
408
 
409
+ // Update bytelength of the single buffer.
420
410
  if ( json.buffers && json.buffers.length > 0 ) json.buffers[ 0 ].byteLength = blob.size;
421
-
422
411
  if ( options.binary === true ) {
423
412
 
424
413
  // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
414
+
425
415
  const reader = new FileReader();
426
416
  reader.readAsArrayBuffer( blob );
427
-
428
417
  reader.onloadend = function () {
429
418
 
430
419
  // Binary chunk.
431
420
  const binaryChunk = getPaddedArrayBuffer( reader.result );
432
421
  const binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
433
422
  binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true );
434
- binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true ); // JSON chunk.
423
+ binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
435
424
 
425
+ // JSON chunk.
436
426
  const jsonChunk = getPaddedArrayBuffer( stringToArrayBuffer( JSON.stringify( json ) ), 0x20 );
437
427
  const jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
438
428
  jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true );
439
- jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true ); // GLB header.
429
+ jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
440
430
 
431
+ // GLB header.
441
432
  const header = new ArrayBuffer( GLB_HEADER_BYTES );
442
433
  const headerView = new DataView( header );
443
434
  headerView.setUint32( 0, GLB_HEADER_MAGIC, true );
@@ -449,7 +440,6 @@
449
440
  } );
450
441
  const glbReader = new FileReader();
451
442
  glbReader.readAsArrayBuffer( glbBlob );
452
-
453
443
  glbReader.onloadend = function () {
454
444
 
455
445
  onDone( glbReader.result );
@@ -464,7 +454,6 @@
464
454
 
465
455
  const reader = new FileReader();
466
456
  reader.readAsDataURL( blob );
467
-
468
457
  reader.onloadend = function () {
469
458
 
470
459
  const base64data = reader.result;
@@ -482,28 +471,24 @@
482
471
  }
483
472
 
484
473
  }
474
+
485
475
  /**
486
476
  * Serializes a userData.
487
477
  *
488
478
  * @param {THREE.Object3D|THREE.Material} object
489
479
  * @param {Object} objectDef
490
480
  */
491
-
492
-
493
481
  serializeUserData( object, objectDef ) {
494
482
 
495
483
  if ( Object.keys( object.userData ).length === 0 ) return;
496
484
  const options = this.options;
497
485
  const extensionsUsed = this.extensionsUsed;
498
-
499
486
  try {
500
487
 
501
488
  const json = JSON.parse( JSON.stringify( object.userData ) );
502
-
503
489
  if ( options.includeCustomExtensions && json.gltfExtensions ) {
504
490
 
505
491
  if ( objectDef.extensions === undefined ) objectDef.extensions = {};
506
-
507
492
  for ( const extensionName in json.gltfExtensions ) {
508
493
 
509
494
  objectDef.extensions[ extensionName ] = json.gltfExtensions[ extensionName ];
@@ -524,13 +509,12 @@
524
509
  }
525
510
 
526
511
  }
512
+
527
513
  /**
528
514
  * Returns ids for buffer attributes.
529
515
  * @param {Object} object
530
516
  * @return {Integer}
531
517
  */
532
-
533
-
534
518
  getUID( attribute, isRelativeCopy = false ) {
535
519
 
536
520
  if ( this.uids.has( attribute ) === false ) {
@@ -546,20 +530,18 @@
546
530
  return uids.get( isRelativeCopy );
547
531
 
548
532
  }
533
+
549
534
  /**
550
535
  * Checks if normal attribute values are normalized.
551
536
  *
552
537
  * @param {BufferAttribute} normal
553
538
  * @returns {Boolean}
554
539
  */
555
-
556
-
557
540
  isNormalizedNormalAttribute( normal ) {
558
541
 
559
542
  const cache = this.cache;
560
543
  if ( cache.attributesNormalized.has( normal ) ) return false;
561
544
  const v = new THREE.Vector3();
562
-
563
545
  for ( let i = 0, il = normal.count; i < il; i ++ ) {
564
546
 
565
547
  // 0.0005 is from glTF-validator
@@ -570,6 +552,7 @@
570
552
  return true;
571
553
 
572
554
  }
555
+
573
556
  /**
574
557
  * Creates normalized normal buffer attribute.
575
558
  *
@@ -577,19 +560,15 @@
577
560
  * @returns {BufferAttribute}
578
561
  *
579
562
  */
580
-
581
-
582
563
  createNormalizedNormalAttribute( normal ) {
583
564
 
584
565
  const cache = this.cache;
585
566
  if ( cache.attributesNormalized.has( normal ) ) return cache.attributesNormalized.get( normal );
586
567
  const attribute = normal.clone();
587
568
  const v = new THREE.Vector3();
588
-
589
569
  for ( let i = 0, il = attribute.count; i < il; i ++ ) {
590
570
 
591
571
  v.fromBufferAttribute( attribute, i );
592
-
593
572
  if ( v.x === 0 && v.y === 0 && v.z === 0 ) {
594
573
 
595
574
  // if values can't be normalized set (1, 0, 0)
@@ -609,6 +588,7 @@
609
588
  return attribute;
610
589
 
611
590
  }
591
+
612
592
  /**
613
593
  * Applies a texture transform, if present, to the map definition. Requires
614
594
  * the KHR_texture_transform extension.
@@ -616,13 +596,10 @@
616
596
  * @param {Object} mapDef
617
597
  * @param {THREE.Texture} texture
618
598
  */
619
-
620
-
621
599
  applyTextureTransform( mapDef, texture ) {
622
600
 
623
601
  let didTransform = false;
624
602
  const transformDef = {};
625
-
626
603
  if ( texture.offset.x !== 0 || texture.offset.y !== 0 ) {
627
604
 
628
605
  transformDef.offset = texture.offset.toArray();
@@ -653,11 +630,9 @@
653
630
  }
654
631
 
655
632
  }
656
-
657
633
  buildMetalRoughTexture( metalnessMap, roughnessMap ) {
658
634
 
659
635
  if ( metalnessMap === roughnessMap ) return metalnessMap;
660
-
661
636
  function getEncodingConversion( map ) {
662
637
 
663
638
  if ( map.encoding === THREE.sRGBEncoding ) {
@@ -690,13 +665,11 @@
690
665
  context.fillStyle = '#00ffff';
691
666
  context.fillRect( 0, 0, width, height );
692
667
  const composite = context.getImageData( 0, 0, width, height );
693
-
694
668
  if ( metalness ) {
695
669
 
696
670
  context.drawImage( metalness, 0, 0, width, height );
697
671
  const convert = getEncodingConversion( metalnessMap );
698
672
  const data = context.getImageData( 0, 0, width, height ).data;
699
-
700
673
  for ( let i = 2; i < data.length; i += 4 ) {
701
674
 
702
675
  composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
@@ -710,7 +683,6 @@
710
683
  context.drawImage( roughness, 0, 0, width, height );
711
684
  const convert = getEncodingConversion( roughnessMap );
712
685
  const data = context.getImageData( 0, 0, width, height ).data;
713
-
714
686
  for ( let i = 1; i < data.length; i += 4 ) {
715
687
 
716
688
  composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
@@ -719,7 +691,9 @@
719
691
 
720
692
  }
721
693
 
722
- context.putImageData( composite, 0, 0 ); //
694
+ context.putImageData( composite, 0, 0 );
695
+
696
+ //
723
697
 
724
698
  const reference = metalnessMap || roughnessMap;
725
699
  const texture = reference.clone();
@@ -728,25 +702,26 @@
728
702
  return texture;
729
703
 
730
704
  }
705
+
731
706
  /**
732
707
  * Process a buffer to append to the default one.
733
708
  * @param {ArrayBuffer} buffer
734
709
  * @return {Integer}
735
710
  */
736
-
737
-
738
711
  processBuffer( buffer ) {
739
712
 
740
713
  const json = this.json;
741
714
  const buffers = this.buffers;
742
715
  if ( ! json.buffers ) json.buffers = [ {
743
716
  byteLength: 0
744
- } ]; // All buffers are merged before export.
717
+ } ];
745
718
 
719
+ // All buffers are merged before export.
746
720
  buffers.push( buffer );
747
721
  return 0;
748
722
 
749
723
  }
724
+
750
725
  /**
751
726
  * Process and generate a BufferView
752
727
  * @param {BufferAttribute} attribute
@@ -756,15 +731,14 @@
756
731
  * @param {number} target (Optional) Target usage of the BufferView
757
732
  * @return {Object}
758
733
  */
759
-
760
-
761
734
  processBufferView( attribute, componentType, start, count, target ) {
762
735
 
763
736
  const json = this.json;
764
- if ( ! json.bufferViews ) json.bufferViews = []; // Create a new dataview and dump the attribute's array into it
737
+ if ( ! json.bufferViews ) json.bufferViews = [];
765
738
 
766
- let componentSize;
739
+ // Create a new dataview and dump the attribute's array into it
767
740
 
741
+ let componentSize;
768
742
  if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) {
769
743
 
770
744
  componentSize = 1;
@@ -782,16 +756,15 @@
782
756
  const byteLength = getPaddedBufferSize( count * attribute.itemSize * componentSize );
783
757
  const dataView = new DataView( new ArrayBuffer( byteLength ) );
784
758
  let offset = 0;
785
-
786
759
  for ( let i = start; i < start + count; i ++ ) {
787
760
 
788
761
  for ( let a = 0; a < attribute.itemSize; a ++ ) {
789
762
 
790
763
  let value;
791
-
792
764
  if ( attribute.itemSize > 4 ) {
793
765
 
794
766
  // no support for interleaved data for itemSize > 4
767
+
795
768
  value = attribute.array[ i * attribute.itemSize + a ];
796
769
 
797
770
  } else {
@@ -830,7 +803,6 @@
830
803
  byteLength: byteLength
831
804
  };
832
805
  if ( target !== undefined ) bufferViewDef.target = target;
833
-
834
806
  if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
835
807
 
836
808
  // Only define byteStride for vertex attributes.
@@ -839,8 +811,9 @@
839
811
  }
840
812
 
841
813
  this.byteOffset += byteLength;
842
- json.bufferViews.push( bufferViewDef ); // @TODO Merge bufferViews where possible.
814
+ json.bufferViews.push( bufferViewDef );
843
815
 
816
+ // @TODO Merge bufferViews where possible.
844
817
  const output = {
845
818
  id: json.bufferViews.length - 1,
846
819
  byteLength: 0
@@ -848,13 +821,12 @@
848
821
  return output;
849
822
 
850
823
  }
824
+
851
825
  /**
852
826
  * Process and generate a BufferView from an image Blob.
853
827
  * @param {Blob} blob
854
828
  * @return {Promise<Integer>}
855
829
  */
856
-
857
-
858
830
  processBufferViewImage( blob ) {
859
831
 
860
832
  const writer = this;
@@ -864,7 +836,6 @@
864
836
 
865
837
  const reader = new FileReader();
866
838
  reader.readAsArrayBuffer( blob );
867
-
868
839
  reader.onloadend = function () {
869
840
 
870
841
  const buffer = getPaddedArrayBuffer( reader.result );
@@ -881,6 +852,7 @@
881
852
  } );
882
853
 
883
854
  }
855
+
884
856
  /**
885
857
  * Process attribute to generate an accessor
886
858
  * @param {BufferAttribute} attribute Attribute to process
@@ -889,11 +861,8 @@
889
861
  * @param {Integer} count (Optional)
890
862
  * @return {Integer|null} Index of the processed accessor on the "accessors" array
891
863
  */
892
-
893
-
894
864
  processAccessor( attribute, geometry, start, count ) {
895
865
 
896
- const options = this.options;
897
866
  const json = this.json;
898
867
  const types = {
899
868
  1: 'SCALAR',
@@ -902,8 +871,9 @@
902
871
  4: 'VEC4',
903
872
  16: 'MAT4'
904
873
  };
905
- let componentType; // Detect the component type of the attribute array (float, uint or ushort)
874
+ let componentType;
906
875
 
876
+ // Detect the component type of the attribute array (float, uint or ushort)
907
877
  if ( attribute.array.constructor === Float32Array ) {
908
878
 
909
879
  componentType = WEBGL_CONSTANTS.FLOAT;
@@ -927,24 +897,15 @@
927
897
  }
928
898
 
929
899
  if ( start === undefined ) start = 0;
930
- if ( count === undefined ) count = attribute.count; // @TODO Indexed buffer geometry with drawRange not supported yet
931
-
932
- if ( options.truncateDrawRange && geometry !== undefined && geometry.index === null ) {
933
-
934
- const end = start + count;
935
- const end2 = geometry.drawRange.count === Infinity ? attribute.count : geometry.drawRange.start + geometry.drawRange.count;
936
- start = Math.max( start, geometry.drawRange.start );
937
- count = Math.min( end, end2 ) - start;
938
- if ( count < 0 ) count = 0;
939
-
940
- } // Skip creating an accessor if the attribute doesn't have data to export
941
-
900
+ if ( count === undefined ) count = attribute.count;
942
901
 
902
+ // Skip creating an accessor if the attribute doesn't have data to export
943
903
  if ( count === 0 ) return null;
944
904
  const minMax = getMinMax( attribute, start, count );
945
- let bufferViewTarget; // If geometry isn't provided, don't infer the target usage of the bufferView. For
946
- // animation samplers, target must not be set.
905
+ let bufferViewTarget;
947
906
 
907
+ // If geometry isn't provided, don't infer the target usage of the bufferView. For
908
+ // animation samplers, target must not be set.
948
909
  if ( geometry !== undefined ) {
949
910
 
950
911
  bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
@@ -966,6 +927,7 @@
966
927
  return json.accessors.push( accessorDef ) - 1;
967
928
 
968
929
  }
930
+
969
931
  /**
970
932
  * Process image
971
933
  * @param {Image} image to process
@@ -974,8 +936,6 @@
974
936
  * @param {String} mimeType export format
975
937
  * @return {Integer} Index of the processed texture in the "images" array
976
938
  */
977
-
978
-
979
939
  processImage( image, format, flipY, mimeType = 'image/png' ) {
980
940
 
981
941
  const writer = this;
@@ -995,7 +955,6 @@
995
955
  canvas.width = Math.min( image.width, options.maxTextureSize );
996
956
  canvas.height = Math.min( image.height, options.maxTextureSize );
997
957
  const ctx = canvas.getContext( '2d' );
998
-
999
958
  if ( flipY === true ) {
1000
959
 
1001
960
  ctx.translate( 0, canvas.height );
@@ -1006,6 +965,7 @@
1006
965
  if ( image.data !== undefined ) {
1007
966
 
1008
967
  // THREE.DataTexture
968
+
1009
969
  if ( format !== THREE.RGBAFormat ) {
1010
970
 
1011
971
  console.error( 'GLTFExporter: Only THREE.RGBAFormat is supported.' );
@@ -1019,7 +979,6 @@
1019
979
  }
1020
980
 
1021
981
  const data = new Uint8ClampedArray( image.height * image.width * 4 );
1022
-
1023
982
  for ( let i = 0; i < data.length; i += 4 ) {
1024
983
 
1025
984
  data[ i + 0 ] = image.data[ i + 0 ];
@@ -1068,13 +1027,12 @@
1068
1027
  return index;
1069
1028
 
1070
1029
  }
1030
+
1071
1031
  /**
1072
1032
  * Process sampler
1073
1033
  * @param {Texture} map Texture to process
1074
1034
  * @return {Integer} Index of the processed texture in the "samplers" array
1075
1035
  */
1076
-
1077
-
1078
1036
  processSampler( map ) {
1079
1037
 
1080
1038
  const json = this.json;
@@ -1088,13 +1046,12 @@
1088
1046
  return json.samplers.push( samplerDef ) - 1;
1089
1047
 
1090
1048
  }
1049
+
1091
1050
  /**
1092
1051
  * Process texture
1093
1052
  * @param {Texture} map Map to process
1094
1053
  * @return {Integer} Index of the processed texture in the "textures" array
1095
1054
  */
1096
-
1097
-
1098
1055
  processTexture( map ) {
1099
1056
 
1100
1057
  const cache = this.cache;
@@ -1108,31 +1065,27 @@
1108
1065
  source: this.processImage( map.image, map.format, map.flipY, mimeType )
1109
1066
  };
1110
1067
  if ( map.name ) textureDef.name = map.name;
1111
-
1112
1068
  this._invokeAll( function ( ext ) {
1113
1069
 
1114
1070
  ext.writeTexture && ext.writeTexture( map, textureDef );
1115
1071
 
1116
1072
  } );
1117
-
1118
1073
  const index = json.textures.push( textureDef ) - 1;
1119
1074
  cache.textures.set( map, index );
1120
1075
  return index;
1121
1076
 
1122
1077
  }
1078
+
1123
1079
  /**
1124
1080
  * Process material
1125
1081
  * @param {THREE.Material} material Material to process
1126
1082
  * @return {Integer|null} Index of the processed material in the "materials" array
1127
1083
  */
1128
-
1129
-
1130
1084
  processMaterial( material ) {
1131
1085
 
1132
1086
  const cache = this.cache;
1133
1087
  const json = this.json;
1134
1088
  if ( cache.materials.has( material ) ) return cache.materials.get( material );
1135
-
1136
1089
  if ( material.isShaderMaterial ) {
1137
1090
 
1138
1091
  console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' );
@@ -1140,21 +1093,20 @@
1140
1093
 
1141
1094
  }
1142
1095
 
1143
- if ( ! json.materials ) json.materials = []; // @QUESTION Should we avoid including any attribute that has the default value?
1096
+ if ( ! json.materials ) json.materials = [];
1144
1097
 
1098
+ // @QUESTION Should we avoid including any attribute that has the default value?
1145
1099
  const materialDef = {
1146
1100
  pbrMetallicRoughness: {}
1147
1101
  };
1148
-
1149
1102
  if ( material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true ) {
1150
1103
 
1151
1104
  console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' );
1152
1105
 
1153
- } // pbrMetallicRoughness.baseColorFactor
1154
-
1106
+ }
1155
1107
 
1108
+ // pbrMetallicRoughness.baseColorFactor
1156
1109
  const color = material.color.toArray().concat( [ material.opacity ] );
1157
-
1158
1110
  if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) {
1159
1111
 
1160
1112
  materialDef.pbrMetallicRoughness.baseColorFactor = color;
@@ -1171,9 +1123,9 @@
1171
1123
  materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
1172
1124
  materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
1173
1125
 
1174
- } // pbrMetallicRoughness.metallicRoughnessTexture
1175
-
1126
+ }
1176
1127
 
1128
+ // pbrMetallicRoughness.metallicRoughnessTexture
1177
1129
  if ( material.metalnessMap || material.roughnessMap ) {
1178
1130
 
1179
1131
  const metalRoughTexture = this.buildMetalRoughTexture( material.metalnessMap, material.roughnessMap );
@@ -1183,9 +1135,9 @@
1183
1135
  this.applyTextureTransform( metalRoughMapDef, metalRoughTexture );
1184
1136
  materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
1185
1137
 
1186
- } // pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture
1187
-
1138
+ }
1188
1139
 
1140
+ // pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture
1189
1141
  if ( material.map ) {
1190
1142
 
1191
1143
  const baseColorMapDef = {
@@ -1201,7 +1153,6 @@
1201
1153
  // note: emissive components are limited to stay within the 0 - 1 range to accommodate glTF spec. see #21849 and #22000.
1202
1154
  const emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity );
1203
1155
  const maxEmissiveComponent = Math.max( emissive.r, emissive.g, emissive.b );
1204
-
1205
1156
  if ( maxEmissiveComponent > 1 ) {
1206
1157
 
1207
1158
  emissive.multiplyScalar( 1 / maxEmissiveComponent );
@@ -1213,9 +1164,9 @@
1213
1164
 
1214
1165
  materialDef.emissiveFactor = emissive.toArray();
1215
1166
 
1216
- } // emissiveTexture
1217
-
1167
+ }
1218
1168
 
1169
+ // emissiveTexture
1219
1170
  if ( material.emissiveMap ) {
1220
1171
 
1221
1172
  const emissiveMapDef = {
@@ -1226,15 +1177,14 @@
1226
1177
 
1227
1178
  }
1228
1179
 
1229
- } // normalTexture
1230
-
1180
+ }
1231
1181
 
1182
+ // normalTexture
1232
1183
  if ( material.normalMap ) {
1233
1184
 
1234
1185
  const normalMapDef = {
1235
1186
  index: this.processTexture( material.normalMap )
1236
1187
  };
1237
-
1238
1188
  if ( material.normalScale && material.normalScale.x !== 1 ) {
1239
1189
 
1240
1190
  // glTF normal scale is univariate. Ignore `y`, which may be flipped.
@@ -1246,16 +1196,15 @@
1246
1196
  this.applyTextureTransform( normalMapDef, material.normalMap );
1247
1197
  materialDef.normalTexture = normalMapDef;
1248
1198
 
1249
- } // occlusionTexture
1250
-
1199
+ }
1251
1200
 
1201
+ // occlusionTexture
1252
1202
  if ( material.aoMap ) {
1253
1203
 
1254
1204
  const occlusionMapDef = {
1255
1205
  index: this.processTexture( material.aoMap ),
1256
1206
  texCoord: 1
1257
1207
  };
1258
-
1259
1208
  if ( material.aoMapIntensity !== 1.0 ) {
1260
1209
 
1261
1210
  occlusionMapDef.strength = material.aoMapIntensity;
@@ -1265,9 +1214,9 @@
1265
1214
  this.applyTextureTransform( occlusionMapDef, material.aoMap );
1266
1215
  materialDef.occlusionTexture = occlusionMapDef;
1267
1216
 
1268
- } // alphaMode
1269
-
1217
+ }
1270
1218
 
1219
+ // alphaMode
1271
1220
  if ( material.transparent ) {
1272
1221
 
1273
1222
  materialDef.alphaMode = 'BLEND';
@@ -1281,37 +1230,33 @@
1281
1230
 
1282
1231
  }
1283
1232
 
1284
- } // doubleSided
1285
-
1233
+ }
1286
1234
 
1235
+ // doubleSided
1287
1236
  if ( material.side === THREE.DoubleSide ) materialDef.doubleSided = true;
1288
1237
  if ( material.name !== '' ) materialDef.name = material.name;
1289
1238
  this.serializeUserData( material, materialDef );
1290
-
1291
1239
  this._invokeAll( function ( ext ) {
1292
1240
 
1293
1241
  ext.writeMaterial && ext.writeMaterial( material, materialDef );
1294
1242
 
1295
1243
  } );
1296
-
1297
1244
  const index = json.materials.push( materialDef ) - 1;
1298
1245
  cache.materials.set( material, index );
1299
1246
  return index;
1300
1247
 
1301
1248
  }
1249
+
1302
1250
  /**
1303
1251
  * Process mesh
1304
1252
  * @param {THREE.Mesh} mesh Mesh to process
1305
1253
  * @return {Integer|null} Index of the processed mesh in the "meshes" array
1306
1254
  */
1307
-
1308
-
1309
1255
  processMesh( mesh ) {
1310
1256
 
1311
1257
  const cache = this.cache;
1312
1258
  const json = this.json;
1313
1259
  const meshCacheKeyParts = [ mesh.geometry.uuid ];
1314
-
1315
1260
  if ( Array.isArray( mesh.material ) ) {
1316
1261
 
1317
1262
  for ( let i = 0, l = mesh.material.length; i < l; i ++ ) {
@@ -1329,8 +1274,9 @@
1329
1274
  const meshCacheKey = meshCacheKeyParts.join( ':' );
1330
1275
  if ( cache.meshes.has( meshCacheKey ) ) return cache.meshes.get( meshCacheKey );
1331
1276
  const geometry = mesh.geometry;
1332
- let mode; // Use the correct mode
1277
+ let mode;
1333
1278
 
1279
+ // Use the correct mode
1334
1280
  if ( mesh.isLineSegments ) {
1335
1281
 
1336
1282
  mode = WEBGL_CONSTANTS.LINES;
@@ -1356,8 +1302,9 @@
1356
1302
  const meshDef = {};
1357
1303
  const attributes = {};
1358
1304
  const primitives = [];
1359
- const targets = []; // Conversion between attributes names in threejs and gltf spec
1305
+ const targets = [];
1360
1306
 
1307
+ // Conversion between attributes names in threejs and gltf spec
1361
1308
  const nameConversion = {
1362
1309
  uv: 'TEXCOORD_0',
1363
1310
  uv2: 'TEXCOORD_1',
@@ -1366,40 +1313,37 @@
1366
1313
  skinIndex: 'JOINTS_0'
1367
1314
  };
1368
1315
  const originalNormal = geometry.getAttribute( 'normal' );
1369
-
1370
1316
  if ( originalNormal !== undefined && ! this.isNormalizedNormalAttribute( originalNormal ) ) {
1371
1317
 
1372
1318
  console.warn( 'THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.' );
1373
1319
  geometry.setAttribute( 'normal', this.createNormalizedNormalAttribute( originalNormal ) );
1374
1320
 
1375
- } // @QUESTION Detect if .vertexColors = true?
1376
- // For every attribute create an accessor
1377
-
1321
+ }
1378
1322
 
1323
+ // @QUESTION Detect if .vertexColors = true?
1324
+ // For every attribute create an accessor
1379
1325
  let modifiedAttribute = null;
1380
-
1381
1326
  for ( let attributeName in geometry.attributes ) {
1382
1327
 
1383
1328
  // Ignore morph target attributes, which are exported later.
1384
1329
  if ( attributeName.slice( 0, 5 ) === 'morph' ) continue;
1385
1330
  const attribute = geometry.attributes[ attributeName ];
1386
- attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase(); // Prefix all geometry attributes except the ones specifically
1387
- // listed in the spec; non-spec attributes are considered custom.
1331
+ attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
1388
1332
 
1333
+ // Prefix all geometry attributes except the ones specifically
1334
+ // listed in the spec; non-spec attributes are considered custom.
1389
1335
  const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
1390
1336
  if ( ! validVertexAttributes.test( attributeName ) ) attributeName = '_' + attributeName;
1391
-
1392
1337
  if ( cache.attributes.has( this.getUID( attribute ) ) ) {
1393
1338
 
1394
1339
  attributes[ attributeName ] = cache.attributes.get( this.getUID( attribute ) );
1395
1340
  continue;
1396
1341
 
1397
- } // JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
1398
-
1342
+ }
1399
1343
 
1344
+ // JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
1400
1345
  modifiedAttribute = null;
1401
1346
  const array = attribute.array;
1402
-
1403
1347
  if ( attributeName === 'JOINTS_0' && ! ( array instanceof Uint16Array ) && ! ( array instanceof Uint8Array ) ) {
1404
1348
 
1405
1349
  console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
@@ -1408,7 +1352,6 @@
1408
1352
  }
1409
1353
 
1410
1354
  const accessor = this.processAccessor( modifiedAttribute || attribute, geometry );
1411
-
1412
1355
  if ( accessor !== null ) {
1413
1356
 
1414
1357
  attributes[ attributeName ] = accessor;
@@ -1418,16 +1361,17 @@
1418
1361
 
1419
1362
  }
1420
1363
 
1421
- if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal ); // Skip if no exportable attributes found
1364
+ if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal );
1422
1365
 
1423
- if ( Object.keys( attributes ).length === 0 ) return null; // Morph targets
1366
+ // Skip if no exportable attributes found
1367
+ if ( Object.keys( attributes ).length === 0 ) return null;
1424
1368
 
1369
+ // Morph targets
1425
1370
  if ( mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0 ) {
1426
1371
 
1427
1372
  const weights = [];
1428
1373
  const targetNames = [];
1429
1374
  const reverseDictionary = {};
1430
-
1431
1375
  if ( mesh.morphTargetDictionary !== undefined ) {
1432
1376
 
1433
1377
  for ( const key in mesh.morphTargetDictionary ) {
@@ -1442,11 +1386,11 @@
1442
1386
 
1443
1387
  const target = {};
1444
1388
  let warned = false;
1445
-
1446
1389
  for ( const attributeName in geometry.morphAttributes ) {
1447
1390
 
1448
1391
  // glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
1449
1392
  // Three.js doesn't support TANGENT yet.
1393
+
1450
1394
  if ( attributeName !== 'position' && attributeName !== 'normal' ) {
1451
1395
 
1452
1396
  if ( ! warned ) {
@@ -1461,23 +1405,23 @@
1461
1405
  }
1462
1406
 
1463
1407
  const attribute = geometry.morphAttributes[ attributeName ][ i ];
1464
- const gltfAttributeName = attributeName.toUpperCase(); // Three.js morph attribute has absolute values while the one of glTF has relative values.
1408
+ const gltfAttributeName = attributeName.toUpperCase();
1409
+
1410
+ // Three.js morph attribute has absolute values while the one of glTF has relative values.
1465
1411
  //
1466
1412
  // glTF 2.0 Specification:
1467
1413
  // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
1468
1414
 
1469
1415
  const baseAttribute = geometry.attributes[ attributeName ];
1470
-
1471
1416
  if ( cache.attributes.has( this.getUID( attribute, true ) ) ) {
1472
1417
 
1473
1418
  target[ gltfAttributeName ] = cache.attributes.get( this.getUID( attribute, true ) );
1474
1419
  continue;
1475
1420
 
1476
- } // Clones attribute not to override
1477
-
1421
+ }
1478
1422
 
1423
+ // Clones attribute not to override
1479
1424
  const relativeAttribute = attribute.clone();
1480
-
1481
1425
  if ( ! geometry.morphTargetsRelative ) {
1482
1426
 
1483
1427
  for ( let j = 0, jl = attribute.count; j < jl; j ++ ) {
@@ -1500,7 +1444,6 @@
1500
1444
  }
1501
1445
 
1502
1446
  meshDef.weights = weights;
1503
-
1504
1447
  if ( targetNames.length > 0 ) {
1505
1448
 
1506
1449
  meshDef.extras = {};
@@ -1518,7 +1461,6 @@
1518
1461
  start: undefined,
1519
1462
  count: undefined
1520
1463
  } ];
1521
-
1522
1464
  for ( let i = 0, il = groups.length; i < il; i ++ ) {
1523
1465
 
1524
1466
  const primitive = {
@@ -1527,11 +1469,9 @@
1527
1469
  };
1528
1470
  this.serializeUserData( geometry, primitive );
1529
1471
  if ( targets.length > 0 ) primitive.targets = targets;
1530
-
1531
1472
  if ( geometry.index !== null ) {
1532
1473
 
1533
1474
  let cacheKey = this.getUID( geometry.index );
1534
-
1535
1475
  if ( groups[ i ].start !== undefined || groups[ i ].count !== undefined ) {
1536
1476
 
1537
1477
  cacheKey += ':' + groups[ i ].start + ':' + groups[ i ].count;
@@ -1561,25 +1501,22 @@
1561
1501
 
1562
1502
  meshDef.primitives = primitives;
1563
1503
  if ( ! json.meshes ) json.meshes = [];
1564
-
1565
1504
  this._invokeAll( function ( ext ) {
1566
1505
 
1567
1506
  ext.writeMesh && ext.writeMesh( mesh, meshDef );
1568
1507
 
1569
1508
  } );
1570
-
1571
1509
  const index = json.meshes.push( meshDef ) - 1;
1572
1510
  cache.meshes.set( meshCacheKey, index );
1573
1511
  return index;
1574
1512
 
1575
1513
  }
1514
+
1576
1515
  /**
1577
1516
  * Process camera
1578
1517
  * @param {THREE.Camera} camera Camera to process
1579
1518
  * @return {Integer} Index of the processed mesh in the "camera" array
1580
1519
  */
1581
-
1582
-
1583
1520
  processCamera( camera ) {
1584
1521
 
1585
1522
  const json = this.json;
@@ -1588,7 +1525,6 @@
1588
1525
  const cameraDef = {
1589
1526
  type: isOrtho ? 'orthographic' : 'perspective'
1590
1527
  };
1591
-
1592
1528
  if ( isOrtho ) {
1593
1529
 
1594
1530
  cameraDef.orthographic = {
@@ -1607,13 +1543,14 @@
1607
1543
  znear: camera.near < 0 ? 0 : camera.near
1608
1544
  };
1609
1545
 
1610
- } // Question: Is saving "type" as name intentional?
1611
-
1546
+ }
1612
1547
 
1548
+ // Question: Is saving "type" as name intentional?
1613
1549
  if ( camera.name !== '' ) cameraDef.name = camera.type;
1614
1550
  return json.cameras.push( cameraDef ) - 1;
1615
1551
 
1616
1552
  }
1553
+
1617
1554
  /**
1618
1555
  * Creates glTF animation entry from AnimationClip object.
1619
1556
  *
@@ -1624,8 +1561,6 @@
1624
1561
  * @param {THREE.Object3D} root
1625
1562
  * @return {number|null}
1626
1563
  */
1627
-
1628
-
1629
1564
  processAnimation( clip, root ) {
1630
1565
 
1631
1566
  const json = this.json;
@@ -1635,14 +1570,12 @@
1635
1570
  const tracks = clip.tracks;
1636
1571
  const channels = [];
1637
1572
  const samplers = [];
1638
-
1639
1573
  for ( let i = 0; i < tracks.length; ++ i ) {
1640
1574
 
1641
1575
  const track = tracks[ i ];
1642
1576
  const trackBinding = THREE.PropertyBinding.parseTrackName( track.name );
1643
1577
  let trackNode = THREE.PropertyBinding.findNode( root, trackBinding.nodeName );
1644
1578
  const trackProperty = PATH_PROPERTIES[ trackBinding.propertyName ];
1645
-
1646
1579
  if ( trackBinding.objectName === 'bones' ) {
1647
1580
 
1648
1581
  if ( trackNode.isSkinnedMesh === true ) {
@@ -1666,24 +1599,26 @@
1666
1599
 
1667
1600
  const inputItemSize = 1;
1668
1601
  let outputItemSize = track.values.length / track.times.length;
1669
-
1670
1602
  if ( trackProperty === PATH_PROPERTIES.morphTargetInfluences ) {
1671
1603
 
1672
1604
  outputItemSize /= trackNode.morphTargetInfluences.length;
1673
1605
 
1674
1606
  }
1675
1607
 
1676
- let interpolation; // @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
1608
+ let interpolation;
1609
+
1610
+ // @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
1611
+
1677
1612
  // Detecting glTF cubic spline interpolant by checking factory method's special property
1678
1613
  // GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
1679
1614
  // valid value from .getInterpolation().
1680
-
1681
1615
  if ( track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true ) {
1682
1616
 
1683
- interpolation = 'CUBICSPLINE'; // itemSize of CUBICSPLINE keyframe is 9
1617
+ interpolation = 'CUBICSPLINE';
1618
+
1619
+ // itemSize of CUBICSPLINE keyframe is 9
1684
1620
  // (VEC3 * 3: inTangent, splineVertex, and outTangent)
1685
1621
  // but needs to be stored as VEC3 so dividing by 3 here.
1686
-
1687
1622
  outputItemSize /= 3;
1688
1623
 
1689
1624
  } else if ( track.getInterpolation() === THREE.InterpolateDiscrete ) {
@@ -1719,12 +1654,11 @@
1719
1654
  return json.animations.length - 1;
1720
1655
 
1721
1656
  }
1657
+
1722
1658
  /**
1723
1659
  * @param {THREE.Object3D} object
1724
1660
  * @return {number|null}
1725
1661
  */
1726
-
1727
-
1728
1662
  processSkin( object ) {
1729
1663
 
1730
1664
  const json = this.json;
@@ -1737,7 +1671,6 @@
1737
1671
  const joints = [];
1738
1672
  const inverseBindMatrices = new Float32Array( skeleton.bones.length * 16 );
1739
1673
  const temporaryBoneInverse = new THREE.Matrix4();
1740
-
1741
1674
  for ( let i = 0; i < skeleton.bones.length; ++ i ) {
1742
1675
 
1743
1676
  joints.push( nodeMap.get( skeleton.bones[ i ] ) );
@@ -1756,13 +1689,12 @@
1756
1689
  return skinIndex;
1757
1690
 
1758
1691
  }
1692
+
1759
1693
  /**
1760
1694
  * Process Object3D node
1761
1695
  * @param {THREE.Object3D} node Object3D to processNode
1762
1696
  * @return {Integer} Index of the node in the nodes list
1763
1697
  */
1764
-
1765
-
1766
1698
  processNode( object ) {
1767
1699
 
1768
1700
  const json = this.json;
@@ -1770,13 +1702,11 @@
1770
1702
  const nodeMap = this.nodeMap;
1771
1703
  if ( ! json.nodes ) json.nodes = [];
1772
1704
  const nodeDef = {};
1773
-
1774
1705
  if ( options.trs ) {
1775
1706
 
1776
1707
  const rotation = object.quaternion.toArray();
1777
1708
  const position = object.position.toArray();
1778
1709
  const scale = object.scale.toArray();
1779
-
1780
1710
  if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
1781
1711
 
1782
1712
  nodeDef.rotation = rotation;
@@ -1809,12 +1739,11 @@
1809
1739
 
1810
1740
  }
1811
1741
 
1812
- } // We don't export empty strings name because it represents no-name in Three.js.
1813
-
1742
+ }
1814
1743
 
1744
+ // We don't export empty strings name because it represents no-name in Three.js.
1815
1745
  if ( object.name !== '' ) nodeDef.name = String( object.name );
1816
1746
  this.serializeUserData( object, nodeDef );
1817
-
1818
1747
  if ( object.isMesh || object.isLine || object.isPoints ) {
1819
1748
 
1820
1749
  const meshIndex = this.processMesh( object );
@@ -1827,15 +1756,12 @@
1827
1756
  }
1828
1757
 
1829
1758
  if ( object.isSkinnedMesh ) this.skins.push( object );
1830
-
1831
1759
  if ( object.children.length > 0 ) {
1832
1760
 
1833
1761
  const children = [];
1834
-
1835
1762
  for ( let i = 0, l = object.children.length; i < l; i ++ ) {
1836
1763
 
1837
1764
  const child = object.children[ i ];
1838
-
1839
1765
  if ( child.visible || options.onlyVisible === false ) {
1840
1766
 
1841
1767
  const nodeIndex = this.processNode( child );
@@ -1854,23 +1780,20 @@
1854
1780
  ext.writeNode && ext.writeNode( object, nodeDef );
1855
1781
 
1856
1782
  } );
1857
-
1858
1783
  const nodeIndex = json.nodes.push( nodeDef ) - 1;
1859
1784
  nodeMap.set( object, nodeIndex );
1860
1785
  return nodeIndex;
1861
1786
 
1862
1787
  }
1788
+
1863
1789
  /**
1864
1790
  * Process THREE.Scene
1865
1791
  * @param {Scene} node THREE.Scene to process
1866
1792
  */
1867
-
1868
-
1869
1793
  processScene( scene ) {
1870
1794
 
1871
1795
  const json = this.json;
1872
1796
  const options = this.options;
1873
-
1874
1797
  if ( ! json.scenes ) {
1875
1798
 
1876
1799
  json.scenes = [];
@@ -1882,11 +1805,9 @@
1882
1805
  if ( scene.name !== '' ) sceneDef.name = scene.name;
1883
1806
  json.scenes.push( sceneDef );
1884
1807
  const nodes = [];
1885
-
1886
1808
  for ( let i = 0, l = scene.children.length; i < l; i ++ ) {
1887
1809
 
1888
1810
  const child = scene.children[ i ];
1889
-
1890
1811
  if ( child.visible || options.onlyVisible === false ) {
1891
1812
 
1892
1813
  const nodeIndex = this.processNode( child );
@@ -1900,17 +1821,15 @@
1900
1821
  this.serializeUserData( scene, sceneDef );
1901
1822
 
1902
1823
  }
1824
+
1903
1825
  /**
1904
1826
  * Creates a THREE.Scene to hold a list of objects and parse it
1905
1827
  * @param {Array} objects List of objects to process
1906
1828
  */
1907
-
1908
-
1909
1829
  processObjects( objects ) {
1910
1830
 
1911
1831
  const scene = new THREE.Scene();
1912
1832
  scene.name = 'AuxScene';
1913
-
1914
1833
  for ( let i = 0; i < objects.length; i ++ ) {
1915
1834
 
1916
1835
  // We push directly to children instead of calling `add` to prevent
@@ -1922,24 +1841,20 @@
1922
1841
  this.processScene( scene );
1923
1842
 
1924
1843
  }
1844
+
1925
1845
  /**
1926
1846
  * @param {THREE.Object3D|Array<THREE.Object3D>} input
1927
1847
  */
1928
-
1929
-
1930
1848
  processInput( input ) {
1931
1849
 
1932
1850
  const options = this.options;
1933
1851
  input = input instanceof Array ? input : [ input ];
1934
-
1935
1852
  this._invokeAll( function ( ext ) {
1936
1853
 
1937
1854
  ext.beforeParse && ext.beforeParse( input );
1938
1855
 
1939
1856
  } );
1940
-
1941
1857
  const objectsWithoutScene = [];
1942
-
1943
1858
  for ( let i = 0; i < input.length; i ++ ) {
1944
1859
 
1945
1860
  if ( input[ i ] instanceof THREE.Scene ) {
@@ -1955,7 +1870,6 @@
1955
1870
  }
1956
1871
 
1957
1872
  if ( objectsWithoutScene.length > 0 ) this.processObjects( objectsWithoutScene );
1958
-
1959
1873
  for ( let i = 0; i < this.skins.length; ++ i ) {
1960
1874
 
1961
1875
  this.processSkin( this.skins[ i ] );
@@ -1975,7 +1889,6 @@
1975
1889
  } );
1976
1890
 
1977
1891
  }
1978
-
1979
1892
  _invokeAll( func ) {
1980
1893
 
1981
1894
  for ( let i = 0, il = this.plugins.length; i < il; i ++ ) {
@@ -1987,13 +1900,12 @@
1987
1900
  }
1988
1901
 
1989
1902
  }
1903
+
1990
1904
  /**
1991
1905
  * Punctual Lights Extension
1992
1906
  *
1993
1907
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
1994
1908
  */
1995
-
1996
-
1997
1909
  class GLTFLightExtension {
1998
1910
 
1999
1911
  constructor( writer ) {
@@ -2002,11 +1914,9 @@
2002
1914
  this.name = 'KHR_lights_punctual';
2003
1915
 
2004
1916
  }
2005
-
2006
1917
  writeNode( light, nodeDef ) {
2007
1918
 
2008
1919
  if ( ! light.isLight ) return;
2009
-
2010
1920
  if ( ! light.isDirectionalLight && ! light.isPointLight && ! light.isSpotLight ) {
2011
1921
 
2012
1922
  console.warn( 'THREE.GLTFExporter: Only directional, point, and spot lights are supported.', light );
@@ -2021,7 +1931,6 @@
2021
1931
  if ( light.name ) lightDef.name = light.name;
2022
1932
  lightDef.color = light.color.toArray();
2023
1933
  lightDef.intensity = light.intensity;
2024
-
2025
1934
  if ( light.isDirectionalLight ) {
2026
1935
 
2027
1936
  lightDef.type = 'directional';
@@ -2073,13 +1982,12 @@
2073
1982
  }
2074
1983
 
2075
1984
  }
1985
+
2076
1986
  /**
2077
1987
  * Unlit Materials Extension
2078
1988
  *
2079
1989
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
2080
1990
  */
2081
-
2082
-
2083
1991
  class GLTFMaterialsUnlitExtension {
2084
1992
 
2085
1993
  constructor( writer ) {
@@ -2088,7 +1996,6 @@
2088
1996
  this.name = 'KHR_materials_unlit';
2089
1997
 
2090
1998
  }
2091
-
2092
1999
  writeMaterial( material, materialDef ) {
2093
2000
 
2094
2001
  if ( ! material.isMeshBasicMaterial ) return;
@@ -2103,13 +2010,12 @@
2103
2010
  }
2104
2011
 
2105
2012
  }
2013
+
2106
2014
  /**
2107
2015
  * Specular-Glossiness Extension
2108
2016
  *
2109
2017
  * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness
2110
2018
  */
2111
-
2112
-
2113
2019
  class GLTFMaterialsPBRSpecularGlossiness {
2114
2020
 
2115
2021
  constructor( writer ) {
@@ -2118,14 +2024,12 @@
2118
2024
  this.name = 'KHR_materials_pbrSpecularGlossiness';
2119
2025
 
2120
2026
  }
2121
-
2122
2027
  writeMaterial( material, materialDef ) {
2123
2028
 
2124
2029
  if ( ! material.isGLTFSpecularGlossinessMaterial ) return;
2125
2030
  const writer = this.writer;
2126
2031
  const extensionsUsed = writer.extensionsUsed;
2127
2032
  const extensionDef = {};
2128
-
2129
2033
  if ( materialDef.pbrMetallicRoughness.baseColorFactor ) {
2130
2034
 
2131
2035
  extensionDef.diffuseFactor = materialDef.pbrMetallicRoughness.baseColorFactor;
@@ -2136,7 +2040,6 @@
2136
2040
  material.specular.toArray( specularFactor, 0 );
2137
2041
  extensionDef.specularFactor = specularFactor;
2138
2042
  extensionDef.glossinessFactor = material.glossiness;
2139
-
2140
2043
  if ( materialDef.pbrMetallicRoughness.baseColorTexture ) {
2141
2044
 
2142
2045
  extensionDef.diffuseTexture = materialDef.pbrMetallicRoughness.baseColorTexture;
@@ -2160,13 +2063,12 @@
2160
2063
  }
2161
2064
 
2162
2065
  }
2066
+
2163
2067
  /**
2164
2068
  * Clearcoat Materials Extension
2165
2069
  *
2166
2070
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
2167
2071
  */
2168
-
2169
-
2170
2072
  class GLTFMaterialsClearcoatExtension {
2171
2073
 
2172
2074
  constructor( writer ) {
@@ -2175,7 +2077,6 @@
2175
2077
  this.name = 'KHR_materials_clearcoat';
2176
2078
 
2177
2079
  }
2178
-
2179
2080
  writeMaterial( material, materialDef ) {
2180
2081
 
2181
2082
  if ( ! material.isMeshPhysicalMaterial ) return;
@@ -2183,7 +2084,6 @@
2183
2084
  const extensionsUsed = writer.extensionsUsed;
2184
2085
  const extensionDef = {};
2185
2086
  extensionDef.clearcoatFactor = material.clearcoat;
2186
-
2187
2087
  if ( material.clearcoatMap ) {
2188
2088
 
2189
2089
  const clearcoatMapDef = {
@@ -2195,7 +2095,6 @@
2195
2095
  }
2196
2096
 
2197
2097
  extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
2198
-
2199
2098
  if ( material.clearcoatRoughnessMap ) {
2200
2099
 
2201
2100
  const clearcoatRoughnessMapDef = {
@@ -2223,13 +2122,12 @@
2223
2122
  }
2224
2123
 
2225
2124
  }
2125
+
2226
2126
  /**
2227
2127
  * Iridescence Materials Extension
2228
2128
  *
2229
2129
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
2230
2130
  */
2231
-
2232
-
2233
2131
  class GLTFMaterialsIridescenceExtension {
2234
2132
 
2235
2133
  constructor( writer ) {
@@ -2238,7 +2136,6 @@
2238
2136
  this.name = 'KHR_materials_iridescence';
2239
2137
 
2240
2138
  }
2241
-
2242
2139
  writeMaterial( material, materialDef ) {
2243
2140
 
2244
2141
  if ( ! material.isMeshPhysicalMaterial ) return;
@@ -2246,7 +2143,6 @@
2246
2143
  const extensionsUsed = writer.extensionsUsed;
2247
2144
  const extensionDef = {};
2248
2145
  extensionDef.iridescenceFactor = material.iridescence;
2249
-
2250
2146
  if ( material.iridescenceMap ) {
2251
2147
 
2252
2148
  const iridescenceMapDef = {
@@ -2260,7 +2156,6 @@
2260
2156
  extensionDef.iridescenceIor = material.iridescenceIOR;
2261
2157
  extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[ 0 ];
2262
2158
  extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[ 1 ];
2263
-
2264
2159
  if ( material.iridescenceThicknessMap ) {
2265
2160
 
2266
2161
  const iridescenceThicknessMapDef = {
@@ -2278,13 +2173,12 @@
2278
2173
  }
2279
2174
 
2280
2175
  }
2176
+
2281
2177
  /**
2282
2178
  * Transmission Materials Extension
2283
2179
  *
2284
2180
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
2285
2181
  */
2286
-
2287
-
2288
2182
  class GLTFMaterialsTransmissionExtension {
2289
2183
 
2290
2184
  constructor( writer ) {
@@ -2293,7 +2187,6 @@
2293
2187
  this.name = 'KHR_materials_transmission';
2294
2188
 
2295
2189
  }
2296
-
2297
2190
  writeMaterial( material, materialDef ) {
2298
2191
 
2299
2192
  if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
@@ -2301,7 +2194,6 @@
2301
2194
  const extensionsUsed = writer.extensionsUsed;
2302
2195
  const extensionDef = {};
2303
2196
  extensionDef.transmissionFactor = material.transmission;
2304
-
2305
2197
  if ( material.transmissionMap ) {
2306
2198
 
2307
2199
  const transmissionMapDef = {
@@ -2319,13 +2211,12 @@
2319
2211
  }
2320
2212
 
2321
2213
  }
2214
+
2322
2215
  /**
2323
2216
  * Materials Volume Extension
2324
2217
  *
2325
2218
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
2326
2219
  */
2327
-
2328
-
2329
2220
  class GLTFMaterialsVolumeExtension {
2330
2221
 
2331
2222
  constructor( writer ) {
@@ -2334,7 +2225,6 @@
2334
2225
  this.name = 'KHR_materials_volume';
2335
2226
 
2336
2227
  }
2337
-
2338
2228
  writeMaterial( material, materialDef ) {
2339
2229
 
2340
2230
  if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
@@ -2342,7 +2232,6 @@
2342
2232
  const extensionsUsed = writer.extensionsUsed;
2343
2233
  const extensionDef = {};
2344
2234
  extensionDef.thicknessFactor = material.thickness;
2345
-
2346
2235
  if ( material.thicknessMap ) {
2347
2236
 
2348
2237
  const thicknessMapDef = {
@@ -2362,26 +2251,22 @@
2362
2251
  }
2363
2252
 
2364
2253
  }
2254
+
2365
2255
  /**
2366
2256
  * Static utility functions
2367
2257
  */
2368
-
2369
-
2370
2258
  GLTFExporter.Utils = {
2371
2259
  insertKeyframe: function ( track, time ) {
2372
2260
 
2373
2261
  const tolerance = 0.001; // 1ms
2374
-
2375
2262
  const valueSize = track.getValueSize();
2376
2263
  const times = new track.TimeBufferType( track.times.length + 1 );
2377
2264
  const values = new track.ValueBufferType( track.values.length + valueSize );
2378
2265
  const interpolant = track.createInterpolant( new track.ValueBufferType( valueSize ) );
2379
2266
  let index;
2380
-
2381
2267
  if ( track.times.length === 0 ) {
2382
2268
 
2383
2269
  times[ 0 ] = time;
2384
-
2385
2270
  for ( let i = 0; i < valueSize; i ++ ) {
2386
2271
 
2387
2272
  values[ i ] = 0;
@@ -2418,7 +2303,6 @@
2418
2303
  for ( let i = 0; i < track.times.length; i ++ ) {
2419
2304
 
2420
2305
  if ( Math.abs( track.times[ i ] - time ) < tolerance ) return i;
2421
-
2422
2306
  if ( track.times[ i ] < time && track.times[ i + 1 ] > time ) {
2423
2307
 
2424
2308
  times.set( track.times.slice( 0, i + 1 ), 0 );
@@ -2446,13 +2330,11 @@
2446
2330
  const tracks = [];
2447
2331
  const mergedTracks = {};
2448
2332
  const sourceTracks = clip.tracks;
2449
-
2450
2333
  for ( let i = 0; i < sourceTracks.length; ++ i ) {
2451
2334
 
2452
2335
  let sourceTrack = sourceTracks[ i ];
2453
2336
  const sourceTrackBinding = THREE.PropertyBinding.parseTrackName( sourceTrack.name );
2454
2337
  const sourceTrackNode = THREE.PropertyBinding.findNode( root, sourceTrackBinding.nodeName );
2455
-
2456
2338
  if ( sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined ) {
2457
2339
 
2458
2340
  // Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is.
@@ -2479,29 +2361,28 @@
2479
2361
 
2480
2362
  const targetCount = sourceTrackNode.morphTargetInfluences.length;
2481
2363
  const targetIndex = sourceTrackNode.morphTargetDictionary[ sourceTrackBinding.propertyIndex ];
2482
-
2483
2364
  if ( targetIndex === undefined ) {
2484
2365
 
2485
2366
  throw new Error( 'THREE.GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex );
2486
2367
 
2487
2368
  }
2488
2369
 
2489
- let mergedTrack; // If this is the first time we've seen this object, create a new
2490
- // track to store merged keyframe data for each morph target.
2370
+ let mergedTrack;
2491
2371
 
2372
+ // If this is the first time we've seen this object, create a new
2373
+ // track to store merged keyframe data for each morph target.
2492
2374
  if ( mergedTracks[ sourceTrackNode.uuid ] === undefined ) {
2493
2375
 
2494
2376
  mergedTrack = sourceTrack.clone();
2495
2377
  const values = new mergedTrack.ValueBufferType( targetCount * mergedTrack.times.length );
2496
-
2497
2378
  for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
2498
2379
 
2499
2380
  values[ j * targetCount + targetIndex ] = mergedTrack.values[ j ];
2500
2381
 
2501
- } // We need to take into consideration the intended target node
2502
- // of our original un-merged morphTarget animation.
2503
-
2382
+ }
2504
2383
 
2384
+ // We need to take into consideration the intended target node
2385
+ // of our original un-merged morphTarget animation.
2505
2386
  mergedTrack.name = ( sourceTrackBinding.nodeName || '' ) + '.morphTargetInfluences';
2506
2387
  mergedTrack.values = values;
2507
2388
  mergedTracks[ sourceTrackNode.uuid ] = mergedTrack;
@@ -2511,18 +2392,19 @@
2511
2392
  }
2512
2393
 
2513
2394
  const sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) );
2514
- mergedTrack = mergedTracks[ sourceTrackNode.uuid ]; // For every existing keyframe of the merged track, write a (possibly
2515
- // interpolated) value from the source track.
2395
+ mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
2516
2396
 
2397
+ // For every existing keyframe of the merged track, write a (possibly
2398
+ // interpolated) value from the source track.
2517
2399
  for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
2518
2400
 
2519
2401
  mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] );
2520
2402
 
2521
- } // For every existing keyframe of the source track, write a (possibly
2403
+ }
2404
+
2405
+ // For every existing keyframe of the source track, write a (possibly
2522
2406
  // new) keyframe to the merged track. Values from the previous loop may
2523
2407
  // be written again, but keyframes are de-duplicated.
2524
-
2525
-
2526
2408
  for ( let j = 0; j < sourceTrack.times.length; j ++ ) {
2527
2409
 
2528
2410
  const keyframeIndex = this.insertKeyframe( mergedTrack, sourceTrack.times[ j ] );