super-three 0.141.0 → 0.147.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (646) hide show
  1. package/README.md +9 -9
  2. package/build/three.cjs +2441 -1569
  3. package/build/three.js +2441 -1569
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +2847 -1576
  6. package/examples/js/animation/AnimationClipCreator.js +0 -8
  7. package/examples/js/animation/CCDIKSolver.js +50 -67
  8. package/examples/js/animation/MMDAnimationHelper.js +66 -137
  9. package/examples/js/animation/MMDPhysics.js +71 -150
  10. package/examples/js/cameras/CinematicCamera.js +33 -22
  11. package/examples/js/controls/ArcballControls.js +149 -403
  12. package/examples/js/controls/DragControls.js +8 -33
  13. package/examples/js/controls/FirstPersonControls.js +32 -61
  14. package/examples/js/controls/FlyControls.js +29 -63
  15. package/examples/js/controls/OrbitControls.js +125 -103
  16. package/examples/js/controls/PointerLockControls.js +5 -22
  17. package/examples/js/controls/TrackballControls.js +33 -88
  18. package/examples/js/controls/TransformControls.js +101 -182
  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 +6 -20
  28. package/examples/js/effects/AsciiEffect.js +32 -31
  29. package/examples/js/effects/OutlineEffect.js +30 -54
  30. package/examples/js/effects/ParallaxBarrierEffect.js +2 -15
  31. package/examples/js/effects/PeppersGhostEffect.js +14 -41
  32. package/examples/js/effects/StereoEffect.js +2 -6
  33. package/examples/js/environments/RoomEnvironment.js +32 -8
  34. package/examples/js/exporters/ColladaExporter.js +52 -78
  35. package/examples/js/exporters/DRACOExporter.js +22 -34
  36. package/examples/js/exporters/EXRExporter.js +15 -18
  37. package/examples/js/exporters/GLTFExporter.js +168 -345
  38. package/examples/js/exporters/MMDExporter.js +5 -12
  39. package/examples/js/exporters/OBJExporter.js +40 -52
  40. package/examples/js/exporters/PLYExporter.js +50 -57
  41. package/examples/js/exporters/STLExporter.js +5 -14
  42. package/examples/js/exporters/USDZExporter.js +119 -27
  43. package/examples/js/geometries/BoxLineGeometry.js +0 -1
  44. package/examples/js/geometries/ConvexGeometry.js +12 -7
  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 +23 -17
  49. package/examples/js/geometries/RoundedBoxGeometry.js +21 -19
  50. package/examples/js/geometries/TeapotGeometry.js +54 -50
  51. package/examples/js/geometries/TextGeometry.js +6 -4
  52. package/examples/js/helpers/LightProbeHelper.js +1 -2
  53. package/examples/js/helpers/OctreeHelper.js +22 -20
  54. package/examples/js/helpers/PositionalAudioHelper.js +8 -6
  55. package/examples/js/helpers/RectAreaLightHelper.js +6 -7
  56. package/examples/js/helpers/VertexNormalsHelper.js +15 -13
  57. package/examples/js/helpers/VertexTangentsHelper.js +15 -9
  58. package/examples/js/helpers/ViewHelper.js +31 -16
  59. package/examples/js/interactive/HTMLMesh.js +25 -39
  60. package/examples/js/interactive/InteractiveGroup.js +9 -14
  61. package/examples/js/interactive/SelectionBox.js +3 -70
  62. package/examples/js/interactive/SelectionHelper.js +2 -8
  63. package/examples/js/libs/ktx-parse.umd.js +1 -0
  64. package/examples/js/libs/meshopt_decoder.js +98 -32
  65. package/examples/js/lights/LightProbeGenerator.js +32 -39
  66. package/examples/js/lights/RectAreaLightUniformsLib.js +5 -1
  67. package/examples/js/lines/LineGeometry.js +3 -5
  68. package/examples/js/lines/LineMaterial.js +4 -11
  69. package/examples/js/lines/LineSegments2.js +40 -89
  70. package/examples/js/lines/LineSegmentsGeometry.js +7 -28
  71. package/examples/js/lines/Wireframe.js +2 -7
  72. package/examples/js/lines/WireframeGeometry2.js +3 -1
  73. package/examples/js/loaders/3DMLoader.js +58 -155
  74. package/examples/js/loaders/3MFLoader.js +72 -106
  75. package/examples/js/loaders/AMFLoader.js +0 -25
  76. package/examples/js/loaders/BVHLoader.js +44 -43
  77. package/examples/js/loaders/BasisTextureLoader.js +16 -46
  78. package/examples/js/loaders/ColladaLoader.js +229 -359
  79. package/examples/js/loaders/DDSLoader.js +24 -25
  80. package/examples/js/loaders/DRACOLoader.js +30 -90
  81. package/examples/js/loaders/EXRLoader.js +69 -177
  82. package/examples/js/loaders/FBXLoader.js +294 -441
  83. package/examples/js/loaders/FontLoader.js +9 -31
  84. package/examples/js/loaders/GCodeLoader.js +15 -16
  85. package/examples/js/loaders/GLTFLoader.js +458 -739
  86. package/examples/js/loaders/HDRCubeTextureLoader.js +0 -17
  87. package/examples/js/loaders/KMZLoader.js +3 -7
  88. package/examples/js/loaders/KTXLoader.js +12 -30
  89. package/examples/js/loaders/LDrawLoader.js +309 -355
  90. package/examples/js/loaders/LUT3dlLoader.js +7 -11
  91. package/examples/js/loaders/LUTCubeLoader.js +0 -8
  92. package/examples/js/loaders/LWOLoader.js +59 -124
  93. package/examples/js/loaders/LogLuvLoader.js +27 -77
  94. package/examples/js/loaders/LottieLoader.js +4 -4
  95. package/examples/js/loaders/MD2Loader.js +26 -27
  96. package/examples/js/loaders/MDDLoader.js +6 -10
  97. package/examples/js/loaders/MMDLoader.js +180 -189
  98. package/examples/js/loaders/MTLLoader.js +18 -47
  99. package/examples/js/loaders/NRRDLoader.js +44 -84
  100. package/examples/js/loaders/OBJLoader.js +56 -77
  101. package/examples/js/loaders/PCDLoader.js +92 -42
  102. package/examples/js/loaders/PDBLoader.js +17 -13
  103. package/examples/js/loaders/PLYLoader.js +65 -51
  104. package/examples/js/loaders/PRWMLoader.js +11 -22
  105. package/examples/js/loaders/PVRLoader.js +7 -16
  106. package/examples/js/loaders/RGBELoader.js +36 -61
  107. package/examples/js/loaders/RGBMLoader.js +26 -87
  108. package/examples/js/loaders/STLLoader.js +20 -27
  109. package/examples/js/loaders/SVGLoader.js +365 -236
  110. package/examples/js/loaders/TDSLoader.js +81 -118
  111. package/examples/js/loaders/TGALoader.js +39 -41
  112. package/examples/js/loaders/TIFFLoader.js +30 -0
  113. package/examples/js/loaders/TTFLoader.js +0 -8
  114. package/examples/js/loaders/TiltLoader.js +14 -15
  115. package/examples/js/loaders/VOXLoader.js +8 -16
  116. package/examples/js/loaders/VRMLLoader.js +266 -354
  117. package/examples/js/loaders/VTKLoader.js +102 -119
  118. package/examples/js/loaders/XYZLoader.js +2 -4
  119. package/examples/js/loaders/lwo/IFFParser.js +55 -136
  120. package/examples/js/loaders/lwo/LWO2Parser.js +39 -89
  121. package/examples/js/loaders/lwo/LWO3Parser.js +38 -79
  122. package/examples/js/materials/MeshGouraudMaterial.js +387 -0
  123. package/examples/js/math/Capsule.js +0 -17
  124. package/examples/js/math/ColorConverter.js +3 -53
  125. package/examples/js/math/ConvexHull.js +185 -141
  126. package/examples/js/math/ImprovedNoise.js +1 -1
  127. package/examples/js/math/Lut.js +8 -15
  128. package/examples/js/math/MeshSurfaceSampler.js +6 -28
  129. package/examples/js/math/OBB.js +90 -49
  130. package/examples/js/math/Octree.js +2 -57
  131. package/examples/js/math/SimplexNoise.js +74 -88
  132. package/examples/js/misc/ConvexObjectBreaker.js +37 -48
  133. package/examples/js/misc/GPUComputationRenderer.js +47 -14
  134. package/examples/js/misc/Gyroscope.js +5 -9
  135. package/examples/js/misc/MD2Character.js +14 -23
  136. package/examples/js/misc/MD2CharacterComplex.js +73 -54
  137. package/examples/js/misc/MorphAnimMesh.js +0 -6
  138. package/examples/js/misc/MorphBlendMesh.js +3 -30
  139. package/examples/js/misc/ProgressiveLightMap.js +47 -43
  140. package/examples/js/misc/RollerCoaster.js +17 -24
  141. package/examples/js/misc/TubePainter.js +18 -12
  142. package/examples/js/misc/Volume.js +173 -194
  143. package/examples/js/misc/VolumeSlice.js +91 -99
  144. package/examples/js/modifiers/CurveModifier.js +19 -21
  145. package/examples/js/modifiers/EdgeSplitModifier.js +0 -30
  146. package/examples/js/modifiers/SimplifyModifier.js +57 -60
  147. package/examples/js/modifiers/TessellateModifier.js +2 -9
  148. package/examples/js/objects/GroundProjectedEnv.js +181 -0
  149. package/examples/js/objects/Lensflare.js +47 -38
  150. package/examples/js/objects/LightningStorm.js +10 -13
  151. package/examples/js/objects/MarchingCubes.js +80 -59
  152. package/examples/js/objects/Reflector.js +31 -22
  153. package/examples/js/objects/ReflectorForSSRPass.js +20 -25
  154. package/examples/js/objects/Refractor.js +61 -33
  155. package/examples/js/objects/ShadowMesh.js +6 -3
  156. package/examples/js/objects/Sky.js +2 -7
  157. package/examples/js/objects/Water.js +23 -18
  158. package/examples/js/objects/Water2.js +20 -19
  159. package/examples/js/physics/AmmoPhysics.js +23 -20
  160. package/examples/js/physics/OimoPhysics.js +19 -17
  161. package/examples/js/postprocessing/AdaptiveToneMappingPass.js +13 -20
  162. package/examples/js/postprocessing/AfterimagePass.js +19 -12
  163. package/examples/js/postprocessing/BloomPass.js +38 -17
  164. package/examples/js/postprocessing/BokehPass.js +29 -12
  165. package/examples/js/postprocessing/ClearPass.js +1 -6
  166. package/examples/js/postprocessing/CubeTexturePass.js +12 -9
  167. package/examples/js/postprocessing/DotScreenPass.js +7 -5
  168. package/examples/js/postprocessing/EffectComposer.js +25 -32
  169. package/examples/js/postprocessing/FilmPass.js +7 -5
  170. package/examples/js/postprocessing/GlitchPass.js +10 -11
  171. package/examples/js/postprocessing/HalftonePass.js +9 -9
  172. package/examples/js/postprocessing/LUTPass.js +2 -15
  173. package/examples/js/postprocessing/MaskPass.js +20 -17
  174. package/examples/js/postprocessing/OutlinePass.js +49 -38
  175. package/examples/js/postprocessing/Pass.js +11 -14
  176. package/examples/js/postprocessing/RenderPass.js +3 -7
  177. package/examples/js/postprocessing/RenderPixelatedPass.js +215 -0
  178. package/examples/js/postprocessing/SAOPass.js +40 -32
  179. package/examples/js/postprocessing/SMAAPass.js +34 -17
  180. package/examples/js/postprocessing/SSAARenderPass.js +14 -14
  181. package/examples/js/postprocessing/SSAOPass.js +56 -42
  182. package/examples/js/postprocessing/SSRPass.js +78 -61
  183. package/examples/js/postprocessing/SavePass.js +14 -6
  184. package/examples/js/postprocessing/ShaderPass.js +9 -8
  185. package/examples/js/postprocessing/TAARenderPass.js +11 -9
  186. package/examples/js/postprocessing/TexturePass.js +7 -4
  187. package/examples/js/postprocessing/UnrealBloomPass.js +43 -25
  188. package/examples/js/renderers/CSS2DRenderer.js +4 -23
  189. package/examples/js/renderers/CSS3DRenderer.js +5 -26
  190. package/examples/js/renderers/Projector.js +31 -108
  191. package/examples/js/renderers/SVGRenderer.js +4 -50
  192. package/examples/js/shaders/ACESFilmicToneMappingShader.js +3 -6
  193. package/examples/js/shaders/AfterimageShader.js +3 -6
  194. package/examples/js/shaders/BasicShader.js +3 -6
  195. package/examples/js/shaders/BleachBypassShader.js +3 -6
  196. package/examples/js/shaders/BlendShader.js +3 -6
  197. package/examples/js/shaders/BokehShader.js +3 -6
  198. package/examples/js/shaders/BokehShader2.js +4 -13
  199. package/examples/js/shaders/BrightnessContrastShader.js +3 -6
  200. package/examples/js/shaders/ColorCorrectionShader.js +2 -6
  201. package/examples/js/shaders/ColorifyShader.js +2 -6
  202. package/examples/js/shaders/ConvolutionShader.js +5 -10
  203. package/examples/js/shaders/CopyShader.js +3 -6
  204. package/examples/js/shaders/DOFMipMapShader.js +3 -6
  205. package/examples/js/shaders/DepthLimitedBlurShader.js +2 -9
  206. package/examples/js/shaders/DigitalGlitch.js +3 -6
  207. package/examples/js/shaders/DotScreenShader.js +2 -6
  208. package/examples/js/shaders/FXAAShader.js +1 -3
  209. package/examples/js/shaders/FilmShader.js +3 -6
  210. package/examples/js/shaders/FocusShader.js +3 -6
  211. package/examples/js/shaders/FreiChenShader.js +2 -6
  212. package/examples/js/shaders/GammaCorrectionShader.js +3 -6
  213. package/examples/js/shaders/GodRaysShader.js +11 -24
  214. package/examples/js/shaders/HalftoneShader.js +3 -6
  215. package/examples/js/shaders/HorizontalBlurShader.js +3 -6
  216. package/examples/js/shaders/HorizontalTiltShiftShader.js +3 -6
  217. package/examples/js/shaders/HueSaturationShader.js +3 -6
  218. package/examples/js/shaders/KaleidoShader.js +3 -6
  219. package/examples/js/shaders/LuminosityHighPassShader.js +2 -6
  220. package/examples/js/shaders/LuminosityShader.js +4 -7
  221. package/examples/js/shaders/MMDToonShader.js +2 -4
  222. package/examples/js/shaders/MirrorShader.js +3 -6
  223. package/examples/js/shaders/NormalMapShader.js +2 -6
  224. package/examples/js/shaders/RGBShiftShader.js +3 -6
  225. package/examples/js/shaders/SAOShader.js +2 -6
  226. package/examples/js/shaders/SMAAShader.js +6 -18
  227. package/examples/js/shaders/SSAOShader.js +2 -6
  228. package/examples/js/shaders/SSRShader.js +6 -18
  229. package/examples/js/shaders/SepiaShader.js +3 -6
  230. package/examples/js/shaders/SobelOperatorShader.js +2 -6
  231. package/examples/js/shaders/TechnicolorShader.js +3 -6
  232. package/examples/js/shaders/ToneMapShader.js +4 -7
  233. package/examples/js/shaders/ToonShader.js +8 -24
  234. package/examples/js/shaders/TriangleBlurShader.js +2 -6
  235. package/examples/js/shaders/UnpackDepthRGBAShader.js +3 -6
  236. package/examples/js/shaders/VelocityShader.js +126 -0
  237. package/examples/js/shaders/VerticalBlurShader.js +3 -6
  238. package/examples/js/shaders/VerticalTiltShiftShader.js +3 -6
  239. package/examples/js/shaders/VignetteShader.js +3 -6
  240. package/examples/js/shaders/VolumeShader.js +2 -6
  241. package/examples/js/shaders/WaterRefractionShader.js +2 -6
  242. package/examples/js/textures/FlakesTexture.js +0 -1
  243. package/examples/js/utils/BufferGeometryUtils.js +237 -171
  244. package/examples/js/utils/CameraUtils.js +5 -20
  245. package/examples/js/utils/GPUStatsPanel.js +3 -12
  246. package/examples/js/utils/GeometryCompressionUtils.js +19 -44
  247. package/examples/js/utils/GeometryUtils.js +15 -36
  248. package/examples/js/utils/LDrawUtils.js +8 -11
  249. package/examples/js/utils/PackedPhongMaterial.js +6 -4
  250. package/examples/js/utils/SceneUtils.js +109 -14
  251. package/examples/js/utils/ShadowMapViewer.js +17 -14
  252. package/examples/js/utils/SkeletonUtils.js +13 -27
  253. package/examples/js/utils/UVsDebug.js +20 -12
  254. package/examples/js/utils/WorkerPool.js +1 -11
  255. package/examples/jsm/animation/CCDIKSolver.js +27 -3
  256. package/examples/jsm/animation/MMDPhysics.js +28 -22
  257. package/examples/jsm/capabilities/WebGPU.js +3 -1
  258. package/examples/jsm/controls/ArcballControls.js +17 -2
  259. package/examples/jsm/controls/FirstPersonControls.js +20 -27
  260. package/examples/jsm/controls/FlyControls.js +16 -24
  261. package/examples/jsm/controls/OrbitControls.js +44 -9
  262. package/examples/jsm/controls/PointerLockControls.js +0 -7
  263. package/examples/jsm/controls/TrackballControls.js +14 -5
  264. package/examples/jsm/controls/TransformControls.js +18 -16
  265. package/examples/jsm/csm/CSM.js +1 -0
  266. package/examples/jsm/csm/CSMHelper.js +30 -0
  267. package/examples/jsm/effects/AnaglyphEffect.js +2 -2
  268. package/examples/jsm/effects/OutlineEffect.js +4 -25
  269. package/examples/jsm/effects/ParallaxBarrierEffect.js +2 -2
  270. package/examples/jsm/effects/PeppersGhostEffect.js +2 -2
  271. package/examples/jsm/effects/StereoEffect.js +2 -2
  272. package/examples/jsm/environments/RoomEnvironment.js +23 -0
  273. package/examples/jsm/exporters/ColladaExporter.js +4 -13
  274. package/examples/jsm/exporters/DRACOExporter.js +0 -13
  275. package/examples/jsm/exporters/GLTFExporter.js +29 -110
  276. package/examples/jsm/exporters/KTX2Exporter.js +29 -29
  277. package/examples/jsm/exporters/OBJExporter.js +0 -18
  278. package/examples/jsm/exporters/PLYExporter.js +14 -22
  279. package/examples/jsm/exporters/STLExporter.js +1 -9
  280. package/examples/jsm/exporters/USDZExporter.js +107 -4
  281. package/examples/jsm/geometries/ConvexGeometry.js +1 -1
  282. package/examples/jsm/geometries/ParametricGeometry.js +0 -6
  283. package/examples/jsm/helpers/OctreeHelper.js +22 -8
  284. package/examples/jsm/helpers/VertexNormalsHelper.js +7 -1
  285. package/examples/jsm/helpers/VertexTangentsHelper.js +7 -0
  286. package/examples/jsm/helpers/ViewHelper.js +24 -0
  287. package/examples/jsm/interactive/HTMLMesh.js +14 -15
  288. package/examples/jsm/interactive/InteractiveGroup.js +4 -2
  289. package/examples/jsm/interactive/SelectionHelper.js +5 -3
  290. package/examples/jsm/libs/flow.module.js +610 -160
  291. package/examples/jsm/libs/lottie_canvas.module.js +14844 -0
  292. package/examples/jsm/libs/meshopt_decoder.module.js +97 -32
  293. package/examples/jsm/libs/utif.module.js +1579 -0
  294. package/examples/jsm/libs/zstddec.module.js +1 -0
  295. package/examples/jsm/lines/LineSegments2.js +4 -0
  296. package/examples/jsm/loaders/3DMLoader.js +1 -2
  297. package/examples/jsm/loaders/ColladaLoader.js +29 -0
  298. package/examples/jsm/loaders/DRACOLoader.js +2 -28
  299. package/examples/jsm/loaders/EXRLoader.js +3 -13
  300. package/examples/jsm/loaders/FBXLoader.js +26 -3
  301. package/examples/jsm/loaders/FontLoader.js +3 -16
  302. package/examples/jsm/loaders/GLTFLoader.js +321 -464
  303. package/examples/jsm/loaders/HDRCubeTextureLoader.js +0 -13
  304. package/examples/jsm/loaders/KTX2Loader.js +254 -53
  305. package/examples/jsm/loaders/LDrawLoader.js +149 -87
  306. package/examples/jsm/loaders/LottieLoader.js +4 -2
  307. package/examples/jsm/loaders/MaterialXLoader.js +728 -0
  308. package/examples/jsm/loaders/OBJLoader.js +6 -14
  309. package/examples/jsm/loaders/PCDLoader.js +60 -14
  310. package/examples/jsm/loaders/PLYLoader.js +71 -19
  311. package/examples/jsm/loaders/RGBELoader.js +1 -1
  312. package/examples/jsm/loaders/SVGLoader.js +231 -17
  313. package/examples/jsm/loaders/TIFFLoader.js +36 -0
  314. package/examples/jsm/loaders/USDZLoader.js +633 -0
  315. package/examples/jsm/loaders/VRMLLoader.js +36 -26
  316. package/examples/jsm/loaders/VTKLoader.js +1 -1
  317. package/examples/jsm/loaders/lwo/LWO2Parser.js +6 -8
  318. package/examples/jsm/loaders/lwo/LWO3Parser.js +6 -8
  319. package/examples/jsm/materials/MeshGouraudMaterial.js +423 -0
  320. package/examples/jsm/math/ColorConverter.js +1 -49
  321. package/examples/jsm/math/ConvexHull.js +4 -4
  322. package/examples/jsm/math/Octree.js +1 -1
  323. package/examples/jsm/misc/GPUComputationRenderer.js +43 -0
  324. package/examples/jsm/misc/Volume.js +169 -171
  325. package/examples/jsm/misc/VolumeSlice.js +78 -80
  326. package/examples/jsm/modifiers/SimplifyModifier.js +1 -1
  327. package/examples/jsm/node-editor/NodeEditor.js +91 -12
  328. package/examples/jsm/node-editor/accessors/MatcapUVEditor.js +1 -1
  329. package/examples/jsm/node-editor/accessors/NormalEditor.js +1 -1
  330. package/examples/jsm/node-editor/accessors/PositionEditor.js +1 -1
  331. package/examples/jsm/node-editor/accessors/UVEditor.js +1 -1
  332. package/examples/jsm/node-editor/core/BaseNode.js +10 -3
  333. package/examples/jsm/node-editor/display/BlendEditor.js +1 -1
  334. package/examples/jsm/node-editor/display/NormalMapEditor.js +1 -1
  335. package/examples/jsm/node-editor/inputs/ColorEditor.js +1 -1
  336. package/examples/jsm/node-editor/inputs/FloatEditor.js +1 -1
  337. package/examples/jsm/node-editor/inputs/SliderEditor.js +1 -1
  338. package/examples/jsm/node-editor/inputs/TextureEditor.js +1 -1
  339. package/examples/jsm/node-editor/inputs/Vector2Editor.js +1 -1
  340. package/examples/jsm/node-editor/inputs/Vector3Editor.js +1 -1
  341. package/examples/jsm/node-editor/inputs/Vector4Editor.js +1 -1
  342. package/examples/jsm/node-editor/materials/BasicMaterialEditor.js +7 -10
  343. package/examples/jsm/node-editor/materials/PointsMaterialEditor.js +1 -1
  344. package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +7 -10
  345. package/examples/jsm/node-editor/math/AngleEditor.js +4 -4
  346. package/examples/jsm/node-editor/math/DotEditor.js +1 -1
  347. package/examples/jsm/node-editor/math/InvertEditor.js +3 -3
  348. package/examples/jsm/node-editor/math/LimiterEditor.js +1 -1
  349. package/examples/jsm/node-editor/math/NormalizeEditor.js +1 -1
  350. package/examples/jsm/node-editor/math/OperatorEditor.js +1 -1
  351. package/examples/jsm/node-editor/math/PowerEditor.js +1 -1
  352. package/examples/jsm/node-editor/math/TrigonometryEditor.js +1 -1
  353. package/examples/jsm/node-editor/procedural/CheckerEditor.js +1 -1
  354. package/examples/jsm/node-editor/scene/MeshEditor.js +11 -8
  355. package/examples/jsm/node-editor/utils/JoinEditor.js +1 -1
  356. package/examples/jsm/node-editor/utils/OscillatorEditor.js +1 -1
  357. package/examples/jsm/node-editor/utils/PreviewEditor.js +7 -3
  358. package/examples/jsm/node-editor/utils/SplitEditor.js +1 -1
  359. package/examples/jsm/node-editor/utils/TimerEditor.js +1 -1
  360. package/examples/jsm/nodes/Nodes.js +70 -13
  361. package/examples/jsm/nodes/accessors/BitangentNode.js +62 -0
  362. package/examples/jsm/nodes/accessors/CubeTextureNode.js +9 -5
  363. package/examples/jsm/nodes/accessors/NormalNode.js +8 -8
  364. package/examples/jsm/nodes/accessors/Object3DNode.js +1 -1
  365. package/examples/jsm/nodes/accessors/PositionNode.js +11 -5
  366. package/examples/jsm/nodes/accessors/ReferenceNode.js +1 -1
  367. package/examples/jsm/nodes/accessors/ReflectVectorNode.js +31 -0
  368. package/examples/jsm/nodes/accessors/SkinningNode.js +8 -1
  369. package/examples/jsm/nodes/accessors/TangentNode.js +95 -0
  370. package/examples/jsm/nodes/core/AttributeNode.js +32 -9
  371. package/examples/jsm/nodes/core/CodeNode.js +3 -3
  372. package/examples/jsm/nodes/core/FunctionCallNode.js +20 -5
  373. package/examples/jsm/nodes/core/FunctionNode.js +2 -2
  374. package/examples/jsm/nodes/core/Node.js +15 -13
  375. package/examples/jsm/nodes/core/NodeBuilder.js +67 -18
  376. package/examples/jsm/nodes/core/NodeFrame.js +2 -2
  377. package/examples/jsm/nodes/core/NodeUtils.js +23 -1
  378. package/examples/jsm/nodes/core/NodeVarying.js +17 -0
  379. package/examples/jsm/nodes/core/VaryingNode.js +56 -0
  380. package/examples/jsm/nodes/core/constants.js +13 -13
  381. package/examples/jsm/nodes/display/BlendModeNode.js +85 -0
  382. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +84 -0
  383. package/examples/jsm/nodes/display/NormalMapNode.js +19 -12
  384. package/examples/jsm/nodes/display/PosterizeNode.js +25 -0
  385. package/examples/jsm/nodes/display/ViewportNode.js +106 -0
  386. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +5 -5
  387. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +3 -3
  388. package/examples/jsm/nodes/functions/light/getDistanceAttenuation.js +2 -2
  389. package/examples/jsm/nodes/geometry/RangeNode.js +109 -0
  390. package/examples/jsm/nodes/gpgpu/ComputeNode.js +3 -1
  391. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +1 -1
  392. package/examples/jsm/nodes/lighting/EnvironmentNode.js +8 -7
  393. package/examples/jsm/nodes/lighting/LightingContextNode.js +4 -4
  394. package/examples/jsm/nodes/loaders/NodeLoader.js +2 -2
  395. package/examples/jsm/nodes/loaders/NodeMaterialLoader.js +33 -0
  396. package/examples/jsm/nodes/materials/Materials.js +21 -31
  397. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +70 -0
  398. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +4 -7
  399. package/examples/jsm/nodes/materials/NodeMaterial.js +11 -3
  400. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +28 -17
  401. package/examples/jsm/nodes/materialx/DISCLAIMER.md +199 -0
  402. package/examples/jsm/nodes/materialx/MaterialXNodes.js +59 -0
  403. package/examples/jsm/nodes/materialx/lib/mx_hsv.js +56 -0
  404. package/examples/jsm/nodes/materialx/lib/mx_noise.js +617 -0
  405. package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +18 -0
  406. package/examples/jsm/nodes/math/MathNode.js +7 -17
  407. package/examples/jsm/nodes/math/OperatorNode.js +16 -3
  408. package/examples/jsm/nodes/parsers/GLSLNodeFunction.js +21 -6
  409. package/examples/jsm/nodes/procedural/CheckerNode.js +2 -2
  410. package/examples/jsm/nodes/shadernode/ShaderNode.js +40 -25
  411. package/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js +95 -68
  412. package/examples/jsm/nodes/shadernode/ShaderNodeElements.js +49 -6
  413. package/examples/jsm/nodes/utils/ConvertNode.js +18 -12
  414. package/examples/jsm/nodes/utils/EquirectUVNode.js +27 -0
  415. package/examples/jsm/nodes/utils/JoinNode.js +15 -9
  416. package/examples/jsm/nodes/utils/MatcapUVNode.js +2 -4
  417. package/examples/jsm/nodes/utils/MaxMipLevelNode.js +3 -2
  418. package/examples/jsm/nodes/utils/OscNode.js +2 -2
  419. package/examples/jsm/nodes/utils/RemapNode.js +34 -0
  420. package/examples/jsm/nodes/utils/RotateUVNode.js +32 -0
  421. package/examples/jsm/nodes/utils/SplitNode.js +21 -5
  422. package/examples/jsm/nodes/utils/SpriteSheetUVNode.js +8 -10
  423. package/examples/jsm/nodes/utils/TimerNode.js +23 -3
  424. package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +51 -0
  425. package/examples/jsm/objects/GroundProjectedEnv.js +186 -0
  426. package/examples/jsm/objects/Reflector.js +12 -5
  427. package/examples/jsm/objects/ReflectorForSSRPass.js +3 -5
  428. package/examples/jsm/objects/Refractor.js +12 -6
  429. package/examples/jsm/objects/ShadowMesh.js +8 -2
  430. package/examples/jsm/postprocessing/AfterimagePass.js +17 -4
  431. package/examples/jsm/postprocessing/BloomPass.js +22 -3
  432. package/examples/jsm/postprocessing/BokehPass.js +18 -4
  433. package/examples/jsm/postprocessing/CubeTexturePass.js +12 -5
  434. package/examples/jsm/postprocessing/DotScreenPass.js +8 -0
  435. package/examples/jsm/postprocessing/EffectComposer.js +9 -0
  436. package/examples/jsm/postprocessing/FilmPass.js +8 -0
  437. package/examples/jsm/postprocessing/GlitchPass.js +13 -1
  438. package/examples/jsm/postprocessing/HalftonePass.js +8 -0
  439. package/examples/jsm/postprocessing/OutlinePass.js +25 -3
  440. package/examples/jsm/postprocessing/Pass.js +2 -0
  441. package/examples/jsm/postprocessing/RenderPixelatedPass.js +234 -0
  442. package/examples/jsm/postprocessing/SAOPass.js +20 -0
  443. package/examples/jsm/postprocessing/SMAAPass.js +16 -0
  444. package/examples/jsm/postprocessing/SSAARenderPass.js +4 -0
  445. package/examples/jsm/postprocessing/SavePass.js +17 -1
  446. package/examples/jsm/postprocessing/ShaderPass.js +8 -0
  447. package/examples/jsm/postprocessing/TAARenderPass.js +9 -0
  448. package/examples/jsm/postprocessing/TexturePass.js +8 -0
  449. package/examples/jsm/postprocessing/UnrealBloomPass.js +16 -0
  450. package/examples/jsm/renderers/CSS2DRenderer.js +2 -2
  451. package/examples/jsm/renderers/CSS3DRenderer.js +2 -2
  452. package/examples/jsm/renderers/Projector.js +2 -24
  453. package/examples/jsm/renderers/webgl/nodes/SlotNode.js +9 -5
  454. package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +363 -231
  455. package/examples/jsm/renderers/webgl/nodes/WebGLNodes.js +7 -3
  456. package/examples/jsm/renderers/webgpu/WebGPUAnimation.js +58 -0
  457. package/examples/jsm/renderers/webgpu/WebGPUAttributes.js +63 -5
  458. package/examples/jsm/renderers/webgpu/WebGPUBackground.js +68 -3
  459. package/examples/jsm/renderers/webgpu/WebGPUComputePipelines.js +6 -0
  460. package/examples/jsm/renderers/webgpu/WebGPUGeometries.js +6 -0
  461. package/examples/jsm/renderers/webgpu/WebGPUObjects.js +1 -1
  462. package/examples/jsm/renderers/webgpu/WebGPURenderPipeline.js +17 -19
  463. package/examples/jsm/renderers/webgpu/WebGPURenderPipelines.js +16 -14
  464. package/examples/jsm/renderers/webgpu/WebGPURenderStates.js +2 -2
  465. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +113 -93
  466. package/examples/jsm/renderers/webgpu/WebGPUTextureUtils.js +5 -3
  467. package/examples/jsm/renderers/webgpu/WebGPUTextures.js +2 -2
  468. package/examples/jsm/renderers/webgpu/WebGPUUtils.js +81 -0
  469. package/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js +63 -36
  470. package/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js +1 -1
  471. package/examples/jsm/shaders/LuminosityShader.js +1 -1
  472. package/examples/jsm/shaders/MMDToonShader.js +2 -4
  473. package/examples/jsm/shaders/ToneMapShader.js +1 -1
  474. package/examples/jsm/shaders/VelocityShader.js +128 -0
  475. package/examples/jsm/utils/BufferGeometryUtils.js +176 -43
  476. package/examples/jsm/utils/GeometryUtils.js +17 -25
  477. package/examples/jsm/utils/PackedPhongMaterial.js +0 -1
  478. package/examples/jsm/utils/SceneUtils.js +117 -12
  479. package/examples/jsm/webxr/OculusHandModel.js +3 -2
  480. package/examples/jsm/webxr/OculusHandPointerModel.js +6 -1
  481. package/examples/jsm/webxr/VRButton.js +1 -7
  482. package/examples/jsm/webxr/XRHandMeshModel.js +8 -3
  483. package/package.json +22 -18
  484. package/src/Three.Legacy.js +262 -36
  485. package/src/Three.js +4 -2
  486. package/src/animation/AnimationAction.js +6 -5
  487. package/src/animation/AnimationClip.js +1 -1
  488. package/src/animation/AnimationMixer.js +1 -1
  489. package/src/animation/AnimationUtils.js +204 -199
  490. package/src/animation/KeyframeTrack.js +1 -1
  491. package/src/animation/PropertyBinding.js +31 -5
  492. package/src/audio/AudioContext.js +5 -5
  493. package/src/cameras/CubeCamera.js +14 -21
  494. package/src/constants.js +2 -4
  495. package/src/core/BufferAttribute.js +81 -111
  496. package/src/core/BufferGeometry.js +3 -41
  497. package/src/core/InstancedBufferAttribute.js +0 -10
  498. package/src/core/InstancedBufferGeometry.js +1 -7
  499. package/src/core/InterleavedBuffer.js +1 -1
  500. package/src/core/InterleavedBufferAttribute.js +57 -8
  501. package/src/core/Object3D.js +22 -5
  502. package/src/core/Uniform.js +0 -7
  503. package/src/core/UniformsGroup.js +92 -0
  504. package/src/extras/DataUtils.js +104 -88
  505. package/src/extras/Earcut.js +67 -67
  506. package/src/extras/core/Path.js +1 -0
  507. package/src/extras/core/ShapePath.js +1 -4
  508. package/src/extras/curves/CatmullRomCurve3.js +4 -2
  509. package/src/geometries/BoxGeometry.js +1 -1
  510. package/src/geometries/CapsuleGeometry.js +1 -1
  511. package/src/geometries/CircleGeometry.js +1 -1
  512. package/src/geometries/ConeGeometry.js +1 -1
  513. package/src/geometries/CylinderGeometry.js +2 -1
  514. package/src/geometries/DodecahedronGeometry.js +1 -1
  515. package/src/geometries/EdgesGeometry.js +5 -4
  516. package/src/geometries/ExtrudeGeometry.js +2 -11
  517. package/src/geometries/IcosahedronGeometry.js +1 -1
  518. package/src/geometries/LatheGeometry.js +2 -2
  519. package/src/geometries/OctahedronGeometry.js +1 -1
  520. package/src/geometries/PlaneGeometry.js +2 -1
  521. package/src/geometries/PolyhedronGeometry.js +2 -2
  522. package/src/geometries/RingGeometry.js +1 -1
  523. package/src/geometries/ShapeGeometry.js +3 -2
  524. package/src/geometries/SphereGeometry.js +2 -1
  525. package/src/geometries/TetrahedronGeometry.js +1 -1
  526. package/src/geometries/TorusGeometry.js +2 -1
  527. package/src/geometries/TorusKnotGeometry.js +2 -1
  528. package/src/geometries/TubeGeometry.js +2 -1
  529. package/src/geometries/WireframeGeometry.js +1 -0
  530. package/src/helpers/ArrowHelper.js +9 -0
  531. package/src/helpers/Box3Helper.js +7 -0
  532. package/src/helpers/BoxHelper.js +7 -1
  533. package/src/helpers/CameraHelper.js +97 -38
  534. package/src/helpers/DirectionalLightHelper.js +6 -1
  535. package/src/helpers/GridHelper.js +7 -0
  536. package/src/helpers/HemisphereLightHelper.js +5 -1
  537. package/src/helpers/PlaneHelper.js +15 -9
  538. package/src/helpers/PointLightHelper.js +2 -1
  539. package/src/helpers/PolarGridHelper.js +25 -14
  540. package/src/helpers/SkeletonHelper.js +7 -0
  541. package/src/helpers/SpotLightHelper.js +5 -2
  542. package/src/lights/LightShadow.js +1 -2
  543. package/src/lights/PointLight.js +2 -2
  544. package/src/lights/SpotLight.js +4 -2
  545. package/src/loaders/FileLoader.js +16 -2
  546. package/src/loaders/LoadingManager.js +1 -1
  547. package/src/loaders/MaterialLoader.js +49 -7
  548. package/src/loaders/ObjectLoader.js +9 -42
  549. package/src/materials/Material.js +2 -34
  550. package/src/materials/Materials.js +0 -27
  551. package/src/materials/MeshLambertMaterial.js +28 -1
  552. package/src/materials/MeshPhysicalMaterial.js +1 -1
  553. package/src/materials/ShaderMaterial.js +3 -7
  554. package/src/math/Color.js +8 -18
  555. package/src/math/MathUtils.js +1 -7
  556. package/src/math/Matrix3.js +54 -25
  557. package/src/math/Matrix4.js +3 -27
  558. package/src/math/Quaternion.js +1 -21
  559. package/src/math/Ray.js +2 -5
  560. package/src/math/Sphere.js +36 -21
  561. package/src/math/Vector2.js +4 -24
  562. package/src/math/Vector3.js +7 -46
  563. package/src/math/Vector4.js +4 -24
  564. package/src/objects/InstancedMesh.js +7 -0
  565. package/src/objects/LOD.js +25 -6
  566. package/src/renderers/WebGL3DRenderTarget.js +1 -1
  567. package/src/renderers/WebGLArrayRenderTarget.js +1 -1
  568. package/src/renderers/WebGLCubeRenderTarget.js +1 -1
  569. package/src/renderers/WebGLMultipleRenderTargets.js +1 -1
  570. package/src/renderers/WebGLRenderTarget.js +1 -1
  571. package/src/renderers/WebGLRenderer.js +119 -69
  572. package/src/renderers/shaders/ShaderChunk/bsdfs.glsl.js +12 -12
  573. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -5
  574. package/src/renderers/shaders/ShaderChunk/common.glsl.js +6 -5
  575. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +24 -24
  576. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +0 -4
  577. package/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl.js +1 -1
  578. package/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl.js +1 -1
  579. package/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl.js +2 -1
  580. package/src/renderers/shaders/ShaderChunk/iridescence_fragment.glsl.js +113 -99
  581. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +34 -13
  582. package/src/renderers/shaders/ShaderChunk/lights_lambert_fragment.glsl.js +5 -0
  583. package/src/renderers/shaders/ShaderChunk/lights_lambert_pars_fragment.glsl.js +28 -0
  584. package/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js +0 -2
  585. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +3 -1
  586. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +13 -1
  587. package/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js +0 -2
  588. package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -4
  589. package/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl.js +2 -4
  590. package/src/renderers/shaders/ShaderChunk/output_fragment.glsl.js +1 -1
  591. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +8 -0
  592. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +18 -7
  593. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +8 -3
  594. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +9 -6
  595. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  596. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +14 -10
  597. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +2 -2
  598. package/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js +1 -1
  599. package/src/renderers/shaders/ShaderChunk.js +7 -2
  600. package/src/renderers/shaders/ShaderLib/background.glsl.js +7 -2
  601. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +62 -0
  602. package/src/renderers/shaders/ShaderLib/cube.glsl.js +4 -6
  603. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +0 -1
  604. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +22 -50
  605. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +0 -1
  606. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +0 -3
  607. package/src/renderers/shaders/ShaderLib.js +50 -36
  608. package/src/renderers/shaders/UniformsLib.js +13 -12
  609. package/src/renderers/shaders/UniformsUtils.js +29 -0
  610. package/src/renderers/webgl/WebGLAttributes.js +2 -0
  611. package/src/renderers/webgl/WebGLBackground.js +17 -9
  612. package/src/renderers/webgl/WebGLLights.js +37 -17
  613. package/src/renderers/webgl/WebGLMaterials.js +2 -1
  614. package/src/renderers/webgl/WebGLMorphtargets.js +0 -20
  615. package/src/renderers/webgl/WebGLProgram.js +6 -11
  616. package/src/renderers/webgl/WebGLPrograms.js +30 -26
  617. package/src/renderers/webgl/WebGLRenderLists.js +5 -4
  618. package/src/renderers/webgl/WebGLRenderStates.js +5 -4
  619. package/src/renderers/webgl/WebGLShaderCache.js +9 -6
  620. package/src/renderers/webgl/WebGLShadowMap.js +13 -16
  621. package/src/renderers/webgl/WebGLState.js +125 -41
  622. package/src/renderers/webgl/WebGLTextures.js +94 -39
  623. package/src/renderers/webgl/WebGLUniforms.js +156 -28
  624. package/src/renderers/webgl/WebGLUniformsGroups.js +372 -0
  625. package/src/renderers/webgl/WebGLUtils.js +3 -1
  626. package/src/renderers/webvr/WebVRManager.js +42 -9
  627. package/src/renderers/webvr/WebVRUtils.js +1 -1
  628. package/src/renderers/webxr/WebXRController.js +91 -50
  629. package/src/renderers/webxr/WebXRManager.js +127 -34
  630. package/src/scenes/Scene.js +24 -3
  631. package/src/textures/CompressedArrayTexture.js +18 -0
  632. package/src/textures/Source.js +1 -1
  633. package/src/textures/Texture.js +2 -1
  634. package/src/utils.js +1 -1
  635. package/examples/js/controls/experimental/CameraControls.js +0 -1048
  636. package/examples/js/libs/lottie_canvas.js +0 -12751
  637. package/examples/js/loaders/KTX2Loader.js +0 -558
  638. package/examples/js/shaders/PixelShader.js +0 -51
  639. package/examples/jsm/controls/experimental/CameraControls.js +0 -1248
  640. package/examples/jsm/nodes/accessors/ReflectNode.js +0 -70
  641. package/examples/jsm/nodes/core/NodeVary.js +0 -14
  642. package/examples/jsm/nodes/core/VaryNode.js +0 -54
  643. package/examples/jsm/package.json +0 -3
  644. package/examples/jsm/renderers/webgl/nodes/WebGLPhysicalContextNode.js +0 -45
  645. package/examples/jsm/shaders/PixelShader.js +0 -44
  646. package/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl.js +0 -122
