@plastic-software/three 0.181.3 → 0.183.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 (437) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -4
  3. package/build/three.cjs +11330 -10017
  4. package/build/three.core.js +10011 -9493
  5. package/build/three.core.min.js +2 -2
  6. package/build/three.module.js +1414 -631
  7. package/build/three.module.min.js +2 -2
  8. package/build/three.tsl.js +21 -13
  9. package/build/three.tsl.min.js +2 -2
  10. package/build/three.webgpu.js +8007 -5427
  11. package/build/three.webgpu.min.js +2 -2
  12. package/build/three.webgpu.nodes.js +8005 -5426
  13. package/build/three.webgpu.nodes.min.js +2 -2
  14. package/examples/jsm/Addons.js +0 -3
  15. package/examples/jsm/animation/CCDIKSolver.js +2 -2
  16. package/examples/jsm/controls/ArcballControls.js +3 -3
  17. package/examples/jsm/controls/MapControls.js +55 -1
  18. package/examples/jsm/controls/OrbitControls.js +109 -6
  19. package/examples/jsm/controls/TrackballControls.js +6 -6
  20. package/examples/jsm/csm/CSM.js +2 -1
  21. package/examples/jsm/effects/AnaglyphEffect.js +102 -7
  22. package/examples/jsm/environments/ColorEnvironment.js +59 -0
  23. package/examples/jsm/environments/RoomEnvironment.js +3 -0
  24. package/examples/jsm/exporters/EXRExporter.js +1 -1
  25. package/examples/jsm/exporters/GLTFExporter.js +131 -4
  26. package/examples/jsm/exporters/USDZExporter.js +22 -3
  27. package/examples/jsm/geometries/DecalGeometry.js +1 -1
  28. package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
  29. package/examples/jsm/helpers/LightProbeHelperGPU.js +1 -1
  30. package/examples/jsm/helpers/TextureHelperGPU.js +1 -1
  31. package/examples/jsm/helpers/ViewHelper.js +67 -8
  32. package/examples/jsm/inspector/Inspector.js +74 -14
  33. package/examples/jsm/inspector/RendererInspector.js +12 -2
  34. package/examples/jsm/inspector/tabs/Console.js +41 -7
  35. package/examples/jsm/inspector/tabs/Parameters.js +18 -2
  36. package/examples/jsm/inspector/tabs/Performance.js +2 -2
  37. package/examples/jsm/inspector/tabs/Viewer.js +4 -4
  38. package/examples/jsm/inspector/ui/Profiler.js +1836 -31
  39. package/examples/jsm/inspector/ui/Style.js +973 -14
  40. package/examples/jsm/inspector/ui/Tab.js +188 -1
  41. package/examples/jsm/inspector/ui/Values.js +17 -1
  42. package/examples/jsm/libs/meshopt_decoder.module.js +6 -5
  43. package/examples/jsm/lines/LineMaterial.js +6 -0
  44. package/examples/jsm/loaders/3DMLoader.js +5 -4
  45. package/examples/jsm/loaders/3MFLoader.js +2 -2
  46. package/examples/jsm/loaders/AMFLoader.js +2 -2
  47. package/examples/jsm/loaders/ColladaLoader.js +24 -4026
  48. package/examples/jsm/loaders/DRACOLoader.js +5 -5
  49. package/examples/jsm/loaders/EXRLoader.js +5 -5
  50. package/examples/jsm/loaders/FBXLoader.js +2 -4
  51. package/examples/jsm/loaders/GCodeLoader.js +34 -8
  52. package/examples/jsm/loaders/GLTFLoader.js +122 -171
  53. package/examples/jsm/loaders/HDRLoader.js +0 -1
  54. package/examples/jsm/loaders/KMZLoader.js +5 -5
  55. package/examples/jsm/loaders/KTX2Loader.js +19 -3
  56. package/examples/jsm/loaders/LDrawLoader.js +2 -3
  57. package/examples/jsm/loaders/LWOLoader.js +7 -39
  58. package/examples/jsm/loaders/NRRDLoader.js +2 -2
  59. package/examples/jsm/loaders/PCDLoader.js +4 -2
  60. package/examples/jsm/loaders/SVGLoader.js +1 -1
  61. package/examples/jsm/loaders/TDSLoader.js +0 -2
  62. package/examples/jsm/loaders/TGALoader.js +0 -2
  63. package/examples/jsm/loaders/USDLoader.js +100 -40
  64. package/examples/jsm/loaders/UltraHDRLoader.js +285 -160
  65. package/examples/jsm/loaders/VOXLoader.js +660 -117
  66. package/examples/jsm/loaders/VRMLLoader.js +79 -2
  67. package/examples/jsm/loaders/VTKLoader.js +37 -24
  68. package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
  69. package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
  70. package/examples/jsm/loaders/usd/USDAParser.js +447 -366
  71. package/examples/jsm/loaders/usd/USDCParser.js +1841 -6
  72. package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
  73. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +2 -2
  74. package/examples/jsm/materials/WoodNodeMaterial.js +11 -11
  75. package/examples/jsm/math/Octree.js +131 -1
  76. package/examples/jsm/misc/Volume.js +0 -1
  77. package/examples/jsm/misc/VolumeSlice.js +0 -1
  78. package/examples/jsm/objects/LensflareMesh.js +1 -1
  79. package/examples/jsm/objects/Sky.js +76 -4
  80. package/examples/jsm/objects/SkyMesh.js +127 -10
  81. package/examples/jsm/objects/Water.js +4 -3
  82. package/examples/jsm/objects/Water2.js +5 -3
  83. package/examples/jsm/objects/WaterMesh.js +5 -7
  84. package/examples/jsm/physics/AmmoPhysics.js +12 -7
  85. package/examples/jsm/physics/JoltPhysics.js +10 -6
  86. package/examples/jsm/physics/RapierPhysics.js +9 -5
  87. package/examples/jsm/postprocessing/EffectComposer.js +7 -5
  88. package/examples/jsm/postprocessing/OutputPass.js +9 -0
  89. package/examples/jsm/postprocessing/RenderPass.js +10 -0
  90. package/examples/jsm/postprocessing/RenderTransitionPass.js +1 -1
  91. package/examples/jsm/postprocessing/UnrealBloomPass.js +48 -18
  92. package/examples/jsm/renderers/CSS3DRenderer.js +1 -1
  93. package/examples/jsm/renderers/Projector.js +268 -30
  94. package/examples/jsm/renderers/SVGRenderer.js +193 -60
  95. package/examples/jsm/shaders/GTAOShader.js +19 -6
  96. package/examples/jsm/shaders/HalftoneShader.js +12 -1
  97. package/examples/jsm/shaders/PoissonDenoiseShader.js +6 -2
  98. package/examples/jsm/shaders/SAOShader.js +17 -4
  99. package/examples/jsm/shaders/SSAOShader.js +11 -1
  100. package/examples/jsm/shaders/SSRShader.js +6 -5
  101. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -4
  102. package/examples/jsm/shaders/VignetteShader.js +1 -1
  103. package/examples/jsm/transpiler/AST.js +44 -0
  104. package/examples/jsm/transpiler/GLSLDecoder.js +61 -4
  105. package/examples/jsm/transpiler/ShaderToyDecoder.js +2 -0
  106. package/examples/jsm/transpiler/TSLEncoder.js +46 -3
  107. package/examples/jsm/transpiler/TranspilerUtils.js +3 -3
  108. package/examples/jsm/transpiler/WGSLEncoder.js +27 -0
  109. package/examples/jsm/tsl/display/AfterImageNode.js +1 -1
  110. package/examples/jsm/tsl/display/AnaglyphPassNode.js +458 -16
  111. package/examples/jsm/tsl/display/AnamorphicNode.js +1 -1
  112. package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
  113. package/examples/jsm/tsl/display/BloomNode.js +16 -6
  114. package/examples/jsm/tsl/display/CRT.js +150 -0
  115. package/examples/jsm/tsl/display/DenoiseNode.js +1 -1
  116. package/examples/jsm/tsl/display/DepthOfFieldNode.js +1 -1
  117. package/examples/jsm/tsl/display/DotScreenNode.js +1 -1
  118. package/examples/jsm/tsl/display/FXAANode.js +2 -2
  119. package/examples/jsm/tsl/display/GTAONode.js +5 -4
  120. package/examples/jsm/tsl/display/GaussianBlurNode.js +11 -2
  121. package/examples/jsm/tsl/display/GodraysNode.js +624 -0
  122. package/examples/jsm/tsl/display/LensflareNode.js +1 -1
  123. package/examples/jsm/tsl/display/Lut3DNode.js +1 -1
  124. package/examples/jsm/tsl/display/OutlineNode.js +3 -3
  125. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -2
  126. package/examples/jsm/tsl/display/PixelationPassNode.js +7 -6
  127. package/examples/jsm/tsl/display/RGBShiftNode.js +2 -2
  128. package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
  129. package/examples/jsm/tsl/display/SMAANode.js +2 -2
  130. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  131. package/examples/jsm/tsl/display/SSGINode.js +8 -20
  132. package/examples/jsm/tsl/display/SSRNode.js +8 -8
  133. package/examples/jsm/tsl/display/SSSNode.js +6 -4
  134. package/examples/jsm/tsl/display/Shape.js +29 -0
  135. package/examples/jsm/tsl/display/SobelOperatorNode.js +2 -2
  136. package/examples/jsm/tsl/display/StereoCompositePassNode.js +8 -1
  137. package/examples/jsm/tsl/display/StereoPassNode.js +1 -2
  138. package/examples/jsm/tsl/display/TRAANode.js +273 -125
  139. package/examples/jsm/tsl/display/TransitionNode.js +1 -1
  140. package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
  141. package/examples/jsm/tsl/display/radialBlur.js +68 -0
  142. package/examples/jsm/tsl/math/Bayer.js +40 -1
  143. package/examples/jsm/utils/LDrawUtils.js +1 -1
  144. package/examples/jsm/utils/ShadowMapViewer.js +24 -10
  145. package/examples/jsm/utils/ShadowMapViewerGPU.js +1 -1
  146. package/examples/jsm/utils/WebGPUTextureUtils.js +1 -1
  147. package/package.json +20 -26
  148. package/src/Three.Core.js +2 -1
  149. package/src/Three.TSL.js +19 -11
  150. package/src/Three.WebGPU.Nodes.js +2 -0
  151. package/src/Three.WebGPU.js +3 -0
  152. package/src/Three.js +1 -0
  153. package/src/animation/AnimationAction.js +1 -1
  154. package/src/animation/AnimationClip.js +1 -1
  155. package/src/animation/AnimationMixer.js +6 -0
  156. package/src/animation/AnimationUtils.js +1 -12
  157. package/src/animation/KeyframeTrack.js +47 -8
  158. package/src/animation/PropertyMixer.js +4 -4
  159. package/src/animation/tracks/BooleanKeyframeTrack.js +1 -1
  160. package/src/animation/tracks/ColorKeyframeTrack.js +1 -1
  161. package/src/animation/tracks/NumberKeyframeTrack.js +1 -1
  162. package/src/animation/tracks/QuaternionKeyframeTrack.js +1 -1
  163. package/src/animation/tracks/StringKeyframeTrack.js +1 -1
  164. package/src/animation/tracks/VectorKeyframeTrack.js +1 -1
  165. package/src/audio/Audio.js +1 -1
  166. package/src/audio/AudioListener.js +5 -3
  167. package/src/cameras/Camera.js +32 -2
  168. package/src/cameras/CubeCamera.js +20 -0
  169. package/src/constants.js +90 -5
  170. package/src/core/BufferGeometry.js +14 -2
  171. package/src/core/Clock.js +7 -0
  172. package/src/core/Object3D.js +56 -4
  173. package/src/core/Raycaster.js +2 -2
  174. package/src/core/RenderTarget.js +3 -4
  175. package/src/extras/PMREMGenerator.js +7 -18
  176. package/src/extras/TextureUtils.js +5 -1
  177. package/src/geometries/ExtrudeGeometry.js +2 -2
  178. package/src/geometries/PolyhedronGeometry.js +1 -1
  179. package/src/geometries/TorusGeometry.js +8 -3
  180. package/src/helpers/CameraHelper.js +3 -0
  181. package/src/helpers/DirectionalLightHelper.js +4 -1
  182. package/src/helpers/HemisphereLightHelper.js +3 -0
  183. package/src/helpers/PointLightHelper.js +1 -25
  184. package/src/helpers/SpotLightHelper.js +3 -0
  185. package/src/lights/DirectionalLight.js +13 -0
  186. package/src/lights/HemisphereLight.js +10 -0
  187. package/src/lights/Light.js +1 -11
  188. package/src/lights/LightProbe.js +0 -15
  189. package/src/lights/LightShadow.js +15 -6
  190. package/src/lights/PointLight.js +15 -0
  191. package/src/lights/PointLightShadow.js +0 -86
  192. package/src/lights/SpotLight.js +22 -1
  193. package/src/lights/webgpu/IESSpotLight.js +2 -1
  194. package/src/loaders/Cache.js +28 -0
  195. package/src/loaders/FileLoader.js +1 -1
  196. package/src/loaders/ImageBitmapLoader.js +8 -3
  197. package/src/loaders/Loader.js +6 -0
  198. package/src/loaders/MaterialLoader.js +2 -1
  199. package/src/loaders/ObjectLoader.js +21 -2
  200. package/src/loaders/nodes/NodeLoader.js +2 -2
  201. package/src/materials/Material.js +2 -0
  202. package/src/materials/MeshLambertMaterial.js +9 -0
  203. package/src/materials/MeshPhongMaterial.js +9 -0
  204. package/src/materials/ShaderMaterial.js +20 -1
  205. package/src/materials/nodes/Line2NodeMaterial.js +7 -7
  206. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +5 -2
  207. package/src/materials/nodes/MeshStandardNodeMaterial.js +5 -4
  208. package/src/materials/nodes/NodeMaterial.js +72 -25
  209. package/src/materials/nodes/manager/NodeMaterialObserver.js +10 -4
  210. package/src/math/Line3.js +3 -5
  211. package/src/math/MathUtils.js +10 -10
  212. package/src/math/Matrix4.js +74 -65
  213. package/src/math/Quaternion.js +3 -29
  214. package/src/math/Sphere.js +1 -1
  215. package/src/math/Vector3.js +3 -5
  216. package/src/math/interpolants/BezierInterpolant.js +108 -0
  217. package/src/nodes/Nodes.js +87 -68
  218. package/src/nodes/TSL.js +6 -6
  219. package/src/nodes/accessors/Arrays.js +1 -1
  220. package/src/nodes/accessors/BatchNode.js +10 -10
  221. package/src/nodes/accessors/Bitangent.js +5 -5
  222. package/src/nodes/accessors/BufferAttributeNode.js +98 -12
  223. package/src/nodes/accessors/BufferNode.js +29 -2
  224. package/src/nodes/accessors/Camera.js +149 -28
  225. package/src/nodes/accessors/ClippingNode.js +4 -4
  226. package/src/nodes/accessors/CubeTextureNode.js +20 -1
  227. package/src/nodes/accessors/InstanceNode.js +148 -43
  228. package/src/nodes/accessors/MaterialNode.js +9 -1
  229. package/src/nodes/accessors/MaterialReferenceNode.js +1 -2
  230. package/src/nodes/accessors/ModelNode.js +1 -1
  231. package/src/nodes/accessors/Normal.js +11 -11
  232. package/src/nodes/accessors/Position.js +34 -2
  233. package/src/nodes/accessors/ReferenceBaseNode.js +4 -4
  234. package/src/nodes/accessors/ReferenceNode.js +4 -4
  235. package/src/nodes/accessors/RendererReferenceNode.js +1 -2
  236. package/src/nodes/accessors/SceneProperties.js +53 -0
  237. package/src/nodes/accessors/SkinningNode.js +27 -26
  238. package/src/nodes/accessors/StorageBufferNode.js +4 -21
  239. package/src/nodes/accessors/StorageTextureNode.js +37 -1
  240. package/src/nodes/accessors/Tangent.js +4 -14
  241. package/src/nodes/accessors/Texture3DNode.js +32 -35
  242. package/src/nodes/accessors/TextureNode.js +58 -22
  243. package/src/nodes/accessors/UniformArrayNode.js +4 -2
  244. package/src/nodes/accessors/UserDataNode.js +1 -2
  245. package/src/nodes/accessors/VertexColorNode.js +1 -2
  246. package/src/nodes/code/FunctionNode.js +1 -2
  247. package/src/nodes/core/ArrayNode.js +20 -1
  248. package/src/nodes/core/AssignNode.js +2 -2
  249. package/src/nodes/core/AttributeNode.js +2 -2
  250. package/src/nodes/core/ContextNode.js +103 -4
  251. package/src/nodes/core/MRTNode.js +48 -2
  252. package/src/nodes/core/Node.js +29 -3
  253. package/src/nodes/core/NodeBuilder.js +170 -53
  254. package/src/nodes/core/NodeError.js +28 -0
  255. package/src/nodes/core/NodeFrame.js +12 -4
  256. package/src/nodes/core/NodeUtils.js +10 -8
  257. package/src/nodes/core/OutputStructNode.js +12 -10
  258. package/src/nodes/core/ParameterNode.js +3 -3
  259. package/src/nodes/core/PropertyNode.js +19 -3
  260. package/src/nodes/core/StackNode.js +65 -16
  261. package/src/nodes/core/StackTrace.js +139 -0
  262. package/src/nodes/core/StructNode.js +16 -2
  263. package/src/nodes/core/StructTypeNode.js +11 -17
  264. package/src/nodes/core/SubBuildNode.js +1 -1
  265. package/src/nodes/core/UniformNode.js +21 -5
  266. package/src/nodes/core/VarNode.js +47 -22
  267. package/src/nodes/core/VaryingNode.js +1 -18
  268. package/src/nodes/display/BlendModes.js +0 -64
  269. package/src/nodes/display/ColorAdjustment.js +17 -0
  270. package/src/nodes/display/ColorSpaceNode.js +3 -3
  271. package/src/nodes/display/NormalMapNode.js +39 -4
  272. package/src/nodes/display/PassNode.js +98 -9
  273. package/src/nodes/display/RenderOutputNode.js +3 -3
  274. package/src/nodes/display/ScreenNode.js +3 -1
  275. package/src/nodes/display/ToneMappingNode.js +1 -1
  276. package/src/nodes/display/ToonOutlinePassNode.js +2 -2
  277. package/src/nodes/display/ViewportDepthNode.js +52 -4
  278. package/src/nodes/display/ViewportTextureNode.js +21 -4
  279. package/src/nodes/fog/Fog.js +18 -35
  280. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +3 -3
  281. package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
  282. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  283. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +1 -1
  284. package/src/nodes/functions/PhysicalLightingModel.js +126 -45
  285. package/src/nodes/geometry/RangeNode.js +4 -2
  286. package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -2
  287. package/src/nodes/gpgpu/ComputeNode.js +5 -4
  288. package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
  289. package/src/nodes/gpgpu/WorkgroupInfoNode.js +4 -4
  290. package/src/nodes/lighting/AnalyticLightNode.js +53 -0
  291. package/src/nodes/lighting/EnvironmentNode.js +28 -3
  292. package/src/nodes/lighting/LightsNode.js +2 -2
  293. package/src/nodes/lighting/PointShadowNode.js +162 -149
  294. package/src/nodes/lighting/ShadowFilterNode.js +53 -65
  295. package/src/nodes/lighting/ShadowNode.js +97 -41
  296. package/src/nodes/math/BitcountNode.js +433 -0
  297. package/src/nodes/math/ConditionalNode.js +2 -2
  298. package/src/nodes/math/MathNode.js +3 -40
  299. package/src/nodes/math/OperatorNode.js +2 -1
  300. package/src/nodes/math/PackFloatNode.js +98 -0
  301. package/src/nodes/math/UnpackFloatNode.js +96 -0
  302. package/src/nodes/pmrem/PMREMNode.js +1 -1
  303. package/src/nodes/pmrem/PMREMUtils.js +9 -15
  304. package/src/nodes/tsl/TSLCore.js +17 -14
  305. package/src/nodes/utils/ArrayElementNode.js +13 -0
  306. package/src/nodes/utils/DebugNode.js +11 -11
  307. package/src/nodes/utils/EventNode.js +1 -2
  308. package/src/nodes/utils/JoinNode.js +2 -2
  309. package/src/nodes/utils/LoopNode.js +1 -1
  310. package/src/nodes/utils/MemberNode.js +1 -1
  311. package/src/nodes/utils/Packing.js +13 -1
  312. package/src/nodes/utils/PostProcessingUtils.js +33 -1
  313. package/src/nodes/utils/RTTNode.js +1 -1
  314. package/src/nodes/utils/ReflectorNode.js +3 -4
  315. package/src/nodes/utils/SampleNode.js +1 -1
  316. package/src/nodes/utils/SpriteSheetUV.js +35 -0
  317. package/src/nodes/utils/UVUtils.js +28 -0
  318. package/src/objects/BatchedMesh.js +27 -14
  319. package/src/objects/InstancedMesh.js +11 -0
  320. package/src/objects/Line.js +1 -1
  321. package/src/objects/Mesh.js +1 -1
  322. package/src/objects/Points.js +1 -1
  323. package/src/objects/Skeleton.js +9 -0
  324. package/src/renderers/WebGLRenderer.js +178 -92
  325. package/src/renderers/common/Backend.js +29 -0
  326. package/src/renderers/common/Background.js +24 -11
  327. package/src/renderers/common/BindGroup.js +1 -9
  328. package/src/renderers/common/Binding.js +11 -0
  329. package/src/renderers/common/Bindings.js +27 -12
  330. package/src/renderers/common/BlendMode.js +143 -0
  331. package/src/renderers/common/Buffer.js +40 -0
  332. package/src/renderers/common/BundleGroup.js +1 -1
  333. package/src/renderers/common/ChainMap.js +30 -6
  334. package/src/renderers/common/CubeRenderTarget.js +50 -6
  335. package/src/renderers/common/Geometries.js +29 -3
  336. package/src/renderers/common/Lighting.js +5 -21
  337. package/src/renderers/common/Pipelines.js +4 -4
  338. package/src/renderers/common/PostProcessing.js +8 -206
  339. package/src/renderers/common/RenderBundles.js +2 -1
  340. package/src/renderers/common/RenderContext.js +16 -0
  341. package/src/renderers/common/RenderContexts.js +33 -49
  342. package/src/renderers/common/RenderLists.js +2 -1
  343. package/src/renderers/common/RenderObject.js +15 -3
  344. package/src/renderers/common/RenderObjectPipeline.js +40 -0
  345. package/src/renderers/common/RenderObjects.js +18 -2
  346. package/src/renderers/common/RenderPipeline.js +203 -17
  347. package/src/renderers/common/Renderer.js +257 -72
  348. package/src/renderers/common/Sampler.js +4 -4
  349. package/src/renderers/common/StorageBuffer.js +13 -1
  350. package/src/renderers/common/Textures.js +17 -1
  351. package/src/renderers/common/TimestampQueryPool.js +5 -3
  352. package/src/renderers/common/Uniform.js +8 -0
  353. package/src/renderers/common/UniformsGroup.js +61 -0
  354. package/src/renderers/common/XRManager.js +3 -2
  355. package/src/renderers/common/extras/PMREMGenerator.js +2 -8
  356. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  357. package/src/renderers/common/nodes/{Nodes.js → NodeManager.js} +18 -6
  358. package/src/renderers/common/nodes/NodeStorageBuffer.js +13 -2
  359. package/src/renderers/common/nodes/NodeUniformBuffer.js +52 -0
  360. package/src/renderers/shaders/DFGLUTData.js +19 -34
  361. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
  362. package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
  363. package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
  364. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
  365. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
  366. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
  367. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +5 -2
  368. package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
  369. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
  370. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
  371. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +112 -51
  372. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
  373. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +225 -186
  374. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  375. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  376. package/src/renderers/shaders/ShaderChunk.js +3 -3
  377. package/src/renderers/shaders/ShaderLib/depth.glsl.js +3 -0
  378. package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +1 -2
  379. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
  380. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
  381. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
  382. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
  383. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
  384. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -1
  385. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
  386. package/src/renderers/shaders/ShaderLib.js +7 -5
  387. package/src/renderers/shaders/UniformsLib.js +0 -3
  388. package/src/renderers/webgl/WebGLBackground.js +2 -2
  389. package/src/renderers/webgl/WebGLBindingStates.js +99 -27
  390. package/src/renderers/webgl/WebGLCapabilities.js +3 -4
  391. package/src/renderers/webgl/WebGLEnvironments.js +228 -0
  392. package/src/renderers/webgl/WebGLGeometries.js +10 -7
  393. package/src/renderers/webgl/WebGLLights.js +18 -1
  394. package/src/renderers/webgl/WebGLMaterials.js +12 -0
  395. package/src/renderers/webgl/WebGLObjects.js +3 -1
  396. package/src/renderers/webgl/WebGLOutput.js +267 -0
  397. package/src/renderers/webgl/WebGLProgram.js +45 -109
  398. package/src/renderers/webgl/WebGLPrograms.js +45 -49
  399. package/src/renderers/webgl/WebGLRenderLists.js +15 -0
  400. package/src/renderers/webgl/WebGLShadowMap.js +188 -24
  401. package/src/renderers/webgl/WebGLState.js +32 -37
  402. package/src/renderers/webgl/WebGLTextures.js +89 -28
  403. package/src/renderers/webgl/WebGLUniforms.js +40 -3
  404. package/src/renderers/webgl/WebGLUtils.js +6 -2
  405. package/src/renderers/webgl-fallback/WebGLBackend.js +148 -18
  406. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +156 -35
  407. package/src/renderers/webgl-fallback/utils/WebGLState.js +181 -5
  408. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +5 -3
  409. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +9 -9
  410. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +6 -2
  411. package/src/renderers/webgpu/WebGPUBackend.js +119 -13
  412. package/src/renderers/webgpu/WebGPURenderer.js +2 -1
  413. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +322 -68
  414. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -17
  415. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +357 -200
  416. package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -0
  417. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +61 -23
  418. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +152 -200
  419. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +65 -42
  420. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +7 -7
  421. package/src/renderers/webgpu/utils/WebGPUUtils.js +17 -11
  422. package/src/renderers/webxr/WebXRManager.js +2 -2
  423. package/src/textures/CubeDepthTexture.js +76 -0
  424. package/src/textures/Source.js +1 -1
  425. package/src/textures/Texture.js +3 -3
  426. package/src/utils.js +258 -3
  427. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -434
  428. package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -167
  429. package/examples/jsm/shaders/GodRaysShader.js +0 -333
  430. package/src/nodes/accessors/SceneNode.js +0 -145
  431. package/src/nodes/code/ScriptableNode.js +0 -726
  432. package/src/nodes/code/ScriptableValueNode.js +0 -253
  433. package/src/nodes/display/PosterizeNode.js +0 -65
  434. package/src/nodes/functions/BSDF/DFGApprox.js +0 -71
  435. package/src/nodes/utils/SpriteSheetUVNode.js +0 -90
  436. package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
  437. package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -134
