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
@@ -1,29 +1,27 @@
1
1
  ( function () {
2
2
 
3
+ // Special surface finish tag types.
3
4
  // Note: "MATERIAL" tag (e.g. GLITTER, SPECKLE) is not implemented
4
-
5
5
  const FINISH_TYPE_DEFAULT = 0;
6
6
  const FINISH_TYPE_CHROME = 1;
7
7
  const FINISH_TYPE_PEARLESCENT = 2;
8
8
  const FINISH_TYPE_RUBBER = 3;
9
9
  const FINISH_TYPE_MATTE_METALLIC = 4;
10
- const FINISH_TYPE_METAL = 5; // State machine to search a subobject path.
11
- // The LDraw standard establishes these various possible subfolders.
10
+ const FINISH_TYPE_METAL = 5;
12
11
 
13
- const FILE_LOCATION_AS_IS = 0;
14
- const FILE_LOCATION_TRY_PARTS = 1;
15
- const FILE_LOCATION_TRY_P = 2;
16
- const FILE_LOCATION_TRY_MODELS = 3;
12
+ // State machine to search a subobject path.
13
+ // The LDraw standard establishes these various possible subfolders.
14
+ const FILE_LOCATION_TRY_PARTS = 0;
15
+ const FILE_LOCATION_TRY_P = 1;
16
+ const FILE_LOCATION_TRY_MODELS = 2;
17
+ const FILE_LOCATION_AS_IS = 3;
17
18
  const FILE_LOCATION_TRY_RELATIVE = 4;
18
19
  const FILE_LOCATION_TRY_ABSOLUTE = 5;
19
20
  const FILE_LOCATION_NOT_FOUND = 6;
20
21
  const MAIN_COLOUR_CODE = '16';
21
22
  const MAIN_EDGE_COLOUR_CODE = '24';
22
-
23
23
  const _tempVec0 = new THREE.Vector3();
24
-
25
24
  const _tempVec1 = new THREE.Vector3();
26
-
27
25
  class LDrawConditionalLineMaterial extends THREE.ShaderMaterial {
28
26
 
29
27
  constructor( parameters ) {
@@ -37,9 +35,7 @@
37
35
  value: 1.0
38
36
  }
39
37
  } ] ),
40
- vertexShader:
41
- /* glsl */
42
- `
38
+ vertexShader: /* glsl */`
43
39
  attribute vec3 control0;
44
40
  attribute vec3 control1;
45
41
  attribute vec3 direction;
@@ -86,9 +82,7 @@
86
82
  #include <fog_vertex>
87
83
  }
