@needle-tools/three 0.145.2 → 0.146.1

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 (394) hide show
  1. package/README.md +1 -1
  2. package/build/three.cjs +3559 -6924
  3. package/build/three.js +3559 -6924
  4. package/build/three.min.js +1 -2
  5. package/build/three.module.js +732 -339
  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 +94 -28
  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/WebGLCubeUVMaps.js +1 -1
  381. package/src/renderers/webgl/WebGLLights.js +0 -4
  382. package/src/renderers/webgl/WebGLMaterials.js +2 -1
  383. package/src/renderers/webgl/WebGLShadowMap.js +3 -1
  384. package/src/renderers/webgl/WebGLState.js +31 -1
  385. package/src/renderers/webgl/WebGLTextures.js +71 -18
  386. package/src/renderers/webgl/WebGLUniforms.js +116 -20
  387. package/src/renderers/webgl/WebGLUtils.js +1 -1
  388. package/src/renderers/webxr/WebXRController.js +46 -13
  389. package/src/renderers/webxr/WebXRManager.js +85 -3
  390. package/src/scenes/Scene.js +8 -0
  391. package/src/textures/CompressedArrayTexture.js +18 -0
  392. package/examples/js/libs/lottie_canvas.js +0 -12751
  393. package/examples/js/shaders/PixelShader.js +0 -51
  394. package/examples/jsm/shaders/PixelShader.js +0 -44
@@ -7,7 +7,6 @@
7
7
  super( manager );
8
8
 
9
9
  }
10
-
11
10
  load( url, onLoad, onProgress, onError ) {
12
11
 
13
12
  const scope = this;
@@ -41,19 +40,17 @@
41
40
  }, onProgress, onError );
42
41
 
43
42
  }
