@gnsx/three 0.185.15 → 0.186.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 (417) hide show
  1. package/build/three.cjs +10 -82600
  2. package/build/three.core.js +1303 -728
  3. package/build/three.module.js +439 -338
  4. package/build/three.tsl.js +74 -44
  5. package/build/three.webgpu.js +6036 -2184
  6. package/build/three.webgpu.nodes.js +6020 -2184
  7. package/examples/jsm/Addons.js +6 -6
  8. package/examples/jsm/controls/ArcballControls.js +1 -1
  9. package/examples/jsm/controls/FirstPersonControls.js +44 -20
  10. package/examples/jsm/controls/OrbitControls.js +9 -0
  11. package/examples/jsm/controls/TrackballControls.js +109 -4
  12. package/examples/jsm/csm/CSMShadowNode.js +13 -0
  13. package/examples/jsm/exporters/GLTFExporter.js +23 -7
  14. package/examples/jsm/exporters/USDZExporter.js +2 -2
  15. package/examples/jsm/generators/CityGenerator.js +377 -45
  16. package/examples/jsm/generators/ForestGenerator.js +12 -12
  17. package/examples/jsm/generators/TerrainGenerator.js +49 -37
  18. package/examples/jsm/generators/TreeGenerator.js +70 -76
  19. package/examples/jsm/generators/city/BenchGenerator.js +127 -0
  20. package/examples/jsm/generators/city/CarGenerator.js +479 -0
  21. package/examples/jsm/generators/city/CityGeneratorUtils.js +31 -0
  22. package/examples/jsm/generators/city/HydrantGenerator.js +106 -0
  23. package/examples/jsm/generators/city/InstancedMeshGenerator.js +86 -0
  24. package/examples/jsm/generators/city/PersonGenerator.js +447 -0
  25. package/examples/jsm/generators/city/SidewalkGenerator.js +33 -38
  26. package/examples/jsm/generators/city/SkyscraperGenerator.js +448 -48
  27. package/examples/jsm/generators/city/StreetTreeGenerator.js +231 -0
  28. package/examples/jsm/generators/city/StreetlightGenerator.js +100 -0
  29. package/examples/jsm/generators/city/TrafficlightGenerator.js +106 -0
  30. package/examples/jsm/generators/city/TrashcanGenerator.js +100 -0
  31. package/examples/jsm/geometries/BoxLineGeometry.js +1 -1
  32. package/examples/jsm/geometries/ParametricGeometry.js +1 -1
  33. package/examples/jsm/geometries/RoundedBoxGeometry.js +1 -1
  34. package/examples/jsm/gpgpu/CountingSort.js +271 -0
  35. package/examples/jsm/helpers/LightProbeGridHelper.js +60 -239
  36. package/examples/jsm/helpers/LightProbeGridHelperWebGL.js +221 -0
  37. package/examples/jsm/inspector/Extension.js +94 -0
  38. package/examples/jsm/inspector/Inspector.js +145 -41
  39. package/examples/jsm/inspector/RendererInspector.js +100 -52
  40. package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +2609 -0
  41. package/examples/jsm/inspector/extensions/color-grading/ColorWheel.js +352 -0
  42. package/examples/jsm/inspector/extensions/color-grading/CurveEditor.js +599 -0
  43. package/examples/jsm/inspector/extensions/color-grading/LUT3DStyle.js +1201 -0
  44. package/examples/jsm/inspector/extensions/color-grading/LUTMath.js +788 -0
  45. package/examples/jsm/inspector/extensions/color-grading/modules/BrightnessModule.js +72 -0
  46. package/examples/jsm/inspector/extensions/color-grading/modules/ColorWheelModule.js +112 -0
  47. package/examples/jsm/inspector/extensions/color-grading/modules/ContrastModule.js +82 -0
  48. package/examples/jsm/inspector/extensions/color-grading/modules/CurvesModule.js +109 -0
  49. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureHueModule.js +110 -0
  50. package/examples/jsm/inspector/extensions/color-grading/modules/ExposureModule.js +73 -0
  51. package/examples/jsm/inspector/extensions/color-grading/modules/HueModule.js +78 -0
  52. package/examples/jsm/inspector/extensions/color-grading/modules/ImportedCubeModule.js +89 -0
  53. package/examples/jsm/inspector/extensions/color-grading/modules/Module.js +285 -0
  54. package/examples/jsm/inspector/extensions/color-grading/modules/OutputModule.js +101 -0
  55. package/examples/jsm/inspector/extensions/color-grading/modules/RendererModule.js +225 -0
  56. package/examples/jsm/inspector/extensions/color-grading/modules/SatVibranceModule.js +102 -0
  57. package/examples/jsm/inspector/extensions/color-grading/modules/SaturationModule.js +76 -0
  58. package/examples/jsm/inspector/extensions/color-grading/modules/VibranceModule.js +76 -0
  59. package/examples/jsm/inspector/extensions/color-grading/modules/WhiteBalanceModule.js +86 -0
  60. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +26 -31
  61. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -0
  62. package/examples/jsm/inspector/tabs/Memory.js +0 -2
  63. package/examples/jsm/inspector/tabs/Settings.js +4 -0
  64. package/examples/jsm/inspector/tabs/Timeline.js +223 -171
  65. package/examples/jsm/inspector/tabs/Viewer.js +515 -21
  66. package/examples/jsm/inspector/ui/List.js +15 -9
  67. package/examples/jsm/inspector/ui/Profiler.js +170 -14
  68. package/examples/jsm/inspector/ui/Style.js +269 -23
  69. package/examples/jsm/inspector/ui/Tab.js +2 -0
  70. package/examples/jsm/inspector/ui/Values.js +14 -2
  71. package/examples/jsm/interactive/HTMLMesh.js +19 -3
  72. package/examples/jsm/lighting/LightProbeGrid.js +484 -889
  73. package/examples/jsm/lighting/LightProbeGridUtils.js +107 -0
  74. package/examples/jsm/lighting/LightProbeGridWebGL.js +841 -0
  75. package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +194 -0
  76. package/examples/jsm/lighting/vxgi/VXGINode.js +660 -0
  77. package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +478 -0
  78. package/examples/jsm/lighting/vxgi/VXGIVolume.js +1430 -0
  79. package/examples/jsm/lights/SunLight.js +95 -0
  80. package/examples/jsm/lights/SunLightNode.js +56 -0
  81. package/examples/jsm/lights/SunLightShadow.js +319 -0
  82. package/examples/jsm/lights/SunShadowNode.js +312 -0
  83. package/examples/jsm/loaders/3DMLoader.js +150 -49
  84. package/examples/jsm/loaders/3MFLoader.js +202 -1
  85. package/examples/jsm/loaders/FBXLoader.js +81 -5
  86. package/examples/jsm/loaders/GLTFGaussianSplatLoaderExtension.js +330 -0
  87. package/examples/jsm/loaders/GLTFLoader.js +79 -14
  88. package/examples/jsm/loaders/GaussianSplatPLYLoader.js +386 -0
  89. package/examples/jsm/loaders/KSPLATLoader.js +463 -0
  90. package/examples/jsm/loaders/MaterialXLoader.js +111 -1010
  91. package/examples/jsm/loaders/PCDLoader.js +1 -1
  92. package/examples/jsm/loaders/SPLATLoader.js +139 -0
  93. package/examples/jsm/loaders/SPZLoader.js +561 -0
  94. package/examples/jsm/loaders/materialx/MaterialXArchive.js +108 -0
  95. package/examples/jsm/loaders/materialx/MaterialXDocument.js +878 -0
  96. package/examples/jsm/loaders/materialx/MaterialXHextile.js +183 -0
  97. package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +376 -0
  98. package/examples/jsm/loaders/materialx/MaterialXLog.js +75 -0
  99. package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +4 -0
  100. package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +1021 -0
  101. package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +661 -0
  102. package/examples/jsm/loaders/materialx/MaterialXUtils.js +57 -0
  103. package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +997 -0
  104. package/examples/jsm/loaders/materialx/parse/MaterialXParser.js +28 -0
  105. package/examples/jsm/loaders/usd/USDAParser.js +15 -2
  106. package/examples/jsm/loaders/usd/USDCParser.js +1 -4
  107. package/examples/jsm/loaders/usd/USDComposer.js +80 -42
  108. package/examples/jsm/materials/WoodNodeMaterial.js +6 -108
  109. package/examples/jsm/misc/RollerCoaster.js +2 -2
  110. package/examples/jsm/misc/SculptGL.LICENSE.txt +21 -0
  111. package/examples/jsm/misc/Sculptor.js +1679 -0
  112. package/examples/jsm/misc/SculptorMesh.js +1504 -0
  113. package/examples/jsm/misc/SculptorTools.js +1180 -0
  114. package/examples/jsm/misc/SculptorUtils.js +345 -0
  115. package/examples/jsm/misc/TubePainter.js +28 -16
  116. package/examples/jsm/misc/VolumeSlice.js +24 -24
  117. package/examples/jsm/modifiers/SimplifyModifier.js +63 -556
  118. package/examples/jsm/objects/GaussianSplat.js +1039 -0
  119. package/examples/jsm/objects/Sky.js +66 -45
  120. package/examples/jsm/objects/SkyMesh.js +70 -51
  121. package/examples/jsm/physics/JoltPhysics.js +1 -1
  122. package/examples/jsm/postprocessing/AfterimagePass.js +4 -2
  123. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  124. package/examples/jsm/postprocessing/GTAOPass.js +1 -1
  125. package/examples/jsm/postprocessing/OutlinePass.js +5 -5
  126. package/examples/jsm/postprocessing/SAOPass.js +1 -1
  127. package/examples/jsm/postprocessing/SSAOPass.js +1 -1
  128. package/examples/jsm/postprocessing/SSRPass.js +4 -2
  129. package/examples/jsm/postprocessing/SavePass.js +1 -1
  130. package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
  131. package/examples/jsm/postprocessing/UnrealBloomPass.js +30 -13
  132. package/examples/jsm/renderers/CSS2DRenderer.js +29 -5
  133. package/examples/jsm/shaders/DepthLimitedBlurShader.js +4 -1
  134. package/examples/jsm/shaders/ExposureShader.js +1 -1
  135. package/examples/jsm/shaders/FilmShader.js +2 -1
  136. package/examples/jsm/transpiler/AST.js +21 -2
  137. package/examples/jsm/transpiler/GLSLDecoder.js +498 -8
  138. package/examples/jsm/transpiler/TSLEncoder.js +82 -10
  139. package/examples/jsm/transpiler/WGSLEncoder.js +33 -4
  140. package/examples/jsm/tsl/WebGLNodesHandler.js +29 -39
  141. package/examples/jsm/tsl/display/AfterImageNode.js +2 -0
  142. package/examples/jsm/tsl/display/AnaglyphPassNode.js +3 -2
  143. package/examples/jsm/tsl/display/BilateralBlurNode.js +5 -2
  144. package/examples/jsm/tsl/display/BloomNode.js +55 -30
  145. package/examples/jsm/tsl/display/DenoiseNode.js +21 -1
  146. package/examples/jsm/tsl/display/DepthOfFieldNode.js +24 -6
  147. package/examples/jsm/tsl/display/DotScreenNode.js +11 -11
  148. package/examples/jsm/tsl/display/FSR1Node.js +8 -4
  149. package/examples/jsm/tsl/display/GTAONode.js +199 -86
  150. package/examples/jsm/tsl/display/GaussianBlurNode.js +65 -52
  151. package/examples/jsm/tsl/display/GodraysNode.js +5 -2
  152. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +2 -2
  153. package/examples/jsm/tsl/display/LensflareNode.js +5 -2
  154. package/examples/jsm/tsl/display/OITPassNode.js +352 -0
  155. package/examples/jsm/tsl/display/OutlineNode.js +2 -0
  156. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +3 -2
  157. package/examples/jsm/tsl/display/RGBShiftNode.js +9 -9
  158. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +7 -4
  159. package/examples/jsm/tsl/display/RetroPassNode.js +1 -1
  160. package/examples/jsm/tsl/display/SMAANode.js +22 -61
  161. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -4
  162. package/examples/jsm/tsl/display/SSAONode.js +436 -0
  163. package/examples/jsm/tsl/display/SSGINode.js +5 -2
  164. package/examples/jsm/tsl/display/SSRNode.js +7 -2
  165. package/examples/jsm/tsl/display/SSSNode.js +5 -2
  166. package/examples/jsm/tsl/display/SharpenNode.js +5 -4
  167. package/examples/jsm/tsl/display/StereoCompositePassNode.js +1 -3
  168. package/examples/jsm/tsl/display/StereoPassNode.js +1 -3
  169. package/examples/jsm/tsl/display/TAAUNode.js +22 -125
  170. package/examples/jsm/tsl/display/TRAANode.js +16 -142
  171. package/examples/jsm/tsl/display/TemporalReprojectNode.js +21 -15
  172. package/examples/jsm/tsl/display/depthAwareBlur.js +63 -0
  173. package/examples/jsm/tsl/display/hashBlur.js +3 -2
  174. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +38 -27
  175. package/examples/jsm/tsl/lighting/LightProbeGridNode.js +136 -0
  176. package/examples/jsm/tsl/math/voronoiNoise.js +112 -0
  177. package/examples/jsm/tsl/shadows/TileShadowNode.js +4 -6
  178. package/examples/jsm/tsl/utils/Raymarching.js +5 -5
  179. package/examples/jsm/tsl/utils/SoftParticles.js +60 -0
  180. package/examples/jsm/tsl/utils/TAAUtils.js +195 -0
  181. package/examples/jsm/utils/BufferGeometryUtils.js +14 -14
  182. package/examples/jsm/utils/GaussianSplatUtils.js +229 -0
  183. package/examples/jsm/utils/WebGLTextureUtils.js +1 -1
  184. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  185. package/examples/jsm/webxr/WebGLXRFallback.js +2 -16
  186. package/examples/jsm/webxr/XRControllerModelFactory.js +16 -4
  187. package/package.json +9 -16
  188. package/src/Three.Core.js +2 -1
  189. package/src/Three.TSL.js +73 -43
  190. package/src/Three.WebGPU.Nodes.js +1 -0
  191. package/src/Three.WebGPU.js +1 -0
  192. package/src/animation/AnimationClip.js +15 -2
  193. package/src/animation/AnimationObjectGroup.js +18 -6
  194. package/src/animation/AnimationUtils.js +26 -0
  195. package/src/animation/KeyframeTrack.js +37 -0
  196. package/src/constants.js +23 -1
  197. package/src/core/BufferAttribute.js +3 -2
  198. package/src/core/BufferGeometry.js +1 -1
  199. package/src/core/InterleavedBuffer.js +5 -1
  200. package/src/core/Object3D.js +40 -12
  201. package/src/core/Raycaster.js +4 -0
  202. package/src/core/RenderTarget.js +99 -9
  203. package/src/core/RenderTarget3D.js +12 -8
  204. package/src/extras/Controls.js +0 -8
  205. package/src/extras/PMREMGenerator.js +99 -205
  206. package/src/geometries/TorusGeometry.js +1 -1
  207. package/src/helpers/ArrowHelper.js +2 -0
  208. package/src/helpers/AxesHelper.js +2 -0
  209. package/src/helpers/Box3Helper.js +2 -0
  210. package/src/helpers/BoxHelper.js +2 -0
  211. package/src/helpers/CameraHelper.js +2 -0
  212. package/src/helpers/DirectionalLightHelper.js +2 -0
  213. package/src/helpers/GridHelper.js +2 -0
  214. package/src/helpers/HemisphereLightHelper.js +2 -0
  215. package/src/helpers/PlaneHelper.js +2 -0
  216. package/src/helpers/PointLightHelper.js +2 -0
  217. package/src/helpers/PolarGridHelper.js +2 -0
  218. package/src/helpers/SkeletonHelper.js +2 -0
  219. package/src/helpers/SpotLightHelper.js +2 -0
  220. package/src/lights/Light.js +0 -10
  221. package/src/lights/LightShadow.js +43 -12
  222. package/src/lights/SpotLightShadow.js +18 -0
  223. package/src/loaders/BufferGeometryLoader.js +5 -0
  224. package/src/loaders/ImageBitmapLoader.js +3 -1
  225. package/src/loaders/ObjectLoader.js +8 -5
  226. package/src/materials/Material.js +80 -57
  227. package/src/materials/MeshPhysicalMaterial.js +32 -0
  228. package/src/materials/nodes/Line2NodeMaterial.js +17 -8
  229. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +42 -5
  230. package/src/materials/nodes/NodeMaterial.js +19 -13
  231. package/src/materials/nodes/PointsNodeMaterial.js +2 -1
  232. package/src/materials/nodes/manager/NodeMaterialObserver.js +282 -55
  233. package/src/math/Frustum.js +9 -0
  234. package/src/math/FrustumArray.js +1 -1
  235. package/src/math/MathUtils.js +5 -3
  236. package/src/math/Matrix4.js +2 -9
  237. package/src/math/Plane.js +30 -1
  238. package/src/math/Quaternion.js +0 -10
  239. package/src/math/Ray.js +95 -45
  240. package/src/math/Triangle.js +0 -2
  241. package/src/math/Vector3.js +2 -2
  242. package/src/math/Vector4.js +0 -4
  243. package/src/math/interpolants/BezierInterpolant.js +36 -23
  244. package/src/nodes/Nodes.js +2 -0
  245. package/src/nodes/TSL.js +11 -3
  246. package/src/nodes/accessors/Batch.js +85 -13
  247. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  248. package/src/nodes/accessors/BuiltinNode.js +1 -1
  249. package/src/nodes/accessors/Instance.js +19 -18
  250. package/src/nodes/accessors/MaterialNode.js +9 -0
  251. package/src/nodes/accessors/ModelNode.js +85 -9
  252. package/src/nodes/accessors/ReferenceBaseNode.js +1 -70
  253. package/src/nodes/accessors/ReferenceElementNode.js +72 -0
  254. package/src/nodes/accessors/ReferenceNode.js +1 -70
  255. package/src/nodes/accessors/Skinning.js +124 -12
  256. package/src/nodes/accessors/StorageTextureNode.js +7 -3
  257. package/src/nodes/accessors/Texture3DNode.js +1 -1
  258. package/src/nodes/accessors/TextureNode.js +51 -21
  259. package/src/nodes/accessors/TextureSizeNode.js +4 -2
  260. package/src/nodes/accessors/UniformArrayNode.js +30 -5
  261. package/src/nodes/code/CodeNode.js +1 -1
  262. package/src/nodes/code/FunctionNode.js +12 -2
  263. package/src/nodes/core/ArrayNode.js +2 -2
  264. package/src/nodes/core/ContextNode.js +57 -4
  265. package/src/nodes/core/IndexNode.js +69 -4
  266. package/src/nodes/core/InspectorNode.js +2 -2
  267. package/src/nodes/core/MRTNode.js +44 -2
  268. package/src/nodes/core/Node.js +6 -3
  269. package/src/nodes/core/NodeBuilder.js +65 -50
  270. package/src/nodes/core/NodeFrame.js +11 -3
  271. package/src/nodes/core/NodeUtils.js +88 -0
  272. package/src/nodes/core/PropertyNode.js +8 -0
  273. package/src/nodes/core/StackNode.js +0 -1
  274. package/src/nodes/core/StructNode.js +4 -3
  275. package/src/nodes/core/UniformGroupNode.js +3 -2
  276. package/src/nodes/core/UniformNode.js +26 -12
  277. package/src/nodes/core/VarNode.js +0 -1
  278. package/src/nodes/display/BumpMapNode.js +2 -2
  279. package/src/nodes/display/ColorAdjustment.js +1 -1
  280. package/src/nodes/display/PassNode.js +76 -15
  281. package/src/nodes/display/ScreenNode.js +22 -65
  282. package/src/nodes/fog/Fog.js +4 -4
  283. package/src/nodes/functions/BSDF/BRDF_GGX.js +6 -6
  284. package/src/nodes/functions/BSDF/BRDF_Sheen.js +1 -1
  285. package/src/nodes/functions/BSDF/DFGLUT.js +2 -1
  286. package/src/nodes/functions/BSDF/LTC.js +1 -1
  287. package/src/nodes/functions/PhongLightingModel.js +1 -1
  288. package/src/nodes/functions/PhysicalLightingModel.js +83 -25
  289. package/src/nodes/functions/ToonLightingModel.js +2 -2
  290. package/src/nodes/functions/material/getParallaxCorrectNormal.js +3 -3
  291. package/src/nodes/gpgpu/AtomicFunctionNode.js +64 -13
  292. package/src/nodes/gpgpu/BarrierNode.js +13 -4
  293. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
  294. package/src/nodes/gpgpu/ComputeNode.js +20 -17
  295. package/src/nodes/gpgpu/SubgroupFunctionNode.js +165 -37
  296. package/src/nodes/gpgpu/WorkgroupInfoNode.js +44 -6
  297. package/src/nodes/lighting/EnvironmentNode.js +40 -4
  298. package/src/nodes/lighting/LightsNode.js +20 -4
  299. package/src/nodes/lighting/ShadowBaseNode.js +158 -1
  300. package/src/nodes/lighting/ShadowFilterNode.js +2 -106
  301. package/src/nodes/lighting/ShadowNode.js +22 -91
  302. package/src/nodes/materialx/{lib/mx_hsv.js → MaterialXColor.js} +3 -6
  303. package/src/nodes/materialx/{lib/mx_transform_color.js → MaterialXColorTransform.js} +3 -6
  304. package/src/nodes/materialx/MaterialXCore.js +37 -0
  305. package/src/nodes/materialx/MaterialXNodes.js +64 -72
  306. package/src/nodes/materialx/{lib/mx_noise.js → MaterialXNoise.js} +426 -197
  307. package/src/nodes/math/BitcountNode.js +24 -4
  308. package/src/nodes/math/MathNode.js +4 -4
  309. package/src/nodes/math/MathUtils.js +15 -4
  310. package/src/nodes/math/OperatorNode.js +2 -2
  311. package/src/nodes/math/PackFloatNode.js +29 -1
  312. package/src/nodes/math/Packed4x8IntegerNode.js +433 -0
  313. package/src/nodes/math/UnpackFloatNode.js +30 -2
  314. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  315. package/src/nodes/pmrem/PMREMNode.js +1 -1
  316. package/src/nodes/pmrem/PMREMUtils.js +31 -74
  317. package/src/nodes/shapes/Shapes.js +1 -1
  318. package/src/nodes/tsl/TSLCore.js +1 -31
  319. package/src/nodes/utils/EventNode.js +75 -0
  320. package/src/nodes/utils/LoopNode.js +54 -13
  321. package/src/nodes/utils/PostProcessingUtils.js +23 -2
  322. package/src/nodes/utils/RTTNode.js +97 -32
  323. package/src/nodes/utils/ReflectorNode.js +8 -4
  324. package/src/nodes/utils/RotateNode.js +85 -8
  325. package/src/nodes/utils/SpriteUtils.js +58 -23
  326. package/src/objects/BatchedMesh.js +6 -0
  327. package/src/objects/InstancedMesh.js +1 -1
  328. package/src/objects/LOD.js +1 -1
  329. package/src/objects/Line.js +12 -0
  330. package/src/objects/Mesh.js +12 -0
  331. package/src/objects/Points.js +12 -0
  332. package/src/objects/Sprite.js +12 -0
  333. package/src/renderers/WebGLRenderer.js +93 -27
  334. package/src/renderers/common/Animation.js +12 -2
  335. package/src/renderers/common/Backend.js +38 -10
  336. package/src/renderers/common/BindGroup.js +0 -1
  337. package/src/renderers/common/Bindings.js +50 -4
  338. package/src/renderers/common/BundleGroup.js +4 -0
  339. package/src/renderers/common/ClippingContext.js +11 -1
  340. package/src/renderers/common/Color4.js +9 -0
  341. package/src/renderers/common/Constants.js +0 -5
  342. package/src/renderers/common/DirectRenderPipeline.js +233 -0
  343. package/src/renderers/common/Geometries.js +24 -3
  344. package/src/renderers/common/Info.js +3 -3
  345. package/src/renderers/common/InspectorBase.js +37 -8
  346. package/src/renderers/common/Lighting.js +11 -4
  347. package/src/renderers/common/Pipelines.js +6 -4
  348. package/src/renderers/common/QuadMesh.js +16 -2
  349. package/src/renderers/common/RenderContext.js +8 -0
  350. package/src/renderers/common/RenderList.js +53 -19
  351. package/src/renderers/common/RenderLists.js +58 -11
  352. package/src/renderers/common/RenderObject.js +14 -0
  353. package/src/renderers/common/RenderObjects.js +14 -9
  354. package/src/renderers/common/RenderPipeline.js +52 -44
  355. package/src/renderers/common/Renderer.js +226 -55
  356. package/src/renderers/common/Storage3DTexture.js +16 -0
  357. package/src/renderers/common/Textures.js +3 -3
  358. package/src/renderers/common/XRManager.js +79 -72
  359. package/src/renderers/common/extras/PMREMGenerator.js +76 -144
  360. package/src/renderers/common/nodes/NodeManager.js +144 -6
  361. package/src/renderers/common/nodes/NodeStorageBuffer.js +3 -1
  362. package/src/renderers/common/nodes/NodeUniformBuffer.js +3 -1
  363. package/src/renderers/shaders/DFGLUTData.js +2 -1
  364. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +4 -2
  365. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +48 -0
  366. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +53 -4
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +20 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +20 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +61 -57
  371. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +82 -0
  372. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +9 -0
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +8 -1
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +15 -0
  375. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  376. package/src/renderers/shaders/ShaderLib.js +1 -0
  377. package/src/renderers/shaders/UniformsLib.js +16 -0
  378. package/src/renderers/webgl/WebGLAnimation.js +2 -2
  379. package/src/renderers/webgl/WebGLCapabilities.js +2 -2
  380. package/src/renderers/webgl/WebGLLights.js +74 -4
  381. package/src/renderers/webgl/WebGLMaterials.js +6 -0
  382. package/src/renderers/webgl/WebGLOutput.js +36 -24
  383. package/src/renderers/webgl/WebGLProgram.js +3 -0
  384. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  385. package/src/renderers/webgl/WebGLRenderLists.js +6 -10
  386. package/src/renderers/webgl/WebGLShadowMap.js +47 -44
  387. package/src/renderers/webgl/WebGLTextures.js +7 -7
  388. package/src/renderers/webgl-fallback/WebGLBackend.js +153 -45
  389. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +83 -29
  390. package/src/renderers/webgl-fallback/utils/WebGLState.js +163 -17
  391. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +32 -5
  392. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +11 -4
  393. package/src/renderers/webgpu/WebGPUBackend.js +513 -145
  394. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +99 -20
  395. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -1
  396. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +3 -12
  397. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +24 -14
  398. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +80 -14
  399. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +62 -7
  400. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +9 -3
  401. package/src/renderers/webgpu/utils/WebGPUUtils.js +16 -4
  402. package/src/renderers/webxr/WebXRManager.js +25 -2
  403. package/src/scenes/Scene.js +3 -3
  404. package/src/textures/CompressedArrayTexture.js +16 -0
  405. package/src/textures/Data3DTexture.js +16 -0
  406. package/src/textures/DataArrayTexture.js +16 -0
  407. package/src/textures/DepthTexture.js +3 -3
  408. package/src/textures/Texture.js +3 -3
  409. package/src/textures/{Source.js → TextureSource.js} +39 -8
  410. package/build/three.core.min.js +0 -6
  411. package/build/three.module.min.js +0 -6
  412. package/build/three.tsl.min.js +0 -6
  413. package/build/three.webgpu.min.js +0 -6
  414. package/build/three.webgpu.nodes.min.js +0 -6
  415. package/examples/jsm/libs/ecsy.module.js +0 -1792
  416. package/examples/jsm/loaders/LottieLoader.js +0 -130
  417. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +0 -52