@@ -4,14 +4,15 @@
4
4
 
5
5
  constructor( manager ) {
6
6
 
7
- super( manager ); // Default dots per inch
7
+ super( manager );
8
8
 
9
- this.defaultDPI = 90; // Accepted units: 'mm', 'cm', 'in', 'pt', 'pc', 'px'
9
+ // Default dots per inch
10
+ this.defaultDPI = 90;
10
11
 
12
+ // Accepted units: 'mm', 'cm', 'in', 'pt', 'pc', 'px'
11
13
  this.defaultUnit = 'px';
12
14
 
13
15
  }
14
-
15
16
  load( url, onLoad, onProgress, onError ) {
16
17
 
17
18
  const scope = this;
@@ -44,76 +45,62 @@
44
45
  }, onProgress, onError );
45
46
 
46
47
  }
47
-
48
48
  parse( text ) {
49
49
 
50
50
  const scope = this;
51
-
52
51
  function parseNode( node, style ) {
53
52
 
54
53
  if ( node.nodeType !== 1 ) return;
55
54
  const transform = getNodeTransform( node );
56
55
  let isDefsNode = false;
57
56
  let path = null;
58
-
59
57
  switch ( node.nodeName ) {
60
58
 
61
59
  case 'svg':
60
+ style = parseStyle( node, style );
62
61
  break;
63
-
64
62
  case 'style':
65
63
  parseCSSStylesheet( node );
66
64
  break;
67
-
68
65
  case 'g':
69
66
  style = parseStyle( node, style );
70
67
  break;
71
-
72
68
  case 'path':
73
69
  style = parseStyle( node, style );
74
70
  if ( node.hasAttribute( 'd' ) ) path = parsePathNode( node );
75
71
  break;
76
-
77
72
  case 'rect':
78
73
  style = parseStyle( node, style );
79
74
  path = parseRectNode( node );
80
75
  break;
81
-
82
76
  case 'polygon':
83
77
  style = parseStyle( node, style );
84
78
  path = parsePolygonNode( node );
85
79
  break;
86
-
87
80
  case 'polyline':
88
81
  style = parseStyle( node, style );
89
82
  path = parsePolylineNode( node );
90
83
  break;
91
-
92
84
  case 'circle':
93
85
  style = parseStyle( node, style );
94
86
  path = parseCircleNode( node );
95
87
  break;
96
-
97
88
  case 'ellipse':
98
89
  style = parseStyle( node, style );
99
90
  path = parseEllipseNode( node );
100
91
  break;
101
-
102
92
  case 'line':
103
93
  style = parseStyle( node, style );
104
94
  path = parseLineNode( node );
105
95
  break;
106
-
107
96
  case 'defs':
108
97
  isDefsNode = true;
109
98
  break;
110
-
111
99
  case 'use':
112
100
  style = parseStyle( node, style );
113
101
  const href = node.getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ) || '';
114
102
  const usedNodeId = href.substring( 1 );
115
103
  const usedNode = node.viewportElement.getElementById( usedNodeId );
116
-
117
104
  if ( usedNode ) {
118
105
 
119
106
  parseNode( usedNode, style );
@@ -125,8 +112,8 @@
125
112
  }
126
113
 
127
114
  break;
128
-
129
- default: // console.log( node );
115
+ default:
116
+ // console.log( node );
130
117
 
131
118
  }
132
119
 
@@ -148,11 +135,9 @@
148
135
  }