88
84
  `,
89
- fragmentShader:
90
- /* glsl */
91
- `
85
+ fragmentShader: /* glsl */`
92
86
  uniform vec3 diffuse;
93
87
  uniform float opacity;
94
88
  varying float discardFlag;
@@ -143,7 +137,6 @@
143
137
  }
144
138
 
145
139
  }
146
-
147
140
  class ConditionalLineSegments extends THREE.LineSegments {
148
141
 
149
142
  constructor( geometry, material ) {
@@ -154,7 +147,6 @@
154
147
  }
155
148
 
156
149
  }
157
-
158
150
  function generateFaceNormals( faces ) {
159
151
 
160
152
  for ( let i = 0, l = faces.length; i < l; i ++ ) {
@@ -164,11 +156,8 @@
164
156
  const v0 = vertices[ 0 ];
165
157
  const v1 = vertices[ 1 ];
166
158
  const v2 = vertices[ 2 ];
167
-
168
159
  _tempVec0.subVectors( v1, v0 );
169
-
170
160
  _tempVec1.subVectors( v2, v1 );
171
-
172
161
  face.faceNormal = new THREE.Vector3().crossVectors( _tempVec0, _tempVec1 ).normalize();
173
162
 
174
163
  }
@@ -176,7 +165,6 @@
176
165
  }
177
166
 
178
167
  const _ray = new THREE.Ray();
179
-
180
168
  function smoothNormals( faces, lineSegments, checkSubSegments = false ) {
181
169
 
182
170
  // NOTE: 1e2 is pretty coarse but was chosen to quantize the resulting value because
@@ -187,8 +175,8 @@
187
175
  // vertices that should be merged might be set to "1.7" and "1.6999..." meaning they won't
188
176
  // get merged. This added epsilon attempts to push these error values to the same quantized
189
177
  // value for the sake of hashing. See "AT-ST mini" dishes. See mrdoob/three#23169.
190
- const hashMultiplier = ( 1 + 1e-10 ) * 1e2;
191
178
 
179
+ const hashMultiplier = ( 1 + 1e-10 ) * 1e2;
192
180
  function hashVertex( v ) {
193
181
 
194
182
  const x = ~ ~ ( v.x * hashMultiplier );
@@ -202,10 +190,10 @@
202
190
 
203
191
  return `${hashVertex( v0 )}_${hashVertex( v1 )}`;
204
192
 
205
- } // converts the two vertices to a ray with a normalized direction and origin of 0, 0, 0 projected
206
- // onto the original line.
207
-
193
+ }
208
194
 
195
+ // converts the two vertices to a ray with a normalized direction and origin of 0, 0, 0 projected
196
+ // onto the original line.
209
197
  function toNormalizedRay( v0, v1, targetRay ) {
210
198
 
211
199
  targetRay.direction.subVectors( v1, v0 ).normalize();
@@ -224,8 +212,9 @@
224
212
  const hardEdges = new Set();
225
213
  const hardEdgeRays = new Map();
226
214
  const halfEdgeList = {};
227
- const normals = []; // Save the list of hard edges by hash
215
+ const normals = [];
228
216
 
217
+ // Save the list of hard edges by hash
229
218
  for ( let i = 0, l = lineSegments.length; i < l; i ++ ) {
230
219
 
231
220
  const ls = lineSegments[ i ];
@@ -233,15 +222,15 @@
233
222
  const v0 = vertices[ 0 ];
234
223
  const v1 = vertices[ 1 ];
235
224
  hardEdges.add( hashEdge( v0, v1 ) );
236
- hardEdges.add( hashEdge( v1, v0 ) ); // only generate the hard edge ray map if we're checking subsegments because it's more expensive to check
237
- // and requires more memory.
225
+ hardEdges.add( hashEdge( v1, v0 ) );
238
226
 
227
+ // only generate the hard edge ray map if we're checking subsegments because it's more expensive to check
228
+ // and requires more memory.
239
229
  if ( checkSubSegments ) {
240
230
 
241
231
  // add both ray directions to the map
242
232
  const ray = toNormalizedRay( v0, v1, new THREE.Ray() );
243
233
  const rh1 = hashRay( ray );
244
-
245
234
  if ( ! hardEdgeRays.has( rh1 ) ) {
246
235
 
247
236
  toNormalizedRay( v1, v0, ray );
@@ -253,14 +242,13 @@
253
242
  hardEdgeRays.set( rh1, info );
254
243
  hardEdgeRays.set( rh2, info );
255
244
 
256
- } // store both segments ends in min, max order in the distances array to check if a face edge is a
257
- // subsegment later.
258
-
245
+ }
259
246
 
247
+ // store both segments ends in min, max order in the distances array to check if a face edge is a
248
+ // subsegment later.
260
249
  const info = hardEdgeRays.get( rh1 );
261
250
  let d0 = info.ray.direction.dot( v0 );
262
251
  let d1 = info.ray.direction.dot( v1 );
263
-
264
252
  if ( d0 > d1 ) {
265
253
 
266
254
  [ d0, d1 ] = [ d1, d0 ];
@@ -271,35 +259,34 @@
271
259
 
272
260
  }
273
261
 
274
- } // track the half edges associated with each triangle
275
-
262
+ }
276
263
 
264
+ // track the half edges associated with each triangle
277
265
  for ( let i = 0, l = faces.length; i < l; i ++ ) {
278
266
 
279
267
  const tri = faces[ i ];
280
268
  const vertices = tri.vertices;
281
269
  const vertCount = vertices.length;
282
-
283
270
  for ( let i2 = 0; i2 < vertCount; i2 ++ ) {
284
271
 
285
272
  const index = i2;
286
273
  const next = ( i2 + 1 ) % vertCount;
287
274
  const v0 = vertices[ index ];
288
275
  const v1 = vertices[ next ];
289
- const hash = hashEdge( v0, v1 ); // don't add the triangle if the edge is supposed to be hard
276
+ const hash = hashEdge( v0, v1 );
290
277
 
278
+ // don't add the triangle if the edge is supposed to be hard
291
279
  if ( hardEdges.has( hash ) ) {
292
280
 
293
281
  continue;
294
282
 
295
- } // if checking subsegments then check to see if this edge lies on a hard edge ray and whether its within any ray bounds
296
-
283
+ }
297
284
 
285
+ // if checking subsegments then check to see if this edge lies on a hard edge ray and whether its within any ray bounds
298
286
  if ( checkSubSegments ) {
299
287
 
300
288
  toNormalizedRay( v0, v1, _ray );
301
289
  const rayHash = hashRay( _ray );
302
-
303
290
  if ( hardEdgeRays.has( rayHash ) ) {
304
291
 
305
292
  const info = hardEdgeRays.get( rayHash );
@@ -309,16 +296,14 @@
309
296
  } = info;
310
297
  let d0 = ray.direction.dot( v0 );
311
298
  let d1 = ray.direction.dot( v1 );
312
-
313
299
  if ( d0 > d1 ) {
314
300
 
315
301
  [ d0, d1 ] = [ d1, d0 ];
316
302
 
317
- } // return early if the face edge is found to be a subsegment of a line edge meaning the edge will have "hard" normals
318
-
303
+ }
319
304
 
305
+ // return early if the face edge is found to be a subsegment of a line edge meaning the edge will have "hard" normals
320
306
  let found = false;
321
-
322
307
  for ( let i = 0, l = distances.length; i < l; i += 2 ) {
323
308
 
324
309
  if ( d0 >= distances[ i ] && d1 <= distances[ i + 1 ] ) {
@@ -348,14 +333,13 @@
348
333
 
349
334
  }
350
335
 
351
- } // Iterate until we've tried to connect all faces to share normals
352
-
336
+ }
353
337
 
338
+ // Iterate until we've tried to connect all faces to share normals
354
339
  while ( true ) {
355
340
 
356
341
  // Stop if there are no more faces left
357
342
  let halfEdge = null;
358
-
359
343
  for ( const key in halfEdgeList ) {
360
344
 
361
345
  halfEdge = halfEdgeList[ key ];
@@ -367,62 +351,61 @@
367
351
 
368
352
  break;
369
353
 
370
- } // Exhaustively find all connected faces
371
-
354
+ }
372
355
 
356
+ // Exhaustively find all connected faces
373
357
  const queue = [ halfEdge ];
374
-
375
358
  while ( queue.length > 0 ) {
376
359
 
377
360
  // initialize all vertex normals in this triangle
378
361
  const tri = queue.pop().tri;
379
362
  const vertices = tri.vertices;
380
363
  const vertNormals = tri.normals;
381
- const faceNormal = tri.faceNormal; // Check if any edge is connected to another triangle edge
364
+ const faceNormal = tri.faceNormal;
382
365
 
366
+ // Check if any edge is connected to another triangle edge
383
367
  const vertCount = vertices.length;
384
-
385
368
  for ( let i2 = 0; i2 < vertCount; i2 ++ ) {
386
369
 
387
370
  const index = i2;
388
371
  const next = ( i2 + 1 ) % vertCount;
389
372
  const v0 = vertices[ index ];
390
- const v1 = vertices[ next ]; // delete this triangle from the list so it won't be found again
373
+ const v1 = vertices[ next ];
391
374
 
375
+ // delete this triangle from the list so it won't be found again
392
376
  const hash = hashEdge( v0, v1 );
393
377
  delete halfEdgeList[ hash ];
394
378
  const reverseHash = hashEdge( v1, v0 );
395
379
  const otherInfo = halfEdgeList[ reverseHash ];
396
-
397
380
  if ( otherInfo ) {
398
381
 
399
382
  const otherTri = otherInfo.tri;
400
383
  const otherIndex = otherInfo.index;
401
384
  const otherNormals = otherTri.normals;
402
385
  const otherVertCount = otherNormals.length;
403
- const otherFaceNormal = otherTri.faceNormal; // NOTE: If the angle between faces is > 67.5 degrees then assume it's
386
+ const otherFaceNormal = otherTri.faceNormal;
387
+
388
+ // NOTE: If the angle between faces is > 67.5 degrees then assume it's
404
389
  // hard edge. There are some cases where the line segments do not line up exactly
405
390
  // with or span multiple triangle edges (see Lunar Vehicle wheels).
406
-
407
391
  if ( Math.abs( otherTri.faceNormal.dot( tri.faceNormal ) ) < 0.25 ) {
408
392
 
409
393
  continue;
410
394
 
411
- } // if this triangle has already been traversed then it won't be in
395
+ }
396
+
397
+ // if this triangle has already been traversed then it won't be in
412
398
  // the halfEdgeList. If it has not then add it to the queue and delete
413
399
  // it so it won't be found again.
414
-
415
-
416
400
  if ( reverseHash in halfEdgeList ) {
417
401
 
418
402
  queue.push( otherInfo );
419
403
  delete halfEdgeList[ reverseHash ];
420
404
 
421
- } // share the first normal
422
-
405
+ }
423
406
 
407
+ // share the first normal
424
408
  const otherNext = ( otherIndex + 1 ) % otherVertCount;
425
-
426
409
  if ( vertNormals[ index ] && otherNormals[ otherNext ] && vertNormals[ index ] !== otherNormals[ otherNext ] ) {
427
410
 
428
411
  otherNormals[ otherNext ].norm.add( vertNormals[ index ].norm );
@@ -431,7 +414,6 @@
431
414
  }
432
415
 
433
416
  let sharedNormal1 = vertNormals[ index ] || otherNormals[ otherNext ];
434
-
435
417
  if ( sharedNormal1 === null ) {
436
418
 
437
419
  // it's possible to encounter an edge of a triangle that has already been traversed meaning
@@ -456,9 +438,9 @@
456
438
  otherNormals[ otherNext ] = sharedNormal1;
457
439
  sharedNormal1.norm.add( otherFaceNormal );
458
440
 
459
- } // share the second normal
460
-
441
+ }
461
442
 
443
+ // share the second normal
462
444
  if ( vertNormals[ next ] && otherNormals[ otherIndex ] && vertNormals[ next ] !== otherNormals[ otherIndex ] ) {
463
445
 
464
446
  otherNormals[ otherIndex ].norm.add( vertNormals[ next ].norm );
@@ -467,7 +449,6 @@
467
449
  }
468
450
 
469
451
  let sharedNormal2 = vertNormals[ next ] || otherNormals[ otherIndex ];
470
-
471
452
  if ( sharedNormal2 === null ) {
472
453
 
473
454
  sharedNormal2 = {
@@ -497,9 +478,9 @@
497
478
 
498
479
  }
499
480
 
500
- } // The normals of each face have been added up so now we average them by normalizing the vector.
501
-
481
+ }
502
482
 
483
+ // The normals of each face have been added up so now we average them by normalizing the vector.
503
484
  for ( let i = 0, l = normals.length; i < l; i ++ ) {
504
485
 
505
486
  normals[ i ].normalize();
@@ -531,13 +512,11 @@
531
512
  this.lineNumber = lineNumber;
532
513
 
533
514
  }
534
-
535
515
  seekNonSpace() {
536
516
 
537
517
  while ( this.currentCharIndex < this.lineLength ) {
538
518
 
539
519
  this.currentChar = this.line.charAt( this.currentCharIndex );
540
-
541
520
  if ( this.currentChar !== ' ' && this.currentChar !== '\t' ) {
542
521
 
543
522
  return;
@@ -549,15 +528,14 @@
549
528
  }
550
529
 
551
530
  }
552
-
553
531
  getToken() {
554
532
 
555
- const pos0 = this.currentCharIndex ++; // Seek space
533
+ const pos0 = this.currentCharIndex ++;
556
534
 
535
+ // Seek space
557
536
  while ( this.currentCharIndex < this.lineLength ) {
558
537
 
559
538
  this.currentChar = this.line.charAt( this.currentCharIndex );
560
-
561
539
  if ( this.currentChar === ' ' || this.currentChar === '\t' ) {
562
540
 
563
541
  break;
@@ -573,40 +551,35 @@
573
551
  return this.line.substring( pos0, pos1 );
574
552
 
575
553
  }
576
-
577
554
  getVector() {
578
555
 
579
556
  return new THREE.Vector3( parseFloat( this.getToken() ), parseFloat( this.getToken() ), parseFloat( this.getToken() ) );
580
557
 
581
558
  }
582
-
583
559
  getRemainingString() {
584
560
 
585
561
  return this.line.substring( this.currentCharIndex, this.lineLength );
586
562
 
587
563
  }
588
-
589
564
  isAtTheEnd() {
590
565
 
591
566
  return this.currentCharIndex >= this.lineLength;
592
567
 
593
568
  }
594
-
595
569
  setToEnd() {
596
570
 
597
571
  this.currentCharIndex = this.lineLength;
598
572
 
599
573
  }
600
-
601
574
  getLineNumberString() {
602
575
 
603
576
  return this.lineNumber >= 0 ? ' at line ' + this.lineNumber : '';
604
577
 
605
578
  }
606
579
 
607
- } // Fetches and parses an intermediate representation of LDraw parts files.
608
-
580
+ }
609
581
 
582
+ // Fetches and parses an intermediate representation of LDraw parts files.
610
583
  class LDrawParsedCache {
611
584
 
612
585
  constructor( loader ) {
@@ -615,12 +588,12 @@
615
588
  this._cache = {};
616
589
 
617
590
  }
618
-
619
591
  cloneResult( original ) {
620
592
 
621
- const result = {}; // vertices are transformed and normals computed before being converted to geometry
622
- // so these pieces must be cloned.
593
+ const result = {};
623
594
 
595
+ // vertices are transformed and normals computed before being converted to geometry
596
+ // so these pieces must be cloned.
624
597
  result.faces = original.faces.map( face => {
625
598
 
626
599
  return {
@@ -650,55 +623,50 @@
650
623
  vertices: face.vertices.map( v => v.clone() )
651
624
  };
652
625
 
653
- } ); // none if this is subsequently modified
626
+ } );
654
627
 
628
+ // none if this is subsequently modified
655
629
  result.type = original.type;
656
630
  result.category = original.category;
657
631
  result.keywords = original.keywords;
632
+ result.author = original.author;
658
633
  result.subobjects = original.subobjects;
634
+ result.fileName = original.fileName;
659
635
  result.totalFaces = original.totalFaces;
660
- result.startingConstructionStep = original.startingConstructionStep;
636
+ result.startingBuildingStep = original.startingBuildingStep;
661
637
  result.materials = original.materials;
662
638
  result.group = null;
663
639
  return result;
664
640
 
665
641
  }
666
-
667
642
  async fetchData( fileName ) {
668
643
 
669
644
  let triedLowerCase = false;
670
- let locationState = FILE_LOCATION_AS_IS;
671
-
645
+ let locationState = FILE_LOCATION_TRY_PARTS;
672
646
  while ( locationState !== FILE_LOCATION_NOT_FOUND ) {
673
647
 
674
648
  let subobjectURL = fileName;
675
-
676
649
  switch ( locationState ) {
677
650
 
678
651
  case FILE_LOCATION_AS_IS:
679
652
  locationState = locationState + 1;
680
653
  break;
681
-
682
654
  case FILE_LOCATION_TRY_PARTS:
683
655
  subobjectURL = 'parts/' + subobjectURL;
684
656
  locationState = locationState + 1;
685
657
  break;
686
-
687
658
  case FILE_LOCATION_TRY_P:
688
659
  subobjectURL = 'p/' + subobjectURL;
689
660
  locationState = locationState + 1;
690
661
  break;
691
-
692
662
  case FILE_LOCATION_TRY_MODELS:
693
663
  subobjectURL = 'models/' + subobjectURL;
694
664
  locationState = locationState + 1;
695
665
  break;
696
-
697
666
  case FILE_LOCATION_TRY_RELATIVE:
698
667
  subobjectURL = fileName.substring( 0, fileName.lastIndexOf( '/' ) + 1 ) + subobjectURL;
699
668
  locationState = locationState + 1;
700
669
  break;
701
-
702
670
  case FILE_LOCATION_TRY_ABSOLUTE:
703
671
  if ( triedLowerCase ) {
704
672
 
@@ -711,7 +679,7 @@
711
679
  fileName = fileName.toLowerCase();
712
680
  subobjectURL = fileName;
713
681
  triedLowerCase = true;
714
- locationState = FILE_LOCATION_AS_IS;
682
+ locationState = FILE_LOCATION_TRY_PARTS;
715
683
 
716
684
  }
717
685
 
@@ -724,7 +692,6 @@
724
692
  fileLoader.setPath( loader.partsLibraryPath );
725
693
  fileLoader.setRequestHeader( loader.requestHeader );
726
694
  fileLoader.setWithCredentials( loader.withCredentials );
727
-
728
695
  try {
729
696
 
730
697
  const text = await fileLoader.loadAsync( subobjectURL );
@@ -741,17 +708,16 @@
741
708
  throw new Error( 'LDrawLoader: Subobject "' + fileName + '" could not be loaded.' );
742
709
 
743
710
  }
744
-
745
711
  parse( text, fileName = null ) {
746
712
 
747
- const loader = this.loader; // final results
713
+ const loader = this.loader;
748
714
 
715
+ // final results
749
716
  const faces = [];
750
717
  const lineSegments = [];
751
718
  const conditionalSegments = [];
752
719
  const subobjects = [];
753
720
  const materials = {};
754
-
755
721
  const getLocalMaterial = colorCode => {
756
722
 
757
723
  return materials[ colorCode ] || null;
@@ -761,8 +727,10 @@
761
727
  let type = 'Model';
762
728
  let category = null;
763
729
  let keywords = null;
764
- let totalFaces = 0; // split into lines
730
+ let author = null;
731
+ let totalFaces = 0;
765
732
 
733
+ // split into lines
766
734
  if ( text.indexOf( '\r\n' ) !== - 1 ) {
767
735
 
768
736
  // This is faster than String.split with regex that splits on both
@@ -779,20 +747,21 @@
779
747
  let bfcCCW = true;
780
748
  let bfcInverted = false;
781
749
  let bfcCull = true;
782
- let startingConstructionStep = false; // Parse all line commands
750
+ let startingBuildingStep = false;
783
751
 
752
+ // Parse all line commands
784
753
  for ( let lineIndex = 0; lineIndex < numLines; lineIndex ++ ) {
785
754
 
786
755
  const line = lines[ lineIndex ];
787
756
  if ( line.length === 0 ) continue;
788
-
789
757
  if ( parsingEmbeddedFiles ) {
790
758
 
791
759
  if ( line.startsWith( '0 FILE ' ) ) {
792
760
 
793
761
  // Save previous embedded file in the cache
794
- this.setData( currentEmbeddedFileName, currentEmbeddedText ); // New embedded text file
762
+ this.setData( currentEmbeddedFileName, currentEmbeddedText );
795
763
 
764
+ // New embedded text file
796
765
  currentEmbeddedFileName = line.substring( 7 );
797
766
  currentEmbeddedText = '';
798
767
 
@@ -808,15 +777,14 @@
808
777
 
809
778
  const lp = new LineParser( line, lineIndex + 1 );
810
779
  lp.seekNonSpace();
811
-
812
780
  if ( lp.isAtTheEnd() ) {
813
781
 
814
782
  // Empty line
815
783
  continue;
816
784
 
817
- } // Parse the line type
818
-
785
+ }
819
786
 
787
+ // Parse the line type
820
788
  const lineType = lp.getToken();
821
789
  let material;
822
790
  let colorCode;
@@ -824,14 +792,12 @@
824
792
  let ccw;
825
793
  let doubleSided;
826
794
  let v0, v1, v2, v3, c0, c1;
827
-
828
795
  switch ( lineType ) {
829
796
 
830
797
  // Line type 0: Comment or META
831
798
  case '0':
832
799
  // Parse meta directive
833
800
  const meta = lp.getToken();
834
-
835
801
  if ( meta ) {
836
802
 
837
803
  switch ( meta ) {
@@ -839,10 +805,8 @@
839
805
  case '!LDRAW_ORG':
840
806
  type = lp.getToken();
841
807
  break;
842
-
843
808
  case '!COLOUR':
844
809
  material = loader.parseColorMetaDirective( lp );
845
-
846
810
  if ( material ) {
847
811
 
848
812
  materials[ material.userData.code ] = material;
@@ -854,14 +818,11 @@
854
818
  }
855
819
 
856
820
  break;
857
-
858
821
  case '!CATEGORY':
859
822
  category = lp.getToken();
860
823
  break;
861
-
862
824
  case '!KEYWORDS':
863
825
  const newKeywords = lp.getRemainingString().split( ',' );
864
-
865
826
  if ( newKeywords.length > 0 ) {
866
827
 
867
828
  if ( ! keywords ) {
@@ -879,7 +840,6 @@
879
840
  }
880
841
 
881
842
  break;
882
-
883
843
  case 'FILE':
884
844
  if ( lineIndex > 0 ) {
885
845
 
@@ -893,13 +853,11 @@
893
853
  }
894
854
 
895
855
  break;
896
-
897
856
  case 'BFC':
898
857
  // Changes to the backface culling state
899
858
  while ( ! lp.isAtTheEnd() ) {
900
859
 
901
860
  const token = lp.getToken();
902
-
903
861
  switch ( token ) {
904
862
 
905
863
  case 'CERTIFY':
@@ -907,21 +865,17 @@
907
865
  bfcCertified = token === 'CERTIFY';
908
866
  bfcCCW = true;
909
867
  break;
910
-
911
868
  case 'CW':
912
869
  case 'CCW':
913
870
  bfcCCW = token === 'CCW';
914
871
  break;
915
-
916
872
  case 'INVERTNEXT':
917
873
  bfcInverted = true;
918
874
  break;
919
-
920
875
  case 'CLIP':
921
876
  case 'NOCLIP':
922
877
  bfcCull = token === 'CLIP';
923
878
  break;
924
-
925
879
  default:
926
880
  console.warn( 'THREE.LDrawLoader: BFC directive "' + token + '" is unknown.' );
927
881
  break;
@@ -931,11 +885,12 @@
931
885
  }
932
886
 
933
887
  break;
934
-
935
888
  case 'STEP':
936
- startingConstructionStep = true;
889
+ startingBuildingStep = true;
890
+ break;
891
+ case 'Author:':
892
+ author = lp.getToken();
937
893
  break;
938
-
939
894
  default:
940
895
  // Other meta directives are not implemented
941
896
  break;
@@ -945,8 +900,8 @@
945
900
  }
946
901
 
947
902
  break;
948
- // Line type 1: Sub-object file
949
903
 
904
+ // Line type 1: Sub-object file
950
905
  case '1':
951
906
  colorCode = lp.getToken();
952
907
  material = getLocalMaterial( colorCode );
@@ -964,7 +919,6 @@
964
919
  const m8 = parseFloat( lp.getToken() );
965
920
  const matrix = new THREE.Matrix4().set( m0, m1, m2, posX, m3, m4, m5, posY, m6, m7, m8, posZ, 0, 0, 0, 1 );
966
921
  let fileName = lp.getRemainingString().trim().replace( /\\/g, '/' );
967
-
968
922
  if ( loader.fileMap[ fileName ] ) {
969
923
 
970
924
  // Found the subobject path in the preloaded file path map
@@ -991,12 +945,13 @@
991
945
  matrix: matrix,
992
946
  fileName: fileName,
993
947
  inverted: bfcInverted,
994
- startingConstructionStep: startingConstructionStep
948
+ startingBuildingStep: startingBuildingStep
995
949
  } );
950
+ startingBuildingStep = false;
996
951
  bfcInverted = false;
997
952
  break;
998
- // Line type 2: Line segment
999
953
 
954
+ // Line type 2: Line segment
1000
955
  case '2':
1001
956
  colorCode = lp.getToken();
1002
957
  material = getLocalMaterial( colorCode );
@@ -1009,8 +964,8 @@
1009
964
  };
1010
965
  lineSegments.push( segment );
1011
966
  break;
1012
- // Line type 5: Conditional Line segment
1013
967
 
968
+ // Line type 5: Conditional Line segment
1014
969
  case '5':
1015
970
  colorCode = lp.getToken();
1016
971
  material = getLocalMaterial( colorCode );
@@ -1026,14 +981,13 @@
1026
981
  };
1027
982
  conditionalSegments.push( segment );
1028
983
  break;
1029
- // Line type 3: Triangle
1030
984
 
985
+ // Line type 3: Triangle
1031
986
  case '3':
1032
987
  colorCode = lp.getToken();
1033
988
  material = getLocalMaterial( colorCode );
1034
989
  ccw = bfcCCW;
1035
990
  doubleSided = ! bfcCertified || ! bfcCull;
1036
-
1037
991
  if ( ccw === true ) {
1038
992
 
1039
993
  v0 = lp.getVector();
@@ -1056,7 +1010,6 @@
1056
1010
  normals: [ null, null, null ]
1057
1011
  } );
1058
1012
  totalFaces ++;
1059
-
1060
1013
  if ( doubleSided === true ) {
1061
1014
 
1062
1015
  faces.push( {
@@ -1071,14 +1024,13 @@
1071
1024
  }
1072
1025
 
1073
1026
  break;
1074
- // Line type 4: Quadrilateral
1075
1027
 
1028
+ // Line type 4: Quadrilateral
1076
1029
  case '4':
1077
1030
  colorCode = lp.getToken();
1078
1031
  material = getLocalMaterial( colorCode );
1079
1032
  ccw = bfcCCW;
1080
1033
  doubleSided = ! bfcCertified || ! bfcCull;
1081
-
1082
1034
  if ( ccw === true ) {
1083
1035
 
1084
1036
  v0 = lp.getVector();
@@ -1093,10 +1045,10 @@
1093
1045
  v1 = lp.getVector();
1094
1046
  v0 = lp.getVector();
1095
1047
 
1096
- } // specifically place the triangle diagonal in the v0 and v1 slots so we can
1097
- // account for the doubling of vertices later when smoothing normals.
1098
-
1048
+ }
1099
1049
 
1050
+ // specifically place the triangle diagonal in the v0 and v1 slots so we can
1051
+ // account for the doubling of vertices later when smoothing normals.
1100
1052
  faces.push( {
1101
1053
  material: material,
1102
1054
  colorCode: colorCode,
@@ -1105,7 +1057,6 @@
1105
1057
  normals: [ null, null, null, null ]
1106
1058
  } );
1107
1059
  totalFaces += 2;
1108
-
1109
1060
  if ( doubleSided === true ) {
1110
1061
 
1111
1062
  faces.push( {
@@ -1120,7 +1071,6 @@
1120
1071
  }
1121
1072
 
1122
1073
  break;
1123
-
1124
1074
  default:
1125
1075
  throw new Error( 'LDrawLoader: Unknown line type "' + lineType + '"' + lp.getLineNumberString() + '.' );
1126
1076
 
@@ -1141,22 +1091,22 @@
1141
1091
  type,
1142
1092
  category,
1143
1093
  keywords,
1094
+ author,
1144
1095
  subobjects,
1145
1096
  totalFaces,
1146
- startingConstructionStep,
1097
+ startingBuildingStep,
1147
1098
  materials,
1148
1099
  fileName,
1149
1100
  group: null
1150
1101
  };
1151
1102
 
1152
- } // returns an (optionally cloned) instance of the data
1153
-
1103
+ }
1154
1104
 
1105
+ // returns an (optionally cloned) instance of the data
1155
1106
  getData( fileName, clone = true ) {
1156
1107
 
1157
1108
  const key = fileName.toLowerCase();
1158
1109
  const result = this._cache[ key ];
1159
-
1160
1110
  if ( result === null || result instanceof Promise ) {
1161
1111
 
1162
1112
  return null;
@@ -1173,14 +1123,13 @@
1173
1123
 
1174
1124
  }
1175
1125
 
1176
- } // kicks off a fetch and parse of the requested data if it hasn't already been loaded. Returns when
1177
- // the data is ready to use and can be retrieved synchronously with "getData".
1178
-
1126
+ }
1179
1127
 
1128
+ // kicks off a fetch and parse of the requested data if it hasn't already been loaded. Returns when
1129
+ // the data is ready to use and can be retrieved synchronously with "getData".
1180
1130
  async ensureDataLoaded( fileName ) {
1181
1131
 
1182
1132
  const key = fileName.toLowerCase();
1183
-
1184
1133
  if ( ! ( key in this._cache ) ) {
1185
1134
 
1186
1135
  // replace the promise with a copy of the parsed data for immediate processing
@@ -1196,9 +1145,9 @@
1196
1145
 
1197
1146
  await this._cache[ key ];
1198
1147
 
1199
- } // sets the data in the cache from parsed data
1200
-
1148
+ }
1201
1149
 
1150
+ // sets the data in the cache from parsed data
1202
1151
  setData( fileName, text ) {
1203
1152
 
1204
1153
  const key = fileName.toLowerCase();
@@ -1206,14 +1155,13 @@
1206
1155
 
1207
1156
  }
1208
1157
 
1209
- } // returns the material for an associated color code. If the color code is 16 for a face or 24 for
1210
- // an edge then the passthroughColorCode is used.
1211
-
1158
+ }
1212
1159
 
1160
+ // returns the material for an associated color code. If the color code is 16 for a face or 24 for
1161
+ // an edge then the passthroughColorCode is used.
1213
1162
  function getMaterialFromCode( colorCode, parentColorCode, materialHierarchy, forEdge ) {
1214
1163
 
1215
1164
  const isPassthrough = ! forEdge && colorCode === MAIN_COLOUR_CODE || forEdge && colorCode === MAIN_EDGE_COLOUR_CODE;
1216
-
1217
1165
  if ( isPassthrough ) {
1218
1166
 
1219
1167
  colorCode = parentColorCode;
@@ -1222,9 +1170,9 @@
1222
1170
 
1223
1171
  return materialHierarchy[ colorCode ] || null;
1224
1172
 
1225
- } // Class used to parse and build LDraw parts as three.js objects and cache them if they're a "Part" type.
1226
-
1173
+ }
1227
1174
 
1175
+ // Class used to parse and build LDraw parts as three.js objects and cache them if they're a "Part" type.
1228
1176
  class LDrawPartsGeometryCache {
1229
1177
 
1230
1178
  constructor( loader ) {
@@ -1233,29 +1181,30 @@
1233
1181
  this.parseCache = new LDrawParsedCache( loader );
1234
1182
  this._cache = {};
1235
1183
 
1236
- } // Convert the given file information into a mesh by processing subobjects.
1237
-
1184
+ }
1238
1185
 
1186
+ // Convert the given file information into a mesh by processing subobjects.
1239
1187
  async processIntoMesh( info ) {
1240
1188
 
1241
1189
  const loader = this.loader;
1242
1190
  const parseCache = this.parseCache;
1243
- const faceMaterials = new Set(); // Processes the part subobject information to load child parts and merge geometry onto part
1244
- // piece object.
1191
+ const faceMaterials = new Set();
1245
1192
 
1193
+ // Processes the part subobject information to load child parts and merge geometry onto part
1194
+ // piece object.
1246
1195
  const processInfoSubobjects = async ( info, subobject = null ) => {
1247
1196
 
1248
1197
  const subobjects = info.subobjects;
1249
- const promises = []; // Trigger load of all subobjects. If a subobject isn't a primitive then load it as a separate
1250
- // group which lets instruction steps apply correctly.
1198
+ const promises = [];
1251
1199
 
1200
+ // Trigger load of all subobjects. If a subobject isn't a primitive then load it as a separate
1201
+ // group which lets instruction steps apply correctly.
1252
1202
  for ( let i = 0, l = subobjects.length; i < l; i ++ ) {
1253
1203
 
1254
1204
  const subobject = subobjects[ i ];
1255
1205
  const promise = parseCache.ensureDataLoaded( subobject.fileName ).then( () => {
1256
1206
 
1257
1207
  const subobjectInfo = parseCache.getData( subobject.fileName, false );
1258
-
1259
1208
  if ( ! isPrimitiveType( subobjectInfo.type ) ) {
1260
1209
 
1261
1210
  return this.loadModel( subobject.fileName ).catch( error => {
@@ -1277,43 +1226,45 @@
1277
1226
  const group = new THREE.Group();
1278
1227
  group.userData.category = info.category;
1279
1228
  group.userData.keywords = info.keywords;
1229
+ group.userData.author = info.author;
1230
+ group.userData.type = info.type;
1231
+ group.userData.fileName = info.fileName;
1280
1232
  info.group = group;
1281
1233
  const subobjectInfos = await Promise.all( promises );
1282
-
1283
1234
  for ( let i = 0, l = subobjectInfos.length; i < l; i ++ ) {
1284
1235
 
1285
1236
  const subobject = info.subobjects[ i ];
1286
1237
  const subobjectInfo = subobjectInfos[ i ];
1287
-
1288
1238
  if ( subobjectInfo === null ) {
1289
1239
 
1290
1240
  // the subobject failed to load
1291
1241
  continue;
1292
1242
 
1293
- } // if the subobject was loaded as a separate group then apply the parent scopes materials
1294
-
1243
+ }
1295
1244
 
1245
+ // if the subobject was loaded as a separate group then apply the parent scopes materials
1296
1246
  if ( subobjectInfo.isGroup ) {
1297
1247
 
1298
1248
  const subobjectGroup = subobjectInfo;
1299
1249
  subobject.matrix.decompose( subobjectGroup.position, subobjectGroup.quaternion, subobjectGroup.scale );
1300
- subobjectGroup.userData.startingConstructionStep = subobject.startingConstructionStep;
1250
+ subobjectGroup.userData.startingBuildingStep = subobject.startingBuildingStep;
1301
1251
  subobjectGroup.name = subobject.fileName;
1302
1252
  loader.applyMaterialsToMesh( subobjectGroup, subobject.colorCode, info.materials );
1253
+ subobjectGroup.userData.colorCode = subobject.colorCode;
1303
1254
  group.add( subobjectGroup );
1304
1255
  continue;
1305
1256
 
1306
- } // add the subobject group if it has children in case it has both children and primitives
1307
-
1257
+ }
1308
1258
 
1259
+ // add the subobject group if it has children in case it has both children and primitives
1309
1260
  if ( subobjectInfo.group.children.length ) {
1310
1261
 
1311
1262
  group.add( subobjectInfo.group );
1312
1263
 
1313
- } // transform the primitives into the local space of the parent piece and append them to
1314
- // to the parent primitives list.
1315
-
1264
+ }
1316
1265
 
1266
+ // transform the primitives into the local space of the parent piece and append them to
1267
+ // to the parent primitives list.
1317
1268
  const parentLineSegments = info.lineSegments;
1318
1269
  const parentConditionalSegments = info.conditionalSegments;
1319
1270
  const parentFaces = info.faces;
@@ -1325,7 +1276,6 @@
1325
1276
  const matrixScaleInverted = matrix.determinant() < 0;
1326
1277
  const colorCode = subobject.colorCode;
1327
1278
  const lineColorCode = colorCode === MAIN_COLOUR_CODE ? MAIN_EDGE_COLOUR_CODE : colorCode;
1328
-
1329
1279
  for ( let i = 0, l = lineSegments.length; i < l; i ++ ) {
1330
1280
 
1331
1281
  const ls = lineSegments[ i ];
@@ -1357,7 +1307,6 @@
1357
1307
 
1358
1308
  const tri = faces[ i ];
1359
1309
  const vertices = tri.vertices;
1360
-
1361
1310
  for ( let i = 0, l = vertices.length; i < l; i ++ ) {
1362
1311
 
1363
1312
  vertices[ i ].applyMatrix4( matrix );
@@ -1366,9 +1315,10 @@
1366
1315
 
1367
1316
  tri.colorCode = tri.colorCode === MAIN_COLOUR_CODE ? colorCode : tri.colorCode;
1368
1317
  tri.material = tri.material || getMaterialFromCode( tri.colorCode, colorCode, info.materials, false );
1369
- faceMaterials.add( tri.colorCode ); // If the scale of the object is negated then the triangle winding order
1370
- // needs to be flipped.
1318
+ faceMaterials.add( tri.colorCode );
1371
1319
 
1320
+ // If the scale of the object is negated then the triangle winding order
1321
+ // needs to be flipped.
1372
1322
  if ( matrixScaleInverted !== inverted ) {
1373
1323
 
1374
1324
  vertices.reverse();
@@ -1381,21 +1331,22 @@
1381
1331
 
1382
1332
  info.totalFaces += subobjectInfo.totalFaces;
1383
1333
 
1384
- } // Apply the parent subobjects pass through material code to this object. This is done several times due
1385
- // to material scoping.
1386
-
1334
+ }
1387
1335
 
1336
+ // Apply the parent subobjects pass through material code to this object. This is done several times due
1337
+ // to material scoping.
1388
1338
  if ( subobject ) {
1389
1339
 
1390
1340
  loader.applyMaterialsToMesh( group, subobject.colorCode, info.materials );
1341
+ group.userData.colorCode = subobject.colorCode;
1391
1342
 
1392
1343
  }
1393
1344
 
1394
1345
  return info;
1395
1346
 
1396
- }; // Track material use to see if we need to use the normal smooth slow path for hard edges.
1397
-
1347
+ };
1398
1348
 
1349
+ // Track material use to see if we need to use the normal smooth slow path for hard edges.
1399
1350
  for ( let i = 0, l = info.faces; i < l; i ++ ) {
1400
1351
 
1401
1352
  faceMaterials.add( info.faces[ i ].colorCode );
@@ -1403,18 +1354,16 @@
1403
1354
  }
1404
1355
 
1405
1356
  await processInfoSubobjects( info );
1406
-
1407
1357
  if ( loader.smoothNormals ) {
1408
1358
 
1409
1359
  const checkSubSegments = faceMaterials.size > 1;
1410
1360
  generateFaceNormals( info.faces );
1411
1361
  smoothNormals( info.faces, info.lineSegments, checkSubSegments );
1412
1362
 
1413
- } // Add the primitive objects and metadata.
1414
-
1363
+ }
1415
1364
 
1365
+ // Add the primitive objects and metadata.
1416
1366
  const group = info.group;
1417
-
1418
1367
  if ( info.faces.length > 0 ) {
1419
1368
 
1420
1369
  group.add( createObject( info.faces, 3, false, info.totalFaces ) );
@@ -1436,13 +1385,11 @@
1436
1385
  return group;
1437
1386
 
1438
1387
  }
1439
-
1440
1388
  hasCachedModel( fileName ) {
1441
1389
 
1442
1390
  return fileName !== null && fileName.toLowerCase() in this._cache;
1443
1391
 
1444
1392
  }
1445
-
1446
1393
  async getCachedModel( fileName ) {
1447
1394
 
1448
1395
  if ( fileName !== null && this.hasCachedModel( fileName ) ) {
@@ -1457,14 +1404,13 @@
1457
1404
 
1458
1405
  }
1459
1406
 
1460
- } // Loads and parses the model with the given file name. Returns a cached copy if available.
1461
-
1407
+ }
1462
1408
 
1409
+ // Loads and parses the model with the given file name. Returns a cached copy if available.
1463
1410
  async loadModel( fileName ) {
1464
1411
 
1465
1412
  const parseCache = this.parseCache;
1466
1413
  const key = fileName.toLowerCase();
1467
-
1468
1414
  if ( this.hasCachedModel( fileName ) ) {
1469
1415
 
1470
1416
  // Return cached model if available.
@@ -1476,37 +1422,37 @@
1476
1422
  // Ensure the file data is loaded and pre parsed.
1477
1423
  await parseCache.ensureDataLoaded( fileName );
1478
1424
  const info = parseCache.getData( fileName );
1479
- const promise = this.processIntoMesh( info ); // Now that the file has loaded it's possible that another part parse has been waiting in parallel
1425
+ const promise = this.processIntoMesh( info );
1426
+
1427
+ // Now that the file has loaded it's possible that another part parse has been waiting in parallel
1480
1428
  // so check the cache again to see if it's been added since the last async operation so we don't
1481
1429
  // do unnecessary work.
1482
-
1483
1430
  if ( this.hasCachedModel( fileName ) ) {
1484
1431
 
1485
1432
  return this.getCachedModel( fileName );
1486
1433
 
1487
- } // Cache object if it's a part so it can be reused later.
1488
-
1434
+ }
1489
1435
 
1436
+ // Cache object if it's a part so it can be reused later.
1490
1437
  if ( isPartType( info.type ) ) {
1491
1438
 
1492
1439
  this._cache[ key ] = promise;
1493
1440
 
1494
- } // return a copy
1495
-
1441
+ }
1496
1442
 
1443
+ // return a copy
1497
1444
  const group = await promise;
1498
1445
  return group.clone();
1499
1446
 
1500
1447
  }
1501
1448
 
1502
- } // parses the given model text into a renderable object. Returns cached copy if available.
1503
-
1449
+ }
1504
1450
 
1451
+ // parses the given model text into a renderable object. Returns cached copy if available.
1505
1452
  async parseModel( text ) {
1506
1453
 
1507
1454
  const parseCache = this.parseCache;
1508
1455
  const info = parseCache.parse( text );
1509
-
1510
1456
  if ( isPartType( info.type ) && this.hasCachedModel( info.fileName ) ) {
1511
1457
 
1512
1458
  return this.getCachedModel( info.fileName );
@@ -1518,7 +1464,6 @@
1518
1464
  }
1519
1465
 
1520
1466
  }
1521
-
1522
1467
  function sortByMaterial( a, b ) {
1523
1468
 
1524
1469
  if ( a.colorCode === b.colorCode ) {
@@ -1541,9 +1486,9 @@
1541
1486
 
1542
1487
  // Creates a THREE.LineSegments (elementSize = 2) or a THREE.Mesh (elementSize = 3 )
1543
1488
  // With per face / segment material, implemented with mesh groups and materials array
1489
+
1544
1490
  // Sort the faces or line segments by color code to make later the mesh groups
1545
1491
  elements.sort( sortByMaterial );
1546
-
1547
1492
  if ( totalElements === null ) {
1548
1493
 
1549
1494
  totalElements = elements.length;
@@ -1559,12 +1504,10 @@
1559
1504
  let index0 = 0;
1560
1505
  let numGroupVerts = 0;
1561
1506
  let offset = 0;
1562
-
1563
1507
  for ( let iElem = 0, nElem = elements.length; iElem < nElem; iElem ++ ) {
1564
1508
 
1565
1509
  const elem = elements[ iElem ];
1566
1510
  let vertices = elem.vertices;
1567
-
1568
1511
  if ( vertices.length === 4 ) {
1569
1512
 
1570
1513
  quadArray[ 0 ] = vertices[ 0 ];
@@ -1585,9 +1528,9 @@
1585
1528
  positions[ index + 1 ] = v.y;
1586
1529
  positions[ index + 2 ] = v.z;
1587
1530
 
1588
- } // create the normals array if this is a set of faces
1589
-
1531
+ }
1590
1532
 
1533
+ // create the normals array if this is a set of faces
1591
1534
  if ( elementSize === 3 ) {
1592
1535
 
1593
1536
  if ( ! elem.faceNormal ) {
@@ -1595,17 +1538,13 @@
1595
1538
  const v0 = vertices[ 0 ];
1596
1539
  const v1 = vertices[ 1 ];
1597
1540
  const v2 = vertices[ 2 ];
1598
-
1599
1541
  _tempVec0.subVectors( v1, v0 );
1600
-
1601
1542
  _tempVec1.subVectors( v2, v1 );
1602
-
1603
1543
  elem.faceNormal = new THREE.Vector3().crossVectors( _tempVec0, _tempVec1 ).normalize();
1604
1544
 
1605
1545
  }
1606
1546
 
1607
1547
  let elemNormals = elem.normals;
1608
-
1609
1548
  if ( elemNormals.length === 4 ) {
1610
1549
 
1611
1550
  quadArray[ 0 ] = elemNormals[ 0 ];
@@ -1622,7 +1561,6 @@
1622
1561
 
1623
1562
  // use face normal if a vertex normal is not provided
1624
1563
  let n = elem.faceNormal;
1625
-
1626
1564
  if ( elemNormals[ j ] ) {
1627
1565
 
1628
1566
  n = elemNormals[ j ].norm;
@@ -1647,7 +1585,6 @@
1647
1585
  }
1648
1586
 
1649
1587
  const material = elem.material;
1650
-
1651
1588
  if ( material !== null ) {
1652
1589
 
1653
1590
  if ( elementSize === 3 ) {
@@ -1697,7 +1634,6 @@
1697
1634
  }
1698
1635
 
1699
1636
  bufferGeometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
1700
-
1701
1637
  if ( normals !== null ) {
1702
1638
 
1703
1639
  bufferGeometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
@@ -1705,7 +1641,6 @@
1705
1641
  }
1706
1642
 
1707
1643
  let object3d = null;
1708
-
1709
1644
  if ( elementSize === 2 ) {
1710
1645
 
1711
1646
  if ( isConditionalSegments ) {
@@ -1730,7 +1665,6 @@
1730
1665
  const controlArray0 = new Float32Array( elements.length * 3 * 2 );
1731
1666
  const controlArray1 = new Float32Array( elements.length * 3 * 2 );
1732
1667
  const directionArray = new Float32Array( elements.length * 3 * 2 );
1733
-
1734
1668
  for ( let i = 0, l = elements.length; i < l; i ++ ) {
1735
1669
 
1736
1670
  const os = elements[ i ];
@@ -1770,37 +1704,61 @@
1770
1704
 
1771
1705
  return object3d;
1772
1706
 
1773
- } //
1707
+ }
1774
1708
 
1709
+ //
1775
1710
 
1776
1711
  class LDrawLoader extends THREE.Loader {
1777
1712
 
1778
1713
  constructor( manager ) {
1779
1714
 
1780
- super( manager ); // Array of THREE.Material
1715
+ super( manager );
1781
1716
 
1717
+ // Array of THREE.Material
1782
1718
  this.materials = [];
1783
- this.materialLibrary = {}; // This also allows to handle the embedded text files ("0 FILE" lines)
1719
+ this.materialLibrary = {};
1784
1720
 
1785
- this.partsCache = new LDrawPartsGeometryCache( this ); // This object is a map from file names to paths. It agilizes the paths search. If it is not set then files will be searched by trial and error.
1721
+ // This also allows to handle the embedded text files ("0 FILE" lines)
1722
+ this.partsCache = new LDrawPartsGeometryCache( this );
1786
1723
 
1787
- this.fileMap = {}; // Initializes the materials library with default materials
1724
+ // This object is a map from file names to paths. It agilizes the paths search. If it is not set then files will be searched by trial and error.
1725
+ this.fileMap = {};
1788
1726
 
1789
- this.setMaterials( [] ); // If this flag is set to true the vertex normals will be smoothed.
1727
+ // Initializes the materials library with default materials
1728
+ this.setMaterials( [] );
1790
1729
 
1791
- this.smoothNormals = true; // The path to load parts from the LDraw parts library from.
1730
+ // If this flag is set to true the vertex normals will be smoothed.
1731
+ this.smoothNormals = true;
1792
1732
 
1733
+ // The path to load parts from the LDraw parts library from.
1793
1734
  this.partsLibraryPath = '';
1794
1735
 
1795
- }
1736
+ // Material assigned to not available colors for meshes and edges
1737
+ this.missingColorMaterial = new THREE.MeshStandardMaterial( {
1738
+ color: 0xFF00FF,
1739
+ roughness: 0.3,
1740
+ metalness: 0
1741
+ } );
1742
+ this.missingColorMaterial.name = 'Missing material';
1743
+ this.missingEdgeColorMaterial = new THREE.LineBasicMaterial( {
1744
+ color: 0xFF00FF
1745
+ } );
1746
+ this.missingEdgeColorMaterial.name = 'Missing material - Edge';
1747
+ this.missingConditionalEdgeColorMaterial = new LDrawConditionalLineMaterial( {
1748
+ fog: true,
1749
+ color: 0xFF00FF
1750
+ } );
1751
+ this.missingConditionalEdgeColorMaterial.name = 'Missing material - Conditional Edge';
1752
+ this.missingColorMaterial.userData.edgeMaterial = this.missingEdgeColorMaterial;
1753
+ this.missingEdgeColorMaterial.userData.conditionalEdgeMaterial = this.missingConditionalEdgeColorMaterial;
1796
1754
 
1755
+ }
1797
1756
  setPartsLibraryPath( path ) {
1798
1757
 
1799
1758
  this.partsLibraryPath = path;
1800
1759
  return this;
1801
1760
 
1802
1761
  }
1803
-
1804
1762
  async preloadMaterials( url ) {
1805
1763
 
1806
1764
  const fileLoader = new THREE.FileLoader( this.manager );
@@ -1811,11 +1769,9 @@
1811
1769
  const colorLineRegex = /^0 !COLOUR/;
1812
1770
  const lines = text.split( /[\n\r]/g );
1813
1771
  const materials = [];
1814
-
1815
1772
  for ( let i = 0, l = lines.length; i < l; i ++ ) {
1816
1773
 
1817
1774
  const line = lines[ i ];
1818
-
1819
1775
  if ( colorLineRegex.test( line ) ) {
1820
1776
 
1821
1777
  const directive = line.replace( colorLineRegex, '' );
@@ -1829,7 +1785,6 @@
1829
1785
  this.setMaterials( materials );
1830
1786
 
1831
1787
  }
1832
-
1833
1788
  load( url, onLoad, onProgress, onError ) {
1834
1789
 
1835
1790
  const fileLoader = new THREE.FileLoader( this.manager );
@@ -1841,7 +1796,8 @@
1841
1796
  this.partsCache.parseModel( text, this.materialLibrary ).then( group => {
1842
1797
 
1843
1798
  this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true );
1844
- this.computeConstructionSteps( group );
1799
+ this.computeBuildingSteps( group );
1800
+ group.userData.fileName = url;
1845
1801
  onLoad( group );
1846
1802
 
1847
1803
  } ).catch( onError );
@@ -1849,48 +1805,45 @@
1849
1805
  }, onProgress, onError );
1850
1806
 
1851
1807
  }
1852
-
1853
1808
  parse( text, onLoad ) {
1854
1809
 
1855
1810
  this.partsCache.parseModel( text, this.materialLibrary ).then( group => {
1856
1811
 
1857
- this.computeConstructionSteps( group );
1812
+ this.applyMaterialsToMesh( group, MAIN_COLOUR_CODE, this.materialLibrary, true );
1813
+ this.computeBuildingSteps( group );
1814
+ group.userData.fileName = '';
1858
1815
  onLoad( group );
1859
1816
 
1860
1817
  } );
1861
1818
 
1862
1819
  }
1863
-
1864
1820
  setMaterials( materials ) {
1865
1821
 
1866
1822
  this.materialLibrary = {};
1867
1823
  this.materials = [];
1868
-
1869
1824
  for ( let i = 0, l = materials.length; i < l; i ++ ) {
1870
1825
 
1871
1826
  this.addMaterial( materials[ i ] );
1872
1827
 
1873
- } // Add default main triangle and line edge materials (used in pieces that can be colored with a main color)
1874
-
1828
+ }
1875
1829
 
1830
+ // Add default main triangle and line edge materials (used in pieces that can be colored with a main color)
1876
1831
  this.addMaterial( this.parseColorMetaDirective( new LineParser( 'Main_Colour CODE 16 VALUE #FF8080 EDGE #333333' ) ) );
1877
1832
  this.addMaterial( this.parseColorMetaDirective( new LineParser( 'Edge_Colour CODE 24 VALUE #A0A0A0 EDGE #333333' ) ) );
1878
1833
  return this;
1879
1834
 
1880
1835
  }
1881
-
1882
1836
  setFileMap( fileMap ) {
1883
1837
 
1884
1838
  this.fileMap = fileMap;
1885
1839
  return this;
1886
1840
 
1887
1841
  }
1888
-
1889
1842
  addMaterial( material ) {
1890
1843
 
1891
1844
  // Adds a material to the material library which is on top of the parse scopes stack. And also to the materials array
1892
- const matLib = this.materialLibrary;
1893
1845
 
1846
+ const matLib = this.materialLibrary;
1894
1847
  if ( ! matLib[ material.userData.code ] ) {
1895
1848
 
1896
1849
  this.materials.push( material );
@@ -1901,7 +1854,6 @@
1901
1854
  return this;
1902
1855
 
1903
1856
  }
1904
-
1905
1857
  getMaterial( colorCode ) {
1906
1858
 
1907
1859
  if ( colorCode.startsWith( '0x2' ) ) {
@@ -1914,10 +1866,10 @@
1914
1866
 
1915
1867
  return this.materialLibrary[ colorCode ] || null;
1916
1868
 
1917
- } // Applies the appropriate materials to a prebuilt hierarchy of geometry. Assumes that color codes are present
1918
- // in the material array if they need to be filled in.
1919
-
1869
+ }
1920
1870
 
1871
+ // Applies the appropriate materials to a prebuilt hierarchy of geometry. Assumes that color codes are present
1872
+ // in the material array if they need to be filled in.
1921
1873
  applyMaterialsToMesh( group, parentColorCode, materialHierarchy, finalMaterialPass = false ) {
1922
1874
 
1923
1875
  // find any missing materials as indicated by a color code string and replace it with a material from the current material lib
@@ -1947,10 +1899,11 @@
1947
1899
 
1948
1900
  }
1949
1901
 
1950
- } ); // Returns the appropriate material for the object (line or face) given color code. If the code is "pass through"
1902
+ } );
1903
+
1904
+ // Returns the appropriate material for the object (line or face) given color code. If the code is "pass through"
1951
1905
  // (24 for lines, 16 for edges) then the pass through color code is used. If that is also pass through then it's
1952
1906
  // simply returned for the subsequent material application.
1953
-
1954
1907
  function getMaterial( c, colorCode ) {
1955
1908
 
1956
1909
  // if our parent is a passthrough color code and we don't have the current material color available then
@@ -1963,7 +1916,6 @@
1963
1916
 
1964
1917
  const forEdge = c.isLineSegments || c.isConditionalLine;
1965
1918
  const isPassthrough = ! forEdge && colorCode === MAIN_COLOUR_CODE || forEdge && colorCode === MAIN_EDGE_COLOUR_CODE;
1966
-
1967
1919
  if ( isPassthrough ) {
1968
1920
 
1969
1921
  colorCode = parentColorCode;
@@ -1971,7 +1923,6 @@
1971
1923
  }
1972
1924
 
1973
1925
  let material = null;
1974
-
1975
1926
  if ( colorCode in materialHierarchy ) {
1976
1927
 
1977
1928
  material = materialHierarchy[ colorCode ];
@@ -1981,11 +1932,13 @@
1981
1932
  // see if we can get the final material from from the "getMaterial" function which will attempt to
1982
1933
  // parse the "direct" colors
1983
1934
  material = loader.getMaterial( colorCode );
1984
-
1985
1935
  if ( material === null ) {
1986
1936
 
1987
- // otherwise throw an error if this is final opportunity to set the material
1988
- throw new Error( `LDrawLoader: Material properties for code ${colorCode} not available.` );
1937
+ // otherwise throw a warning if this is final opportunity to set the material
1938
+ console.warn( `LDrawLoader: Material properties for code ${colorCode} not available.` );
1939
+
1940
+ // And return the 'missing color' material
1941
+ material = loader.missingColorMaterial;
1989
1942
 
1990
1943
  }
1991
1944
 
@@ -1998,7 +1951,6 @@
1998
1951
  if ( c.isLineSegments ) {
1999
1952
 
2000
1953
  material = material.userData.edgeMaterial;
2001
-
2002
1954
  if ( c.isConditionalLine ) {
2003
1955
 
2004
1956
  material = material.userData.conditionalEdgeMaterial;
@@ -2012,166 +1964,147 @@
2012
1964
  }
2013
1965
 
2014
1966
  }
2015
-
2016
1967
  getMainMaterial() {
2017
1968
 
2018
1969
  return this.getMaterial( MAIN_COLOUR_CODE );
2019
1970
 
2020
1971
  }
2021
-
2022
1972
  getMainEdgeMaterial() {
2023
1973
 
2024
- const mainMat = this.getMainMaterial();
2025
- return mainMat && mainMat.userData ? mainMat.userData.edgeMaterial : null;
1974
+ const mat = this.getMaterial( MAIN_EDGE_COLOUR_CODE );
1975
+ return mat ? mat.userData.edgeMaterial : null;
2026
1976
 
2027
1977
  }
2028
-
2029
1978
  parseColorMetaDirective( lineParser ) {
2030
1979
 
2031
1980
  // Parses a color definition and returns a THREE.Material
2032
- let code = null; // Triangle and line colors
2033
1981
 
1982
+ let code = null;
1983
+
1984
+ // Triangle and line colors
2034
1985
  let color = 0xFF00FF;
2035
- let edgeColor = 0xFF00FF; // Transparency
1986
+ let edgeColor = 0xFF00FF;
2036
1987
 
1988
+ // Transparency
2037
1989
  let alpha = 1;
2038
- let isTransparent = false; // Self-illumination:
2039
-
1990
+ let isTransparent = false;
1991
+ // Self-illumination:
2040
1992
  let luminance = 0;
2041
1993
  let finishType = FINISH_TYPE_DEFAULT;
2042
1994
  let edgeMaterial = null;
2043
1995
  const name = lineParser.getToken();
2044
-
2045
1996
  if ( ! name ) {
2046
1997
 
2047
1998
  throw new Error( 'LDrawLoader: Material name was expected after "!COLOUR tag' + lineParser.getLineNumberString() + '.' );
2048
1999
 
2049
- } // Parse tag tokens and their parameters
2050
-
2000
+ }
2051
2001
 
2002
+ // Parse tag tokens and their parameters
2052
2003
  let token = null;
2053
-
2054
2004
  while ( true ) {
2055
2005
 
2056
2006
  token = lineParser.getToken();
2057
-
2058
2007
  if ( ! token ) {
2059
2008
 
2060
2009
  break;
2061
2010
 
2062
2011
  }
2063
2012
 
2064
- switch ( token.toUpperCase() ) {
2013
+ if ( ! parseLuminance( token ) ) {
2065
2014
 
2066
- case 'CODE':
2067
- code = lineParser.getToken();
2068
- break;
2069
-
2070
- case 'VALUE':
2071
- color = lineParser.getToken();
2015
+ switch ( token.toUpperCase() ) {
2072
2016
 
2073
- if ( color.startsWith( '0x' ) ) {
2017
+ case 'CODE':
2018
+ code = lineParser.getToken();
2019
+ break;
2020
+ case 'VALUE':
2021
+ color = lineParser.getToken();
2022
+ if ( color.startsWith( '0x' ) ) {
2074
2023
 
2075
- color = '#' + color.substring( 2 );
2024
+ color = '#' + color.substring( 2 );
2076
2025
 
2077
- } else if ( ! color.startsWith( '#' ) ) {
2026
+ } else if ( ! color.startsWith( '#' ) ) {
2078
2027
 
2079
- throw new Error( 'LDrawLoader: Invalid color while parsing material' + lineParser.getLineNumberString() + '.' );
2028
+ throw new Error( 'LDrawLoader: Invalid color while parsing material' + lineParser.getLineNumberString() + '.' );
2080
2029
 
2081
- }
2082
-
2083
- break;
2084
-
2085
- case 'EDGE':
2086
- edgeColor = lineParser.getToken();
2087
-
2088
- if ( edgeColor.startsWith( '0x' ) ) {
2089
-
2090
- edgeColor = '#' + edgeColor.substring( 2 );
2091
-
2092
- } else if ( ! edgeColor.startsWith( '#' ) ) {
2093
-
2094
- // Try to see if edge color is a color code
2095
- edgeMaterial = this.getMaterial( edgeColor );
2096
-
2097
- if ( ! edgeMaterial ) {
2098
-
2099
- throw new Error( 'LDrawLoader: Invalid edge color while parsing material' + lineParser.getLineNumberString() + '.' );
2100
-
2101
- } // Get the edge material for this triangle material
2102
-
2103
-
2104
- edgeMaterial = edgeMaterial.userData.edgeMaterial;
2105
-
2106
- }
2107
-
2108
- break;
2109
-
2110
- case 'ALPHA':
2111
- alpha = parseInt( lineParser.getToken() );
2030
+ }
2112
2031
 
2113
- if ( isNaN( alpha ) ) {
2032
+ break;
2033
+ case 'EDGE':
2034
+ edgeColor = lineParser.getToken();
2035
+ if ( edgeColor.startsWith( '0x' ) ) {
2114
2036
 
2115
- throw new Error( 'LDrawLoader: Invalid alpha value in material definition' + lineParser.getLineNumberString() + '.' );
2037
+ edgeColor = '#' + edgeColor.substring( 2 );
2116
2038
 
2117
- }
2039
+ } else if ( ! edgeColor.startsWith( '#' ) ) {
2118
2040
 
2119
- alpha = Math.max( 0, Math.min( 1, alpha / 255 ) );
2041
+ // Try to see if edge color is a color code
2042
+ edgeMaterial = this.getMaterial( edgeColor );
2043
+ if ( ! edgeMaterial ) {
2120
2044
 
2121
- if ( alpha < 1 ) {
2045
+ throw new Error( 'LDrawLoader: Invalid edge color while parsing material' + lineParser.getLineNumberString() + '.' );
2122
2046
 
2123
- isTransparent = true;
2047
+ }
2124
2048
 
2125
- }
2049
+ // Get the edge material for this triangle material
2050
+ edgeMaterial = edgeMaterial.userData.edgeMaterial;
2126
2051
 
2127
- break;
2128
-
2129
- case 'LUMINANCE':
2130
- luminance = parseInt( lineParser.getToken() );
2052
+ }
2131
2053
 
2132
- if ( isNaN( luminance ) ) {
2054
+ break;
2055
+ case 'ALPHA':
2056
+ alpha = parseInt( lineParser.getToken() );
2057
+ if ( isNaN( alpha ) ) {
2133
2058
 
2134
- throw new Error( 'LDrawLoader: Invalid luminance value in material definition' + LineParser.getLineNumberString() + '.' );
2059
+ throw new Error( 'LDrawLoader: Invalid alpha value in material definition' + lineParser.getLineNumberString() + '.' );
2135
2060
 
2136
- }
2061
+ }
2137
2062
 
2138
- luminance = Math.max( 0, Math.min( 1, luminance / 255 ) );
2139
- break;
2063
+ alpha = Math.max( 0, Math.min( 1, alpha / 255 ) );
2064
+ if ( alpha < 1 ) {
2140
2065
 
2141
- case 'CHROME':
2142
- finishType = FINISH_TYPE_CHROME;
2143
- break;
2066
+ isTransparent = true;
2144
2067
 
2145
- case 'PEARLESCENT':
2146
- finishType = FINISH_TYPE_PEARLESCENT;
2147
- break;
2068
+ }
2148
2069
 
2149
- case 'RUBBER':
2150
- finishType = FINISH_TYPE_RUBBER;
2151
- break;
2070
+ break;
2071
+ case 'LUMINANCE':
2072
+ if ( ! parseLuminance( lineParser.getToken() ) ) {
2152
2073
 
2153
- case 'MATTE_METALLIC':
2154
- finishType = FINISH_TYPE_MATTE_METALLIC;
2155
- break;
2074
+ throw new Error( 'LDrawLoader: Invalid luminance value in material definition' + LineParser.getLineNumberString() + '.' );
2156
2075
 
2157
- case 'METAL':
2158
- finishType = FINISH_TYPE_METAL;
2159
- break;
2076
+ }
2160
2077
 
2161
- case 'MATERIAL':
2162
- // Not implemented
2163
- lineParser.setToEnd();
2164
- break;
2078
+ break;
2079
+ case 'CHROME':
2080
+ finishType = FINISH_TYPE_CHROME;
2081
+ break;
2082
+ case 'PEARLESCENT':
2083
+ finishType = FINISH_TYPE_PEARLESCENT;
2084
+ break;
2085
+ case 'RUBBER':
2086
+ finishType = FINISH_TYPE_RUBBER;
2087
+ break;
2088
+ case 'MATTE_METALLIC':
2089
+ finishType = FINISH_TYPE_MATTE_METALLIC;
2090
+ break;
2091
+ case 'METAL':
2092
+ finishType = FINISH_TYPE_METAL;
2093
+ break;
2094
+ case 'MATERIAL':
2095
+ // Not implemented
2096
+ lineParser.setToEnd();
2097
+ break;
2098
+ default:
2099
+ throw new Error( 'LDrawLoader: Unknown token "' + token + '" while parsing material' + lineParser.getLineNumberString() + '.' );
2165
2100
 
2166
- default:
2167
- throw new Error( 'LDrawLoader: Unknown token "' + token + '" while parsing material' + lineParser.getLineNumberString() + '.' );
2101
+ }
2168
2102
 
2169
2103
  }
2170
2104
 
2171
2105
  }
2172
2106
 
2173
2107
  let material = null;
2174
-
2175
2108
  switch ( finishType ) {
2176
2109
 
2177
2110
  case FINISH_TYPE_DEFAULT:
@@ -2181,7 +2114,6 @@
2181
2114
  metalness: 0
2182
2115
  } );
2183
2116
  break;
2184
-
2185
2117
  case FINISH_TYPE_PEARLESCENT:
2186
2118
  // Try to imitate pearlescency by making the surface glossy
2187
2119
  material = new THREE.MeshStandardMaterial( {
@@ -2190,7 +2122,6 @@
2190
2122
  metalness: 0.25
2191
2123
  } );
2192
2124
  break;
2193
-
2194
2125
  case FINISH_TYPE_CHROME:
2195
2126
  // Mirror finish surface
2196
2127
  material = new THREE.MeshStandardMaterial( {
@@ -2199,7 +2130,6 @@
2199
2130
  metalness: 1
2200
2131
  } );
2201
2132
  break;
2202
-
2203
2133
  case FINISH_TYPE_RUBBER:
2204
2134
  // Rubber finish
2205
2135
  material = new THREE.MeshStandardMaterial( {
@@ -2208,7 +2138,6 @@
2208
2138
  metalness: 0
2209
2139
  } );
2210
2140
  break;
2211
-
2212
2141
  case FINISH_TYPE_MATTE_METALLIC:
2213
2142
  // Brushed metal finish
2214
2143
  material = new THREE.MeshStandardMaterial( {
@@ -2217,7 +2146,6 @@
2217
2146
  metalness: 0.4
2218
2147
  } );
2219
2148
  break;
2220
-
2221
2149
  case FINISH_TYPE_METAL:
2222
2150
  // Average metal finish
2223
2151
  material = new THREE.MeshStandardMaterial( {
@@ -2226,7 +2154,6 @@
2226
2154
  metalness: 0.85
2227
2155
  } );
2228
2156
  break;
2229
-
2230
2157
  default:
2231
2158
  // Should not happen
2232
2159
  break;
@@ -2240,7 +2167,6 @@
2240
2167
  material.color.convertSRGBToLinear();
2241
2168
  material.polygonOffset = true;
2242
2169
  material.polygonOffsetFactor = 1;
2243
-
2244
2170
  if ( luminance !== 0 ) {
2245
2171
 
2246
2172
  material.emissive.set( material.color ).multiplyScalar( luminance );
@@ -2258,8 +2184,9 @@
2258
2184
  } );
2259
2185
  edgeMaterial.userData.code = code;
2260
2186
  edgeMaterial.name = name + ' - Edge';
2261
- edgeMaterial.color.convertSRGBToLinear(); // This is the material used for conditional edges
2187
+ edgeMaterial.color.convertSRGBToLinear();
2262
2188
 
2189
+ // This is the material used for conditional edges
2263
2190
  edgeMaterial.userData.conditionalEdgeMaterial = new LDrawConditionalLineMaterial( {
2264
2191
  fog: true,
2265
2192
  transparent: isTransparent,
@@ -2268,6 +2195,8 @@
2268
2195
  opacity: alpha
2269
2196
  } );
2270
2197
  edgeMaterial.userData.conditionalEdgeMaterial.color.convertSRGBToLinear();
2198
+ edgeMaterial.userData.conditionalEdgeMaterial.userData.code = code;
2199
+ edgeMaterial.userData.conditionalEdgeMaterial.name = name + ' - Conditional Edge';
2271
2200
 
2272
2201
  }
2273
2202
 
@@ -2276,29 +2205,54 @@
2276
2205
  material.userData.edgeMaterial = edgeMaterial;
2277
2206
  this.addMaterial( material );
2278
2207
  return material;
2208
+ function parseLuminance( token ) {
2209
+
2210
+ // Returns success
2211
+
2212
+ let lum;
2213
+ if ( token.startsWith( 'LUMINANCE' ) ) {
2214
+
2215
+ lum = parseInt( token.substring( 9 ) );
2216
+
2217
+ } else {
2218
+
2219
+ lum = parseInt( token );
2220
+
2221
+ }
2222
+
2223
+ if ( isNaN( lum ) ) {
2224
+
2225
+ return false;
2226
+
2227
+ }
2228
+
2229
+ luminance = Math.max( 0, Math.min( 1, lum / 255 ) );
2230
+ return true;
2231
+
2232
+ }
2279
2233
 
2280
2234
  }
2235
+ computeBuildingSteps( model ) {
2281
2236
 
2282
- computeConstructionSteps( model ) {
2237
+ // Sets userdata.buildingStep number in THREE.Group objects and userData.numBuildingSteps number in the root THREE.Group object.
2283
2238
 
2284
- // Sets userdata.constructionStep number in THREE.Group objects and userData.numConstructionSteps number in the root THREE.Group object.
2285
2239
  let stepNumber = 0;
2286
2240
  model.traverse( c => {
2287
2241
 
2288
2242
  if ( c.isGroup ) {
2289
2243
 
2290
- if ( c.userData.startingConstructionStep ) {
2244
+ if ( c.userData.startingBuildingStep ) {
2291
2245
 
2292
2246
  stepNumber ++;
2293
2247
 
2294
2248
  }
2295
2249
 
2296
- c.userData.constructionStep = stepNumber;
2250
+ c.userData.buildingStep = stepNumber;
2297
2251
 
2298
2252
  }
2299
2253
 
2300
2254
  } );
2301
- model.userData.numConstructionSteps = stepNumber + 1;
2255
+ model.userData.numBuildingSteps = stepNumber + 1;
2302
2256
 
2303
2257
  }
2304
2258