@@ -1,4 +1,6 @@
1
1
  import {
2
+ BufferAttribute,
3
+ BufferGeometry,
2
4
  BufferGeometryLoader,
3
5
  CanvasTexture,
4
6
  ClampToEdgeWrapping,
@@ -30,6 +32,7 @@ import {
30
32
  import { EXRLoader } from '../loaders/EXRLoader.js';
31
33
 
32
34
  const _taskCache = new WeakMap();
35
+ const _bufferGeometryLoader = new BufferGeometryLoader();
33
36
 
34
37
  /**
35
38
  * A loader for Rhinoceros 3D files and objects.
@@ -38,11 +41,11 @@ const _taskCache = new WeakMap();
38
41
  * animate, and translate NURBS curves, surfaces, breps, extrusions, point clouds,
39
42
  * as well as polygon meshes and SubD objects. `rhino3dm.js` is compiled to WebAssembly
40
43
  * from the open source geometry library `openNURBS`. The loader currently uses
41
- * `rhino3dm.js 8.4.0`.
44
+ * `rhino3dm.js 8.32.1`.
42
45
  *
43
46
  * ```js
44
47
  * const loader = new Rhino3dmLoader();
45
- * loader.setLibraryPath( 'https://cdn.jsdelivr.net/npm/rhino3dm@8.17.0/' );
48
+ * loader.setLibraryPath( 'https://cdn.jsdelivr.net/npm/rhino3dm@8.32.1/' );
46
49
  *
47
50
  * const object = await loader.loadAsync( 'models/3dm/Rhino_Logo.3dm' );
48
51
  * scene.add( object );
@@ -77,6 +80,10 @@ class Rhino3dmLoader extends Loader {
77
80
  this.workerSourceURL = '';
78
81
  this.workerConfig = {};
79
82
 
83
+ // Number of global subdivisions applied to SubD objects before meshing. Higher
84
+ // values increase smoothness at the cost of (potentially very large) vertex counts.
85
+ this.subdivisionLevel = 3;
86
+
80
87
  this.materials = [];
81
88
  this.warnings = [];
82
89
 
@@ -112,6 +119,22 @@ class Rhino3dmLoader extends Loader {
112
119
 
113
120
  }
114
121
 
122
+ /**
123
+ * Sets the number of global subdivisions applied to SubD objects before they are
124
+ * meshed for display. The default is `3`. Large models with many SubD objects may
125
+ * benefit from a lower value to keep vertex counts manageable.
126
+ *
127
+ * @param {number} level - The subdivision level.
128
+ * @return {Rhino3dmLoader} A reference to this loader.
129
+ */
130
+ setSubdivisionLevel( level ) {
131
+
132
+ this.subdivisionLevel = level;
133
+
134
+ return this;
135
+
136
+ }
137
+
115
138
  /**
116
139
  * Starts loading from the given URL and passes the loaded 3DM asset
117
140
  * to the `onLoad()` callback.
@@ -189,9 +212,7 @@ class Rhino3dmLoader extends Loader {
189
212
 
190
213
  worker._callbacks[ taskID ] = { resolve, reject };
191
214
 
192
- worker.postMessage( { type: 'decode', id: taskID, buffer }, [ buffer ] );
193
-
194
- // this.debug();
215
+ worker.postMessage( { type: 'decode', id: taskID, buffer, subdivisionLevel: this.subdivisionLevel }, [ buffer ] );
195
216
 
196
217
  } );
197
218
 
@@ -213,7 +234,6 @@ class Rhino3dmLoader extends Loader {
213
234
 
214
235
  this._releaseTask( worker, taskID );
215
236
 
216
- //this.debug();
217
237
 
218
238
  }
219
239
 
@@ -241,14 +261,24 @@ class Rhino3dmLoader extends Loader {
241
261
  */
242
262
  parse( data, onLoad, onError ) {
243
263
 
244
- this.decodeObjects( data, '' )
245
- .then( result => {
264
+ this.parseAsync( data ).then( onLoad ).catch( onError );
246
265
 
247
- result.userData.warnings = this.warnings;
248
- onLoad( result );
266
+ }
249
267
 
250
- } )
251
- .catch( e => onError( e ) );
268
+ /**
269
+ * Parses the given 3DM data and returns a Promise that resolves with the loaded asset.
270
+ *
271
+ * @param {ArrayBuffer} data - The raw 3DM asset data as an array buffer.
272
+ * @return {Promise<Object3D>} A Promise that resolves with the decoded 3D object.
273
+ */
274
+ parseAsync( data ) {
275
+
276
+ return this.decodeObjects( data, '' ).then( result => {
277
+
278
+ result.userData.warnings = this.warnings;
279
+ return result;
280
+
281
+ } );
252
282
 
253
283
  }
254
284
 
@@ -304,19 +334,18 @@ class Rhino3dmLoader extends Loader {
304
334
 
305
335
  }
306
336
 
307
- //console.log(material)
308
337
 
309
338
  const mat = new MeshPhysicalMaterial( {
310
339
 
311
340
  color: new Color( material.diffuseColor.r / 255.0, material.diffuseColor.g / 255.0, material.diffuseColor.b / 255.0 ),
312
- emissive: new Color( material.emissionColor.r, material.emissionColor.g, material.emissionColor.b ),
341
+ emissive: new Color( material.emissionColor.r / 255.0, material.emissionColor.g / 255.0, material.emissionColor.b / 255.0 ),
313
342
  flatShading: material.disableLighting,
314
343
  ior: material.indexOfRefraction,
315
344
  name: material.name,
316
345
  reflectivity: material.reflectivity,
317
346
  opacity: 1.0 - material.transparency,
318
347
  side: DoubleSide,
319
- specularColor: material.specularColor,
348
+ specularColor: new Color( material.specularColor.r / 255.0, material.specularColor.g / 255.0, material.specularColor.b / 255.0 ),
320
349
  transparent: material.transparency > 0 ? true : false
321
350
 
322
351
  } );
@@ -333,20 +362,18 @@ class Rhino3dmLoader extends Loader {
333
362
  mat.clearcoat = pbr.clearcoat;
334
363
  mat.clearcoatRoughness = pbr.clearcoatRoughness;
335
364
  mat.metalness = pbr.metallic;
336
- mat.transmission = 1 - pbr.opacity;
337
365
  mat.roughness = pbr.roughness;
338
366
  mat.sheen = pbr.sheen;
339
367
  mat.specularIntensity = pbr.specular;
340
368
  mat.thickness = pbr.subsurface;
341
369
 
342
- }
343
-
344
- if ( material.pbrSupported && material.pbr.opacity === 0 && material.transparency === 1 ) {
345
-
346
- //some compromises
347
-
348
- mat.opacity = 0.2;
349
- mat.transmission = 1.00;
370
+ // Rhino PBR Opacity is coverage/alpha, not glass transmission, and is
371
+ // 1 = opaque (glTF/Disney convention, matching three.js mat.opacity — unlike
372
+ // the legacy Material.transparency used above, which is 0 = opaque). Map it
373
+ // straight to opacity so it behaves as pure alpha; leave mat.transmission at
374
+ // its default (0) rather than deriving glass from opacity. (RH3DM-190)
375
+ mat.opacity = pbr.opacity;
376
+ mat.transparent = pbr.opacity < 1.0;
350
377
 
351
378
  }
352
379
 
@@ -360,7 +387,6 @@ class Rhino3dmLoader extends Loader {
360
387
 
361
388
  const map = textureLoader.load( texture.image );
362
389
 
363
- //console.log(texture.type )
364
390
 
365
391
  switch ( texture.type ) {
366
392
 
@@ -527,11 +553,13 @@ class Rhino3dmLoader extends Loader {
527
553
  const instanceReferences = [];
528
554
 
529
555
  object.userData[ 'layers' ] = data.layers;
556
+ object.userData[ 'views' ] = data.views;
557
+ object.userData[ 'namedViews' ] = data.namedViews;
530
558
  object.userData[ 'groups' ] = data.groups;
559
+ object.userData[ 'strings' ] = data.strings;
531
560
  object.userData[ 'settings' ] = data.settings;
532
561
  object.userData.settings[ 'renderSettings' ] = data.renderSettings;
533
562
  object.userData[ 'objectType' ] = 'File3dm';
534
- object.userData[ 'materials' ] = null;
535
563
 
536
564
  object.name = this.url;
537
565
 
@@ -677,15 +705,38 @@ class Rhino3dmLoader extends Loader {
677
705
 
678
706
  }
679
707
 
680
- object.userData[ 'materials' ] = this.materials;
681
708
  object.name = '';
682
709
  return object;
683
710
 
684
711
  }
685
712
 
686
- _createObject( obj, mat ) {
713
+ /**
714
+ * Builds a BufferGeometry from a worker payload. Meshes decoded via the fast path
715
+ * arrive as transferable typed arrays (`format: 'buffers'`) and are assembled directly;
716
+ * everything else falls back to the three.js BufferGeometry JSON produced by
717
+ * `toThreejsJSON()` (older rhino3dm, point clouds, curves, …).
718
+ */
719
+ _geometryFromData( data ) {
720
+
721
+ if ( data && data.format === 'buffers' ) {
722
+
723
+ const geometry = new BufferGeometry();
724
+
725
+ if ( data.position && data.position.length ) geometry.setAttribute( 'position', new BufferAttribute( data.position, 3 ) );
726
+ if ( data.normal && data.normal.length ) geometry.setAttribute( 'normal', new BufferAttribute( data.normal, 3 ) );
727
+ if ( data.uv && data.uv.length ) geometry.setAttribute( 'uv', new BufferAttribute( data.uv, 2 ) );
728
+ if ( data.color && data.color.length ) geometry.setAttribute( 'color', new BufferAttribute( data.color, 3 ) );
729
+ if ( data.index && data.index.length ) geometry.setIndex( new BufferAttribute( data.index, 1 ) );
730
+
731
+ return geometry;
687
732
 
688
- const loader = new BufferGeometryLoader();
733
+ }
734
+
735
+ return _bufferGeometryLoader.parse( data );
736
+
737
+ }
738
+
739
+ _createObject( obj, mat ) {
689
740
 
690
741
  const attributes = obj.attributes;
691
742
 
@@ -696,7 +747,7 @@ class Rhino3dmLoader extends Loader {
696
747
  case 'Point':
697
748
  case 'PointSet':
698
749
 
699
- geometry = loader.parse( obj.geometry );
750
+ geometry = this._geometryFromData( obj.geometry );
700
751
 
701
752
  if ( geometry.hasAttribute( 'color' ) ) {
702
753
 
@@ -731,7 +782,7 @@ class Rhino3dmLoader extends Loader {
731
782
 
732
783
  if ( obj.geometry === null ) return;
733
784
 
734
- geometry = loader.parse( obj.geometry );
785
+ geometry = this._geometryFromData( obj.geometry );
735
786
 
736
787
 
737
788
  if ( mat === null ) {
@@ -765,7 +816,7 @@ class Rhino3dmLoader extends Loader {
765
816
 
766
817
  case 'Curve':
767
818
 
768
- geometry = loader.parse( obj.geometry );
819
+ geometry = this._geometryFromData( obj.geometry );
769
820
 
770
821
  _color = attributes.drawColor;
771
822
  color = new Color( _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 );
@@ -1088,16 +1139,20 @@ function Rhino3dmWorker() {
1088
1139
 
1089
1140
  taskID = message.id;
1090
1141
  const buffer = message.buffer;
1142
+ const subdivisionLevel = message.subdivisionLevel;
1091
1143
  libraryPending.then( () => {
1092
1144
 
1093
1145
  try {
1094
1146
 
1095
- const data = decodeObjects( rhino, buffer );
1096
- self.postMessage( { type: 'decode', id: message.id, data } );
1147
+ const data = decodeObjects( rhino, buffer, subdivisionLevel );
1148
+ // Transfer the mesh typed arrays (fast path) instead of structure-cloning
1149
+ // them across the worker boundary.
1150
+ self.postMessage( { type: 'decode', id: message.id, data }, collectTransferables( data ) );
1097
1151
 
1098
1152
  } catch ( error ) {
1099
1153
 
1100
- self.postMessage( { type: 'error', id: message.id, error } );
1154
+ // Error objects don't always survive structured clone with their stack intact.
1155
+ self.postMessage( { type: 'error', id: message.id, error: { message: error.message, stack: error.stack } } );
1101
1156
 
1102
1157
  }
1103
1158
 
@@ -1109,7 +1164,59 @@ function Rhino3dmWorker() {
1109
1164
 
1110
1165
  };
1111
1166
 
1112
- function decodeObjects( rhino, buffer ) {
1167
+ // Converts a rhino3dm mesh or point cloud to a Three.js payload. When the wasm build
1168
+ // supports toThreejsBuffers (rhino3dm >= 8.32.1 for point clouds, >= 8.32 for meshes),
1169
+ // returns transferable typed arrays tagged `format: 'buffers'`; otherwise falls back to
1170
+ // the element-by-element BufferGeometry JSON.
1171
+ function meshToThreejs( geom ) {
1172
+
1173
+ if ( typeof geom.toThreejsBuffers === 'function' ) {
1174
+
1175
+ const b = geom.toThreejsBuffers( false );
1176
+ const g = { format: 'buffers', position: b.position };
1177
+ if ( b.normal ) g.normal = b.normal; // meshes always have normals; point clouds may not
1178
+ if ( b.index ) g.index = b.index; // meshes only (point clouds are non-indexed)
1179
+ if ( b.uv ) g.uv = b.uv;
1180
+ if ( b.color ) g.color = b.color;
1181
+ return g;
1182
+
1183
+ }
1184
+
1185
+ return geom.toThreejsJSON();
1186
+
1187
+ }
1188
+
1189
+ // Gathers the ArrayBuffers backing every fast-path mesh so postMessage can transfer
1190
+ // (move) them to the main thread instead of copying.
1191
+ function collectTransferables( data ) {
1192
+
1193
+ const transfer = new Set();
1194
+
1195
+ if ( data && data.objects ) {
1196
+
1197
+ for ( const obj of data.objects ) {
1198
+
1199
+ const g = obj.geometry;
1200
+
1201
+ if ( g && g.format === 'buffers' ) {
1202
+
1203
+ for ( const key of [ 'position', 'normal', 'uv', 'color', 'index' ] ) {
1204
+
1205
+ if ( g[ key ] && g[ key ].buffer ) transfer.add( g[ key ].buffer );
1206
+
1207
+ }
1208
+
1209
+ }
1210
+
1211
+ }
1212
+
1213
+ }
1214
+
1215
+ return Array.from( transfer );
1216
+
1217
+ }
1218
+
1219
+ function decodeObjects( rhino, buffer, subdivisionLevel ) {
1113
1220
 
1114
1221
  const arr = new Uint8Array( buffer );
1115
1222
  const doc = rhino.File3dm.fromByteArray( arr );
@@ -1131,7 +1238,7 @@ function Rhino3dmWorker() {
1131
1238
 
1132
1239
  const _object = objs.get( i );
1133
1240
 
1134
- const object = extractObjectData( _object, doc );
1241
+ const object = extractObjectData( _object, doc, subdivisionLevel );
1135
1242
 
1136
1243
  _object.delete();
1137
1244
 
@@ -1144,7 +1251,6 @@ function Rhino3dmWorker() {
1144
1251
  }
1145
1252
 
1146
1253
  // Handle instance definitions
1147
- // console.log( `Instance Definitions Count: ${doc.instanceDefinitions().count()}` );
1148
1254
 
1149
1255
  for ( let i = 0; i < doc.instanceDefinitions().count; i ++ ) {
1150
1256
 
@@ -1276,15 +1382,11 @@ function Rhino3dmWorker() {
1276
1382
  //TODO: Handle other document stuff like dimstyles, instance definitions, bitmaps etc.
1277
1383
 
1278
1384
  // Handle dimstyles
1279
- // console.log( `Dimstyle Count: ${doc.dimstyles().count()}` );
1280
1385
 
1281
1386
  // Handle bitmaps
1282
- // console.log( `Bitmap Count: ${doc.bitmaps().count()}` );
1283
1387
 
1284
1388
  // Handle strings
1285
- // console.log( `Document Strings Count: ${doc.strings().count()}` );
1286
1389
  // Note: doc.strings().documentUserTextCount() counts any doc.strings defined in a section
1287
- // console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` );
1288
1390
 
1289
1391
  const strings_count = doc.strings().count;
1290
1392
 
@@ -1437,7 +1539,7 @@ function Rhino3dmWorker() {
1437
1539
 
1438
1540
  }
1439
1541
 
1440
- function extractObjectData( object, doc ) {
1542
+ function extractObjectData( object, doc, subdivisionLevel ) {
1441
1543
 
1442
1544
  const _geometry = object.geometry();
1443
1545
  const _attributes = object.attributes();
@@ -1507,7 +1609,7 @@ function Rhino3dmWorker() {
1507
1609
  case rhino.ObjectType.PointSet:
1508
1610
  case rhino.ObjectType.Mesh:
1509
1611
 
1510
- geometry = _geometry.toThreejsJSON();
1612
+ geometry = meshToThreejs( _geometry );
1511
1613
 
1512
1614
  break;
1513
1615
 
@@ -1535,7 +1637,7 @@ function Rhino3dmWorker() {
1535
1637
  if ( mesh.faces().count > 0 ) {
1536
1638
 
1537
1639
  mesh.compact();
1538
- geometry = mesh.toThreejsJSON();
1640
+ geometry = meshToThreejs( mesh );
1539
1641
  faces.delete();
1540
1642
 
1541
1643
  }
@@ -1550,7 +1652,7 @@ function Rhino3dmWorker() {
1550
1652
 
1551
1653
  if ( mesh ) {
1552
1654
 
1553
- geometry = mesh.toThreejsJSON();
1655
+ geometry = meshToThreejs( mesh );
1554
1656
  mesh.delete();
1555
1657
 
1556
1658
  }
@@ -1592,11 +1694,11 @@ function Rhino3dmWorker() {
1592
1694
  case rhino.ObjectType.SubD:
1593
1695
 
1594
1696
  // TODO: precalculate resulting vertices and faces and warn on excessive results
1595
- _geometry.subdivide( 3 );
1697
+ _geometry.subdivide( subdivisionLevel );
1596
1698
  mesh = rhino.Mesh.createFromSubDControlNet( _geometry, false );
1597
1699
  if ( mesh ) {
1598
1700
 
1599
- geometry = mesh.toThreejsJSON();
1701
+ geometry = meshToThreejs( mesh );
1600
1702
  mesh.delete();
1601
1703
 
1602
1704
  }
@@ -1706,7 +1808,6 @@ function Rhino3dmWorker() {
1706
1808
  } else {
1707
1809
 
1708
1810
  // these are functions that could be called to extract more data.
1709
- //console.log( `${property}: ${object[ property ].constructor.name}` );
1710
1811
 
1711
1812
  }
1712
1813
 
@@ -3,6 +3,7 @@ import {
3
3
  BufferGeometry,
4
4
  ClampToEdgeWrapping,
5
5
  Color,
6
+ CylinderGeometry,
6
7
  FileLoader,
7
8
  Float32BufferAttribute,
8
9
  Group,
@@ -15,14 +16,21 @@ import {
15
16
  MeshStandardMaterial,
16
17
  MirroredRepeatWrapping,
17
18
  NearestFilter,
19
+ Quaternion,
18
20
  RepeatWrapping,
21
+ SphereGeometry,
19
22
  TextureLoader,
20
- SRGBColorSpace
23
+ SRGBColorSpace,
24
+ Vector3
21
25
  } from '@gnsx/three';
22
26
  import { unzipSync } from '../libs/fflate.module.js';
27
+ import { mergeGeometries } from '../utils/BufferGeometryUtils.js';
23
28
 
24
29
  const COLOR_SPACE_3MF = SRGBColorSpace;
25
30
 
31
+ const NS_BEAM_LATTICE = 'http://schemas.microsoft.com/3dmanufacturing/beamlattice/2017/02';
32
+ const NS_BEAM_LATTICE_BALLS = 'http://schemas.microsoft.com/3dmanufacturing/beamlattice/balls/2020/07';
33
+
26
34
  /**
27
35
  * A loader for the [3D Manufacturing Format (3MF)](https://3mf.io/specification/) format.
28
36
  *
@@ -38,6 +46,7 @@ const COLOR_SPACE_3MF = SRGBColorSpace;
38
46
  * - Texture 2D Groups
39
47
  * - Color Groups (Vertex Colors)
40
48
  * - Metallic Display Properties (PBR)
49
+ * - Beam Lattice
41
50
  *
42
51
  * ```js
43
52
  * const loader = new ThreeMFLoader();
@@ -604,10 +613,87 @@ class ThreeMFLoader extends Loader {
604
613
  meshData[ 'triangleProperties' ] = triangleProperties;
605
614
  meshData[ 'triangles' ] = new Uint32Array( triangles );
606
615
 
616
+ const beamLatticeNode = meshNode.getElementsByTagNameNS( NS_BEAM_LATTICE, 'beamlattice' )[ 0 ];
617
+
618
+ if ( beamLatticeNode !== undefined ) {
619
+
620
+ meshData[ 'beamlattice' ] = parseBeamLatticeNode( beamLatticeNode );
621
+
622
+ }
623
+
607
624
  return meshData;
608
625
 
609
626
  }
610
627
 
628
+ function parseBeamLatticeNode( beamLatticeNode ) {
629
+
630
+ const beamLatticeData = {
631
+ radius: parseFloat( beamLatticeNode.getAttribute( 'radius' ) ), // required
632
+ minLength: parseFloat( beamLatticeNode.getAttribute( 'minlength' ) ),
633
+ cap: beamLatticeNode.getAttribute( 'cap' ) || 'sphere',
634
+ ballMode: beamLatticeNode.getAttributeNS( NS_BEAM_LATTICE_BALLS, 'ballmode' ) || 'none',
635
+ ballRadius: parseFloat( beamLatticeNode.getAttributeNS( NS_BEAM_LATTICE_BALLS, 'ballradius' ) ),
636
+ beams: [],
637
+ balls: []
638
+ };
639
+
640
+ // clipping requires boolean operations which are not supported ('clipping' is a legacy name of 'clippingmode')
641
+
642
+ const clippingMode = beamLatticeNode.getAttribute( 'clippingmode' ) || beamLatticeNode.getAttribute( 'clipping' );
643
+
644
+ if ( clippingMode !== null && clippingMode !== 'none' ) {
645
+
646
+ console.warn( 'THREE.3MFLoader: Beam lattice clipping is not supported. The lattice is rendered unclipped.' );
647
+
648
+ }
649
+
650
+ const beamNodes = beamLatticeNode.getElementsByTagNameNS( NS_BEAM_LATTICE, 'beam' );
651
+
652
+ for ( let i = 0; i < beamNodes.length; i ++ ) {
653
+
654
+ const beamNode = beamNodes[ i ];
655
+
656
+ const beamData = {
657
+ v1: parseInt( beamNode.getAttribute( 'v1' ), 10 ), // required
658
+ v2: parseInt( beamNode.getAttribute( 'v2' ), 10 ) // required
659
+ };
660
+
661
+ // optional
662
+
663
+ const r1 = beamNode.getAttribute( 'r1' );
664
+ const r2 = beamNode.getAttribute( 'r2' );
665
+
666
+ if ( r1 !== null ) beamData[ 'r1' ] = parseFloat( r1 );
667
+ if ( r2 !== null ) beamData[ 'r2' ] = parseFloat( r2 );
668
+
669
+ beamLatticeData.beams.push( beamData );
670
+
671
+ }
672
+
673
+ const ballNodes = beamLatticeNode.getElementsByTagNameNS( NS_BEAM_LATTICE_BALLS, 'ball' );
674
+
675
+ for ( let i = 0; i < ballNodes.length; i ++ ) {
676
+
677
+ const ballNode = ballNodes[ i ];
678
+
679
+ const ballData = {
680
+ vindex: parseInt( ballNode.getAttribute( 'vindex' ), 10 ) // required
681
+ };
682
+
683
+ // optional
684
+
685
+ const r = ballNode.getAttribute( 'r' );
686
+
687
+ if ( r !== null ) ballData[ 'r' ] = parseFloat( r );
688
+
689
+ beamLatticeData.balls.push( ballData );
690
+
691
+ }
692
+
693
+ return beamLatticeData;
694
+
695
+ }
696
+
611
697
  function parseComponentsNode( componentsNode ) {
612
698
 
613
699
  const components = [];
@@ -1211,6 +1297,111 @@ class ThreeMFLoader extends Loader {
1211
1297
 
1212
1298
  }
1213
1299
 
1300
+ function buildLatticeMesh( meshData ) {
1301
+
1302
+ const beamLatticeData = meshData[ 'beamlattice' ];
1303
+ const vertices = meshData[ 'vertices' ];
1304
+
1305
+ const geometries = [];
1306
+
1307
+ const p1 = new Vector3();
1308
+ const p2 = new Vector3();
1309
+ const direction = new Vector3();
1310
+ const up = new Vector3( 0, 1, 0 );
1311
+ const quaternion = new Quaternion();
1312
+ const matrix = new Matrix4();
1313
+
1314
+ // beams
1315
+
1316
+ const beams = beamLatticeData.beams;
1317
+ const openEnded = beamLatticeData.cap !== 'butt';
1318
+
1319
+ // spheres for caps and balls are collected per vertex so joints are only built once
1320
+
1321
+ const sphereRadii = new Map();
1322
+
1323
+ for ( let i = 0; i < beams.length; i ++ ) {
1324
+
1325
+ const beam = beams[ i ];
1326
+
1327
+ p1.fromArray( vertices, beam.v1 * 3 );
1328
+ p2.fromArray( vertices, beam.v2 * 3 );
1329
+
1330
+ const length = p1.distanceTo( p2 );
1331
+
1332
+ if ( length < beamLatticeData.minLength ) continue; // consumers must ignore beams shorter than "minlength"
1333
+
1334
+ const r1 = ( beam.r1 !== undefined ) ? beam.r1 : beamLatticeData.radius;
1335
+ const r2 = ( beam.r2 !== undefined ) ? beam.r2 : r1;
1336
+
1337
+ const geometry = new CylinderGeometry( r2, r1, length, 8, 1, openEnded );
1338
+
1339
+ direction.subVectors( p2, p1 ).divideScalar( length );
1340
+ quaternion.setFromUnitVectors( up, direction );
1341
+
1342
+ matrix.makeRotationFromQuaternion( quaternion );
1343
+ matrix.setPosition( p1.add( p2 ).multiplyScalar( 0.5 ) );
1344
+
1345
+ geometry.applyMatrix4( matrix );
1346
+ geometries.push( geometry );
1347
+
1348
+ if ( openEnded ) {
1349
+
1350
+ // approximate "sphere" and "hemisphere" caps with a sphere per beam end
1351
+
1352
+ sphereRadii.set( beam.v1, Math.max( r1, sphereRadii.get( beam.v1 ) || 0 ) );
1353
+ sphereRadii.set( beam.v2, Math.max( r2, sphereRadii.get( beam.v2 ) || 0 ) );
1354
+
1355
+ }
1356
+
1357
+ if ( beamLatticeData.ballMode === 'all' ) {
1358
+
1359
+ sphereRadii.set( beam.v1, Math.max( beamLatticeData.ballRadius, sphereRadii.get( beam.v1 ) || 0 ) );
1360
+ sphereRadii.set( beam.v2, Math.max( beamLatticeData.ballRadius, sphereRadii.get( beam.v2 ) || 0 ) );
1361
+
1362
+ }
1363
+
1364
+ }
1365
+
1366
+ // balls
1367
+
1368
+ const balls = beamLatticeData.balls;
1369
+
1370
+ for ( let i = 0; i < balls.length; i ++ ) {
1371
+
1372
+ const ball = balls[ i ];
1373
+ const r = ( ball.r !== undefined ) ? ball.r : beamLatticeData.ballRadius;
1374
+
1375
+ sphereRadii.set( ball.vindex, Math.max( r, sphereRadii.get( ball.vindex ) || 0 ) );
1376
+
1377
+ }
1378
+
1379
+ for ( const [ vindex, radius ] of sphereRadii ) {
1380
+
1381
+ const geometry = new SphereGeometry( radius, 8, 6 );
1382
+
1383
+ p1.fromArray( vertices, vindex * 3 );
1384
+ geometry.translate( p1.x, p1.y, p1.z );
1385
+
1386
+ geometries.push( geometry );
1387
+
1388
+ }
1389
+
1390
+ //
1391
+
1392
+ const geometry = mergeGeometries( geometries );
1393
+
1394
+ const material = new MeshPhongMaterial( {
1395
+ name: Loader.DEFAULT_MATERIAL_NAME,
1396
+ color: 0xffffff
1397
+ } );
1398
+
1399
+ const mesh = new Mesh( geometry, material );
1400
+
1401
+ return mesh;
1402
+
1403
+ }
1404
+
1214
1405
  function buildMeshes( resourceMap, meshData, objects, modelData, textureData, objectData ) {
1215
1406
 
1216
1407
  const keys = Object.keys( resourceMap );
@@ -1329,6 +1520,16 @@ class ThreeMFLoader extends Loader {
1329
1520
  const resourceMap = analyzeObject( meshData, objectData );
1330
1521
  const meshes = buildMeshes( resourceMap, meshData, objects, modelData, textureData, objectData );
1331
1522
 
1523
+ if ( meshData[ 'beamlattice' ] !== undefined ) {
1524
+
1525
+ const latticeMesh = buildLatticeMesh( meshData );
1526
+
1527
+ if ( objectData.name ) latticeMesh.name = objectData.name;
1528
+
1529
+ meshes.push( latticeMesh );
1530
+
1531
+ }
1532
+
1332
1533
  for ( let i = 0, l = meshes.length; i < l; i ++ ) {
1333
1534
 
1334
1535
  group.add( meshes[ i ] );