149
136
 
150
137
  const childNodes = node.childNodes;
151
-
152
138
  for ( let i = 0; i < childNodes.length; i ++ ) {
153
139
 
154
140
  const node = childNodes[ i ];
155
-
156
141
  if ( isDefsNode && node.nodeName !== 'style' && node.nodeName !== 'defs' ) {
157
142
 
158
143
  // Ignore everything in defs except CSS style definitions
@@ -169,7 +154,6 @@
169
154
  if ( transform ) {
170
155
 
171
156
  transformStack.pop();
172
-
173
157
  if ( transformStack.length > 0 ) {
174
158
 
175
159
  currentTransform.copy( transformStack[ transformStack.length - 1 ] );
@@ -192,16 +176,16 @@
192
176
  const firstPoint = new THREE.Vector2();
193
177
  let isFirstPoint = true;
194
178
  let doSetFirstPoint = false;
195
- const d = node.getAttribute( 'd' ); // console.log( d );
179
+ const d = node.getAttribute( 'd' );
196
180
 
197
- const commands = d.match( /[a-df-z][^a-df-z]*/ig );
181
+ // console.log( d );
198
182
 
183
+ const commands = d.match( /[a-df-z][^a-df-z]*/ig );
199
184
  for ( let i = 0, l = commands.length; i < l; i ++ ) {
200
185
 
201
186
  const command = commands[ i ];
202
187
  const type = command.charAt( 0 );
203
188
  const data = command.slice( 1 ).trim();
204
-
205
189
  if ( isFirstPoint === true ) {
206
190
 
207
191
  doSetFirstPoint = true;
@@ -210,19 +194,16 @@
210
194
  }
211
195
 
212
196
  let numbers;
213
-
214
197
  switch ( type ) {
215
198
 
216
199
  case 'M':
217
200
  numbers = parseFloats( data );
218
-
219
201
  for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {
220
202
 
221
203
  point.x = numbers[ j + 0 ];
222
204
  point.y = numbers[ j + 1 ];
223
205
  control.x = point.x;
224
206
  control.y = point.y;
225
-
226
207
  if ( j === 0 ) {
227
208
 
228
209
  path.moveTo( point.x, point.y );
@@ -238,10 +219,8 @@
238
219
  }
239
220
 
240
221
  break;
241
-
242
222
  case 'H':
243
223
  numbers = parseFloats( data );
244
-
245
224
  for ( let j = 0, jl = numbers.length; j < jl; j ++ ) {
246
225
 
247
226
  point.x = numbers[ j ];
@@ -253,10 +232,8 @@
253
232
  }
254
233
 
255
234
  break;
256
-
257
235
  case 'V':
258
236
  numbers = parseFloats( data );
259
-
260
237
  for ( let j = 0, jl = numbers.length; j < jl; j ++ ) {
261
238
 
262
239
  point.y = numbers[ j ];
@@ -268,10 +245,8 @@
268
245
  }
269
246
 
270
247
  break;
271
-
272
248
  case 'L':
273
249
  numbers = parseFloats( data );
274
-
275
250
  for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {
276
251
 
277
252
  point.x = numbers[ j + 0 ];
@@ -284,10 +259,8 @@
284
259
  }
285
260
 
286
261
  break;
287
-
288
262
  case 'C':
289
263
  numbers = parseFloats( data );
290
-
291
264
  for ( let j = 0, jl = numbers.length; j < jl; j += 6 ) {
292
265
 
293
266
  path.bezierCurveTo( numbers[ j + 0 ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], numbers[ j + 5 ] );
@@ -300,10 +273,8 @@
300
273
  }
301
274
 
302
275
  break;
303
-
304
276
  case 'S':
305
277
  numbers = parseFloats( data );
306
-
307
278
  for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {
308
279
 
309
280
  path.bezierCurveTo( getReflection( point.x, control.x ), getReflection( point.y, control.y ), numbers[ j + 0 ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ] );
@@ -316,10 +287,8 @@
316
287
  }
317
288
 
318
289
  break;
319
-
320
290
  case 'Q':
321
291
  numbers = parseFloats( data );
322
-
323
292
  for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {
324
293
 
325
294
  path.quadraticCurveTo( numbers[ j + 0 ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ] );
@@ -332,10 +301,8 @@
332
301
  }
333
302
 
334
303
  break;
335
-
336
304
  case 'T':
337
305
  numbers = parseFloats( data );
338
-
339
306
  for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {
340
307
 
341
308
  const rx = getReflection( point.x, control.x );
@@ -350,10 +317,8 @@
350
317
  }
351
318
 
352
319
  break;
353
-
354
320
  case 'A':
355
321
  numbers = parseFloats( data, [ 3, 4 ], 7 );
356
-
357
322
  for ( let j = 0, jl = numbers.length; j < jl; j += 7 ) {
358
323
 
359
324
  // skip command if start point == end point
@@ -369,17 +334,14 @@
369
334
  }
370
335
 
371
336
  break;
372
-
373
337
  case 'm':
374
338
  numbers = parseFloats( data );
375
-
376
339
  for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {
377
340
 
378
341
  point.x += numbers[ j + 0 ];
379
342
  point.y += numbers[ j + 1 ];
380
343
  control.x = point.x;
381
344
  control.y = point.y;
382
-
383
345
  if ( j === 0 ) {
384
346
 
385
347
  path.moveTo( point.x, point.y );
@@ -395,10 +357,8 @@
395
357
  }
396
358
 
397
359
  break;
398
-
399
360
  case 'h':
400
361
  numbers = parseFloats( data );
401
-
402
362
  for ( let j = 0, jl = numbers.length; j < jl; j ++ ) {
403
363
 
404
364
  point.x += numbers[ j ];
@@ -410,10 +370,8 @@
410
370
  }
411
371
 
412
372
  break;
413
-
414
373
  case 'v':
415
374
  numbers = parseFloats( data );
416
-
417
375
  for ( let j = 0, jl = numbers.length; j < jl; j ++ ) {
418
376
 
419
377
  point.y += numbers[ j ];
@@ -425,10 +383,8 @@
425
383
  }
426
384
 
427
385
  break;
428
-
429
386
  case 'l':
430
387
  numbers = parseFloats( data );
431
-
432
388
  for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {
433
389
 
434
390
  point.x += numbers[ j + 0 ];
@@ -441,10 +397,8 @@
441
397
  }
442
398
 
443
399
  break;
444
-
445
400
  case 'c':
446
401
  numbers = parseFloats( data );
447
-
448
402
  for ( let j = 0, jl = numbers.length; j < jl; j += 6 ) {
449
403
 
450
404
  path.bezierCurveTo( point.x + numbers[ j + 0 ], point.y + numbers[ j + 1 ], point.x + numbers[ j + 2 ], point.y + numbers[ j + 3 ], point.x + numbers[ j + 4 ], point.y + numbers[ j + 5 ] );
@@ -457,10 +411,8 @@
457
411
  }
458
412
 
459
413
  break;
460
-
461
414
  case 's':
462
415
  numbers = parseFloats( data );
463
-
464
416
  for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {
465
417
 
466
418
  path.bezierCurveTo( getReflection( point.x, control.x ), getReflection( point.y, control.y ), point.x + numbers[ j + 0 ], point.y + numbers[ j + 1 ], point.x + numbers[ j + 2 ], point.y + numbers[ j + 3 ] );
@@ -473,10 +425,8 @@
473
425
  }
474
426
 
475
427
  break;
476
-
477
428
  case 'q':
478
429
  numbers = parseFloats( data );
479
-
480
430
  for ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {
481
431
 
482
432
  path.quadraticCurveTo( point.x + numbers[ j + 0 ], point.y + numbers[ j + 1 ], point.x + numbers[ j + 2 ], point.y + numbers[ j + 3 ] );
@@ -489,10 +439,8 @@
489
439
  }
490
440
 
491
441
  break;
492
-
493
442
  case 't':
494
443
  numbers = parseFloats( data );
495
-
496
444
  for ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {
497
445
 
498
446
  const rx = getReflection( point.x, control.x );
@@ -507,10 +455,8 @@
507
455
  }
508
456
 
509
457
  break;
510
-
511
458
  case 'a':
512
459
  numbers = parseFloats( data, [ 3, 4 ], 7 );
513
-
514
460
  for ( let j = 0, jl = numbers.length; j < jl; j += 7 ) {
515
461
 
516
462
  // skip command if no displacement
@@ -526,11 +472,9 @@
526
472
  }
527
473
 
528
474
  break;
529
-
530
475
  case 'Z':
531
476
  case 'z':
532
477
  path.currentPath.autoClose = true;
533
-
534
478
  if ( path.currentPath.curves.length > 0 ) {
535
479
 
536
480
  // Reset point to beginning of THREE.Path
@@ -541,12 +485,12 @@
541
485
  }
542
486
 
543
487
  break;
544
-
545
488
  default:
546
489
  console.warn( command );
547
490
 
548
- } // console.log( type, parseFloats( data ), parseFloats( data ).length )
491
+ }
549
492
 
493
+ // console.log( type, parseFloats( data ), parseFloats( data ).length )
550
494
 
551
495
  doSetFirstPoint = false;
552
496
 
@@ -559,13 +503,11 @@
559
503
  function parseCSSStylesheet( node ) {
560
504
 
561
505
  if ( ! node.sheet || ! node.sheet.cssRules || ! node.sheet.cssRules.length ) return;
562
-
563
506
  for ( let i = 0; i < node.sheet.cssRules.length; i ++ ) {
564
507
 
565
508
  const stylesheet = node.sheet.cssRules[ i ];
566
509
  if ( stylesheet.type !== 1 ) continue;
567
510
  const selectorList = stylesheet.selectorText.split( /,/gm ).filter( Boolean ).map( i => i.trim() );
568
-
569
511
  for ( let j = 0; j < selectorList.length; j ++ ) {
570
512
 
571
513
  // Remove empty rules
@@ -577,6 +519,7 @@
577
519
  }
578
520
 
579
521
  }
522
+
580
523
  /**
581
524
  * https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
582
525
  * https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/ Appendix: Endpoint to center arc conversion
@@ -586,7 +529,6 @@
586
529
  * aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation
587
530
  */
588
531
 
589
-
590
532
  function parseArcCommand( path, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, start, end ) {
591
533
 
592
534
  if ( rx == 0 || ry == 0 ) {
@@ -597,23 +539,26 @@
597
539
 
598
540
  }
599
541
 
600
- x_axis_rotation = x_axis_rotation * Math.PI / 180; // Ensure radii are positive
542
+ x_axis_rotation = x_axis_rotation * Math.PI / 180;
601
543
 
544
+ // Ensure radii are positive
602
545
  rx = Math.abs( rx );
603
- ry = Math.abs( ry ); // Compute (x1', y1')
546
+ ry = Math.abs( ry );
604
547
 
548
+ // Compute (x1', y1')
605
549
  const dx2 = ( start.x - end.x ) / 2.0;
606
550
  const dy2 = ( start.y - end.y ) / 2.0;
607
551
  const x1p = Math.cos( x_axis_rotation ) * dx2 + Math.sin( x_axis_rotation ) * dy2;
608
- const y1p = - Math.sin( x_axis_rotation ) * dx2 + Math.cos( x_axis_rotation ) * dy2; // Compute (cx', cy')
552
+ const y1p = - Math.sin( x_axis_rotation ) * dx2 + Math.cos( x_axis_rotation ) * dy2;
609
553
 
554
+ // Compute (cx', cy')
610
555
  let rxs = rx * rx;
611
556
  let rys = ry * ry;
612
557
  const x1ps = x1p * x1p;
613
- const y1ps = y1p * y1p; // Ensure radii are large enough
558
+ const y1ps = y1p * y1p;
614
559
 
560
+ // Ensure radii are large enough
615
561
  const cr = x1ps / rxs + y1ps / rys;
616
-
617
562
  if ( cr > 1 ) {
618
563
 
619
564
  // scale up rx,ry equally so cr == 1
@@ -630,11 +575,13 @@
630
575
  let q = Math.sqrt( Math.max( 0, pq ) );
631
576
  if ( large_arc_flag === sweep_flag ) q = - q;
632
577
  const cxp = q * rx * y1p / ry;
633
- const cyp = - q * ry * x1p / rx; // Step 3: Compute (cx, cy) from (cx', cy')
578
+ const cyp = - q * ry * x1p / rx;
634
579
 
580
+ // Step 3: Compute (cx, cy) from (cx', cy')
635
581
  const cx = Math.cos( x_axis_rotation ) * cxp - Math.sin( x_axis_rotation ) * cyp + ( start.x + end.x ) / 2;
636
- const cy = Math.sin( x_axis_rotation ) * cxp + Math.cos( x_axis_rotation ) * cyp + ( start.y + end.y ) / 2; // Step 4: Compute θ1 and Δθ
582
+ const cy = Math.sin( x_axis_rotation ) * cxp + Math.cos( x_axis_rotation ) * cyp + ( start.y + end.y ) / 2;
637
583
 
584
+ // Step 4: Compute θ1 and Δθ
638
585
  const theta = svgAngle( 1, 0, ( x1p - cxp ) / rx, ( y1p - cyp ) / ry );
639
586
  const delta = svgAngle( ( x1p - cxp ) / rx, ( y1p - cyp ) / ry, ( - x1p - cxp ) / rx, ( - y1p - cyp ) / ry ) % ( Math.PI * 2 );
640
587
  path.currentPath.absellipse( cx, cy, rx, ry, theta, theta + delta, sweep_flag === 0, x_axis_rotation );
@@ -646,17 +593,15 @@
646
593
  const dot = ux * vx + uy * vy;
647
594
  const len = Math.sqrt( ux * ux + uy * uy ) * Math.sqrt( vx * vx + vy * vy );
648
595
  let ang = Math.acos( Math.max( - 1, Math.min( 1, dot / len ) ) ); // floating point precision, slightly over values appear
649
-
650
596
  if ( ux * vy - uy * vx < 0 ) ang = - ang;
651
597
  return ang;
652
598
 
653
599
  }
600
+
654
601
  /*
655
602
  * According to https://www.w3.org/TR/SVG/shapes.html#RectElementRXAttribute
656
603
  * rounded corner should be rendered to elliptical arc, but bezier curve does the job well enough
657
604
  */
658
-
659
-
660
605
  function parseRectNode( node ) {
661
606
 
662
607
  const x = parseFloatWithUnits( node.getAttribute( 'x' ) || 0 );
@@ -664,43 +609,42 @@
664
609
  const rx = parseFloatWithUnits( node.getAttribute( 'rx' ) || node.getAttribute( 'ry' ) || 0 );
665
610
  const ry = parseFloatWithUnits( node.getAttribute( 'ry' ) || node.getAttribute( 'rx' ) || 0 );
666
611
  const w = parseFloatWithUnits( node.getAttribute( 'width' ) );
667
- const h = parseFloatWithUnits( node.getAttribute( 'height' ) ); // Ellipse arc to Bezier approximation Coefficient (Inversed). See:
668
- // https://spencermortensen.com/articles/bezier-circle/
612
+ const h = parseFloatWithUnits( node.getAttribute( 'height' ) );
669
613
 
614
+ // Ellipse arc to Bezier approximation Coefficient (Inversed). See:
615
+ // https://spencermortensen.com/articles/bezier-circle/
670
616
  const bci = 1 - 0.551915024494;
671
- const path = new THREE.ShapePath(); // top left
617
+ const path = new THREE.ShapePath();
672
618
 
673
- path.moveTo( x + rx, y ); // top right
619
+ // top left
620
+ path.moveTo( x + rx, y );
674
621
 
622
+ // top right
675
623
  path.lineTo( x + w - rx, y );
676
-
677
624
  if ( rx !== 0 || ry !== 0 ) {
678
625
 
679
626
  path.bezierCurveTo( x + w - rx * bci, y, x + w, y + ry * bci, x + w, y + ry );
680
627
 
681
- } // bottom right
682
-
628
+ }
683
629
 
630
+ // bottom right
684
631
  path.lineTo( x + w, y + h - ry );
685
-
686
632
  if ( rx !== 0 || ry !== 0 ) {
687
633
 
688
634
  path.bezierCurveTo( x + w, y + h - ry * bci, x + w - rx * bci, y + h, x + w - rx, y + h );
689
635
 
690
- } // bottom left
691
-
636
+ }
692
637
 
638
+ // bottom left
693
639
  path.lineTo( x + rx, y + h );
694
-
695
640
  if ( rx !== 0 || ry !== 0 ) {
696
641
 
697
642
  path.bezierCurveTo( x + rx * bci, y + h, x, y + h - ry * bci, x, y + h - ry );
698
643
 
699
- } // back to top left
700
-
644
+ }
701
645
 
646
+ // back to top left
702
647
  path.lineTo( x, y + ry );
703
-
704
648
  if ( rx !== 0 || ry !== 0 ) {
705
649
 
706
650
  path.bezierCurveTo( x, y + ry * bci, x + rx * bci, y, x + rx, y );
@@ -717,7 +661,6 @@
717
661
 
718
662
  const x = parseFloatWithUnits( a );
719
663
  const y = parseFloatWithUnits( b );
720
-
721
664
  if ( index === 0 ) {
722
665
 
723
666
  path.moveTo( x, y );
@@ -747,7 +690,6 @@
747
690
 
748
691
  const x = parseFloatWithUnits( a );
749
692
  const y = parseFloatWithUnits( b );
750
-
751
693
  if ( index === 0 ) {
752
694
 
753
695
  path.moveTo( x, y );
@@ -810,19 +752,18 @@
810
752
  path.currentPath.autoClose = false;
811
753
  return path;
812
754
 
813
- } //
755
+ }
814
756
 
757
+ //
815
758
 
816
759
  function parseStyle( node, style ) {
817
760
 
818
761
  style = Object.assign( {}, style ); // clone style
819
762
 
820
763
  let stylesheetStyles = {};
821
-
822
764
  if ( node.hasAttribute( 'class' ) ) {
823
765
 
824
766
  const classSelectors = node.getAttribute( 'class' ).split( /\s/ ).filter( Boolean ).map( i => i.trim() );
825
-
826
767
  for ( let i = 0; i < classSelectors.length; i ++ ) {
827
768
 
828
769
  stylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '.' + classSelectors[ i ] ] );
@@ -877,15 +818,17 @@
877
818
  addStyle( 'visibility', 'visibility' );
878
819
  return style;
879
820
 
880
- } // http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes
821
+ }
881
822
 
823
+ // http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes
882
824
 
883
825
  function getReflection( a, b ) {
884
826
 
885
827
  return a - ( b - a );
886
828
 
887
- } // from https://github.com/ppvg/svg-numbers (MIT License)
829
+ }
888
830
 
831
+ // from https://github.com/ppvg/svg-numbers (MIT License)
889
832
 
890
833
  function parseFloats( input, flags, stride ) {
891
834
 
@@ -893,9 +836,9 @@
893
836
 
894
837
  throw new TypeError( 'Invalid input: ' + typeof input );
895
838
 
896
- } // Character groups
897
-
839
+ }
898
840
 
841
+ // Character groups
899
842
  const RE = {
900
843
  SEPARATOR: /[ \t\r\n\,.\-+]/,
901
844
  WHITESPACE: /[ \t\r\n]/,
@@ -905,8 +848,9 @@
905
848
  COMMA: /,/,
906
849
  EXP: /e/i,
907
850
  FLAGS: /[01]/
908
- }; // States
851
+ };
909
852
 
853
+ // States
910
854
  const SEP = 0;
911
855
  const INT = 1;
912
856
  const FLOAT = 2;
@@ -916,7 +860,6 @@
916
860
  let number = '',
917
861
  exponent = '';
918
862
  const result = [];
919
-
920
863
  function throwSyntaxError( current, i, partial ) {
921
864
 
922
865
  const error = new SyntaxError( 'Unexpected character "' + current + '" at index ' + i + '.' );
@@ -940,11 +883,11 @@
940
883
 
941
884
  let current;
942
885
  const length = input.length;
943
-
944
886
  for ( let i = 0; i < length; i ++ ) {
945
887
 
946
- current = input[ i ]; // check for flags
888
+ current = input[ i ];
947
889
 
890
+ // check for flags
948
891
  if ( Array.isArray( flags ) && flags.includes( result.length % stride ) && RE.FLAGS.test( current ) ) {
949
892
 
950
893
  state = INT;
@@ -952,9 +895,9 @@
952
895
  newNumber();
953
896
  continue;
954
897
 
955
- } // parse until next number
956
-
898
+ }
957
899
 
900
+ // parse until next number
958
901
  if ( state === SEP ) {
959
902
 
960
903
  // eat whitespace
@@ -962,9 +905,9 @@
962
905
 
963
906
  continue;
964
907
 
965
- } // start new number
966
-
908
+ }
967
909
 
910
+ // start new number
968
911
  if ( RE.DIGIT.test( current ) || RE.SIGN.test( current ) ) {
969
912
 
970
913
  state = INT;
@@ -979,9 +922,9 @@
979
922
  number = current;
980
923
  continue;
981
924
 
982
- } // throw on double commas (e.g. "1, , 2")
983
-
925
+ }
984
926
 
927
+ // throw on double commas (e.g. "1, , 2")
985
928
  if ( RE.COMMA.test( current ) ) {
986
929
 
987
930
  if ( seenComma ) {
@@ -994,9 +937,9 @@
994
937
 
995
938
  }
996
939
 
997
- } // parse integer part
998
-
940
+ }
999
941
 
942
+ // parse integer part
1000
943
  if ( state === INT ) {
1001
944
 
1002
945
  if ( RE.DIGIT.test( current ) ) {
@@ -1019,18 +962,18 @@
1019
962
  state = EXP;
1020
963
  continue;
1021
964
 
1022
- } // throw on double signs ("-+1"), but not on sign as separator ("-1-2")
1023
-
965
+ }
1024
966
 
967
+ // throw on double signs ("-+1"), but not on sign as separator ("-1-2")
1025
968
  if ( RE.SIGN.test( current ) && number.length === 1 && RE.SIGN.test( number[ 0 ] ) ) {
1026
969
 
1027
970
  throwSyntaxError( current, i, result );
1028
971
 
1029
972
  }
1030
973
 
1031
- } // parse decimal part
1032
-
974
+ }
1033
975
 