@@ -4,8 +4,10 @@ import {
4
4
  Data3DTexture,
5
5
  FileLoader,
6
6
  Float32BufferAttribute,
7
+ Group,
7
8
  Loader,
8
9
  LinearFilter,
10
+ Matrix4,
9
11
  Mesh,
10
12
  MeshStandardMaterial,
11
13
  NearestFilter,
@@ -13,21 +15,228 @@ import {
13
15
  SRGBColorSpace
14
16
  } from 'three';
15
17
 
18
+ // Helper function to read a STRING from the data view
19
+ function readString( data, offset ) {
20
+
21
+ const size = data.getUint32( offset, true );
22
+ offset += 4;
23
+
24
+ let str = '';
25
+ for ( let i = 0; i < size; i ++ ) {
26
+
27
+ str += String.fromCharCode( data.getUint8( offset ++ ) );
28
+
29
+ }
30
+
31
+ return { value: str, size: 4 + size };
32
+
33
+ }
34
+
35
+ // Helper function to read a DICT from the data view
36
+ function readDict( data, offset ) {
37
+
38
+ const dict = {};
39
+ const count = data.getUint32( offset, true );
40
+ offset += 4;
41
+
42
+ let totalSize = 4;
43
+
44
+ for ( let i = 0; i < count; i ++ ) {
45
+
46
+ const key = readString( data, offset );
47
+ offset += key.size;
48
+ totalSize += key.size;
49
+
50
+ const value = readString( data, offset );
51
+ offset += value.size;
52
+ totalSize += value.size;
53
+
54
+ dict[ key.value ] = value.value;
55
+
56
+ }
57
+
58
+ return { value: dict, size: totalSize };
59
+
60
+ }
61
+
62
+ // Helper function to decode ROTATION byte into a rotation matrix
63
+ function decodeRotation( byte ) {
64
+
65
+ // The rotation is stored as a row-major 3x3 matrix encoded in a single byte
66
+ // Bits 0-1: index of the non-zero entry in the first row
67
+ // Bits 2-3: index of the non-zero entry in the second row
68
+ // Bit 4: sign of the first row entry (0 = positive, 1 = negative)
69
+ // Bit 5: sign of the second row entry
70
+ // Bit 6: sign of the third row entry
71
+ // The third row index is determined by the remaining column
72
+
73
+ const index1 = byte & 0x3;
74
+ const index2 = ( byte >> 2 ) & 0x3;
75
+ const sign1 = ( byte >> 4 ) & 0x1 ? - 1 : 1;
76
+ const sign2 = ( byte >> 5 ) & 0x1 ? - 1 : 1;
77
+ const sign3 = ( byte >> 6 ) & 0x1 ? - 1 : 1;
78
+
79
+ // Find the third row index (the one not used by row 0 or row 1)
80
+ const index3 = 3 - index1 - index2;
81
+
82
+ // Build the VOX rotation matrix (row-major 3x3)
83
+ // r[row][col] - each row has one non-zero entry
84
+ const r = [
85
+ [ 0, 0, 0 ],
86
+ [ 0, 0, 0 ],
87
+ [ 0, 0, 0 ]
88
+ ];
89
+
90
+ r[ 0 ][ index1 ] = sign1;
91
+ r[ 1 ][ index2 ] = sign2;
92
+ r[ 2 ][ index3 ] = sign3;
93
+
94
+ // Convert from VOX coordinate system (Z-up) to Three.js (Y-up)
95
+ // VOX: X-right, Y-forward, Z-up
96
+ // Three.js: X-right, Y-up, Z-backward
97
+ // Transformation: x' = x, y' = z, z' = -y
98
+ //
99
+ // To convert rotation matrix R_vox to R_three:
100
+ // R_three = C * R_vox * C^-1
101
+ // where C converts VOX coords to Three.js coords
102
+
103
+ // Apply coordinate change: swap Y and Z, negate new Z
104
+ // This is equivalent to: C * R * C^-1
105
+ const m = new Matrix4();
106
+ m.set(
107
+ r[ 0 ][ 0 ], r[ 0 ][ 2 ], - r[ 0 ][ 1 ], 0,
108
+ r[ 2 ][ 0 ], r[ 2 ][ 2 ], - r[ 2 ][ 1 ], 0,
109
+ - r[ 1 ][ 0 ], - r[ 1 ][ 2 ], r[ 1 ][ 1 ], 0,
110
+ 0, 0, 0, 1
111
+ );
112
+
113
+ return m;
114
+
115
+ }
116
+
117
+ // Apply VOX transform to a Three.js object
118
+ function applyTransform( object, node ) {
119
+
120
+ if ( node.attributes._name ) {
121
+
122
+ object.name = node.attributes._name;
123
+
124
+ }
125
+
126
+ if ( node.frames.length > 0 ) {
127
+
128
+ const frame = node.frames[ 0 ];
129
+
130
+ if ( frame.rotation ) {
131
+
132
+ object.applyMatrix4( frame.rotation );
133
+
134
+ }
135
+
136
+ if ( frame.translation ) {
137
+
138
+ // VOX uses Z-up, Three.js uses Y-up
139
+ object.position.set(
140
+ frame.translation.x,
141
+ frame.translation.z,
142
+ - frame.translation.y
143
+ );
144
+
145
+ }
146
+
147
+ }
148
+
149
+ }
150
+
151
+ // Recursively build Three.js object graph from VOX nodes
152
+ function buildObject( nodeId, nodes, chunks ) {
153
+
154
+ const node = nodes[ nodeId ];
155
+
156
+ if ( node.type === 'transform' ) {
157
+
158
+ const childNode = nodes[ node.childNodeId ];
159
+
160
+ // Check if this transform has actual transformation data
161
+ const frame = node.frames[ 0 ];
162
+ const hasTransform = frame && ( frame.rotation || frame.translation );
163
+
164
+ // Flatten: if child is a single-model shape, apply transform directly to mesh
165
+ if ( childNode.type === 'shape' && childNode.models.length === 1 ) {
166
+
167
+ const chunk = chunks[ childNode.models[ 0 ].modelId ];
168
+ const mesh = buildMesh( chunk );
169
+ applyTransform( mesh, node );
170
+ return mesh;
171
+
172
+ }
173
+
174
+ // If no transform, just return the child directly (avoid unnecessary group)
175
+ if ( ! hasTransform ) {
176
+
177
+ const child = buildObject( node.childNodeId, nodes, chunks );
178
+ if ( child && node.attributes._name ) child.name = node.attributes._name;
179
+ return child;
180
+
181
+ }
182
+
183
+ // Otherwise create a group
184
+ const group = new Group();
185
+ applyTransform( group, node );
186
+
187
+ const child = buildObject( node.childNodeId, nodes, chunks );
188
+ if ( child ) group.add( child );
189
+
190
+ return group;
191
+
192
+ } else if ( node.type === 'group' ) {
193
+
194
+ const group = new Group();
195
+
196
+ for ( const childId of node.childIds ) {
197
+
198
+ const child = buildObject( childId, nodes, chunks );
199
+ if ( child ) group.add( child );
200
+
201
+ }
202
+
203
+ return group;
204
+
205
+ } else if ( node.type === 'shape' ) {
206
+
207
+ // Shape reached directly (shouldn't happen in well-formed files, but handle it)
208
+ if ( node.models.length === 1 ) {
209
+
210
+ const chunk = chunks[ node.models[ 0 ].modelId ];
211
+ return buildMesh( chunk );
212
+
213
+ }
214
+
215
+ const group = new Group();
216
+
217
+ for ( const model of node.models ) {
218
+
219
+ const chunk = chunks[ model.modelId ];
220
+ group.add( buildMesh( chunk ) );
221
+
222
+ }
223
+
224
+ return group;
225
+
226
+ }
227
+
228
+ return null;
229
+
230
+ }
231
+
16
232
  /**
17
233
  * A loader for the VOX format.
18
234
  *
19
235
  * ```js
20
236
  * const loader = new VOXLoader();
21
- * const chunks = await loader.loadAsync( 'models/vox/monu10.vox' );
22
- *
23
- * for ( let i = 0; i < chunks.length; i ++ ) {
237
+ * const result = await loader.loadAsync( 'models/vox/monu10.vox' );
24
238
  *
25
- * const chunk = chunks[ i ];
26
- * const mesh = new VOXMesh( chunk );
27
- * mesh.scale.setScalar( 0.0015 );
28
- * scene.add( mesh );
29
- *
30
- * }
239
+ * scene.add( result.scene.children[ 0 ] );
31
240
  * ```
32
241
  * @augments Loader
33
242
  * @three_import import { VOXLoader } from 'three/addons/loaders/VOXLoader.js';
@@ -39,7 +248,7 @@ class VOXLoader extends Loader {
39
248
  * to the `onLoad()` callback.
40
249
  *
41
250
  * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
42
- * @param {function(Array<Object>)} onLoad - Executed when the loading process has been finished.
251
+ * @param {function(Object)} onLoad - Executed when the loading process has been finished.
43
252
  * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
44
253
  * @param {onErrorCallback} onError - Executed when errors occur.
45
254
  */
@@ -78,10 +287,10 @@ class VOXLoader extends Loader {
78
287
  }
79
288
 
80
289
  /**
81
- * Parses the given VOX data and returns the resulting chunks.
290
+ * Parses the given VOX data and returns the result object.
82
291
  *
83
292
  * @param {ArrayBuffer} buffer - The raw VOX data as an array buffer.
84
- * @return {Array<Object>} The parsed chunks.
293
+ * @return {Object} The parsed VOX data with properties: chunks, scene.
85
294
  */
86
295
  parse( buffer ) {
87
296
 
@@ -97,7 +306,7 @@ class VOXLoader extends Loader {
97
306
 
98
307
  }
99
308
 
100
- if ( version !== 150 ) {
309
+ if ( version !== 150 && version !== 200 ) {
101
310
 
102
311
  console.error( 'THREE.VOXLoader: Invalid VOX file. Unsupported version:', version );
103
312
  return;
@@ -144,6 +353,10 @@ class VOXLoader extends Loader {
144
353
  let chunk;
145
354
  const chunks = [];
146
355
 
356
+ // Extension data
357
+ const nodes = {};
358
+ let palette = DEFAULT_PALETTE;
359
+
147
360
  while ( i < data.byteLength ) {
148
361
 
149
362
  let id = '';
@@ -181,7 +394,7 @@ class VOXLoader extends Loader {
181
394
 
182
395
  } else if ( id === 'RGBA' ) {
183
396
 
184
- const palette = [ 0 ];
397
+ palette = [ 0 ];
185
398
 
186
399
  for ( let j = 0; j < 256; j ++ ) {
187
400
 
@@ -191,186 +404,516 @@ class VOXLoader extends Loader {
191
404
 
192
405
  chunk.palette = palette;
193
406
 
194
- } else {
407
+ } else if ( id === 'nTRN' ) {
408
+
409
+ // Transform Node
410
+ const nodeId = data.getUint32( i, true ); i += 4;
411
+ const attributes = readDict( data, i );
412
+ i += attributes.size;
413
+
414
+ const childNodeId = data.getUint32( i, true ); i += 4;
415
+ i += 4; // reserved (-1)
416
+ const layerId = data.getInt32( i, true ); i += 4;
417
+ const numFrames = data.getUint32( i, true ); i += 4;
418
+
419
+ const frames = [];
420
+
421
+ for ( let f = 0; f < numFrames; f ++ ) {
422
+
423
+ const frameDict = readDict( data, i );
424
+ i += frameDict.size;
425
+
426
+ const frame = { rotation: null, translation: null };
427
+
428
+ if ( frameDict.value._r !== undefined ) {
429
+
430
+ frame.rotation = decodeRotation( parseInt( frameDict.value._r ) );
195
431
 
196
- // console.log( id, chunkSize, childChunks );
432
+ }
197
433
 
434
+ if ( frameDict.value._t !== undefined ) {
435
+
436
+ const parts = frameDict.value._t.split( ' ' ).map( Number );
437
+ frame.translation = { x: parts[ 0 ], y: parts[ 1 ], z: parts[ 2 ] };
438
+
439
+ }
440
+
441
+ frames.push( frame );
442
+
443
+ }
444
+
445
+ nodes[ nodeId ] = {
446
+ type: 'transform',
447
+ id: nodeId,
448
+ attributes: attributes.value,
449
+ childNodeId: childNodeId,
450
+ layerId: layerId,
451
+ frames: frames
452
+ };
453
+
454
+ } else if ( id === 'nGRP' ) {
455
+
456
+ // Group Node
457
+ const nodeId = data.getUint32( i, true ); i += 4;
458
+ const attributes = readDict( data, i );
459
+ i += attributes.size;
460
+
461
+ const numChildren = data.getUint32( i, true ); i += 4;
462
+ const childIds = [];
463
+
464
+ for ( let c = 0; c < numChildren; c ++ ) {
465
+
466
+ childIds.push( data.getUint32( i, true ) ); i += 4;
467
+
468
+ }
469
+
470
+ nodes[ nodeId ] = {
471
+ type: 'group',
472
+ id: nodeId,
473
+ attributes: attributes.value,
474
+ childIds: childIds
475
+ };
476
+
477
+ } else if ( id === 'nSHP' ) {
478
+
479
+ // Shape Node
480
+ const nodeId = data.getUint32( i, true ); i += 4;
481
+ const attributes = readDict( data, i );
482
+ i += attributes.size;
483
+
484
+ const numModels = data.getUint32( i, true ); i += 4;
485
+ const models = [];
486
+
487
+ for ( let m = 0; m < numModels; m ++ ) {
488
+
489
+ const modelId = data.getUint32( i, true ); i += 4;
490
+ const modelAttributes = readDict( data, i );
491
+ i += modelAttributes.size;
492
+
493
+ models.push( {
494
+ modelId: modelId,
495
+ attributes: modelAttributes.value
496
+ } );
497
+
498
+ }
499
+
500
+ nodes[ nodeId ] = {
501
+ type: 'shape',
502
+ id: nodeId,
503
+ attributes: attributes.value,
504
+ models: models
505
+ };
506
+
507
+ } else {
508
+
509
+ // Skip unknown chunks
198
510
  i += chunkSize;
199
511
 
200
512
  }
201
513
 
202
514
  }
203
515
 
204
- return chunks;
516
+ // Apply palette to all chunks
517
+ for ( let c = 0; c < chunks.length; c ++ ) {
518
+
519
+ chunks[ c ].palette = palette;
520
+
521
+ }
522
+
523
+ // Build Three.js scene graph from nodes
524
+ let scene = null;
525
+
526
+ if ( Object.keys( nodes ).length > 0 ) {
527
+
528
+ scene = buildObject( 0, nodes, chunks );
529
+
530
+ }
531
+
532
+ // Build result object
533
+ const result = {
534
+ chunks: chunks,
535
+ scene: scene
536
+ };
537
+
538
+ // @deprecated, r182
539
+ // Proxy for backwards compatibility with array-like access
540
+ let warned = false;
541
+
542
+ return new Proxy( result, {
543
+
544
+ get( target, prop ) {
545
+
546
+ // Handle numeric indices
547
+ if ( typeof prop === 'string' && /^\d+$/.test( prop ) ) {
548
+
549
+ if ( ! warned ) {
550
+
551
+ console.warn( 'THREE.VOXLoader: Accessing result as an array is deprecated. Use result.chunks[] instead.' );
552
+ warned = true;
553
+
554
+ }
555
+
556
+ return target.chunks[ parseInt( prop ) ];
557
+
558
+ }
559
+
560
+ // Handle array properties/methods
561
+ if ( prop === 'length' ) {
562
+
563
+ if ( ! warned ) {
564
+
565
+ console.warn( 'THREE.VOXLoader: Accessing result as an array is deprecated. Use result.chunks instead.' );
566
+ warned = true;
567
+
568
+ }
569
+
570
+ return target.chunks.length;
571
+
572
+ }
573
+
574
+ // Handle iteration
575
+ if ( prop === Symbol.iterator ) {
576
+
577
+ if ( ! warned ) {
578
+
579
+ console.warn( 'THREE.VOXLoader: Iterating result as an array is deprecated. Use result.chunks instead.' );
580
+ warned = true;
581
+
582
+ }
583
+
584
+ return target.chunks[ Symbol.iterator ].bind( target.chunks );
585
+
586
+ }
587
+
588
+ return target[ prop ];
589
+
590
+ }
591
+
592
+ } );
205
593
 
206
594
  }
207
595
 
208
596
  }
209
597
 
210
598
  /**
211
- * A VOX mesh.
212
- *
213
- * Instances of this class are created from the loaded chunks of {@link VOXLoader}.
599
+ * Builds a mesh from a VOX chunk.
214
600
  *
215
- * @augments Mesh
601
+ * @param {Object} chunk - A VOX chunk loaded via {@link VOXLoader}.
602
+ * @return {Mesh} The generated mesh.
216
603
  */
217
- class VOXMesh extends Mesh {
604
+ function buildMesh( chunk ) {
218
605
 
219
- /**
220
- * Constructs a new VOX mesh.
221
- *
222
- * @param {Object} chunk - A VOX chunk loaded via {@link VOXLoader}.
223
- */
224
- constructor( chunk ) {
606
+ const data = chunk.data;
607
+ const size = chunk.size;
608
+ const palette = chunk.palette;
609
+
610
+ const sx = size.x;
611
+ const sy = size.y;
612
+ const sz = size.z;
613
+
614
+ // Build volume with color indices
615
+
616
+ const volume = new Uint8Array( sx * sy * sz );
617
+
618
+ for ( let j = 0; j < data.length; j += 4 ) {
619
+
620
+ const x = data[ j + 0 ];
621
+ const y = data[ j + 1 ];
622
+ const z = data[ j + 2 ];
623
+ const c = data[ j + 3 ];
624
+
625
+ volume[ x + y * sx + z * sx * sy ] = c;
626
+
627
+ }
628
+
629
+ // Greedy meshing
630
+
631
+ const vertices = [];
632
+ const indices = [];
633
+ const colors = [];
634
+
635
+ const _color = new Color();
636
+ let hasColors = false;
637
+
638
+ // Process each of the 6 face directions
639
+ // dims: the 3 axis sizes, d: which axis is normal to the face
640
+ const dims = [ sx, sy, sz ];
641
+
642
+ for ( let d = 0; d < 3; d ++ ) {
643
+
644
+ const u = ( d + 1 ) % 3;
645
+ const v = ( d + 2 ) % 3;
646
+
647
+ const dimsD = dims[ d ];
648
+ const dimsU = dims[ u ];
649
+ const dimsV = dims[ v ];
650
+
651
+ const q = [ 0, 0, 0 ];
652
+ const mask = new Int16Array( dimsU * dimsV );
653
+
654
+ q[ d ] = 1;
655
+
656
+ // Sweep through slices
657
+ for ( let slice = 0; slice <= dimsD; slice ++ ) {
658
+
659
+ // Build mask for this slice
660
+ let n = 0;
661
+
662
+ for ( let vv = 0; vv < dimsV; vv ++ ) {
663
+
664
+ for ( let uu = 0; uu < dimsU; uu ++ ) {
665
+
666
+ const pos = [ 0, 0, 0 ];
667
+ pos[ d ] = slice;
668
+ pos[ u ] = uu;
669
+ pos[ v ] = vv;
225
670
 
226
- const data = chunk.data;
227
- const size = chunk.size;
228
- const palette = chunk.palette;
671
+ const x0 = pos[ 0 ], y0 = pos[ 1 ], z0 = pos[ 2 ];
229
672
 
230
- //
673
+ // Get voxel behind and in front of this face
674
+ const behind = ( slice > 0 ) ? volume[ ( x0 - q[ 0 ] ) + ( y0 - q[ 1 ] ) * sx + ( z0 - q[ 2 ] ) * sx * sy ] : 0;
675
+ const infront = ( slice < dimsD ) ? volume[ x0 + y0 * sx + z0 * sx * sy ] : 0;
231
676
 
232
- const vertices = [];
233
- const colors = [];
677
+ // Face exists if exactly one side is solid
678
+ if ( behind > 0 && infront === 0 ) {
234
679
 
235
- const nx = [ 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 ];
236
- const px = [ 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0 ];
237
- const py = [ 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 ];
238
- const ny = [ 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0 ];
239
- const nz = [ 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0 ];
240
- const pz = [ 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1 ];
680
+ mask[ n ] = behind; // positive face
241
681
 
242
- const _color = new Color();
682
+ } else if ( infront > 0 && behind === 0 ) {
243
683
 
244
- function add( tile, x, y, z, r, g, b ) {
684
+ mask[ n ] = - infront; // negative face
245
685
 
246
- x -= size.x / 2;
247
- y -= size.z / 2;
248
- z += size.y / 2;
686
+ } else {
249
687
 
250
- for ( let i = 0; i < 18; i += 3 ) {
688
+ mask[ n ] = 0;
251
689
 
252
- _color.setRGB( r, g, b, SRGBColorSpace );
690
+ }
253
691
 
254
- vertices.push( tile[ i + 0 ] + x, tile[ i + 1 ] + y, tile[ i + 2 ] + z );
255
- colors.push( _color.r, _color.g, _color.b );
692
+ n ++;
693
+
694
+ }
256
695
 
257
696
  }
258
697
 
259
- }
698
+ // Greedy merge mask into quads
699
+ n = 0;
260
700
 
261
- // Store data in a volume for sampling
701
+ for ( let vv = 0; vv < dimsV; vv ++ ) {
262
702
 
263
- const offsety = size.x;
264
- const offsetz = size.x * size.y;
703
+ for ( let uu = 0; uu < dimsU; ) {
265
704
 
266
- const array = new Uint8Array( size.x * size.y * size.z );
705
+ const c = mask[ n ];
267
706
 
268
- for ( let j = 0; j < data.length; j += 4 ) {
707
+ if ( c !== 0 ) {
269
708
 
270
- const x = data[ j + 0 ];
271
- const y = data[ j + 1 ];
272
- const z = data[ j + 2 ];
709
+ // Find width
710
+ let w = 1;
273
711
 
274
- const index = x + ( y * offsety ) + ( z * offsetz );
712
+ while ( uu + w < dimsU && mask[ n + w ] === c ) {
275
713
 
276
- array[ index ] = 255;
714
+ w ++;
277
715
 
278
- }
716
+ }
279
717
 
280
- // Construct geometry
718
+ // Find height
719
+ let h = 1;
720
+ let done = false;
281
721
 
282
- let hasColors = false;
722
+ while ( vv + h < dimsV && ! done ) {
283
723
 
284
- for ( let j = 0; j < data.length; j += 4 ) {
724
+ for ( let k = 0; k < w; k ++ ) {
285
725
 
286
- const x = data[ j + 0 ];
287
- const y = data[ j + 1 ];
288
- const z = data[ j + 2 ];
289
- const c = data[ j + 3 ];
726
+ if ( mask[ n + k + h * dimsU ] !== c ) {
290
727
 
291
- const hex = palette[ c ];
292
- const r = ( hex >> 0 & 0xff ) / 0xff;
293
- const g = ( hex >> 8 & 0xff ) / 0xff;
294
- const b = ( hex >> 16 & 0xff ) / 0xff;
728
+ done = true;
729
+ break;
295
730
 
296
- if ( r > 0 || g > 0 || b > 0 ) hasColors = true;
731
+ }
297
732
 
298
- const index = x + ( y * offsety ) + ( z * offsetz );
733
+ }
299
734
 
300
- if ( array[ index + 1 ] === 0 || x === size.x - 1 ) add( px, x, z, - y, r, g, b );
301
- if ( array[ index - 1 ] === 0 || x === 0 ) add( nx, x, z, - y, r, g, b );
302
- if ( array[ index + offsety ] === 0 || y === size.y - 1 ) add( ny, x, z, - y, r, g, b );
303
- if ( array[ index - offsety ] === 0 || y === 0 ) add( py, x, z, - y, r, g, b );
304
- if ( array[ index + offsetz ] === 0 || z === size.z - 1 ) add( pz, x, z, - y, r, g, b );
305
- if ( array[ index - offsetz ] === 0 || z === 0 ) add( nz, x, z, - y, r, g, b );
735
+ if ( ! done ) h ++;
306
736
 
307
- }
737
+ }
738
+
739
+ // Add quad
740
+ const pos = [ 0, 0, 0 ];
741
+ pos[ d ] = slice;
742
+ pos[ u ] = uu;
743
+ pos[ v ] = vv;
744
+
745
+ const du = [ 0, 0, 0 ];
746
+ const dv = [ 0, 0, 0 ];
747
+ du[ u ] = w;
748
+ dv[ v ] = h;
749
+
750
+ // Get color
751
+ const colorIndex = Math.abs( c );
752
+ const hex = palette[ colorIndex ];
753
+ const r = ( hex >> 0 & 0xff ) / 0xff;
754
+ const g = ( hex >> 8 & 0xff ) / 0xff;
755
+ const b = ( hex >> 16 & 0xff ) / 0xff;
756
+
757
+ if ( r > 0 || g > 0 || b > 0 ) hasColors = true;
758
+
759
+ _color.setRGB( r, g, b, SRGBColorSpace );
760
+
761
+ // Convert VOX coords to Three.js coords (Y-up)
762
+ // VOX: X right, Y forward, Z up -> Three.js: X right, Y up, Z back
763
+ const toThree = ( p ) => [
764
+ p[ 0 ] - sx / 2,
765
+ p[ 2 ] - sz / 2,
766
+ - p[ 1 ] + sy / 2
767
+ ];
768
+
769
+ const v0 = toThree( pos );
770
+ const v1 = toThree( [ pos[ 0 ] + du[ 0 ], pos[ 1 ] + du[ 1 ], pos[ 2 ] + du[ 2 ] ] );
771
+ const v2 = toThree( [ pos[ 0 ] + du[ 0 ] + dv[ 0 ], pos[ 1 ] + du[ 1 ] + dv[ 1 ], pos[ 2 ] + du[ 2 ] + dv[ 2 ] ] );
772
+ const v3 = toThree( [ pos[ 0 ] + dv[ 0 ], pos[ 1 ] + dv[ 1 ], pos[ 2 ] + dv[ 2 ] ] );
773
+
774
+ const idx = vertices.length / 3;
775
+
776
+ // Winding order depends on face direction
777
+ if ( c > 0 ) {
778
+
779
+ vertices.push( ...v0, ...v1, ...v2, ...v3 );
780
+ indices.push( idx, idx + 1, idx + 2, idx, idx + 2, idx + 3 );
781
+
782
+ } else {
308
783
 
309
- const geometry = new BufferGeometry();
310
- geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
311
- geometry.computeVertexNormals();
784
+ vertices.push( ...v0, ...v3, ...v2, ...v1 );
785
+ indices.push( idx, idx + 1, idx + 2, idx, idx + 2, idx + 3 );
312
786
 
313
- const material = new MeshStandardMaterial();
787
+ }
314
788
 
315
- if ( hasColors ) {
789
+ colors.push(
790
+ _color.r, _color.g, _color.b,
791
+ _color.r, _color.g, _color.b,
792
+ _color.r, _color.g, _color.b,
793
+ _color.r, _color.g, _color.b
794
+ );
316
795
 
317
- geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
318
- material.vertexColors = true;
796
+ // Clear mask
797
+ for ( let hh = 0; hh < h; hh ++ ) {
798
+
799
+ for ( let ww = 0; ww < w; ww ++ ) {
800
+
801
+ mask[ n + ww + hh * dimsU ] = 0;
802
+
803
+ }
804
+
805
+ }
806
+
807
+ uu += w;
808
+ n += w;
809
+
810
+ } else {
811
+
812
+ uu ++;
813
+ n ++;
814
+
815
+ }
816
+
817
+ }
818
+
819
+ }
319
820
 
320
821
  }
321
822
 
322
- super( geometry, material );
823
+ }
824
+
825
+ const geometry = new BufferGeometry();
826
+ geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
827
+ geometry.setIndex( indices );
828
+ geometry.computeVertexNormals();
829
+
830
+ const material = new MeshStandardMaterial();
831
+
832
+ if ( hasColors ) {
833
+
834
+ geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
835
+ material.vertexColors = true;
323
836
 
324
837
  }
325
838
 
839
+ return new Mesh( geometry, material );
840
+
326
841
  }
327
842
 
328
843
  /**
329
- * A VOX 3D texture.
330
- *
331
- * Instances of this class are created from the loaded chunks of {@link VOXLoader}.
844
+ * Builds a 3D texture from a VOX chunk.
332
845
  *
333
- * @augments Data3DTexture
846
+ * @param {Object} chunk - A VOX chunk loaded via {@link VOXLoader}.
847
+ * @return {Data3DTexture} The generated 3D texture.
334
848
  */
335
- class VOXData3DTexture extends Data3DTexture {
849
+ function buildData3DTexture( chunk ) {
850
+
851
+ const data = chunk.data;
852
+ const size = chunk.size;
853
+
854
+ const offsety = size.x;
855
+ const offsetz = size.x * size.y;
856
+
857
+ const array = new Uint8Array( size.x * size.y * size.z );
858
+
859
+ for ( let j = 0; j < data.length; j += 4 ) {
860
+
861
+ const x = data[ j + 0 ];
862
+ const y = data[ j + 1 ];
863
+ const z = data[ j + 2 ];
864
+
865
+ const index = x + ( y * offsety ) + ( z * offsetz );
866
+
867
+ array[ index ] = 255;
868
+
869
+ }
870
+
871
+ const texture = new Data3DTexture( array, size.x, size.y, size.z );
872
+
873
+ texture.format = RedFormat;
874
+ texture.minFilter = NearestFilter;
875
+ texture.magFilter = LinearFilter;
876
+ texture.unpackAlignment = 1;
877
+ texture.needsUpdate = true;
878
+
879
+ return texture;
880
+
881
+ }
882
+
883
+ // @deprecated, r182
884
+
885
+ class VOXMesh extends Mesh {
336
886
 
337
- /**
338
- * Constructs a new VOX 3D texture.
339
- *
340
- * @param {Object} chunk - A VOX chunk loaded via {@link VOXLoader}.
341
- */
342
887
  constructor( chunk ) {
343
888
 
344
- const data = chunk.data;
345
- const size = chunk.size;
889
+ console.warn( 'VOXMesh has been deprecated. Use buildMesh() instead.' );
346
890
 
347
- const offsety = size.x;
348
- const offsetz = size.x * size.y;
891
+ const mesh = buildMesh( chunk );
349
892
 
350
- const array = new Uint8Array( size.x * size.y * size.z );
893
+ super( mesh.geometry, mesh.material );
351
894
 
352
- for ( let j = 0; j < data.length; j += 4 ) {
895
+ }
353
896
 
354
- const x = data[ j + 0 ];
355
- const y = data[ j + 1 ];
356
- const z = data[ j + 2 ];
897
+ }
357
898
 
358
- const index = x + ( y * offsety ) + ( z * offsetz );
899
+ class VOXData3DTexture extends Data3DTexture {
359
900
 
360
- array[ index ] = 255;
901
+ constructor( chunk ) {
361
902
 
362
- }
903
+ console.warn( 'VOXData3DTexture has been deprecated. Use buildData3DTexture() instead.' );
904
+
905
+ const texture = buildData3DTexture( chunk );
363
906
 
364
- super( array, size.x, size.y, size.z );
907
+ super( texture.image.data, texture.image.width, texture.image.height, texture.image.depth );
365
908
 
366
- this.format = RedFormat;
367
- this.minFilter = NearestFilter;
368
- this.magFilter = LinearFilter;
369
- this.unpackAlignment = 1;
909
+ this.format = texture.format;
910
+ this.minFilter = texture.minFilter;
911
+ this.magFilter = texture.magFilter;
912
+ this.unpackAlignment = texture.unpackAlignment;
370
913
  this.needsUpdate = true;
371
914
 
372
915
  }
373
916
 
374
917
  }
375
918
 
376
- export { VOXLoader, VOXMesh, VOXData3DTexture };
919
+ export { VOXLoader, buildMesh, buildData3DTexture, VOXMesh, VOXData3DTexture };