44
-
45
43
  parse( text, path ) {
46
44
 
47
45
  function getElementsByTagName( xml, name ) {
48
46
 
49
47
  // Non recursive xml.getElementsByTagName() ...
48
+
50
49
  const array = [];
51
50
  const childNodes = xml.childNodes;
52
-
53
51
  for ( let i = 0, l = childNodes.length; i < l; i ++ ) {
54
52
 
55
53
  const child = childNodes[ i ];
56
-
57
54
  if ( child.nodeName === name ) {
58
55
 
59
56
  array.push( child );
@@ -71,7 +68,6 @@
71
68
  if ( text.length === 0 ) return [];
72
69
  const parts = text.trim().split( /\s+/ );
73
70
  const array = new Array( parts.length );
74
-
75
71
  for ( let i = 0, l = parts.length; i < l; i ++ ) {
76
72
 
77
73
  array[ i ] = parts[ i ];
@@ -87,7 +83,6 @@
87
83
  if ( text.length === 0 ) return [];
88
84
  const parts = text.trim().split( /\s+/ );
89
85
  const array = new Array( parts.length );
90
-
91
86
  for ( let i = 0, l = parts.length; i < l; i ++ ) {
92
87
 
93
88
  array[ i ] = parseFloat( parts[ i ] );
@@ -103,7 +98,6 @@
103
98
  if ( text.length === 0 ) return [];
104
99
  const parts = text.trim().split( /\s+/ );
105
100
  const array = new Array( parts.length );
106
-
107
101
  for ( let i = 0, l = parts.length; i < l; i ++ ) {
108
102
 
109
103
  array[ i ] = parseInt( parts[ i ] );
@@ -130,8 +124,9 @@
130
124
 
131
125
  return Object.keys( object ).length === 0;
132
126
 
133
- } // asset
127
+ }
134
128
 
129
+ // asset
135
130
 
136
131
  function parseAsset( xml ) {
137
132
 
@@ -160,17 +155,16 @@
160
155
 
161
156
  return xml !== undefined ? xml.textContent : 'Y_UP';
162
157
 
163
- } // library
158
+ }
164
159
 
160
+ // library
165
161
 
166
162
  function parseLibrary( xml, libraryName, nodeName, parser ) {
167
163
 
168
164
  const library = getElementsByTagName( xml, libraryName )[ 0 ];
169
-
170
165
  if ( library !== undefined ) {
171
166
 
172
167
  const elements = getElementsByTagName( library, nodeName );
173
-
174
168
  for ( let i = 0; i < elements.length; i ++ ) {
175
169
 
176
170
  parser( elements[ i ] );
@@ -190,8 +184,9 @@
190
184
 
191
185
  }
192
186
 
193
- } // get
187
+ }
194
188
 
189
+ // get
195
190
 
196
191
  function getBuild( data, builder ) {
197
192
 
@@ -199,8 +194,9 @@
199
194
  data.build = builder( data );
200
195
  return data.build;
201
196
 
202
- } // animation
197
+ }
203
198
 
199
+ // animation
204
200
 
205
201
  function parseAnimation( xml ) {
206
202
 
@@ -210,36 +206,30 @@
210
206
  channels: {}
211
207
  };
212
208
  let hasChildren = false;
213
-
214
209
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
215
210
 
216
211
  const child = xml.childNodes[ i ];
217
212
  if ( child.nodeType !== 1 ) continue;
218
213
  let id;
219
-
220
214
  switch ( child.nodeName ) {
221
215
 
222
216
  case 'source':
223
217
  id = child.getAttribute( 'id' );
224
218
  data.sources[ id ] = parseSource( child );
225
219
  break;
226
-
227
220
  case 'sampler':
228
221
  id = child.getAttribute( 'id' );
229
222
  data.samplers[ id ] = parseAnimationSampler( child );
230
223
  break;
231
-
232
224
  case 'channel':
233
225
  id = child.getAttribute( 'target' );
234
226
  data.channels[ id ] = parseAnimationChannel( child );
235
227
  break;
236
-
237
228
  case 'animation':
238
229
  // hierarchy of related animations
239
230
  parseAnimation( child );
240
231
  hasChildren = true;
241
232
  break;
242
-
243
233
  default:
244
234
  console.log( child );
245
235
 
@@ -250,6 +240,7 @@
250
240
  if ( hasChildren === false ) {
251
241
 
252
242
  // since 'id' attributes can be optional, it's necessary to generate a UUID for unqiue assignment
243
+
253
244
  library.animations[ xml.getAttribute( 'id' ) || THREE.MathUtils.generateUUID() ] = data;
254
245
 
255
246
  }
@@ -261,12 +252,10 @@
261
252
  const data = {
262
253
  inputs: {}
263
254
  };
264
-
265
255
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
266
256
 
267
257
  const child = xml.childNodes[ i ];
268
258
  if ( child.nodeType !== 1 ) continue;
269
-
270
259
  switch ( child.nodeName ) {
271
260
 
272
261
  case 'input':
@@ -286,18 +275,22 @@
286
275
  function parseAnimationChannel( xml ) {
287
276
 
288
277
  const data = {};
289
- const target = xml.getAttribute( 'target' ); // parsing SID Addressing Syntax
278
+ const target = xml.getAttribute( 'target' );
279
+
280
+ // parsing SID Addressing Syntax
290
281
 
291
282
  let parts = target.split( '/' );
292
283
  const id = parts.shift();
293
- let sid = parts.shift(); // check selection syntax
284
+ let sid = parts.shift();
285
+
286
+ // check selection syntax
294
287
 
295
288
  const arraySyntax = sid.indexOf( '(' ) !== - 1;
296
289
  const memberSyntax = sid.indexOf( '.' ) !== - 1;
297
-
298
290
  if ( memberSyntax ) {
299
291
 
300
292
  // member selection access
293
+
301
294
  parts = sid.split( '.' );
302
295
  sid = parts.shift();
303
296
  data.member = parts.shift();
@@ -305,9 +298,9 @@
305
298
  } else if ( arraySyntax ) {
306
299
 
307
300
  // array-access syntax. can be used to express fields in one-dimensional vectors or two-dimensional matrices.
301
+
308
302
  const indices = sid.split( '(' );
309
303
  sid = indices.shift();
310
-
311
304
  for ( let i = 0; i < indices.length; i ++ ) {
312
305
 
313
306
  indices[ i ] = parseInt( indices[ i ].replace( /\)/, '' ) );
@@ -333,7 +326,6 @@
333
326
  const channels = data.channels;
334
327
  const samplers = data.samplers;
335
328
  const sources = data.sources;
336
-
337
329
  for ( const target in channels ) {
338
330
 
339
331
  if ( channels.hasOwnProperty( target ) ) {
@@ -369,7 +361,9 @@
369
361
  const defaultMatrix = node.matrix.clone().transpose();
370
362
  let time, stride;
371
363
  let i, il, j, jl;
372
- const data = {}; // the collada spec allows the animation of data in various ways.
364
+ const data = {};
365
+
366
+ // the collada spec allows the animation of data in various ways.
373
367
  // depending on the transform type (matrix, translate, rotate, scale), we execute different logic
374
368
 
375
369
  switch ( transform ) {
@@ -380,7 +374,6 @@
380
374
  time = inputSource.array[ i ];
381
375
  stride = i * outputSource.stride;
382
376
  if ( data[ time ] === undefined ) data[ time ] = {};
383
-
384
377
  if ( channel.arraySyntax === true ) {
385
378
 
386
379
  const value = outputSource.array[ stride ];
@@ -400,15 +393,12 @@
400
393
  }
401
394
 
402
395
  break;
403
-
404
396
  case 'translate':
405
397
  console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform );
406
398
  break;
407
-
408
399
  case 'rotate':
409
400
  console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform );
410
401
  break;
411
-
412
402
  case 'scale':
413
403
  console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform );
414
404
  break;
@@ -426,7 +416,9 @@
426
416
 
427
417
  function prepareAnimationData( data, defaultMatrix ) {
428
418
 
429
- const keyframes = []; // transfer data into a sortable array
419
+ const keyframes = [];
420
+
421
+ // transfer data into a sortable array
430
422
 
431
423
  for ( const time in data ) {
432
424
 
@@ -435,10 +427,13 @@
435
427
  value: data[ time ]
436
428
  } );
437
429
 
438
- } // ensure keyframes are sorted by time
430
+ }
431
+
432
+ // ensure keyframes are sorted by time
439
433
 
434
+ keyframes.sort( ascending );
440
435
 
441
- keyframes.sort( ascending ); // now we clean up all animation data, so we can use them for keyframe tracks
436
+ // now we clean up all animation data, so we can use them for keyframe tracks
442
437
 
443
438
  for ( let i = 0; i < 16; i ++ ) {
444
439
 
@@ -446,7 +441,9 @@
446
441
 
447
442
  }
448
443
 
449
- return keyframes; // array sort function
444
+ return keyframes;
445
+
446
+ // array sort function
450
447
 
451
448
  function ascending( a, b ) {
452
449
 
@@ -459,7 +456,6 @@
459
456
  const position = new THREE.Vector3();
460
457
  const scale = new THREE.Vector3();
461
458
  const quaternion = new THREE.Quaternion();
462
-
463
459
  function createKeyframeTracks( animation, tracks ) {
464
460
 
465
461
  const keyframes = animation.keyframes;
@@ -468,7 +464,6 @@
468
464
  const positionData = [];
469
465
  const quaternionData = [];
470
466
  const scaleData = [];
471
-
472
467
  for ( let i = 0, l = keyframes.length; i < l; i ++ ) {
473
468
 
474
469
  const keyframe = keyframes[ i ];
@@ -494,12 +489,13 @@
494
489
 
495
490
  let keyframe;
496
491
  let empty = true;
497
- let i, l; // check, if values of a property are missing in our keyframes
492
+ let i, l;
493
+
494
+ // check, if values of a property are missing in our keyframes
498
495
 
499
496
  for ( i = 0, l = keyframes.length; i < l; i ++ ) {
500
497
 
501
498
  keyframe = keyframes[ i ];
502
-
503
499
  if ( keyframe.value[ property ] === undefined ) {
504
500
 
505
501
  keyframe.value[ property ] = null; // mark as missing
@@ -515,6 +511,7 @@
515
511
  if ( empty === true ) {
516
512
 
517
513
  // no values at all, so we set a default value
514
+
518
515
  for ( i = 0, l = keyframes.length; i < l; i ++ ) {
519
516
 
520
517
  keyframe = keyframes[ i ];
@@ -525,6 +522,7 @@
525
522
  } else {
526
523
 
527
524
  // filling gaps
525
+
528
526
  createMissingKeyframes( keyframes, property );
529
527
 
530
528
  }
@@ -534,16 +532,13 @@
534
532
  function createMissingKeyframes( keyframes, property ) {
535
533
 
536
534
  let prev, next;
537
-
538
535
  for ( let i = 0, l = keyframes.length; i < l; i ++ ) {
539
536
 
540
537
  const keyframe = keyframes[ i ];
541
-
542
538
  if ( keyframe.value[ property ] === null ) {
543
539
 
544
540
  prev = getPrev( keyframes, i, property );
545
541
  next = getNext( keyframes, i, property );
546
-
547
542
  if ( prev === null ) {
548
543
 
549
544
  keyframe.value[ property ] = next.value[ property ];
@@ -605,8 +600,9 @@
605
600
 
606
601
  key.value[ property ] = ( key.time - prev.time ) * ( next.value[ property ] - prev.value[ property ] ) / ( next.time - prev.time ) + prev.value[ property ];
607
602
 
608
- } // animation clips
603
+ }
609
604
 
605
+ // animation clips
610
606
 
611
607
  function parseAnimationClip( xml ) {
612
608
 
@@ -616,12 +612,10 @@
616
612
  end: parseFloat( xml.getAttribute( 'end' ) || 0 ),
617
613
  animations: []
618
614
  };
619
-
620
615
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
621
616
 
622
617
  const child = xml.childNodes[ i ];
623
618
  if ( child.nodeType !== 1 ) continue;
624
-
625
619
  switch ( child.nodeName ) {
626
620
 
627
621
  case 'instance_animation':
@@ -642,11 +636,9 @@
642
636
  const name = data.name;
643
637
  const duration = data.end - data.start || - 1;
644
638
  const animations = data.animations;
645
-
646
639
  for ( let i = 0, il = animations.length; i < il; i ++ ) {
647
640
 
648
641
  const animationTracks = getAnimation( animations[ i ] );
649
-
650
642
  for ( let j = 0, jl = animationTracks.length; j < jl; j ++ ) {
651
643
 
652
644
  tracks.push( animationTracks[ j ] );
@@ -663,18 +655,17 @@
663
655
 
664
656
  return getBuild( library.clips[ id ], buildAnimationClip );
665
657
 
666
- } // controller
658
+ }
667
659
 
660
+ // controller
668
661
 
669
662
  function parseController( xml ) {
670
663
 
671
664
  const data = {};
672
-
673
665
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
674
666
 
675
667
  const child = xml.childNodes[ i ];
676
668
  if ( child.nodeType !== 1 ) continue;
677
-
678
669
  switch ( child.nodeName ) {
679
670
 
680
671
  case 'skin':
@@ -682,7 +673,6 @@
682
673
  data.id = parseId( child.getAttribute( 'source' ) );
683
674
  data.skin = parseSkin( child );
684
675
  break;
685
-
686
676
  case 'morph':
687
677
  data.id = parseId( child.getAttribute( 'source' ) );
688
678
  console.warn( 'THREE.ColladaLoader: Morph target animation not supported yet.' );
@@ -701,27 +691,22 @@
701
691
  const data = {
702
692
  sources: {}
703
693
  };
704
-
705
694
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
706
695
 
707
696
  const child = xml.childNodes[ i ];
708
697
  if ( child.nodeType !== 1 ) continue;
709
-
710
698
  switch ( child.nodeName ) {
711
699
 
712
700
  case 'bind_shape_matrix':
713
701
  data.bindShapeMatrix = parseFloats( child.textContent );
714
702
  break;
715
-
716
703
  case 'source':
717
704
  const id = child.getAttribute( 'id' );
718
705
  data.sources[ id ] = parseSource( child );
719
706
  break;
720
-
721
707
  case 'joints':
722
708
  data.joints = parseJoints( child );
723
709
  break;
724
-
725
710
  case 'vertex_weights':
726
711
  data.vertexWeights = parseVertexWeights( child );
727
712
  break;
@@ -739,12 +724,10 @@
739
724
  const data = {
740
725
  inputs: {}
741
726
  };
742
-
743
727
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
744
728
 
745
729
  const child = xml.childNodes[ i ];
746
730
  if ( child.nodeType !== 1 ) continue;
747
-
748
731
  switch ( child.nodeName ) {
749
732
 
750
733
  case 'input':
@@ -766,12 +749,10 @@
766
749
  const data = {
767
750
  inputs: {}
768
751
  };
769
-
770
752
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
771
753
 
772
754
  const child = xml.childNodes[ i ];
773
755
  if ( child.nodeType !== 1 ) continue;
774
-
775
756
  switch ( child.nodeName ) {
776
757
 
777
758
  case 'input':
@@ -783,11 +764,9 @@
783
764
  offset: offset
784
765
  };
785
766
  break;
786
-
787
767
  case 'vcount':
788
768
  data.vcount = parseInts( child.textContent );
789
769
  break;
790
-
791
770
  case 'v':
792
771
  data.v = parseInts( child.textContent );
793
772
  break;
@@ -806,10 +785,11 @@
806
785
  id: data.id
807
786
  };
808
787
  const geometry = library.geometries[ build.id ];
809
-
810
788
  if ( data.skin !== undefined ) {
811
789
 
812
- build.skin = buildSkin( data.skin ); // we enhance the 'sources' property of the corresponding geometry with our skin data
790
+ build.skin = buildSkin( data.skin );
791
+
792
+ // we enhance the 'sources' property of the corresponding geometry with our skin data
813
793
 
814
794
  geometry.sources.skinIndices = build.skin.indices;
815
795
  geometry.sources.skinWeights = build.skin.weights;
@@ -845,14 +825,14 @@
845
825
  const inverseSource = data.sources[ data.joints.inputs.INV_BIND_MATRIX ];
846
826
  const weights = sources[ vertexWeights.inputs.WEIGHT.id ].array;
847
827
  let stride = 0;
848
- let i, j, l; // procces skin data for each vertex
828
+ let i, j, l;
829
+
830
+ // procces skin data for each vertex
849
831
 
850
832
  for ( i = 0, l = vcount.length; i < l; i ++ ) {
851
833
 
852
834
  const jointCount = vcount[ i ]; // this is the amount of joints that affect a single vertex
853
-
854
835
  const vertexSkinData = [];
855
-
856
836
  for ( j = 0; j < jointCount; j ++ ) {
857
837
 
858
838
  const skinIndex = v[ stride + jointOffset ];
@@ -864,17 +844,19 @@
864
844
  } );
865
845
  stride += 2;
866
846
 
867
- } // we sort the joints in descending order based on the weights.
847
+ }
848
+
849
+ // we sort the joints in descending order based on the weights.
868
850
  // this ensures, we only procced the most important joints of the vertex
869
851
 
852
+ vertexSkinData.sort( descending );
870
853
 
871
- vertexSkinData.sort( descending ); // now we provide for each vertex a set of four index and weight values.
854
+ // now we provide for each vertex a set of four index and weight values.
872
855
  // the order of the skin data matches the order of vertices
873
856
 
874
857
  for ( j = 0; j < BONE_LIMIT; j ++ ) {
875
858
 
876
859
  const d = vertexSkinData[ j ];
877
-
878
860
  if ( d !== undefined ) {
879
861
 
880
862
  build.indices.array.push( d.index );
@@ -889,8 +871,9 @@
889
871
 
890
872
  }
891
873
 
892
- } // setup bind matrix
874
+ }
893
875
 
876
+ // setup bind matrix
894
877
 
895
878
  if ( data.bindShapeMatrix ) {
896
879
 
@@ -900,8 +883,9 @@
900
883
 
901
884
  build.bindMatrix = new THREE.Matrix4().identity();
902
885
 
903
- } // process bones and inverse bind matrix data
886
+ }
904
887
 
888
+ // process bones and inverse bind matrix data
905
889
 
906
890
  for ( i = 0, l = jointSource.array.length; i < l; i ++ ) {
907
891
 
@@ -914,7 +898,9 @@
914
898
 
915
899
  }
916
900
 
917
- return build; // array sort function
901
+ return build;
902
+
903
+ // array sort function
918
904
 
919
905
  function descending( a, b ) {
920
906
 
@@ -928,8 +914,9 @@
928
914
 
929
915
  return getBuild( library.controllers[ id ], buildController );
930
916
 
931
- } // image
917
+ }
932
918
 
919
+ // image
933
920
 
934
921
  function parseImage( xml ) {
935
922
 
@@ -950,7 +937,6 @@
950
937
  function getImage( id ) {
951
938
 
952
939
  const data = library.images[ id ];
953
-
954
940
  if ( data !== undefined ) {
955
941
 
956
942
  return getBuild( data, buildImage );
@@ -960,18 +946,17 @@
960
946
  console.warn( 'THREE.ColladaLoader: Couldn\'t find image with ID:', id );
961
947
  return null;
962
948
 
963
- } // effect
949
+ }
964
950
 
951
+ // effect
965
952
 
966
953
  function parseEffect( xml ) {
967
954
 
968
955
  const data = {};
969
-
970
956
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
971
957
 
972
958
  const child = xml.childNodes[ i ];
973
959
  if ( child.nodeType !== 1 ) continue;
974
-
975
960
  switch ( child.nodeName ) {
976
961
 
977
962
  case 'profile_COMMON':
@@ -992,22 +977,18 @@
992
977
  surfaces: {},
993
978
  samplers: {}
994
979
  };
995
-
996
980
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
997
981
 
998
982
  const child = xml.childNodes[ i ];
999
983
  if ( child.nodeType !== 1 ) continue;
1000
-
1001
984
  switch ( child.nodeName ) {
1002
985
 
1003
986
  case 'newparam':
1004
987
  parseEffectNewparam( child, data );
1005
988
  break;
1006
-
1007
989
  case 'technique':
1008
990
  data.technique = parseEffectTechnique( child );
1009
991
  break;
1010
-
1011
992
  case 'extra':
1012
993
  data.extra = parseEffectExtra( child );
1013
994
  break;
@@ -1023,18 +1004,15 @@
1023
1004
  function parseEffectNewparam( xml, data ) {
1024
1005
 
1025
1006
  const sid = xml.getAttribute( 'sid' );
1026
-
1027
1007
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1028
1008
 
1029
1009
  const child = xml.childNodes[ i ];
1030
1010
  if ( child.nodeType !== 1 ) continue;
1031
-
1032
1011
  switch ( child.nodeName ) {
1033
1012
 
1034
1013
  case 'surface':
1035
1014
  data.surfaces[ sid ] = parseEffectSurface( child );
1036
1015
  break;
1037
-
1038
1016
  case 'sampler2D':
1039
1017
  data.samplers[ sid ] = parseEffectSampler( child );
1040
1018
  break;
@@ -1048,12 +1026,10 @@
1048
1026
  function parseEffectSurface( xml ) {
1049
1027
 
1050
1028
  const data = {};
1051
-
1052
1029
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1053
1030
 
1054
1031
  const child = xml.childNodes[ i ];
1055
1032
  if ( child.nodeType !== 1 ) continue;
1056
-
1057
1033
  switch ( child.nodeName ) {
1058
1034
 
1059
1035
  case 'init_from':
@@ -1071,12 +1047,10 @@
1071
1047
  function parseEffectSampler( xml ) {
1072
1048
 
1073
1049
  const data = {};
1074
-
1075
1050
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1076
1051
 
1077
1052
  const child = xml.childNodes[ i ];
1078
1053
  if ( child.nodeType !== 1 ) continue;
1079
-
1080
1054
  switch ( child.nodeName ) {
1081
1055
 
1082
1056
  case 'source':
@@ -1094,12 +1068,10 @@
1094
1068
  function parseEffectTechnique( xml ) {
1095
1069
 
1096
1070
  const data = {};
1097
-
1098
1071
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1099
1072
 
1100
1073
  const child = xml.childNodes[ i ];
1101
1074
  if ( child.nodeType !== 1 ) continue;
1102
-
1103
1075
  switch ( child.nodeName ) {
1104
1076
 
1105
1077
  case 'constant':
@@ -1109,7 +1081,6 @@
1109
1081
  data.type = child.nodeName;
1110
1082
  data.parameters = parseEffectParameters( child );
1111
1083
  break;
1112
-
1113
1084
  case 'extra':
1114
1085
  data.extra = parseEffectExtra( child );
1115
1086
  break;
@@ -1125,12 +1096,10 @@
1125
1096
  function parseEffectParameters( xml ) {
1126
1097
 
1127
1098
  const data = {};
1128
-
1129
1099
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1130
1100
 
1131
1101
  const child = xml.childNodes[ i ];
1132
1102
  if ( child.nodeType !== 1 ) continue;
1133
-
1134
1103
  switch ( child.nodeName ) {
1135
1104
 
1136
1105
  case 'emission':
@@ -1142,7 +1111,6 @@
1142
1111
  case 'transparency':
1143
1112
  data[ child.nodeName ] = parseEffectParameter( child );
1144
1113
  break;
1145
-
1146
1114
  case 'transparent':
1147
1115
  data[ child.nodeName ] = {
1148
1116
  opaque: child.hasAttribute( 'opaque' ) ? child.getAttribute( 'opaque' ) : 'A_ONE',
@@ -1161,22 +1129,18 @@
1161
1129
  function parseEffectParameter( xml ) {
1162
1130
 
1163
1131
  const data = {};
1164
-
1165
1132
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1166
1133
 
1167
1134
  const child = xml.childNodes[ i ];
1168
1135
  if ( child.nodeType !== 1 ) continue;
1169
-
1170
1136
  switch ( child.nodeName ) {
1171
1137
 
1172
1138
  case 'color':
1173
1139
  data[ child.nodeName ] = parseFloats( child.textContent );
1174
1140
  break;
1175
-
1176
1141
  case 'float':
1177
1142
  data[ child.nodeName ] = parseFloat( child.textContent );
1178
1143
  break;
1179
-
1180
1144
  case 'texture':
1181
1145
  data[ child.nodeName ] = {
1182
1146
  id: child.getAttribute( 'texture' ),
@@ -1197,12 +1161,10 @@
1197
1161
  const data = {
1198
1162
  technique: {}
1199
1163
  };
1200
-
1201
1164
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1202
1165
 
1203
1166
  const child = xml.childNodes[ i ];
1204
1167
  if ( child.nodeType !== 1 ) continue;
1205
-
1206
1168
  switch ( child.nodeName ) {
1207
1169
 
1208
1170
  case 'extra':
@@ -1223,7 +1185,6 @@
1223
1185
 
1224
1186
  const child = xml.childNodes[ i ];
1225
1187
  if ( child.nodeType !== 1 ) continue;
1226
-
1227
1188
  switch ( child.nodeName ) {
1228
1189
 
1229
1190
  case 'technique':
@@ -1242,7 +1203,6 @@
1242
1203
 
1243
1204
  const child = xml.childNodes[ i ];
1244
1205
  if ( child.nodeType !== 1 ) continue;
1245
-
1246
1206
  switch ( child.nodeName ) {
1247
1207
 
1248
1208
  case 'repeatU':
@@ -1251,10 +1211,10 @@
1251
1211
  case 'offsetV':
1252
1212
  data.technique[ child.nodeName ] = parseFloat( child.textContent );
1253
1213
  break;
1254
-
1255
1214
  case 'wrapU':
1256
1215
  case 'wrapV':
1257
1216
  // some files have values for wrapU/wrapV which become NaN via parseInt
1217
+
1258
1218
  if ( child.textContent.toUpperCase() === 'TRUE' ) {
1259
1219
 
1260
1220
  data.technique[ child.nodeName ] = 1;
@@ -1270,7 +1230,6 @@
1270
1230
  }
1271
1231
 
1272
1232
  break;
1273
-
1274
1233
  case 'bump':
1275
1234
  data[ child.nodeName ] = parseEffectExtraTechniqueBump( child );
1276
1235
  break;
@@ -1284,12 +1243,10 @@
1284
1243
  function parseEffectExtra( xml ) {
1285
1244
 
1286
1245
  const data = {};
1287
-
1288
1246
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1289
1247
 
1290
1248
  const child = xml.childNodes[ i ];
1291
1249
  if ( child.nodeType !== 1 ) continue;
1292
-
1293
1250
  switch ( child.nodeName ) {
1294
1251
 
1295
1252
  case 'technique':
@@ -1307,18 +1264,15 @@
1307
1264
  function parseEffectExtraTechnique( xml ) {
1308
1265
 
1309
1266
  const data = {};
1310
-
1311
1267
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1312
1268
 
1313
1269
  const child = xml.childNodes[ i ];
1314
1270
  if ( child.nodeType !== 1 ) continue;
1315
-
1316
1271
  switch ( child.nodeName ) {
1317
1272
 
1318
1273
  case 'double_sided':
1319
1274
  data[ child.nodeName ] = parseInt( child.textContent );
1320
1275
  break;
1321
-
1322
1276
  case 'bump':
1323
1277
  data[ child.nodeName ] = parseEffectExtraTechniqueBump( child );
1324
1278
  break;
@@ -1334,12 +1288,10 @@
1334
1288
  function parseEffectExtraTechniqueBump( xml ) {
1335
1289
 
1336
1290
  const data = {};
1337
-
1338
1291
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1339
1292
 
1340
1293
  const child = xml.childNodes[ i ];
1341
1294
  if ( child.nodeType !== 1 ) continue;
1342
-
1343
1295
  switch ( child.nodeName ) {
1344
1296
 
1345
1297
  case 'texture':
@@ -1368,20 +1320,19 @@
1368
1320
 
1369
1321
  return getBuild( library.effects[ id ], buildEffect );
1370
1322
 
1371
- } // material
1323
+ }
1372
1324
 
1325
+ // material
1373
1326
 
1374
1327
  function parseMaterial( xml ) {
1375
1328
 
1376
1329
  const data = {
1377
1330
  name: xml.getAttribute( 'name' )
1378
1331
  };
1379
-
1380
1332
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1381
1333
 
1382
1334
  const child = xml.childNodes[ i ];
1383
1335
  if ( child.nodeType !== 1 ) continue;
1384
-
1385
1336
  switch ( child.nodeName ) {
1386
1337
 
1387
1338
  case 'instance_effect':
@@ -1400,15 +1351,12 @@
1400
1351
 
1401
1352
  let loader;
1402
1353
  let extension = image.slice( ( image.lastIndexOf( '.' ) - 1 >>> 0 ) + 2 ); // http://www.jstips.co/en/javascript/get-file-extension/
1403
-
1404
1354
  extension = extension.toLowerCase();
1405
-
1406
1355
  switch ( extension ) {
1407
1356
 
1408
1357
  case 'tga':
1409
1358
  loader = tgaLoader;
1410
1359
  break;
1411
-
1412
1360
  default:
1413
1361
  loader = textureLoader;
1414
1362
 
@@ -1423,18 +1371,15 @@
1423
1371
  const effect = getEffect( data.url );
1424
1372
  const technique = effect.profile.technique;
1425
1373
  let material;
1426
-
1427
1374
  switch ( technique.type ) {
1428
1375
 
1429
1376
  case 'phong':
1430
1377
  case 'blinn':
1431
1378
  material = new THREE.MeshPhongMaterial();
1432
1379
  break;
1433
-
1434
1380
  case 'lambert':
1435
1381
  material = new THREE.MeshLambertMaterial();
1436
1382
  break;
1437
-
1438
1383
  default:
1439
1384
  material = new THREE.MeshBasicMaterial();
1440
1385
  break;
@@ -1442,11 +1387,12 @@
1442
1387
  }
1443
1388
 
1444
1389
  material.name = data.name || '';
1445
-
1446
1390
  function getTexture( textureObject, encoding = null ) {
1447
1391
 
1448
1392
  const sampler = effect.profile.samplers[ textureObject.id ];
1449
- let image = null; // get image
1393
+ let image = null;
1394
+
1395
+ // get image
1450
1396
 
1451
1397
  if ( sampler !== undefined ) {
1452
1398
 
@@ -1458,18 +1404,17 @@
1458
1404
  console.warn( 'THREE.ColladaLoader: Undefined sampler. Access image directly (see #12530).' );
1459
1405
  image = getImage( textureObject.id );
1460
1406
 
1461
- } // create texture if image is avaiable
1407
+ }
1462
1408
 
1409
+ // create texture if image is avaiable
1463
1410
 
1464
1411
  if ( image !== null ) {
1465
1412
 
1466
1413
  const loader = getTextureLoader( image );
1467
-
1468
1414
  if ( loader !== undefined ) {
1469
1415
 
1470
1416
  const texture = loader.load( image );
1471
1417
  const extra = textureObject.extra;
1472
-
1473
1418
  if ( extra !== undefined && extra.technique !== undefined && isEmpty( extra.technique ) === false ) {
1474
1419
 
1475
1420
  const technique = extra.technique;
@@ -1510,35 +1455,28 @@
1510
1455
  }
1511
1456
 
1512
1457
  const parameters = technique.parameters;
1513
-
1514
1458
  for ( const key in parameters ) {
1515
1459
 
1516
1460
  const parameter = parameters[ key ];
1517
-
1518
1461
  switch ( key ) {
1519
1462
 
1520
1463
  case 'diffuse':
1521
1464
  if ( parameter.color ) material.color.fromArray( parameter.color );
1522
1465
  if ( parameter.texture ) material.map = getTexture( parameter.texture, THREE.sRGBEncoding );
1523
1466
  break;
1524
-
1525
1467
  case 'specular':
1526
1468
  if ( parameter.color && material.specular ) material.specular.fromArray( parameter.color );
1527
1469
  if ( parameter.texture ) material.specularMap = getTexture( parameter.texture );
1528
1470
  break;
1529
-
1530
1471
  case 'bump':
1531
1472
  if ( parameter.texture ) material.normalMap = getTexture( parameter.texture );
1532
1473
  break;
1533
-
1534
1474
  case 'ambient':
1535
1475
  if ( parameter.texture ) material.lightMap = getTexture( parameter.texture, THREE.sRGBEncoding );
1536
1476
  break;
1537
-
1538
1477
  case 'shininess':
1539
1478
  if ( parameter.float && material.shininess ) material.shininess = parameter.float;
1540
1479
  break;
1541
-
1542
1480
  case 'emission':
1543
1481
  if ( parameter.color && material.emissive ) material.emissive.fromArray( parameter.color );
1544
1482
  if ( parameter.texture ) material.emissiveMap = getTexture( parameter.texture, THREE.sRGBEncoding );
@@ -1550,10 +1488,14 @@
1550
1488
 
1551
1489
  material.color.convertSRGBToLinear();
1552
1490
  if ( material.specular ) material.specular.convertSRGBToLinear();
1553
- if ( material.emissive ) material.emissive.convertSRGBToLinear(); //
1491
+ if ( material.emissive ) material.emissive.convertSRGBToLinear();
1492
+
1493
+ //
1554
1494
 
1555
1495
  let transparent = parameters[ 'transparent' ];
1556
- let transparency = parameters[ 'transparency' ]; // <transparency> does not exist but <transparent>
1496
+ let transparency = parameters[ 'transparency' ];
1497
+
1498
+ // <transparency> does not exist but <transparent>
1557
1499
 
1558
1500
  if ( transparency === undefined && transparent ) {
1559
1501
 
@@ -1561,8 +1503,9 @@
1561
1503
  float: 1
1562
1504
  };
1563
1505
 
1564
- } // <transparent> does not exist but <transparency>
1506
+ }
1565
1507
 
1508
+ // <transparent> does not exist but <transparency>
1566
1509
 
1567
1510
  if ( transparent === undefined && transparency ) {
1568
1511
 
@@ -1578,33 +1521,30 @@
1578
1521
  if ( transparent && transparency ) {
1579
1522
 
1580
1523
  // handle case if a texture exists but no color
1524
+
1581
1525
  if ( transparent.data.texture ) {
1582
1526
 
1583
1527
  // we do not set an alpha map (see #13792)
1528
+
1584
1529
  material.transparent = true;
1585
1530
 
1586
1531
  } else {
1587
1532
 
1588
1533
  const color = transparent.data.color;
1589
-
1590
1534
  switch ( transparent.opaque ) {
1591
1535
 
1592
1536
  case 'A_ONE':
1593
1537
  material.opacity = color[ 3 ] * transparency.float;
1594
1538
  break;
1595
-
1596
1539
  case 'RGB_ZERO':
1597
1540
  material.opacity = 1 - color[ 0 ] * transparency.float;
1598
1541
  break;
1599
-
1600
1542
  case 'A_ZERO':
1601
1543
  material.opacity = 1 - color[ 3 ] * transparency.float;
1602
1544
  break;
1603
-
1604
1545
  case 'RGB_ONE':
1605
1546
  material.opacity = color[ 0 ] * transparency.float;
1606
1547
  break;
1607
-
1608
1548
  default:
1609
1549
  console.warn( 'THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.', transparent.opaque );
1610
1550
 
@@ -1614,23 +1554,21 @@
1614
1554
 
1615
1555
  }
1616
1556
 
1617
- } //
1557
+ }
1618
1558
 
1559
+ //
1619
1560
 
1620
1561
  if ( technique.extra !== undefined && technique.extra.technique !== undefined ) {
1621
1562
 
1622
1563
  const techniques = technique.extra.technique;
1623
-
1624
1564
  for ( const k in techniques ) {
1625
1565
 
1626
1566
  const v = techniques[ k ];
1627
-
1628
1567
  switch ( k ) {
1629
1568
 
1630
1569
  case 'double_sided':
1631
1570
  material.side = v === 1 ? THREE.DoubleSide : THREE.FrontSide;
1632
1571
  break;
1633
-
1634
1572
  case 'bump':
1635
1573
  material.normalMap = getTexture( v.texture );
1636
1574
  material.normalScale = new THREE.Vector2( 1, 1 );
@@ -1650,20 +1588,19 @@
1650
1588
 
1651
1589
  return getBuild( library.materials[ id ], buildMaterial );
1652
1590
 
1653
- } // camera
1591
+ }
1654
1592
 
1593
+ // camera
1655
1594
 
1656
1595
  function parseCamera( xml ) {
1657
1596
 
1658
1597
  const data = {
1659
1598
  name: xml.getAttribute( 'name' )
1660
1599
  };
1661
-
1662
1600
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1663
1601
 
1664
1602
  const child = xml.childNodes[ i ];
1665
1603
  if ( child.nodeType !== 1 ) continue;
1666
-
1667
1604
  switch ( child.nodeName ) {
1668
1605
 
1669
1606
  case 'optics':
@@ -1683,7 +1620,6 @@
1683
1620
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
1684
1621
 
1685
1622
  const child = xml.childNodes[ i ];
1686
-
1687
1623
  switch ( child.nodeName ) {
1688
1624
 
1689
1625
  case 'technique_common':
@@ -1700,11 +1636,9 @@
1700
1636
  function parseCameraTechnique( xml ) {
1701
1637
 
1702
1638
  const data = {};
1703
-
1704
1639
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
1705
1640
 
1706
1641
  const child = xml.childNodes[ i ];
1707
-
1708
1642
  switch ( child.nodeName ) {
1709
1643
 
1710
1644
  case 'perspective':
@@ -1724,11 +1658,9 @@
1724
1658
  function parseCameraParameters( xml ) {
1725
1659
 
1726
1660
  const data = {};
1727
-
1728
1661
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
1729
1662
 
1730
1663
  const child = xml.childNodes[ i ];
1731
-
1732
1664
  switch ( child.nodeName ) {
1733
1665
 
1734
1666
  case 'xfov':
@@ -1752,13 +1684,11 @@
1752
1684
  function buildCamera( data ) {
1753
1685
 
1754
1686
  let camera;
1755
-
1756
1687
  switch ( data.optics.technique ) {
1757
1688
 
1758
1689
  case 'perspective':
1759
1690
  camera = new THREE.PerspectiveCamera( data.optics.parameters.yfov, data.optics.parameters.aspect_ratio, data.optics.parameters.znear, data.optics.parameters.zfar );
1760
1691
  break;
1761
-
1762
1692
  case 'orthographic':
1763
1693
  let ymag = data.optics.parameters.ymag;
1764
1694
  let xmag = data.optics.parameters.xmag;
@@ -1767,10 +1697,10 @@
1767
1697
  ymag = ymag === undefined ? xmag / aspectRatio : ymag;
1768
1698
  xmag *= 0.5;
1769
1699
  ymag *= 0.5;
1770
- camera = new THREE.OrthographicCamera( - xmag, xmag, ymag, - ymag, // left, right, top, bottom
1700
+ camera = new THREE.OrthographicCamera( - xmag, xmag, ymag, - ymag,
1701
+ // left, right, top, bottom
1771
1702
  data.optics.parameters.znear, data.optics.parameters.zfar );
1772
1703
  break;
1773
-
1774
1704
  default:
1775
1705
  camera = new THREE.PerspectiveCamera();
1776
1706
  break;
@@ -1785,7 +1715,6 @@
1785
1715
  function getCamera( id ) {
1786
1716
 
1787
1717
  const data = library.cameras[ id ];
1788
-
1789
1718
  if ( data !== undefined ) {
1790
1719
 
1791
1720
  return getBuild( data, buildCamera );
@@ -1795,18 +1724,17 @@
1795
1724
  console.warn( 'THREE.ColladaLoader: Couldn\'t find camera with ID:', id );
1796
1725
  return null;
1797
1726
 
1798
- } // light
1727
+ }
1799
1728
 
1729
+ // light
1800
1730
 
1801
1731
  function parseLight( xml ) {
1802
1732
 
1803
1733
  let data = {};
1804
-
1805
1734
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1806
1735
 
1807
1736
  const child = xml.childNodes[ i ];
1808
1737
  if ( child.nodeType !== 1 ) continue;
1809
-
1810
1738
  switch ( child.nodeName ) {
1811
1739
 
1812
1740
  case 'technique_common':
@@ -1824,12 +1752,10 @@
1824
1752
  function parseLightTechnique( xml ) {
1825
1753
 
1826
1754
  const data = {};
1827
-
1828
1755
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1829
1756
 
1830
1757
  const child = xml.childNodes[ i ];
1831
1758
  if ( child.nodeType !== 1 ) continue;
1832
-
1833
1759
  switch ( child.nodeName ) {
1834
1760
 
1835
1761
  case 'directional':
@@ -1850,23 +1776,19 @@
1850
1776
  function parseLightParameters( xml ) {
1851
1777
 
1852
1778
  const data = {};
1853
-
1854
1779
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
1855
1780
 
1856
1781
  const child = xml.childNodes[ i ];
1857
1782
  if ( child.nodeType !== 1 ) continue;
1858
-
1859
1783
  switch ( child.nodeName ) {
1860
1784
 
1861
1785
  case 'color':
1862
1786
  const array = parseFloats( child.textContent );
1863
1787
  data.color = new THREE.Color().fromArray( array ).convertSRGBToLinear();
1864
1788
  break;
1865
-
1866
1789
  case 'falloff_angle':
1867
1790
  data.falloffAngle = parseFloat( child.textContent );
1868
1791
  break;
1869
-
1870
1792
  case 'quadratic_attenuation':
1871
1793
  const f = parseFloat( child.textContent );
1872
1794
  data.distance = f ? Math.sqrt( 1 / f ) : 0;
@@ -1883,21 +1805,17 @@
1883
1805
  function buildLight( data ) {
1884
1806
 
1885
1807
  let light;
1886
-
1887
1808
  switch ( data.technique ) {
1888
1809
 
1889
1810
  case 'directional':
1890
1811
  light = new THREE.DirectionalLight();
1891
1812
  break;
1892
-
1893
1813
  case 'point':
1894
1814
  light = new THREE.PointLight();
1895
1815
  break;
1896
-
1897
1816
  case 'spot':
1898
1817
  light = new THREE.SpotLight();
1899
1818
  break;
1900
-
1901
1819
  case 'ambient':
1902
1820
  light = new THREE.AmbientLight();
1903
1821
  break;
@@ -1913,7 +1831,6 @@
1913
1831
  function getLight( id ) {
1914
1832
 
1915
1833
  const data = library.lights[ id ];
1916
-
1917
1834
  if ( data !== undefined ) {
1918
1835
 
1919
1836
  return getBuild( data, buildLight );
@@ -1923,8 +1840,9 @@
1923
1840
  console.warn( 'THREE.ColladaLoader: Couldn\'t find light with ID:', id );
1924
1841
  return null;
1925
1842
 
1926
- } // geometry
1843
+ }
1927
1844
 
1845
+ // geometry
1928
1846
 
1929
1847
  function parseGeometry( xml ) {
1930
1848
 
@@ -1934,38 +1852,33 @@
1934
1852
  vertices: {},
1935
1853
  primitives: []
1936
1854
  };
1937
- const mesh = getElementsByTagName( xml, 'mesh' )[ 0 ]; // the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep
1855
+ const mesh = getElementsByTagName( xml, 'mesh' )[ 0 ];
1938
1856
 
1857
+ // the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep
1939
1858
  if ( mesh === undefined ) return;
1940
-
1941
1859
  for ( let i = 0; i < mesh.childNodes.length; i ++ ) {
1942
1860
 
1943
1861
  const child = mesh.childNodes[ i ];
1944
1862
  if ( child.nodeType !== 1 ) continue;
1945
1863
  const id = child.getAttribute( 'id' );
1946
-
1947
1864
  switch ( child.nodeName ) {
1948
1865
 
1949
1866
  case 'source':
1950
1867
  data.sources[ id ] = parseSource( child );
1951
1868
  break;
1952
-
1953
1869
  case 'vertices':
1954
1870
  // data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ];
1955
1871
  data.vertices = parseGeometryVertices( child );
1956
1872
  break;
1957
-
1958
1873
  case 'polygons':
1959
1874
  console.warn( 'THREE.ColladaLoader: Unsupported primitive type: ', child.nodeName );
1960
1875
  break;
1961
-
1962
1876
  case 'lines':
1963
1877
  case 'linestrips':
1964
1878
  case 'polylist':
1965
1879
  case 'triangles':
1966
1880
  data.primitives.push( parseGeometryPrimitive( child ) );
1967
1881
  break;
1968
-
1969
1882
  default:
1970
1883
  console.log( child );
1971
1884
 
@@ -1983,25 +1896,20 @@
1983
1896
  array: [],
1984
1897
  stride: 3
1985
1898
  };
1986
-
1987
1899
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
1988
1900
 
1989
1901
  const child = xml.childNodes[ i ];
1990
1902
  if ( child.nodeType !== 1 ) continue;
1991
-
1992
1903
  switch ( child.nodeName ) {
1993
1904
 
1994
1905
  case 'float_array':
1995
1906
  data.array = parseFloats( child.textContent );
1996
1907
  break;
1997
-
1998
1908
  case 'Name_array':
1999
1909
  data.array = parseStrings( child.textContent );
2000
1910
  break;
2001
-
2002
1911
  case 'technique_common':
2003
1912
  const accessor = getElementsByTagName( child, 'accessor' )[ 0 ];
2004
-
2005
1913
  if ( accessor !== undefined ) {
2006
1914
 
2007
1915
  data.stride = parseInt( accessor.getAttribute( 'stride' ) );
@@ -2021,7 +1929,6 @@
2021
1929
  function parseGeometryVertices( xml ) {
2022
1930
 
2023
1931
  const data = {};
2024
-
2025
1932
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2026
1933
 
2027
1934
  const child = xml.childNodes[ i ];
@@ -2044,12 +1951,10 @@
2044
1951
  stride: 0,
2045
1952
  hasUV: false
2046
1953
  };
2047
-
2048
1954
  for ( let i = 0, l = xml.childNodes.length; i < l; i ++ ) {
2049
1955
 
2050
1956
  const child = xml.childNodes[ i ];
2051
1957
  if ( child.nodeType !== 1 ) continue;
2052
-
2053
1958
  switch ( child.nodeName ) {
2054
1959
 
2055
1960
  case 'input':
@@ -2065,11 +1970,9 @@
2065
1970
  primitive.stride = Math.max( primitive.stride, offset + 1 );
2066
1971
  if ( semantic === 'TEXCOORD' ) primitive.hasUV = true;
2067
1972
  break;
2068
-
2069
1973
  case 'vcount':
2070
1974
  primitive.vcount = parseInts( child.textContent );
2071
1975
  break;
2072
-
2073
1976
  case 'p':
2074
1977
  primitive.p = parseInts( child.textContent );
2075
1978
  break;
@@ -2085,7 +1988,6 @@
2085
1988
  function groupPrimitives( primitives ) {
2086
1989
 
2087
1990
  const build = {};
2088
-
2089
1991
  for ( let i = 0; i < primitives.length; i ++ ) {
2090
1992
 
2091
1993
  const primitive = primitives[ i ];
@@ -2101,11 +2003,9 @@
2101
2003
  function checkUVCoordinates( primitives ) {
2102
2004
 
2103
2005
  let count = 0;
2104
-
2105
2006
  for ( let i = 0, l = primitives.length; i < l; i ++ ) {
2106
2007
 
2107
2008
  const primitive = primitives[ i ];
2108
-
2109
2009
  if ( primitive.hasUV === true ) {
2110
2010
 
2111
2011
  count ++;
@@ -2128,16 +2028,21 @@
2128
2028
  const sources = data.sources;
2129
2029
  const vertices = data.vertices;
2130
2030
  const primitives = data.primitives;
2131
- if ( primitives.length === 0 ) return {}; // our goal is to create one buffer geometry for a single type of primitives
2031
+ if ( primitives.length === 0 ) return {};
2032
+
2033
+ // our goal is to create one buffer geometry for a single type of primitives
2132
2034
  // first, we group all primitives by their type
2133
2035
 
2134
2036
  const groupedPrimitives = groupPrimitives( primitives );
2135
-
2136
2037
  for ( const type in groupedPrimitives ) {
2137
2038
 
2138
- const primitiveType = groupedPrimitives[ type ]; // second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines)
2039
+ const primitiveType = groupedPrimitives[ type ];
2040
+
2041
+ // second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines)
2042
+
2043
+ checkUVCoordinates( primitiveType );
2139
2044
 
2140
- checkUVCoordinates( primitiveType ); // third, create a buffer geometry for each type of primitives
2045
+ // third, create a buffer geometry for each type of primitives
2141
2046
 
2142
2047
  build[ type ] = buildGeometryType( primitiveType, sources, vertices );
2143
2048
 
@@ -2181,45 +2086,37 @@
2181
2086
  const geometry = new THREE.BufferGeometry();
2182
2087
  const materialKeys = [];
2183
2088
  let start = 0;
2184
-
2185
2089
  for ( let p = 0; p < primitives.length; p ++ ) {
2186
2090
 
2187
2091
  const primitive = primitives[ p ];
2188
- const inputs = primitive.inputs; // groups
2092
+ const inputs = primitive.inputs;
2189
2093
 
2190
- let count = 0;
2094
+ // groups
2191
2095
 
2096
+ let count = 0;
2192
2097
  switch ( primitive.type ) {
2193
2098
 
2194
2099
  case 'lines':
2195
2100
  case 'linestrips':
2196
2101
  count = primitive.count * 2;
2197
2102
  break;
2198
-
2199
2103
  case 'triangles':
2200
2104
  count = primitive.count * 3;
2201
2105
  break;
2202
-
2203
2106
  case 'polylist':
2204
2107
  for ( let g = 0; g < primitive.count; g ++ ) {
2205
2108
 
2206
2109
  const vc = primitive.vcount[ g ];
2207
-
2208
2110
  switch ( vc ) {
2209
2111
 
2210
2112
  case 3:
2211
2113
  count += 3; // single triangle
2212
-
2213
2114
  break;
2214
-
2215
2115
  case 4:
2216
2116
  count += 6; // quad, subdivided into two triangles
2217
-
2218
2117
  break;
2219
-
2220
2118
  default:
2221
2119
  count += ( vc - 2 ) * 3; // polylist with more than four vertices
2222
-
2223
2120
  break;
2224
2121
 
2225
2122
  }
@@ -2227,55 +2124,55 @@
2227
2124
  }
2228
2125
 
2229
2126
  break;
2230
-
2231
2127
  default:
2232
2128
  console.warn( 'THREE.ColladaLoader: Unknow primitive type:', primitive.type );
2233
2129
 
2234
2130
  }
2235
2131
 
2236
2132
  geometry.addGroup( start, count, p );
2237
- start += count; // material
2133
+ start += count;
2134
+
2135
+ // material
2238
2136
 
2239
2137
  if ( primitive.material ) {
2240
2138
 
2241
2139
  materialKeys.push( primitive.material );
2242
2140
 
2243
- } // geometry data
2141
+ }
2244
2142
 
2143
+ // geometry data
2245
2144
 
2246
2145
  for ( const name in inputs ) {
2247
2146
 
2248
2147
  const input = inputs[ name ];
2249
-
2250
2148
  switch ( name ) {
2251
2149
 
2252
2150
  case 'VERTEX':
2253
2151
  for ( const key in vertices ) {
2254
2152
 
2255
2153
  const id = vertices[ key ];
2256
-
2257
2154
  switch ( key ) {
2258
2155
 
2259
2156
  case 'POSITION':
2260
2157
  const prevLength = position.array.length;
2261
2158
  buildGeometryData( primitive, sources[ id ], input.offset, position.array );
2262
2159
  position.stride = sources[ id ].stride;
2263
-
2264
2160
  if ( sources.skinWeights && sources.skinIndices ) {
2265
2161
 
2266
2162
  buildGeometryData( primitive, sources.skinIndices, input.offset, skinIndex.array );
2267
2163
  buildGeometryData( primitive, sources.skinWeights, input.offset, skinWeight.array );
2268
2164
 
2269
- } // see #3803
2165
+ }
2270
2166
 
2167
+ // see #3803
2271
2168
 
2272
2169
  if ( primitive.hasUV === false && primitives.uvsNeedsFix === true ) {
2273
2170
 
2274
2171
  const count = ( position.array.length - prevLength ) / position.stride;
2275
-
2276
2172
  for ( let i = 0; i < count; i ++ ) {
2277
2173
 
2278
2174
  // fill missing uv coordinates
2175
+
2279
2176
  uv.array.push( 0, 0 );
2280
2177
 
2281
2178
  }
@@ -2283,27 +2180,22 @@
2283
2180
  }
2284
2181
 
2285
2182
  break;
2286
-
2287
2183
  case 'NORMAL':
2288
2184
  buildGeometryData( primitive, sources[ id ], input.offset, normal.array );
2289
2185
  normal.stride = sources[ id ].stride;
2290
2186
  break;
2291
-
2292
2187
  case 'COLOR':
2293
2188
  buildGeometryData( primitive, sources[ id ], input.offset, color.array );
2294
2189
  color.stride = sources[ id ].stride;
2295
2190
  break;
2296
-
2297
2191
  case 'TEXCOORD':
2298
2192
  buildGeometryData( primitive, sources[ id ], input.offset, uv.array );
2299
2193
  uv.stride = sources[ id ].stride;
2300
2194
  break;
2301
-
2302
2195
  case 'TEXCOORD1':
2303
2196
  buildGeometryData( primitive, sources[ id ], input.offset, uv2.array );
2304
2197
  uv.stride = sources[ id ].stride;
2305
2198
  break;
2306
-
2307
2199
  default:
2308
2200
  console.warn( 'THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key );
2309
2201
 
@@ -2312,22 +2204,18 @@
2312
2204
  }
2313
2205
 
2314
2206
  break;
2315
-
2316
2207
  case 'NORMAL':
2317
2208
  buildGeometryData( primitive, sources[ input.id ], input.offset, normal.array );
2318
2209
  normal.stride = sources[ input.id ].stride;
2319
2210
  break;
2320
-
2321
2211
  case 'COLOR':
2322
2212
  buildGeometryData( primitive, sources[ input.id ], input.offset, color.array, true );
2323
2213
  color.stride = sources[ input.id ].stride;
2324
2214
  break;
2325
-
2326
2215
  case 'TEXCOORD':
2327
2216
  buildGeometryData( primitive, sources[ input.id ], input.offset, uv.array );
2328
2217
  uv.stride = sources[ input.id ].stride;
2329
2218
  break;
2330
-
2331
2219
  case 'TEXCOORD1':
2332
2220
  buildGeometryData( primitive, sources[ input.id ], input.offset, uv2.array );
2333
2221
  uv2.stride = sources[ input.id ].stride;
@@ -2337,8 +2225,9 @@
2337
2225
 
2338
2226
  }
2339
2227
 
2340
- } // build geometry
2228
+ }
2341
2229
 
2230
+ // build geometry
2342
2231
 
2343
2232
  if ( position.array.length > 0 ) geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position.array, position.stride ) );
2344
2233
  if ( normal.array.length > 0 ) geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) );
@@ -2359,12 +2248,10 @@
2359
2248
  const indices = primitive.p;
2360
2249
  const stride = primitive.stride;
2361
2250
  const vcount = primitive.vcount;
2362
-
2363
2251
  function pushVector( i ) {
2364
2252
 
2365
2253
  let index = indices[ i + offset ] * sourceStride;
2366
2254
  const length = index + sourceStride;
2367
-
2368
2255
  for ( ; index < length; index ++ ) {
2369
2256
 
2370
2257
  array.push( sourceArray[ index ] );
@@ -2386,15 +2273,12 @@
2386
2273
 
2387
2274
  const sourceArray = source.array;
2388
2275
  const sourceStride = source.stride;
2389
-
2390
2276
  if ( primitive.vcount !== undefined ) {
2391
2277
 
2392
2278
  let index = 0;
2393
-
2394
2279
  for ( let i = 0, l = vcount.length; i < l; i ++ ) {
2395
2280
 
2396
2281
  const count = vcount[ i ];
2397
-
2398
2282
  if ( count === 4 ) {
2399
2283
 
2400
2284
  const a = index + stride * 0;
@@ -2452,8 +2336,9 @@
2452
2336
 
2453
2337
  return getBuild( library.geometries[ id ], buildGeometry );
2454
2338
 
2455
- } // kinematics
2339
+ }
2456
2340
 
2341
+ // kinematics
2457
2342
 
2458
2343
  function parseKinematicsModel( xml ) {
2459
2344
 
@@ -2462,12 +2347,10 @@
2462
2347
  joints: {},
2463
2348
  links: []
2464
2349
  };
2465
-
2466
2350
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2467
2351
 
2468
2352
  const child = xml.childNodes[ i ];
2469
2353
  if ( child.nodeType !== 1 ) continue;
2470
-
2471
2354
  switch ( child.nodeName ) {
2472
2355
 
2473
2356
  case 'technique_common':
@@ -2501,13 +2384,11 @@
2501
2384
 
2502
2385
  const child = xml.childNodes[ i ];
2503
2386
  if ( child.nodeType !== 1 ) continue;
2504
-
2505
2387
  switch ( child.nodeName ) {
2506
2388
 
2507
2389
  case 'joint':
2508
2390
  data.joints[ child.getAttribute( 'sid' ) ] = parseKinematicsJoint( child );
2509
2391
  break;
2510
-
2511
2392
  case 'link':
2512
2393
  data.links.push( parseKinematicsLink( child ) );
2513
2394
  break;
@@ -2521,12 +2402,10 @@
2521
2402
  function parseKinematicsJoint( xml ) {
2522
2403
 
2523
2404
  let data;
2524
-
2525
2405
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2526
2406
 
2527
2407
  const child = xml.childNodes[ i ];
2528
2408
  if ( child.nodeType !== 1 ) continue;
2529
-
2530
2409
  switch ( child.nodeName ) {
2531
2410
 
2532
2411
  case 'prismatic':
@@ -2557,19 +2436,16 @@
2557
2436
  zeroPosition: 0,
2558
2437
  middlePosition: 0
2559
2438
  };
2560
-
2561
2439
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2562
2440
 
2563
2441
  const child = xml.childNodes[ i ];
2564
2442
  if ( child.nodeType !== 1 ) continue;
2565
-
2566
2443
  switch ( child.nodeName ) {
2567
2444
 
2568
2445
  case 'axis':
2569
2446
  const array = parseFloats( child.textContent );
2570
2447
  data.axis.fromArray( array );
2571
2448
  break;
2572
-
2573
2449
  case 'limits':
2574
2450
  const max = child.getElementsByTagName( 'max' )[ 0 ];
2575
2451
  const min = child.getElementsByTagName( 'min' )[ 0 ];
@@ -2579,15 +2455,17 @@
2579
2455
 
2580
2456
  }
2581
2457
 
2582
- } // if min is equal to or greater than max, consider the joint static
2458
+ }
2583
2459
 
2460
+ // if min is equal to or greater than max, consider the joint static
2584
2461
 
2585
2462
  if ( data.limits.min >= data.limits.max ) {
2586
2463
 
2587
2464
  data.static = true;
2588
2465
 
2589
- } // calculate middle position
2466
+ }
2590
2467
 
2468
+ // calculate middle position
2591
2469
 
2592
2470
  data.middlePosition = ( data.limits.min + data.limits.max ) / 2.0;
2593
2471
  return data;
@@ -2602,18 +2480,15 @@
2602
2480
  attachments: [],
2603
2481
  transforms: []
2604
2482
  };
2605
-
2606
2483
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2607
2484
 
2608
2485
  const child = xml.childNodes[ i ];
2609
2486
  if ( child.nodeType !== 1 ) continue;
2610
-
2611
2487
  switch ( child.nodeName ) {
2612
2488
 
2613
2489
  case 'attachment_full':
2614
2490
  data.attachments.push( parseKinematicsAttachment( child ) );
2615
2491
  break;
2616
-
2617
2492
  case 'matrix':
2618
2493
  case 'translate':
2619
2494
  case 'rotate':
@@ -2635,18 +2510,15 @@
2635
2510
  transforms: [],
2636
2511
  links: []
2637
2512
  };
2638
-
2639
2513
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2640
2514
 
2641
2515
  const child = xml.childNodes[ i ];
2642
2516
  if ( child.nodeType !== 1 ) continue;
2643
-
2644
2517
  switch ( child.nodeName ) {
2645
2518
 
2646
2519
  case 'link':
2647
2520
  data.links.push( parseKinematicsLink( child ) );
2648
2521
  break;
2649
-
2650
2522
  case 'matrix':
2651
2523
  case 'translate':
2652
2524
  case 'rotate':
@@ -2667,19 +2539,16 @@
2667
2539
  type: xml.nodeName
2668
2540
  };
2669
2541
  const array = parseFloats( xml.textContent );
2670
-
2671
2542
  switch ( data.type ) {
2672
2543
 
2673
2544
  case 'matrix':
2674
2545
  data.obj = new THREE.Matrix4();
2675
2546
  data.obj.fromArray( array ).transpose();
2676
2547
  break;
2677
-
2678
2548
  case 'translate':
2679
2549
  data.obj = new THREE.Vector3();
2680
2550
  data.obj.fromArray( array );
2681
2551
  break;
2682
-
2683
2552
  case 'rotate':
2684
2553
  data.obj = new THREE.Vector3();
2685
2554
  data.obj.fromArray( array );
@@ -2690,8 +2559,9 @@
2690
2559
 
2691
2560
  return data;
2692
2561
 
2693
- } // physics
2562
+ }
2694
2563
 
2564
+ // physics
2695
2565
 
2696
2566
  function parsePhysicsModel( xml ) {
2697
2567
 
@@ -2699,12 +2569,10 @@
2699
2569
  name: xml.getAttribute( 'name' ) || '',
2700
2570
  rigidBodies: {}
2701
2571
  };
2702
-
2703
2572
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2704
2573
 
2705
2574
  const child = xml.childNodes[ i ];
2706
2575
  if ( child.nodeType !== 1 ) continue;
2707
-
2708
2576
  switch ( child.nodeName ) {
2709
2577
 
2710
2578
  case 'rigid_body':
@@ -2726,7 +2594,6 @@
2726
2594
 
2727
2595
  const child = xml.childNodes[ i ];
2728
2596
  if ( child.nodeType !== 1 ) continue;
2729
-
2730
2597
  switch ( child.nodeName ) {
2731
2598
 
2732
2599
  case 'technique_common':
@@ -2745,13 +2612,11 @@
2745
2612
 
2746
2613
  const child = xml.childNodes[ i ];
2747
2614
  if ( child.nodeType !== 1 ) continue;
2748
-
2749
2615
  switch ( child.nodeName ) {
2750
2616
 
2751
2617
  case 'inertia':
2752
2618
  data.inertia = parseFloats( child.textContent );
2753
2619
  break;
2754
-
2755
2620
  case 'mass':
2756
2621
  data.mass = parseFloats( child.textContent )[ 0 ];
2757
2622
  break;
@@ -2760,20 +2625,19 @@
2760
2625
 
2761
2626
  }
2762
2627
 
2763
- } // scene
2628
+ }
2764
2629
 
2630
+ // scene
2765
2631
 
2766
2632
  function parseKinematicsScene( xml ) {
2767
2633
 
2768
2634
  const data = {
2769
2635
  bindJointAxis: []
2770
2636
  };
2771
-
2772
2637
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2773
2638
 
2774
2639
  const child = xml.childNodes[ i ];
2775
2640
  if ( child.nodeType !== 1 ) continue;
2776
-
2777
2641
  switch ( child.nodeName ) {
2778
2642
 
2779
2643
  case 'bind_joint_axis':
@@ -2793,12 +2657,10 @@
2793
2657
  const data = {
2794
2658
  target: xml.getAttribute( 'target' ).split( '/' ).pop()
2795
2659
  };
2796
-
2797
2660
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2798
2661
 
2799
2662
  const child = xml.childNodes[ i ];
2800
2663
  if ( child.nodeType !== 1 ) continue;
2801
-
2802
2664
  switch ( child.nodeName ) {
2803
2665
 
2804
2666
  case 'axis':
@@ -2840,17 +2702,20 @@
2840
2702
  const visualScene = getVisualScene( visualSceneId );
2841
2703
  const bindJointAxis = kinematicsScene.bindJointAxis;
2842
2704
  const jointMap = {};
2843
-
2844
2705
  for ( let i = 0, l = bindJointAxis.length; i < l; i ++ ) {
2845
2706
 
2846
- const axis = bindJointAxis[ i ]; // the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix'
2707
+ const axis = bindJointAxis[ i ];
2847
2708
 
2848
- const targetElement = collada.querySelector( '[sid="' + axis.target + '"]' );
2709
+ // the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix'
2849
2710
 
2711
+ const targetElement = collada.querySelector( '[sid="' + axis.target + '"]' );
2850
2712
  if ( targetElement ) {
2851
2713
 
2852
2714
  // get the parent of the transform element
2853
- const parentVisualElement = targetElement.parentElement; // connect the joint of the kinematics model with the element in the visual scene
2715
+
2716
+ const parentVisualElement = targetElement.parentElement;
2717
+
2718
+ // connect the joint of the kinematics model with the element in the visual scene
2854
2719
 
2855
2720
  connect( axis.jointIndex, parentVisualElement );
2856
2721
 
@@ -2885,7 +2750,6 @@
2885
2750
  getJointValue: function ( jointIndex ) {
2886
2751
 
2887
2752
  const jointData = jointMap[ jointIndex ];
2888
-
2889
2753
  if ( jointData ) {
2890
2754
 
2891
2755
  return jointData.position;
@@ -2900,11 +2764,9 @@
2900
2764
  setJointValue: function ( jointIndex, value ) {
2901
2765
 
2902
2766
  const jointData = jointMap[ jointIndex ];
2903
-
2904
2767
  if ( jointData ) {
2905
2768
 
2906
2769
  const joint = jointData.joint;
2907
-
2908
2770
  if ( value > joint.limits.max || value < joint.limits.min ) {
2909
2771
 
2910
2772
  console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' value ' + value + ' outside of limits (min: ' + joint.limits.min + ', max: ' + joint.limits.max + ').' );
@@ -2918,11 +2780,15 @@
2918
2780
  const object = jointData.object;
2919
2781
  const axis = joint.axis;
2920
2782
  const transforms = jointData.transforms;
2921
- matrix.identity(); // each update, we have to apply all transforms in the correct order
2783
+ matrix.identity();
2784
+
2785
+ // each update, we have to apply all transforms in the correct order
2922
2786
 
2923
2787
  for ( let i = 0; i < transforms.length; i ++ ) {
2924
2788
 
2925
- const transform = transforms[ i ]; // if there is a connection of the transform node with a joint, apply the joint value
2789
+ const transform = transforms[ i ];
2790
+
2791
+ // if there is a connection of the transform node with a joint, apply the joint value
2926
2792
 
2927
2793
  if ( transform.sid && transform.sid.indexOf( jointIndex ) !== - 1 ) {
2928
2794
 
@@ -2931,11 +2797,9 @@
2931
2797
  case 'revolute':
2932
2798
  matrix.multiply( m0.makeRotationAxis( axis, THREE.MathUtils.degToRad( value ) ) );
2933
2799
  break;
2934
-
2935
2800
  case 'prismatic':
2936
2801
  matrix.multiply( m0.makeTranslation( axis.x * value, axis.y * value, axis.z * value ) );
2937
2802
  break;
2938
-
2939
2803
  default:
2940
2804
  console.warn( 'THREE.ColladaLoader: Unknown joint type: ' + joint.type );
2941
2805
  break;
@@ -2949,15 +2813,12 @@
2949
2813
  case 'matrix':
2950
2814
  matrix.multiply( transform.obj );
2951
2815
  break;
2952
-
2953
2816
  case 'translate':
2954
2817
  matrix.multiply( m0.makeTranslation( transform.obj.x, transform.obj.y, transform.obj.z ) );
2955
2818
  break;
2956
-
2957
2819
  case 'scale':
2958
2820
  matrix.scale( transform.obj );
2959
2821
  break;
2960
-
2961
2822
  case 'rotate':
2962
2823
  matrix.multiply( m0.makeRotationAxis( transform.obj, transform.angle ) );
2963
2824
  break;
@@ -2989,13 +2850,11 @@
2989
2850
 
2990
2851
  const transforms = [];
2991
2852
  const xml = collada.querySelector( '[id="' + node.id + '"]' );
2992
-
2993
2853
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
2994
2854
 
2995
2855
  const child = xml.childNodes[ i ];
2996
2856
  if ( child.nodeType !== 1 ) continue;
2997
2857
  let array, vector;
2998
-
2999
2858
  switch ( child.nodeName ) {
3000
2859
 
3001
2860
  case 'matrix':
@@ -3007,7 +2866,6 @@
3007
2866
  obj: matrix
3008
2867
  } );
3009
2868
  break;
3010
-
3011
2869
  case 'translate':
3012
2870
  case 'scale':
3013
2871
  array = parseFloats( child.textContent );
@@ -3018,7 +2876,6 @@
3018
2876
  obj: vector
3019
2877
  } );
3020
2878
  break;
3021
-
3022
2879
  case 'rotate':
3023
2880
  array = parseFloats( child.textContent );
3024
2881
  vector = new THREE.Vector3().fromArray( array );
@@ -3037,17 +2894,19 @@
3037
2894
 
3038
2895
  return transforms;
3039
2896
 
3040
- } // nodes
2897
+ }
3041
2898
 
2899
+ // nodes
3042
2900
 
3043
2901
  function prepareNodes( xml ) {
3044
2902
 
3045
- const elements = xml.getElementsByTagName( 'node' ); // ensure all node elements have id attributes
2903
+ const elements = xml.getElementsByTagName( 'node' );
2904
+
2905
+ // ensure all node elements have id attributes
3046
2906
 
3047
2907
  for ( let i = 0; i < elements.length; i ++ ) {
3048
2908
 
3049
2909
  const element = elements[ i ];
3050
-
3051
2910
  if ( element.hasAttribute( 'id' ) === false ) {
3052
2911
 
3053
2912
  element.setAttribute( 'id', generateId() );
@@ -3060,7 +2919,6 @@
3060
2919
 
3061
2920
  const matrix = new THREE.Matrix4();
3062
2921
  const vector = new THREE.Vector3();
3063
-
3064
2922
  function parseNode( xml ) {
3065
2923
 
3066
2924
  const data = {
@@ -3077,69 +2935,56 @@
3077
2935
  instanceNodes: [],
3078
2936
  transforms: {}
3079
2937
  };
3080
-
3081
2938
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
3082
2939
 
3083
2940
  const child = xml.childNodes[ i ];
3084
2941
  if ( child.nodeType !== 1 ) continue;
3085
2942
  let array;
3086
-
3087
2943
  switch ( child.nodeName ) {
3088
2944
 
3089
2945
  case 'node':
3090
2946
  data.nodes.push( child.getAttribute( 'id' ) );
3091
2947
  parseNode( child );
3092
2948
  break;
3093
-
3094
2949
  case 'instance_camera':
3095
2950
  data.instanceCameras.push( parseId( child.getAttribute( 'url' ) ) );
3096
2951
  break;
3097
-
3098
2952
  case 'instance_controller':
3099
2953
  data.instanceControllers.push( parseNodeInstance( child ) );
3100
2954
  break;
3101
-
3102
2955
  case 'instance_light':
3103
2956
  data.instanceLights.push( parseId( child.getAttribute( 'url' ) ) );
3104
2957
  break;
3105
-
3106
2958
  case 'instance_geometry':
3107
2959
  data.instanceGeometries.push( parseNodeInstance( child ) );
3108
2960
  break;
3109
-
3110
2961
  case 'instance_node':
3111
2962
  data.instanceNodes.push( parseId( child.getAttribute( 'url' ) ) );
3112
2963
  break;
3113
-
3114
2964
  case 'matrix':
3115
2965
  array = parseFloats( child.textContent );
3116
2966
  data.matrix.multiply( matrix.fromArray( array ).transpose() );
3117
2967
  data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName;
3118
2968
  break;
3119
-
3120
2969
  case 'translate':
3121
2970
  array = parseFloats( child.textContent );
3122
2971
  vector.fromArray( array );
3123
2972
  data.matrix.multiply( matrix.makeTranslation( vector.x, vector.y, vector.z ) );
3124
2973
  data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName;
3125
2974
  break;
3126
-
3127
2975
  case 'rotate':
3128
2976
  array = parseFloats( child.textContent );
3129
2977
  const angle = THREE.MathUtils.degToRad( array[ 3 ] );
3130
2978
  data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) );
3131
2979
  data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName;
3132
2980
  break;
3133
-
3134
2981
  case 'scale':
3135
2982
  array = parseFloats( child.textContent );
3136
2983
  data.matrix.scale( vector.fromArray( array ) );
3137
2984
  data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName;
3138
2985
  break;
3139
-
3140
2986
  case 'extra':
3141
2987
  break;
3142
-
3143
2988
  default:
3144
2989
  console.log( child );
3145
2990
 
@@ -3168,16 +3013,13 @@
3168
3013
  materials: {},
3169
3014
  skeletons: []
3170
3015
  };
3171
-
3172
3016
  for ( let i = 0; i < xml.childNodes.length; i ++ ) {
3173
3017
 
3174
3018
  const child = xml.childNodes[ i ];
3175
-
3176
3019
  switch ( child.nodeName ) {
3177
3020
 
3178
3021
  case 'bind_material':
3179
3022
  const instances = child.getElementsByTagName( 'instance_material' );
3180
-
3181
3023
  for ( let j = 0; j < instances.length; j ++ ) {
3182
3024
 
3183
3025
  const instance = instances[ j ];
@@ -3188,11 +3030,9 @@
3188
3030
  }
3189
3031
 
3190
3032
  break;
3191
-
3192
3033
  case 'skeleton':
3193
3034
  data.skeletons.push( parseId( child.textContent ) );
3194
3035
  break;
3195
-
3196
3036
  default:
3197
3037
  break;
3198
3038
 
@@ -3208,14 +3048,15 @@
3208
3048
 
3209
3049
  const boneData = [];
3210
3050
  const sortedBoneData = [];
3211
- let i, j, data; // a skeleton can have multiple root bones. collada expresses this
3051
+ let i, j, data;
3052
+
3053
+ // a skeleton can have multiple root bones. collada expresses this
3212
3054
  // situtation with multiple "skeleton" tags per controller instance
3213
3055
 
3214
3056
  for ( i = 0; i < skeletons.length; i ++ ) {
3215
3057
 
3216
3058
  const skeleton = skeletons[ i ];
3217
3059
  let root;
3218
-
3219
3060
  if ( hasNode( skeleton ) ) {
3220
3061
 
3221
3062
  root = getNode( skeleton );
@@ -3224,13 +3065,12 @@
3224
3065
  } else if ( hasVisualScene( skeleton ) ) {
3225
3066
 
3226
3067
  // handle case where the skeleton refers to the visual scene (#13335)
3068
+
3227
3069
  const visualScene = library.visualScenes[ skeleton ];
3228
3070
  const children = visualScene.children;
3229
-
3230
3071
  for ( let j = 0; j < children.length; j ++ ) {
3231
3072
 
3232
3073
  const child = children[ j ];
3233
-
3234
3074
  if ( child.type === 'JOINT' ) {
3235
3075
 
3236
3076
  const root = getNode( child.id );
@@ -3246,15 +3086,15 @@
3246
3086
 
3247
3087
  }
3248
3088
 
3249
- } // sort bone data (the order is defined in the corresponding controller)
3089
+ }
3250
3090
 
3091
+ // sort bone data (the order is defined in the corresponding controller)
3251
3092
 
3252
3093
  for ( i = 0; i < joints.length; i ++ ) {
3253
3094
 
3254
3095
  for ( j = 0; j < boneData.length; j ++ ) {
3255
3096
 
3256
3097
  data = boneData[ j ];
3257
-
3258
3098
  if ( data.bone.name === joints[ i ].name ) {
3259
3099
 
3260
3100
  sortedBoneData[ i ] = data;
@@ -3265,13 +3105,13 @@
3265
3105
 
3266
3106
  }
3267
3107
 
3268
- } // add unprocessed bone data at the end of the list
3108
+ }
3269
3109
 
3110
+ // add unprocessed bone data at the end of the list
3270
3111
 
3271
3112
  for ( i = 0; i < boneData.length; i ++ ) {
3272
3113
 
3273
3114
  data = boneData[ i ];
3274
-
3275
3115
  if ( data.processed === false ) {
3276
3116
 
3277
3117
  sortedBoneData.push( data );
@@ -3279,12 +3119,12 @@
3279
3119
 
3280
3120
  }
3281
3121
 
3282
- } // setup arrays for skeleton creation
3122
+ }
3283
3123
 
3124
+ // setup arrays for skeleton creation
3284
3125
 
3285
3126
  const bones = [];
3286
3127
  const boneInverses = [];
3287
-
3288
3128
  for ( i = 0; i < sortedBoneData.length; i ++ ) {
3289
3129
 
3290
3130
  data = sortedBoneData[ i ];
@@ -3300,16 +3140,18 @@
3300
3140
  function buildBoneHierarchy( root, joints, boneData ) {
3301
3141
 
3302
3142
  // setup bone data from visual scene
3143
+
3303
3144
  root.traverse( function ( object ) {
3304
3145
 
3305
3146
  if ( object.isBone === true ) {
3306
3147
 
3307
- let boneInverse; // retrieve the boneInverse from the controller data
3148
+ let boneInverse;
3149
+
3150
+ // retrieve the boneInverse from the controller data
3308
3151
 
3309
3152
  for ( let i = 0; i < joints.length; i ++ ) {
3310
3153
 
3311
3154
  const joint = joints[ i ];
3312
-
3313
3155
  if ( joint.name === object.name ) {
3314
3156
 
3315
3157
  boneInverse = joint.boneInverse;
@@ -3326,6 +3168,7 @@
3326
3168
  // for the respective bone. This bone won't affect any vertices, because there are no skin indices
3327
3169
  // and weights defined for it. But we still have to add the bone to the sorted bone list in order to
3328
3170
  // ensure a correct animation of the model.
3171
+
3329
3172
  boneInverse = new THREE.Matrix4();
3330
3173
 
3331
3174
  }
@@ -3352,27 +3195,30 @@
3352
3195
  const instanceControllers = data.instanceControllers;
3353
3196
  const instanceLights = data.instanceLights;
3354
3197
  const instanceGeometries = data.instanceGeometries;
3355
- const instanceNodes = data.instanceNodes; // nodes
3198
+ const instanceNodes = data.instanceNodes;
3199
+
3200
+ // nodes
3356
3201
 
3357
3202
  for ( let i = 0, l = nodes.length; i < l; i ++ ) {
3358
3203
 
3359
3204
  objects.push( getNode( nodes[ i ] ) );
3360
3205
 
3361
- } // instance cameras
3206
+ }
3362
3207
 
3208
+ // instance cameras
3363
3209
 
3364
3210
  for ( let i = 0, l = instanceCameras.length; i < l; i ++ ) {
3365
3211
 
3366
3212
  const instanceCamera = getCamera( instanceCameras[ i ] );
3367
-
3368
3213
  if ( instanceCamera !== null ) {
3369
3214
 
3370
3215
  objects.push( instanceCamera.clone() );
3371
3216
 
3372
3217
  }
3373
3218
 
3374
- } // instance controllers
3219
+ }
3375
3220
 
3221
+ // instance controllers
3376
3222
 
3377
3223
  for ( let i = 0, l = instanceControllers.length; i < l; i ++ ) {
3378
3224
 
@@ -3383,11 +3229,9 @@
3383
3229
  const skeletons = instance.skeletons;
3384
3230
  const joints = controller.skin.joints;
3385
3231
  const skeleton = buildSkeleton( skeletons, joints );
3386
-
3387
3232
  for ( let j = 0, jl = newObjects.length; j < jl; j ++ ) {
3388
3233
 
3389
3234
  const object = newObjects[ j ];
3390
-
3391
3235
  if ( object.isSkinnedMesh ) {
3392
3236
 
3393
3237
  object.bind( skeleton, controller.skin.bindMatrix );
@@ -3399,38 +3243,41 @@
3399
3243
 
3400
3244
  }
3401
3245
 
3402
- } // instance lights
3246
+ }
3403
3247
 
3248
+ // instance lights
3404
3249
 
3405
3250
  for ( let i = 0, l = instanceLights.length; i < l; i ++ ) {
3406
3251
 
3407
3252
  const instanceLight = getLight( instanceLights[ i ] );
3408
-
3409
3253
  if ( instanceLight !== null ) {
3410
3254
 
3411
3255
  objects.push( instanceLight.clone() );
3412
3256
 
3413
3257
  }
3414
3258
 
3415
- } // instance geometries
3259
+ }
3416
3260
 
3261
+ // instance geometries
3417
3262
 
3418
3263
  for ( let i = 0, l = instanceGeometries.length; i < l; i ++ ) {
3419
3264
 
3420
- const instance = instanceGeometries[ i ]; // a single geometry instance in collada can lead to multiple object3Ds.
3265
+ const instance = instanceGeometries[ i ];
3266
+
3267
+ // a single geometry instance in collada can lead to multiple object3Ds.
3421
3268
  // this is the case when primitives are combined like triangles and lines
3422
3269
 
3423
3270
  const geometries = getGeometry( instance.id );
3424
3271
  const newObjects = buildObjects( geometries, instance.materials );
3425
-
3426
3272
  for ( let j = 0, jl = newObjects.length; j < jl; j ++ ) {
3427
3273
 
3428
3274
  objects.push( newObjects[ j ] );
3429
3275
 
3430
3276
  }
3431
3277
 
3432
- } // instance nodes
3278
+ }
3433
3279
 
3280
+ // instance nodes
3434
3281
 
3435
3282
  for ( let i = 0, l = instanceNodes.length; i < l; i ++ ) {
3436
3283
 
@@ -3439,7 +3286,6 @@
3439
3286
  }
3440
3287
 
3441
3288
  let object;
3442
-
3443
3289
  if ( nodes.length === 0 && objects.length === 1 ) {
3444
3290
 
3445
3291
  object = objects[ 0 ];
@@ -3447,7 +3293,6 @@
3447
3293
  } else {
3448
3294
 
3449
3295
  object = type === 'JOINT' ? new THREE.Bone() : new THREE.Group();
3450
-
3451
3296
  for ( let i = 0; i < objects.length; i ++ ) {
3452
3297
 
3453
3298
  object.add( objects[ i ] );
@@ -3466,15 +3311,12 @@
3466
3311
  const fallbackMaterial = new THREE.MeshBasicMaterial( {
3467
3312
  color: 0xff00ff
3468
3313
  } );
3469
-
3470
3314
  function resolveMaterialBinding( keys, instanceMaterials ) {
3471
3315
 
3472
3316
  const materials = [];
3473
-
3474
3317
  for ( let i = 0, l = keys.length; i < l; i ++ ) {
3475
3318
 
3476
3319
  const id = instanceMaterials[ keys[ i ] ];
3477
-
3478
3320
  if ( id === undefined ) {
3479
3321
 
3480
3322
  console.warn( 'THREE.ColladaLoader: Material with key %s not found. Apply fallback material.', keys[ i ] );
@@ -3495,11 +3337,12 @@
3495
3337
  function buildObjects( geometries, instanceMaterials ) {
3496
3338
 
3497
3339
  const objects = [];
3498
-
3499
3340
  for ( const type in geometries ) {
3500
3341
 
3501
3342
  const geometry = geometries[ type ];
3502
- const materials = resolveMaterialBinding( geometry.materialKeys, instanceMaterials ); // handle case if no materials are defined
3343
+ const materials = resolveMaterialBinding( geometry.materialKeys, instanceMaterials );
3344
+
3345
+ // handle case if no materials are defined
3503
3346
 
3504
3347
  if ( materials.length === 0 ) {
3505
3348
 
@@ -3513,25 +3356,27 @@
3513
3356
 
3514
3357
  }
3515
3358
 
3516
- } // regard skinning
3359
+ }
3517
3360
 
3361
+ // regard skinning
3518
3362
 
3519
- const skinning = geometry.data.attributes.skinIndex !== undefined; // choose between a single or multi materials (material array)
3363
+ const skinning = geometry.data.attributes.skinIndex !== undefined;
3520
3364
 
3521
- const material = materials.length === 1 ? materials[ 0 ] : materials; // now create a specific 3D object
3365
+ // choose between a single or multi materials (material array)
3522
3366
 
3523
- let object;
3367
+ const material = materials.length === 1 ? materials[ 0 ] : materials;
3524
3368
 
3369
+ // now create a specific 3D object
3370
+
3371
+ let object;
3525
3372
  switch ( type ) {
3526
3373
 
3527
3374
  case 'lines':
3528
3375
  object = new THREE.LineSegments( geometry.data, material );
3529
3376
  break;
3530
-
3531
3377
  case 'linestrips':
3532
3378
  object = new THREE.Line( geometry.data, material );
3533
3379
  break;
3534
-
3535
3380
  case 'triangles':
3536
3381
  case 'polylist':
3537
3382
  if ( skinning ) {
@@ -3566,8 +3411,9 @@
3566
3411
 
3567
3412
  return getBuild( library.nodes[ id ], buildNode );
3568
3413
 
3569
- } // visual scenes
3414
+ }
3570
3415
 
3416
+ // visual scenes
3571
3417
 
3572
3418
  function parseVisualScene( xml ) {
3573
3419
 
@@ -3577,7 +3423,6 @@
3577
3423
  };
3578
3424
  prepareNodes( xml );
3579
3425
  const elements = getElementsByTagName( xml, 'node' );
3580
-
3581
3426
  for ( let i = 0; i < elements.length; i ++ ) {
3582
3427
 
3583
3428
  data.children.push( parseNode( elements[ i ] ) );
@@ -3593,7 +3438,6 @@
3593
3438
  const group = new THREE.Group();
3594
3439
  group.name = data.name;
3595
3440
  const children = data.children;
3596
-
3597
3441
  for ( let i = 0; i < children.length; i ++ ) {
3598
3442
 
3599
3443
  const child = children[ i ];
@@ -3615,8 +3459,9 @@
3615
3459
 
3616
3460
  return getBuild( library.visualScenes[ id ], buildVisualScene );
3617
3461
 
3618
- } // scenes
3462
+ }
3619
3463
 
3464
+ // scenes
3620
3465
 
3621
3466
  function parseScene( xml ) {
3622
3467
 
@@ -3628,18 +3473,16 @@
3628
3473
  function setupAnimations() {
3629
3474
 
3630
3475
  const clips = library.clips;
3631
-
3632
3476
  if ( isEmpty( clips ) === true ) {
3633
3477
 
3634
3478
  if ( isEmpty( library.animations ) === false ) {
3635
3479
 
3636
3480
  // if there are animations but no clips, we create a default clip for playback
3637
- const tracks = [];
3638
3481
 
3482
+ const tracks = [];
3639
3483
  for ( const id in library.animations ) {
3640
3484
 
3641
3485
  const animationTracks = getAnimation( id );
3642
-
3643
3486
  for ( let i = 0, l = animationTracks.length; i < l; i ++ ) {
3644
3487
 
3645
3488
  tracks.push( animationTracks[ i ] );
@@ -3662,19 +3505,18 @@
3662
3505
 
3663
3506
  }
3664
3507
 
3665
- } // convert the parser error element into text with each child elements text
3666
- // separated by new lines.
3508
+ }
3667
3509
 
3510
+ // convert the parser error element into text with each child elements text
3511
+ // separated by new lines.
3668
3512
 
3669
3513
  function parserErrorToText( parserError ) {
3670
3514
 
3671
3515
  let result = '';
3672
3516
  const stack = [ parserError ];
3673
-
3674
3517
  while ( stack.length ) {
3675
3518
 
3676
3519
  const node = stack.shift();
3677
-
3678
3520
  if ( node.nodeType === Node.TEXT_NODE ) {
3679
3521
 
3680
3522
  result += node.textContent;
@@ -3703,13 +3545,12 @@
3703
3545
  const xml = new DOMParser().parseFromString( text, 'application/xml' );
3704
3546
  const collada = getElementsByTagName( xml, 'COLLADA' )[ 0 ];
3705
3547
  const parserError = xml.getElementsByTagName( 'parsererror' )[ 0 ];
3706
-
3707
3548
  if ( parserError !== undefined ) {
3708
3549
 
3709
3550
  // Chrome will return parser error with a div in it
3551
+
3710
3552
  const errorElement = getElementsByTagName( parserError, 'div' )[ 0 ];
3711
3553
  let errorText;
3712
-
3713
3554
  if ( errorElement ) {
3714
3555
 
3715
3556
  errorText = errorElement.textContent;
@@ -3723,8 +3564,9 @@
3723
3564
  console.error( 'THREE.ColladaLoader: Failed to parse collada file.\n', errorText );
3724
3565
  return null;
3725
3566
 
3726
- } // metadata
3567
+ }
3727
3568
 
3569
+ // metadata
3728
3570
 
3729
3571
  const version = collada.getAttribute( 'version' );
3730
3572
  console.log( 'THREE.ColladaLoader: File version', version );
@@ -3732,19 +3574,21 @@
3732
3574
  const textureLoader = new THREE.TextureLoader( this.manager );
3733
3575
  textureLoader.setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin );
3734
3576
  let tgaLoader;
3735
-
3736
3577
  if ( THREE.TGALoader ) {
3737
3578
 
3738
3579
  tgaLoader = new THREE.TGALoader( this.manager );
3739
3580
  tgaLoader.setPath( this.resourcePath || path );
3740
3581
 
3741
- } //
3582
+ }
3742
3583
 
3584
+ //
3743
3585
 
3744
3586
  const tempColor = new THREE.Color();
3745
3587
  const animations = [];
3746
3588
  let kinematics = {};
3747
- let count = 0; //
3589
+ let count = 0;
3590
+
3591
+ //
3748
3592
 
3749
3593
  const library = {
3750
3594
  animations: {},
@@ -3790,7 +3634,6 @@
3790
3634
  setupKinematics();
3791
3635
  const scene = parseScene( getElementsByTagName( collada, 'scene' )[ 0 ] );
3792
3636
  scene.animations = animations;
3793
-
3794
3637
  if ( asset.upAxis === 'Z_UP' ) {
3795
3638
 
3796
3639
  console.warn( 'THREE.ColladaLoader: You are loading an asset with a Z-UP coordinate system. The loader just rotates the asset to transform it into Y-UP. The vertex data are not converted, see #24289.' );
@@ -3806,7 +3649,6 @@
3806
3649
  return animations;
3807
3650
 
3808
3651
  },
3809
-
3810
3652
  kinematics: kinematics,
3811
3653
  library: library,
3812
3654
  scene: scene