976
+ // parse decimal part
1034
977
  if ( state === FLOAT ) {
1035
978
 
1036
979
  if ( RE.DIGIT.test( current ) ) {
@@ -1045,18 +988,18 @@
1045
988
  state = EXP;
1046
989
  continue;
1047
990
 
1048
- } // throw on double decimal points (e.g. "1..2")
1049
-
991
+ }
1050
992
 
993
+ // throw on double decimal points (e.g. "1..2")
1051
994
  if ( RE.POINT.test( current ) && number[ number.length - 1 ] === '.' ) {
1052
995
 
1053
996
  throwSyntaxError( current, i, result );
1054
997
 
1055
998
  }
1056
999
 
1057
- } // parse exponent part
1058
-
1000
+ }
1059
1001
 
1002
+ // parse exponent part
1060
1003
  if ( state === EXP ) {
1061
1004
 
1062
1005
  if ( RE.DIGIT.test( current ) ) {
@@ -1083,9 +1026,9 @@
1083
1026
 
1084
1027
  }
1085
1028
 
1086
- } // end of number
1087
-
1029
+ }
1088
1030
 
1031
+ // end of number
1089
1032
  if ( RE.WHITESPACE.test( current ) ) {
1090
1033
 
1091
1034
  newNumber();
@@ -1116,17 +1059,19 @@
1116
1059
 
1117
1060
  }
1118
1061
 
1119
- } // add the last number found (if any)
1120
-
1062
+ }
1121
1063
 
1064
+ // add the last number found (if any)
1122
1065
  newNumber();
1123
1066
  return result;
1124
1067
 
1125
- } // Units
1068
+ }
1126
1069
 
1070
+ // Units
1127
1071
 
1128
- const units = [ 'mm', 'cm', 'in', 'pt', 'pc', 'px' ]; // Conversion: [ fromUnit ][ toUnit ] (-1 means dpi dependent)
1072
+ const units = [ 'mm', 'cm', 'in', 'pt', 'pc', 'px' ];
1129
1073
 
1074
+ // Conversion: [ fromUnit ][ toUnit ] (-1 means dpi dependent)
1130
1075
  const unitConversion = {
1131
1076
  'mm': {
1132
1077
  'mm': 1,
@@ -1172,17 +1117,14 @@
1172
1117
  'px': 1
1173
1118
  }
1174
1119
  };
1175
-
1176
1120
  function parseFloatWithUnits( string ) {
1177
1121
 
1178
1122
  let theUnit = 'px';
1179
-
1180
1123
  if ( typeof string === 'string' || string instanceof String ) {
1181
1124
 
1182
1125
  for ( let i = 0, n = units.length; i < n; i ++ ) {
1183
1126
 
1184
1127
  const u = units[ i ];
1185
-
1186
1128
  if ( string.endsWith( u ) ) {
1187
1129
 
1188
1130
  theUnit = u;
@@ -1196,19 +1138,19 @@
1196
1138
  }
1197
1139
 
1198
1140
  let scale = undefined;
1199
-
1200
1141
  if ( theUnit === 'px' && scope.defaultUnit !== 'px' ) {
1201
1142
 
1202
1143
  // Conversion scale from pixels to inches, then to default units
1144
+
1203
1145
  scale = unitConversion[ 'in' ][ scope.defaultUnit ] / scope.defaultDPI;
1204
1146
 
1205
1147
  } else {
1206
1148
 
1207
1149
  scale = unitConversion[ theUnit ][ scope.defaultUnit ];
1208
-
1209
1150
  if ( scale < 0 ) {
1210
1151
 
1211
1152
  // Conversion scale to pixels
1153
+
1212
1154
  scale = unitConversion[ theUnit ][ 'in' ] * scope.defaultDPI;
1213
1155
 
1214
1156
  }
@@ -1217,8 +1159,9 @@
1217
1159
 
1218
1160
  return scale * parseFloat( string );
1219
1161
 
1220
- } // Transforms
1162
+ }
1221
1163
 
1164
+ // Transforms
1222
1165
 
1223
1166
  function getNodeTransform( node ) {
1224
1167
 
@@ -1229,7 +1172,6 @@
1229
1172
  }
1230
1173
 
1231
1174
  const transform = parseNodeTransform( node );
1232
-
1233
1175
  if ( transformStack.length > 0 ) {
1234
1176
 
1235
1177
  transform.premultiply( transformStack[ transformStack.length - 1 ] );
@@ -1246,7 +1188,6 @@
1246
1188
 
1247
1189
  const transform = new THREE.Matrix3();
1248
1190
  const currentTransform = tempTransform0;
1249
-
1250
1191
  if ( node.nodeName === 'use' && ( node.hasAttribute( 'x' ) || node.hasAttribute( 'y' ) ) ) {
1251
1192
 
1252
1193
  const tx = parseFloatWithUnits( node.getAttribute( 'x' ) );
@@ -1258,28 +1199,24 @@
1258
1199
  if ( node.hasAttribute( 'transform' ) ) {
1259
1200
 
1260
1201
  const transformsTexts = node.getAttribute( 'transform' ).split( ')' );
1261
-
1262
1202
  for ( let tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex -- ) {
1263
1203
 
1264
1204
  const transformText = transformsTexts[ tIndex ].trim();
1265
1205
  if ( transformText === '' ) continue;
1266
1206
  const openParPos = transformText.indexOf( '(' );
1267
1207
  const closeParPos = transformText.length;
1268
-
1269
1208
  if ( openParPos > 0 && openParPos < closeParPos ) {
1270
1209
 
1271
1210
  const transformType = transformText.slice( 0, openParPos );
1272
1211
  const array = parseFloats( transformText.slice( openParPos + 1 ) );
1273
1212
  currentTransform.identity();
1274
-
1275
1213
  switch ( transformType ) {
1276
1214
 
1277
1215
  case 'translate':
1278
1216
  if ( array.length >= 1 ) {
1279
1217
 
1280
1218
  const tx = array[ 0 ];
1281
- let ty = tx;
1282
-
1219
+ let ty = 0;
1283
1220
  if ( array.length >= 2 ) {
1284
1221
 
1285
1222
  ty = array[ 1 ];
@@ -1291,41 +1228,38 @@
1291
1228
  }
1292
1229
 
1293
1230
  break;
1294
-
1295
1231
  case 'rotate':
1296
1232
  if ( array.length >= 1 ) {
1297
1233
 
1298
1234
  let angle = 0;
1299
1235
  let cx = 0;
1300
- let cy = 0; // Angle
1301
-
1302
- angle = - array[ 0 ] * Math.PI / 180;
1236
+ let cy = 0;
1303
1237
 
1238
+ // Angle
1239
+ angle = array[ 0 ] * Math.PI / 180;
1304
1240
  if ( array.length >= 3 ) {
1305
1241
 
1306
1242
  // Center x, y
1307
1243
  cx = array[ 1 ];
1308
1244
  cy = array[ 2 ];
1309
1245
 
1310
- } // Rotate around center (cx, cy)
1311
-
1246
+ }
1312
1247
 
1313
- tempTransform1.identity().translate( - cx, - cy );
1314
- tempTransform2.identity().rotate( angle );
1248
+ // Rotate around center (cx, cy)
1249
+ tempTransform1.makeTranslation( - cx, - cy );
1250
+ tempTransform2.makeRotation( angle );
1315
1251
  tempTransform3.multiplyMatrices( tempTransform2, tempTransform1 );
1316
- tempTransform1.identity().translate( cx, cy );
1252
+ tempTransform1.makeTranslation( cx, cy );
1317
1253
  currentTransform.multiplyMatrices( tempTransform1, tempTransform3 );
1318
1254
 
1319
1255
  }
1320
1256
 
1321
1257
  break;
1322
-
1323
1258
  case 'scale':
1324
1259
  if ( array.length >= 1 ) {
1325
1260
 
1326
1261
  const scaleX = array[ 0 ];
1327
1262
  let scaleY = scaleX;
1328
-
1329
1263
  if ( array.length >= 2 ) {
1330
1264
 
1331
1265
  scaleY = array[ 1 ];
@@ -1337,7 +1271,6 @@
1337
1271
  }
1338
1272
 
1339
1273
  break;
1340
-
1341
1274
  case 'skewX':
1342
1275
  if ( array.length === 1 ) {
1343
1276
 
@@ -1346,7 +1279,6 @@
1346
1279
  }
1347
1280
 
1348
1281
  break;
1349
-
1350
1282
  case 'skewY':
1351
1283
  if ( array.length === 1 ) {
1352
1284
 
@@ -1355,7 +1287,6 @@
1355
1287
  }
1356
1288
 
1357
1289
  break;
1358
-
1359
1290
  case 'matrix':
1360
1291
  if ( array.length === 6 ) {
1361
1292
 
@@ -1388,18 +1319,99 @@
1388
1319
 
1389
1320
  }
1390
1321
 
1391
- const isRotated = isTransformRotated( m );
1392
- const subPaths = path.subPaths;
1322
+ function transfEllipseGeneric( curve ) {
1323
+
1324
+ // For math description see:
1325
+ // https://math.stackexchange.com/questions/4544164
1326
+
1327
+ const a = curve.xRadius;
1328
+ const b = curve.yRadius;
1329
+ const cosTheta = Math.cos( curve.aRotation );
1330
+ const sinTheta = Math.sin( curve.aRotation );
1331
+ const v1 = new THREE.Vector3( a * cosTheta, a * sinTheta, 0 );
1332
+ const v2 = new THREE.Vector3( - b * sinTheta, b * cosTheta, 0 );
1333
+ const f1 = v1.applyMatrix3( m );
1334
+ const f2 = v2.applyMatrix3( m );
1335
+ const mF = tempTransform0.set( f1.x, f2.x, 0, f1.y, f2.y, 0, 0, 0, 1 );
1336
+ const mFInv = tempTransform1.copy( mF ).invert();
1337
+ const mFInvT = tempTransform2.copy( mFInv ).transpose();
1338
+ const mQ = mFInvT.multiply( mFInv );
1339
+ const mQe = mQ.elements;
1340
+ const ed = eigenDecomposition( mQe[ 0 ], mQe[ 1 ], mQe[ 4 ] );
1341
+ const rt1sqrt = Math.sqrt( ed.rt1 );
1342
+ const rt2sqrt = Math.sqrt( ed.rt2 );
1343
+ curve.xRadius = 1 / rt1sqrt;
1344
+ curve.yRadius = 1 / rt2sqrt;
1345
+ curve.aRotation = Math.atan2( ed.sn, ed.cs );
1346
+ const isFullEllipse = ( curve.aEndAngle - curve.aStartAngle ) % ( 2 * Math.PI ) < Number.EPSILON;
1347
+
1348
+ // Do not touch angles of a full ellipse because after transformation they
1349
+ // would converge to a sinle value effectively removing the whole curve
1350
+
1351
+ if ( ! isFullEllipse ) {
1352
+
1353
+ const mDsqrt = tempTransform1.set( rt1sqrt, 0, 0, 0, rt2sqrt, 0, 0, 0, 1 );
1354
+ const mRT = tempTransform2.set( ed.cs, ed.sn, 0, - ed.sn, ed.cs, 0, 0, 0, 1 );
1355
+ const mDRF = mDsqrt.multiply( mRT ).multiply( mF );
1356
+ const transformAngle = phi => {
1357
+
1358
+ const {
1359
+ x: cosR,
1360
+ y: sinR
1361
+ } = new THREE.Vector3( Math.cos( phi ), Math.sin( phi ), 0 ).applyMatrix3( mDRF );
1362
+ return Math.atan2( sinR, cosR );
1363
+
1364
+ };
1365
+
1366
+ curve.aStartAngle = transformAngle( curve.aStartAngle );
1367
+ curve.aEndAngle = transformAngle( curve.aEndAngle );
1368
+ if ( isTransformFlipped( m ) ) {
1369
+
1370
+ curve.aClockwise = ! curve.aClockwise;
1371
+
1372
+ }
1373
+
1374
+ }
1375
+
1376
+ }
1377
+
1378
+ function transfEllipseNoSkew( curve ) {
1393
1379
 
1380
+ // Faster shortcut if no skew is applied
1381
+ // (e.g, a euclidean transform of a group containing the ellipse)
1382
+
1383
+ const sx = getTransformScaleX( m );
1384
+ const sy = getTransformScaleY( m );
1385
+ curve.xRadius *= sx;
1386
+ curve.yRadius *= sy;
1387
+
1388
+ // Extract rotation angle from the matrix of form:
1389
+ //
1390
+ // | cosθ sx -sinθ sy |
1391
+ // | sinθ sx cosθ sy |
1392
+ //
1393
+ // Remembering that tanθ = sinθ / cosθ; and that
1394
+ // `sx`, `sy`, or both might be zero.
1395
+ const theta = sx > Number.EPSILON ? Math.atan2( m.elements[ 1 ], m.elements[ 0 ] ) : Math.atan2( - m.elements[ 3 ], m.elements[ 4 ] );
1396
+ curve.aRotation += theta;
1397
+ if ( isTransformFlipped( m ) ) {
1398
+
1399
+ curve.aStartAngle *= - 1;
1400
+ curve.aEndAngle *= - 1;
1401
+ curve.aClockwise = ! curve.aClockwise;
1402
+
1403
+ }
1404
+
1405
+ }
1406
+
1407
+ const subPaths = path.subPaths;
1394
1408
  for ( let i = 0, n = subPaths.length; i < n; i ++ ) {
1395
1409
 
1396
1410
  const subPath = subPaths[ i ];
1397
1411
  const curves = subPath.curves;
1398
-
1399
1412
  for ( let j = 0; j < curves.length; j ++ ) {
1400
1413
 
1401
1414
  const curve = curves[ j ];
1402
-
1403
1415
  if ( curve.isLineCurve ) {
1404
1416
 
1405
1417
  transfVec2( curve.v1 );
@@ -1420,18 +1432,24 @@
1420
1432
 
1421
1433
  } else if ( curve.isEllipseCurve ) {
1422
1434
 
1423
- if ( isRotated ) {
1424
-
1425
- console.warn( 'SVGLoader: Elliptic arc or ellipse rotation or skewing is not implemented.' );
1426
-
1427
- }
1435
+ // Transform ellipse center point
1428
1436
 
1429
1437
  tempV2.set( curve.aX, curve.aY );
1430
1438
  transfVec2( tempV2 );
1431
1439
  curve.aX = tempV2.x;
1432
1440
  curve.aY = tempV2.y;
1433
- curve.xRadius *= getTransformScaleX( m );
1434
- curve.yRadius *= getTransformScaleY( m );
1441
+
1442
+ // Transform ellipse shape parameters
1443
+
1444
+ if ( isTransformSkewed( m ) ) {
1445
+
1446
+ transfEllipseGeneric( curve );
1447
+
1448
+ } else {
1449
+
1450
+ transfEllipseNoSkew( curve );
1451
+
1452
+ }
1435
1453
 
1436
1454
  }
1437
1455
 
@@ -1441,9 +1459,23 @@
1441
1459
 
1442
1460
  }
1443
1461
 
1444
- function isTransformRotated( m ) {
1462
+ function isTransformFlipped( m ) {
1463
+
1464
+ const te = m.elements;
1465
+ return te[ 0 ] * te[ 4 ] - te[ 1 ] * te[ 3 ] < 0;
1466
+
1467
+ }
1468
+
1469
+ function isTransformSkewed( m ) {
1470
+
1471
+ const te = m.elements;
1472
+ const basisDot = te[ 0 ] * te[ 3 ] + te[ 1 ] * te[ 4 ];
1445
1473
 
1446
- return m.elements[ 1 ] !== 0 || m.elements[ 3 ] !== 0;
1474
+ // Shortcut for trivial rotations and transformations
1475
+ if ( basisDot === 0 ) return false;
1476
+ const sx = getTransformScaleX( m );
1477
+ const sy = getTransformScaleY( m );
1478
+ return Math.abs( basisDot / ( sx * sy ) ) > Number.EPSILON;
1447
1479
 
1448
1480
  }
1449
1481
 
@@ -1459,8 +1491,92 @@
1459
1491
  const te = m.elements;
1460
1492
  return Math.sqrt( te[ 3 ] * te[ 3 ] + te[ 4 ] * te[ 4 ] );
1461
1493
 
1462
- } //
1494
+ }
1495
+
1496
+ // Calculates the eigensystem of a real symmetric 2x2 matrix
1497
+ // [ A B ]
1498
+ // [ B C ]
1499
+ // in the form
1500
+ // [ A B ] = [ cs -sn ] [ rt1 0 ] [ cs sn ]
1501
+ // [ B C ] [ sn cs ] [ 0 rt2 ] [ -sn cs ]
1502
+ // where rt1 >= rt2.
1503
+ //
1504
+ // Adapted from: https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html
1505
+ // -> Algorithms for real symmetric matrices -> Analytical (2x2 symmetric)
1506
+ function eigenDecomposition( A, B, C ) {
1507
+
1508
+ let rt1, rt2, cs, sn, t;
1509
+ const sm = A + C;
1510
+ const df = A - C;
1511
+ const rt = Math.sqrt( df * df + 4 * B * B );
1512
+ if ( sm > 0 ) {
1513
+
1514
+ rt1 = 0.5 * ( sm + rt );
1515
+ t = 1 / rt1;
1516
+ rt2 = A * t * C - B * t * B;
1517
+
1518
+ } else if ( sm < 0 ) {
1519
+
1520
+ rt2 = 0.5 * ( sm - rt );
1521
+
1522
+ } else {
1523
+
1524
+ // This case needs to be treated separately to avoid div by 0
1463
1525
 
1526
+ rt1 = 0.5 * rt;
1527
+ rt2 = - 0.5 * rt;
1528
+
1529
+ }
1530
+
1531
+ // Calculate eigenvectors
1532
+
1533
+ if ( df > 0 ) {
1534
+
1535
+ cs = df + rt;
1536
+
1537
+ } else {
1538
+
1539
+ cs = df - rt;
1540
+
1541
+ }
1542
+
1543
+ if ( Math.abs( cs ) > 2 * Math.abs( B ) ) {
1544
+
1545
+ t = - 2 * B / cs;
1546
+ sn = 1 / Math.sqrt( 1 + t * t );
1547
+ cs = t * sn;
1548
+
1549
+ } else if ( Math.abs( B ) === 0 ) {
1550
+
1551
+ cs = 1;
1552
+ sn = 0;
1553
+
1554
+ } else {
1555
+
1556
+ t = - 0.5 * cs / B;
1557
+ cs = 1 / Math.sqrt( 1 + t * t );
1558
+ sn = t * cs;
1559
+
1560
+ }
1561
+
1562
+ if ( df > 0 ) {
1563
+
1564
+ t = cs;
1565
+ cs = - sn;
1566
+ sn = t;
1567
+
1568
+ }
1569
+
1570
+ return {
1571
+ rt1,
1572
+ rt2,
1573
+ cs,
1574
+ sn
1575
+ };
1576
+
1577
+ }
1578
+
1579
+ //
1464
1580
 
1465
1581
  const paths = [];
1466
1582
  const stylesheets = {};
@@ -1486,16 +1602,17 @@
1486
1602
  const data = {
1487
1603
  paths: paths,
1488
1604
  xml: xml.documentElement
1489
- }; // console.log( paths );
1605
+ };
1490
1606
 
1607
+ // console.log( paths );
1491
1608
  return data;
1492
1609
 
1493
1610
  }
1494
-
1495
1611
  static createShapes( shapePath ) {
1496
1612
 
1497
1613
  // Param shapePath: a shapepath as returned by the parse function of this class
1498
1614
  // Returns THREE.Shape object
1615
+
1499
1616
  const BIGNUMBER = 999999999;
1500
1617
  const IntersectionLocationType = {
1501
1618
  ORIGIN: 0,
@@ -1510,7 +1627,6 @@
1510
1627
  loc: IntersectionLocationType.ORIGIN,
1511
1628
  t: 0
1512
1629
  };
1513
-
1514
1630
  function findEdgeIntersection( a0, a1, b0, b1 ) {
1515
1631
 
1516
1632
  const x1 = a0.x;
@@ -1526,20 +1642,21 @@
1526
1642
  const denom = ( y4 - y3 ) * ( x2 - x1 ) - ( x4 - x3 ) * ( y2 - y1 );
1527
1643
  const t1 = nom1 / denom;
1528
1644
  const t2 = nom2 / denom;
1529
-
1530
1645
  if ( denom === 0 && nom1 !== 0 || t1 <= 0 || t1 >= 1 || t2 < 0 || t2 > 1 ) {
1531
1646
 
1532
1647
  //1. lines are parallel or edges don't intersect
1648
+
1533
1649
  return null;
1534
1650
 
1535
1651
  } else if ( nom1 === 0 && denom === 0 ) {
1536
1652
 
1537
1653
  //2. lines are colinear
1654
+
1538
1655
  //check if endpoints of edge2 (b0-b1) lies on edge1 (a0-a1)
1539
1656
  for ( let i = 0; i < 2; i ++ ) {
1540
1657
 
1541
- classifyPoint( i === 0 ? b0 : b1, a0, a1 ); //find position of this endpoints relatively to edge1
1542
-
1658
+ classifyPoint( i === 0 ? b0 : b1, a0, a1 );
1659
+ //find position of this endpoints relatively to edge1
1543
1660
  if ( classifyResult.loc == IntersectionLocationType.ORIGIN ) {
1544
1661
 
1545
1662
  const point = i === 0 ? b0 : b1;
@@ -1568,10 +1685,10 @@
1568
1685
  } else {
1569
1686
 
1570
1687
  //3. edges intersect
1688
+
1571
1689
  for ( let i = 0; i < 2; i ++ ) {
1572
1690
 
1573
1691
  classifyPoint( i === 0 ? b0 : b1, a0, a1 );
1574
-
1575
1692
  if ( classifyResult.loc == IntersectionLocationType.ORIGIN ) {
1576
1693
 
1577
1694
  const point = i === 0 ? b0 : b1;
@@ -1604,7 +1721,6 @@
1604
1721
  const bx = p.x - edgeStart.x;
1605
1722
  const by = p.y - edgeStart.y;
1606
1723
  const sa = ax * by - bx * ay;
1607
-
1608
1724
  if ( p.x === edgeStart.x && p.y === edgeStart.y ) {
1609
1725
 
1610
1726
  classifyResult.loc = IntersectionLocationType.ORIGIN;
@@ -1650,7 +1766,6 @@
1650
1766
  }
1651
1767
 
1652
1768
  let t;
1653
-
1654
1769
  if ( ax !== 0 ) {
1655
1770
 
1656
1771
  t = bx / ax;
@@ -1670,18 +1785,15 @@
1670
1785
 
1671
1786
  const intersectionsRaw = [];
1672
1787
  const intersections = [];
1673
-
1674
1788
  for ( let index = 1; index < path1.length; index ++ ) {
1675
1789
 
1676
1790
  const path1EdgeStart = path1[ index - 1 ];
1677
1791
  const path1EdgeEnd = path1[ index ];
1678
-
1679
1792
  for ( let index2 = 1; index2 < path2.length; index2 ++ ) {
1680
1793
 
1681
1794
  const path2EdgeStart = path2[ index2 - 1 ];
1682
1795
  const path2EdgeEnd = path2[ index2 ];
1683
1796
  const intersection = findEdgeIntersection( path1EdgeStart, path1EdgeEnd, path2EdgeStart, path2EdgeEnd );
1684
-
1685
1797
  if ( intersection !== null && intersectionsRaw.find( i => i.t <= intersection.t + Number.EPSILON && i.t >= intersection.t - Number.EPSILON ) === undefined ) {
1686
1798
 
1687
1799
  intersectionsRaw.push( intersection );
@@ -1764,11 +1876,11 @@
1764
1876
  }
1765
1877
 
1766
1878
  } );
1767
- const firstXOfPath = baseIntersections[ 0 ].point.x; // build up the path hierarchy
1879
+ const firstXOfPath = baseIntersections[ 0 ].point.x;
1768
1880
 
1881
+ // build up the path hierarchy
1769
1882
  const stack = [];
1770
1883
  let i = 0;
1771
-
1772
1884
  while ( i < otherIntersections.length && otherIntersections[ i ].point.x < firstXOfPath ) {
1773
1885
 
1774
1886
  if ( stack.length > 0 && stack[ stack.length - 1 ] === otherIntersections[ i ].identifier ) {
@@ -1786,7 +1898,6 @@
1786
1898
  }
1787
1899
 
1788
1900
  stack.push( simplePath.identifier );
1789
-
1790
1901
  if ( _fillRule === 'evenodd' ) {
1791
1902
 
1792
1903
  const isHole = stack.length % 2 === 0 ? true : false;
@@ -1803,11 +1914,9 @@
1803
1914
  let isHole = true;
1804
1915
  let isHoleFor = null;
1805
1916
  let lastCWValue = null;
1806
-
1807
1917
  for ( let i = 0; i < stack.length; i ++ ) {
1808
1918
 
1809
1919
  const identifier = stack[ i ];
1810
-
1811
1920
  if ( isHole ) {
1812
1921
 
1813
1922
  lastCWValue = allPaths[ identifier ].isCW;
@@ -1835,13 +1944,15 @@
1835
1944
 
1836
1945
  }
1837
1946
 
1838
- } // check for self intersecting paths
1947
+ }
1948
+
1949
+ // check for self intersecting paths
1839
1950
  // TODO
1951
+
1840
1952
  // check intersecting paths
1841
1953
  // TODO
1842
- // prepare paths for hole detection
1843
-
1844
1954
 
1955
+ // prepare paths for hole detection
1845
1956
  let identifier = 0;
1846
1957
  let scanlineMinX = BIGNUMBER;
1847
1958
  let scanlineMaxX = - BIGNUMBER;
@@ -1851,12 +1962,13 @@
1851
1962
  let maxY = - BIGNUMBER;
1852
1963
  let minY = BIGNUMBER;
1853
1964
  let maxX = - BIGNUMBER;
1854
- let minX = BIGNUMBER; //points.forEach(p => p.y *= -1);
1965
+ let minX = BIGNUMBER;
1966
+
1967
+ //points.forEach(p => p.y *= -1);
1855
1968
 
1856
1969
  for ( let i = 0; i < points.length; i ++ ) {
1857
1970
 
1858
1971
  const p = points[ i ];
1859
-
1860
1972
  if ( p.y > maxY ) {
1861
1973
 
1862
1974
  maxY = p.y;
@@ -1881,9 +1993,9 @@
1881
1993
 
1882
1994
  }
1883
1995
 
1884
- } //
1885
-
1996
+ }
1886
1997
 
1998
+ //
1887
1999
  if ( scanlineMaxX <= maxX ) {
1888
2000
 
1889
2001
  scanlineMaxX = maxX + 1;
@@ -1905,14 +2017,14 @@
1905
2017
  };
1906
2018
 
1907
2019
  } );
1908
- simplePaths = simplePaths.filter( sp => sp.points.length > 1 ); // check if path is solid or a hole
2020
+ simplePaths = simplePaths.filter( sp => sp.points.length > 1 );
1909
2021
 
1910
- const isAHole = simplePaths.map( p => isHoleTo( p, simplePaths, scanlineMinX, scanlineMaxX, shapePath.userData.style.fillRule ) );
2022
+ // check if path is solid or a hole
2023
+ const isAHole = simplePaths.map( p => isHoleTo( p, simplePaths, scanlineMinX, scanlineMaxX, shapePath.userData?.style.fillRule ) );
1911
2024
  const shapesToReturn = [];
1912
2025
  simplePaths.forEach( p => {
1913
2026
 
1914
2027
  const amIAHole = isAHole[ p.identifier ];
1915
-
1916
2028
  if ( ! amIAHole.isHole ) {
1917
2029
 
1918
2030
  const shape = new THREE.Shape();
@@ -1934,7 +2046,6 @@
1934
2046
  return shapesToReturn;
1935
2047
 
1936
2048
  }
1937
-
1938
2049
  static getStrokeStyle( width, color, lineJoin, lineCap, miterLimit ) {
1939
2050
 
1940
2051
  // Param width: Stroke width
@@ -1943,6 +2054,7 @@
1943
2054
  // Param lineCap: One of "round", "square" or "butt"
1944
2055
  // Param miterLimit: Maximum join length, in multiples of the "width" parameter (join is truncated if it exceeds that distance)
1945
2056
  // Returns style object
2057
+
1946
2058
  width = width !== undefined ? width : 1;
1947
2059
  color = color !== undefined ? color : '#000';
1948
2060
  lineJoin = lineJoin !== undefined ? lineJoin : 'miter';
@@ -1957,7 +2069,6 @@
1957
2069
  };
1958
2070
 
1959
2071
  }
1960
-
1961
2072
  static pointsToStroke( points, style, arcDivisions, minDistance ) {
1962
2073
 
1963
2074
  // Generates a stroke with some witdh around the given path.
@@ -1967,10 +2078,10 @@
1967
2078
  // Params arcDivisions: Arc divisions for round joins and endcaps. (Optional)
1968
2079
  // Param minDistance: Points closer to this distance will be merged. (Optional)
1969
2080
  // Returns THREE.BufferGeometry with stroke triangles (In plane z = 0). UV coordinates are generated ('u' along path. 'v' across it, from left to right)
2081
+
1970
2082
  const vertices = [];
1971
2083
  const normals = [];
1972
2084
  const uvs = [];
1973
-
1974
2085
  if ( SVGLoader.pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs ) === 0 ) {
1975
2086
 
1976
2087
  return null;
@@ -1984,7 +2095,6 @@
1984
2095
  return geometry;
1985
2096
 
1986
2097
  }
1987
-
1988
2098
  static pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs, vertexOffset ) {
1989
2099
 
1990
2100
  // This function can be called to update existing arrays or buffers.
@@ -1993,6 +2103,7 @@
1993
2103
  // Returns number of written vertices / normals / uvs pairs
1994
2104
  // if 'vertices' parameter is undefined no triangles will be generated, but the returned vertices count will still be valid (useful to preallocate the buffers)
1995
2105
  // 'normals' and 'uvs' buffers are optional
2106
+
1996
2107
  const tempV2_1 = new THREE.Vector2();
1997
2108
  const tempV2_2 = new THREE.Vector2();
1998
2109
  const tempV2_3 = new THREE.Vector2();
@@ -2012,8 +2123,9 @@
2012
2123
  const outerPoint = new THREE.Vector2();
2013
2124
  arcDivisions = arcDivisions !== undefined ? arcDivisions : 12;
2014
2125
  minDistance = minDistance !== undefined ? minDistance : 0.001;
2015
- vertexOffset = vertexOffset !== undefined ? vertexOffset : 0; // First ensure there are no duplicated points
2126
+ vertexOffset = vertexOffset !== undefined ? vertexOffset : 0;
2016
2127
 
2128
+ // First ensure there are no duplicated points
2017
2129
  points = removeDuplicatedPoints( points );
2018
2130
  const numPoints = points.length;
2019
2131
  if ( numPoints < 2 ) return 0;
@@ -2031,18 +2143,19 @@
2031
2143
  let initialJoinIsOnLeftSide = false;
2032
2144
  let numVertices = 0;
2033
2145
  let currentCoordinate = vertexOffset * 3;
2034
- let currentCoordinateUV = vertexOffset * 2; // Get initial left and right stroke points
2146
+ let currentCoordinateUV = vertexOffset * 2;
2035
2147
 
2148
+ // Get initial left and right stroke points
2036
2149
  getNormal( points[ 0 ], points[ 1 ], tempV2_1 ).multiplyScalar( strokeWidth2 );
2037
2150
  lastPointL.copy( points[ 0 ] ).sub( tempV2_1 );
2038
2151
  lastPointR.copy( points[ 0 ] ).add( tempV2_1 );
2039
2152
  point0L.copy( lastPointL );
2040
2153
  point0R.copy( lastPointR );
2041
-
2042
2154
  for ( let iPoint = 1; iPoint < numPoints; iPoint ++ ) {
2043
2155
 
2044
- currentPoint = points[ iPoint ]; // Get next point
2156
+ currentPoint = points[ iPoint ];
2045
2157
 
2158
+ // Get next point
2046
2159
  if ( iPoint === numPoints - 1 ) {
2047
2160
 
2048
2161
  if ( isClosed ) {
@@ -2056,9 +2169,9 @@
2056
2169
 
2057
2170
  nextPoint = points[ iPoint + 1 ];
2058
2171
 
2059
- } // Normal of previous segment in tempV2_1
2060
-
2172
+ }
2061
2173
 
2174
+ // Normal of previous segment in tempV2_1
2062
2175
  const normal1 = tempV2_1;
2063
2176
  getNormal( previousPoint, currentPoint, normal1 );
2064
2177
  tempV2_3.copy( normal1 ).multiplyScalar( strokeWidth2 );
@@ -2066,7 +2179,6 @@
2066
2179
  currentPointR.copy( currentPoint ).add( tempV2_3 );
2067
2180
  u1 = u0 + deltaU;
2068
2181
  innerSideModified = false;
2069
-
2070
2182
  if ( nextPoint !== undefined ) {
2071
2183
 
2072
2184
  // Normal of next segment in tempV2_2
@@ -2076,7 +2188,6 @@
2076
2188
  nextPointR.copy( currentPoint ).add( tempV2_3 );
2077
2189
  joinIsOnLeftSide = true;
2078
2190
  tempV2_3.subVectors( nextPoint, previousPoint );
2079
-
2080
2191
  if ( normal1.dot( tempV2_3 ) < 0 ) {
2081
2192
 
2082
2193
  joinIsOnLeftSide = false;
@@ -2086,9 +2197,10 @@
2086
2197
  if ( iPoint === 1 ) initialJoinIsOnLeftSide = joinIsOnLeftSide;
2087
2198
  tempV2_3.subVectors( nextPoint, currentPoint );
2088
2199
  tempV2_3.normalize();
2089
- const dot = Math.abs( normal1.dot( tempV2_3 ) ); // If path is straight, don't create join
2200
+ const dot = Math.abs( normal1.dot( tempV2_3 ) );
2090
2201
 
2091
- if ( dot !== 0 ) {
2202
+ // If path is straight, don't create join
2203
+ if ( dot > Number.EPSILON ) {
2092
2204
 
2093
2205
  // Compute inner and outer segment intersections
2094
2206
  const miterSide = strokeWidth2 / dot;
@@ -2101,8 +2213,8 @@
2101
2213
  tempV2_4.divideScalar( segmentLengthPrev );
2102
2214
  tempV2_6.subVectors( nextPoint, currentPoint );
2103
2215
  const segmentLengthNext = tempV2_6.length();
2104
- tempV2_6.divideScalar( segmentLengthNext ); // Check that previous and next segments doesn't overlap with the innerPoint of intersection
2105
-
2216
+ tempV2_6.divideScalar( segmentLengthNext );
2217
+ // Check that previous and next segments doesn't overlap with the innerPoint of intersection
2106
2218
  if ( tempV2_4.dot( innerPoint ) < segmentLengthPrev && tempV2_6.dot( innerPoint ) < segmentLengthNext ) {
2107
2219
 
2108
2220
  innerSideModified = true;
@@ -2112,7 +2224,6 @@
2112
2224
  outerPoint.copy( tempV2_5 ).add( currentPoint );
2113
2225
  innerPoint.add( currentPoint );
2114
2226
  isMiter = false;
2115
-
2116
2227
  if ( innerSideModified ) {
2117
2228
 
2118
2229
  if ( joinIsOnLeftSide ) {
@@ -2130,6 +2241,7 @@
2130
2241
  } else {
2131
2242
 
2132
2243
  // The segment triangles are generated here if there was overlapping
2244
+
2133
2245
  makeSegmentTriangles();
2134
2246
 
2135
2247
  }
@@ -2139,10 +2251,12 @@
2139
2251
  case 'bevel':
2140
2252
  makeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 );
2141
2253
  break;
2142
-
2143
2254
  case 'round':
2144
2255
  // Segment triangles
2145
- createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ); // Join triangles
2256
+
2257
+ createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified );
2258
+
2259
+ // Join triangles
2146
2260
 
2147
2261
  if ( joinIsOnLeftSide ) {
2148
2262
 
@@ -2155,15 +2269,14 @@
2155
2269
  }
2156
2270
 
2157
2271
  break;
2158
-
2159
2272
  case 'miter':
2160
2273
  case 'miter-clip':
2161
2274
  default:
2162
2275
  const miterFraction = strokeWidth2 * style.strokeMiterLimit / miterLength2;
2163
-
2164
2276
  if ( miterFraction < 1 ) {
2165
2277
 
2166
2278
  // The join miter length exceeds the miter limit
2279
+
2167
2280
  if ( style.strokeLineJoin !== 'miter-clip' ) {
2168
2281
 
2169
2282
  makeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 );
@@ -2172,7 +2285,10 @@
2172
2285
  } else {
2173
2286
 
2174
2287
  // Segment triangles
2175
- createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ); // Miter-clip join triangles
2288
+
2289
+ createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified );
2290
+
2291
+ // Miter-clip join triangles
2176
2292
 
2177
2293
  if ( joinIsOnLeftSide ) {
2178
2294
 
@@ -2209,9 +2325,11 @@
2209
2325
  } else {
2210
2326
 
2211
2327
  // Miter join segment triangles
2328
+
2212
2329
  if ( innerSideModified ) {
2213
2330
 
2214
2331
  // Optimized segment + join triangles
2332
+
2215
2333
  if ( joinIsOnLeftSide ) {
2216
2334
 
2217
2335
  addVertex( lastPointR, u0, 1 );
@@ -2245,6 +2363,7 @@
2245
2363
  } else {
2246
2364
 
2247
2365
  // Add extra miter join triangles
2366
+
2248
2367
  if ( joinIsOnLeftSide ) {
2249
2368
 
2250
2369
  addVertex( currentPointL, u1, 0 );
@@ -2278,6 +2397,7 @@
2278
2397
  } else {
2279
2398
 
2280
2399
  // The segment triangles are generated here when two consecutive points are collinear
2400
+
2281
2401
  makeSegmentTriangles();
2282
2402
 
2283
2403
  }
@@ -2285,6 +2405,7 @@
2285
2405
  } else {
2286
2406
 
2287
2407
  // The segment triangles are generated here if it is the ending segment
2408
+
2288
2409
  makeSegmentTriangles();
2289
2410
 
2290
2411
  }
@@ -2294,8 +2415,9 @@
2294
2415
  // Start line endcap
2295
2416
  addCapGeometry( points[ 0 ], point0L, point0R, joinIsOnLeftSide, true, u0 );
2296
2417
 
2297
- } // Increment loop variables
2418
+ }
2298
2419
 
2420
+ // Increment loop variables
2299
2421
 
2300
2422
  u0 = u1;
2301
2423
  previousPoint = currentPoint;
@@ -2312,9 +2434,9 @@
2312
2434
  } else if ( innerSideModified && vertices ) {
2313
2435
 
2314
2436
  // Modify path first segment vertices to adjust to the segments inner and outer intersections
2437
+
2315
2438
  let lastOuter = outerPoint;
2316
2439
  let lastInner = innerPoint;
2317
-
2318
2440
  if ( initialJoinIsOnLeftSide !== joinIsOnLeftSide ) {
2319
2441
 
2320
2442
  lastOuter = innerPoint;
@@ -2328,7 +2450,6 @@
2328
2450
 
2329
2451
  lastInner.toArray( vertices, 0 * 3 );
2330
2452
  lastInner.toArray( vertices, 3 * 3 );
2331
-
2332
2453
  if ( isMiter ) {
2333
2454
 
2334
2455
  lastOuter.toArray( vertices, 1 * 3 );
@@ -2343,7 +2464,6 @@
2343
2464
 
2344
2465
  lastInner.toArray( vertices, 1 * 3 );
2345
2466
  lastInner.toArray( vertices, 3 * 3 );
2346
-
2347
2467
  if ( isMiter ) {
2348
2468
 
2349
2469
  lastOuter.toArray( vertices, 0 * 3 );
@@ -2356,7 +2476,10 @@
2356
2476
 
2357
2477
  }
2358
2478
 
2359
- return numVertices; // -- End of algorithm
2479
+ return numVertices;
2480
+
2481
+ // -- End of algorithm
2482
+
2360
2483
  // -- Functions
2361
2484
 
2362
2485
  function getNormal( p1, p2, result ) {
@@ -2373,7 +2496,6 @@
2373
2496
  vertices[ currentCoordinate ] = position.x;
2374
2497
  vertices[ currentCoordinate + 1 ] = position.y;
2375
2498
  vertices[ currentCoordinate + 2 ] = 0;
2376
-
2377
2499
  if ( normals ) {
2378
2500
 
2379
2501
  normals[ currentCoordinate ] = 0;
@@ -2383,7 +2505,6 @@
2383
2505
  }
2384
2506
 
2385
2507
  currentCoordinate += 3;
2386
-
2387
2508
  if ( uvs ) {
2388
2509
 
2389
2510
  uvs[ currentCoordinateUV ] = u;
@@ -2402,6 +2523,7 @@
2402
2523
 
2403
2524
  // param p1, p2: Points in the circle arc.
2404
2525
  // p1 and p2 are in clockwise direction.
2526
+
2405
2527
  tempV2_1.copy( p1 ).sub( center ).normalize();
2406
2528
  tempV2_2.copy( p2 ).sub( center ).normalize();
2407
2529
  let angle = Math.PI;
@@ -2409,7 +2531,6 @@
2409
2531
  if ( Math.abs( dot ) < 1 ) angle = Math.abs( Math.acos( dot ) );
2410
2532
  angle /= arcDivisions;
2411
2533
  tempV2_3.copy( p1 );
2412
-
2413
2534
  for ( let i = 0, il = arcDivisions - 1; i < il; i ++ ) {
2414
2535
 
2415
2536
  tempV2_4.copy( tempV2_3 ).rotateAround( center, angle );
@@ -2442,15 +2563,19 @@
2442
2563
  if ( innerSideModified ) {
2443
2564
 
2444
2565
  // Optimized segment + bevel triangles
2566
+
2445
2567
  if ( joinIsOnLeftSide ) {
2446
2568
 
2447
2569
  // THREE.Path segments triangles
2570
+
2448
2571
  addVertex( lastPointR, u0, 1 );
2449
2572
  addVertex( lastPointL, u0, 0 );
2450
2573
  addVertex( currentPointL, u1, 0 );
2451
2574
  addVertex( lastPointR, u0, 1 );
2452
2575
  addVertex( currentPointL, u1, 0 );
2453
- addVertex( innerPoint, u1, 1 ); // Bevel join triangle
2576
+ addVertex( innerPoint, u1, 1 );
2577
+
2578
+ // Bevel join triangle
2454
2579
 
2455
2580
  addVertex( currentPointL, u, 0 );
2456
2581
  addVertex( nextPointL, u, 0 );
@@ -2459,12 +2584,15 @@
2459
2584
  } else {
2460
2585
 
2461
2586
  // THREE.Path segments triangles
2587
+
2462
2588
  addVertex( lastPointR, u0, 1 );
2463
2589
  addVertex( lastPointL, u0, 0 );
2464
2590
  addVertex( currentPointR, u1, 1 );
2465
2591
  addVertex( lastPointL, u0, 0 );
2466
2592
  addVertex( innerPoint, u1, 0 );
2467
- addVertex( currentPointR, u1, 1 ); // Bevel join triangle
2593
+ addVertex( currentPointR, u1, 1 );
2594
+
2595
+ // Bevel join triangle
2468
2596
 
2469
2597
  addVertex( currentPointR, u, 1 );
2470
2598
  addVertex( nextPointR, u, 0 );
@@ -2475,6 +2603,7 @@
2475
2603
  } else {
2476
2604
 
2477
2605
  // Bevel join triangle. The segment triangles are done in the main loop
2606
+
2478
2607
  if ( joinIsOnLeftSide ) {
2479
2608
 
2480
2609
  addVertex( currentPointL, u, 0 );
@@ -2537,6 +2666,7 @@
2537
2666
 
2538
2667
  // param center: End point of the path
2539
2668
  // param p1, p2: Left and right cap points
2669
+
2540
2670
  switch ( style.strokeLineCap ) {
2541
2671
 
2542
2672
  case 'round':
@@ -2551,15 +2681,15 @@
2551
2681
  }
2552
2682
 
2553
2683
  break;
2554
-
2555
2684
  case 'square':
2556
2685
  if ( start ) {
2557
2686
 
2558
2687
  tempV2_1.subVectors( p1, center );
2559
2688
  tempV2_2.set( tempV2_1.y, - tempV2_1.x );
2560
2689
  tempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center );
2561
- tempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center ); // Modify already existing vertices
2690
+ tempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center );
2562
2691
 
2692
+ // Modify already existing vertices
2563
2693
  if ( joinIsOnLeftSide ) {
2564
2694
 
2565
2695
  tempV2_3.toArray( vertices, 1 * 3 );
@@ -2580,8 +2710,9 @@
2580
2710
  tempV2_2.set( tempV2_1.y, - tempV2_1.x );
2581
2711
  tempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center );
2582
2712
  tempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center );
2583
- const vl = vertices.length; // Modify already existing vertices
2713
+ const vl = vertices.length;
2584
2714
 
2715
+ // Modify already existing vertices
2585
2716
  if ( joinIsOnLeftSide ) {
2586
2717
 
2587
2718
  tempV2_3.toArray( vertices, vl - 1 * 3 );
@@ -2599,7 +2730,6 @@
2599
2730
  }
2600
2731
 
2601
2732
  break;
2602
-
2603
2733
  case 'butt':
2604
2734
  default:
2605
2735
  // Nothing to do here
@@ -2613,8 +2743,8 @@
2613
2743
 
2614
2744
  // Creates a new array if necessary with duplicated points removed.
2615
2745
  // This does not remove duplicated initial and ending points of a closed path.
2616
- let dupPoints = false;
2617
2746
 
2747
+ let dupPoints = false;
2618
2748
  for ( let i = 1, n = points.length - 1; i < n; i ++ ) {
2619
2749
 
2620
2750
  if ( points[ i ].distanceTo( points[ i + 1 ] ) < minDistance ) {
@@ -2629,7 +2759,6 @@
2629
2759
  if ( ! dupPoints ) return points;
2630
2760
  const newPoints = [];
2631
2761
  newPoints.push( points[ 0 ] );
2632
-
2633
2762
  for ( let i = 1, n = points.length - 1; i < n; i ++ ) {
2634
2763
 
2635
2764
  if ( points[ i ].distanceTo( points[ i + 1 ] ) >= minDistance ) {