super-three 0.157.1 → 0.160.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 (303) hide show
  1. package/README.md +6 -4
  2. package/build/three.cjs +3100 -1537
  3. package/build/three.js +3100 -1537
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +3093 -1538
  6. package/build/three.module.min.js +1 -1
  7. package/examples/jsm/Addons.js +291 -0
  8. package/examples/jsm/controls/FlyControls.js +26 -0
  9. package/examples/jsm/controls/OrbitControls.js +62 -41
  10. package/examples/jsm/controls/TransformControls.js +27 -11
  11. package/examples/jsm/csm/CSMShader.js +53 -48
  12. package/examples/jsm/exporters/GLTFExporter.js +151 -3
  13. package/examples/jsm/exporters/USDZExporter.js +27 -19
  14. package/examples/jsm/geometries/InstancedPointsGeometry.js +174 -0
  15. package/examples/jsm/geometries/SDFGeometryGenerator.js +144 -0
  16. package/examples/jsm/helpers/TextureHelper.js +237 -0
  17. package/examples/jsm/interactive/HTMLMesh.js +9 -2
  18. package/examples/jsm/libs/lottie_canvas.module.js +6 -1
  19. package/examples/jsm/libs/opentype.module.js +13 -75
  20. package/examples/jsm/libs/surfaceNet.js +201 -0
  21. package/examples/jsm/lines/LineMaterial.js +16 -33
  22. package/examples/jsm/loaders/ColladaLoader.js +0 -6
  23. package/examples/jsm/loaders/DRACOLoader.js +4 -3
  24. package/examples/jsm/loaders/FBXLoader.js +294 -124
  25. package/examples/jsm/loaders/GLTFLoader.js +83 -6
  26. package/examples/jsm/loaders/LUTImageLoader.js +162 -0
  27. package/examples/jsm/loaders/MaterialXLoader.js +73 -54
  28. package/examples/jsm/loaders/NRRDLoader.js +0 -13
  29. package/examples/jsm/loaders/SVGLoader.js +4 -4
  30. package/examples/jsm/loaders/USDZLoader.js +3 -17
  31. package/examples/jsm/loaders/lwo/IFFParser.js +89 -93
  32. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  33. package/examples/jsm/math/Capsule.js +0 -55
  34. package/examples/jsm/math/Octree.js +85 -7
  35. package/examples/jsm/misc/Timer.js +119 -0
  36. package/examples/jsm/misc/TubePainter.js +3 -6
  37. package/examples/jsm/modifiers/CurveModifier.js +20 -2
  38. package/examples/jsm/modifiers/SimplifyModifier.js +103 -11
  39. package/examples/jsm/modifiers/TessellateModifier.js +3 -3
  40. package/examples/jsm/nodes/Nodes.js +16 -12
  41. package/examples/jsm/nodes/accessors/CameraNode.js +18 -2
  42. package/examples/jsm/nodes/accessors/CubeTextureNode.js +5 -73
  43. package/examples/jsm/nodes/accessors/InstanceNode.js +3 -3
  44. package/examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js +21 -0
  45. package/examples/jsm/nodes/accessors/MaterialNode.js +68 -31
  46. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +11 -2
  47. package/examples/jsm/nodes/accessors/ModelNode.js +1 -2
  48. package/examples/jsm/nodes/accessors/ModelViewProjectionNode.js +12 -3
  49. package/examples/jsm/nodes/accessors/MorphNode.js +191 -16
  50. package/examples/jsm/nodes/accessors/NormalNode.js +1 -1
  51. package/examples/jsm/nodes/accessors/PositionNode.js +1 -1
  52. package/examples/jsm/nodes/accessors/ReferenceNode.js +25 -1
  53. package/examples/jsm/nodes/accessors/SkinningNode.js +13 -3
  54. package/examples/jsm/nodes/accessors/TextureNode.js +123 -37
  55. package/examples/jsm/nodes/code/CodeNode.js +3 -3
  56. package/examples/jsm/nodes/code/FunctionNode.js +1 -1
  57. package/examples/jsm/nodes/core/AssignNode.js +72 -0
  58. package/examples/jsm/nodes/core/AttributeNode.js +7 -1
  59. package/examples/jsm/nodes/core/CacheNode.js +4 -1
  60. package/examples/jsm/nodes/core/ConstNode.js +1 -1
  61. package/examples/jsm/nodes/core/LightingModel.js +3 -1
  62. package/examples/jsm/nodes/core/Node.js +13 -15
  63. package/examples/jsm/nodes/core/NodeBuilder.js +209 -42
  64. package/examples/jsm/nodes/core/NodeFrame.js +10 -8
  65. package/examples/jsm/nodes/core/NodeUniform.js +12 -0
  66. package/examples/jsm/nodes/core/NodeUtils.js +7 -9
  67. package/examples/jsm/nodes/core/OutputStructNode.js +4 -4
  68. package/examples/jsm/nodes/core/ParameterNode.js +33 -0
  69. package/examples/jsm/nodes/core/PropertyNode.js +15 -6
  70. package/examples/jsm/nodes/core/StackNode.js +7 -17
  71. package/examples/jsm/nodes/core/StructTypeNode.js +4 -4
  72. package/examples/jsm/nodes/core/TempNode.js +1 -1
  73. package/examples/jsm/nodes/core/UniformGroup.js +13 -0
  74. package/examples/jsm/nodes/core/UniformGroupNode.js +36 -0
  75. package/examples/jsm/nodes/core/UniformNode.js +17 -0
  76. package/examples/jsm/nodes/core/VarNode.js +7 -34
  77. package/examples/jsm/nodes/core/VaryingNode.js +3 -7
  78. package/examples/jsm/nodes/display/BumpMapNode.js +35 -13
  79. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +6 -10
  80. package/examples/jsm/nodes/display/GaussianBlurNode.js +170 -0
  81. package/examples/jsm/nodes/display/NormalMapNode.js +3 -1
  82. package/examples/jsm/nodes/display/PassNode.js +182 -0
  83. package/examples/jsm/nodes/display/ViewportDepthNode.js +31 -3
  84. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +2 -2
  85. package/examples/jsm/nodes/display/ViewportNode.js +17 -10
  86. package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +20 -6
  87. package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +8 -7
  88. package/examples/jsm/nodes/functions/BSDF/D_GGX.js +8 -3
  89. package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +8 -0
  90. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +8 -0
  91. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +93 -43
  92. package/examples/jsm/nodes/gpgpu/ComputeNode.js +2 -2
  93. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  94. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +55 -6
  95. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +1 -1
  96. package/examples/jsm/nodes/lighting/EnvironmentNode.js +8 -18
  97. package/examples/jsm/nodes/lighting/LightingContextNode.js +21 -57
  98. package/examples/jsm/nodes/lighting/LightsNode.js +80 -20
  99. package/examples/jsm/nodes/lighting/PointLightNode.js +1 -1
  100. package/examples/jsm/nodes/lighting/SpotLightNode.js +1 -1
  101. package/examples/jsm/nodes/materials/InstancedPointsNodeMaterial.js +162 -0
  102. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +76 -77
  103. package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +5 -5
  104. package/examples/jsm/nodes/materials/Materials.js +1 -0
  105. package/examples/jsm/nodes/materials/MeshBasicNodeMaterial.js +1 -0
  106. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +3 -3
  107. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +3 -3
  108. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +47 -20
  109. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +6 -6
  110. package/examples/jsm/nodes/materials/NodeMaterial.js +82 -60
  111. package/examples/jsm/nodes/materials/PointsNodeMaterial.js +0 -10
  112. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +0 -7
  113. package/examples/jsm/nodes/materialx/MaterialXNodes.js +10 -10
  114. package/examples/jsm/nodes/materialx/lib/mx_hsv.js +128 -54
  115. package/examples/jsm/nodes/materialx/lib/mx_noise.js +1430 -618
  116. package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +24 -14
  117. package/examples/jsm/nodes/math/MathNode.js +2 -0
  118. package/examples/jsm/nodes/math/OperatorNode.js +24 -27
  119. package/examples/jsm/nodes/shadernode/ShaderNode.js +158 -10
  120. package/examples/jsm/nodes/utils/ArrayElementNode.js +2 -0
  121. package/examples/jsm/nodes/utils/DiscardNode.js +3 -2
  122. package/examples/jsm/nodes/utils/FunctionOverloadingNode.js +95 -0
  123. package/examples/jsm/nodes/utils/JoinNode.js +11 -1
  124. package/examples/jsm/nodes/utils/LoopNode.js +36 -24
  125. package/examples/jsm/nodes/utils/RemapNode.js +2 -2
  126. package/examples/jsm/nodes/utils/SplitNode.js +10 -2
  127. package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +3 -3
  128. package/examples/jsm/objects/InstancedPoints.js +21 -0
  129. package/examples/jsm/objects/Lensflare.js +20 -0
  130. package/examples/jsm/objects/QuadMesh.js +60 -0
  131. package/examples/jsm/objects/ReflectorForSSRPass.js +3 -0
  132. package/examples/jsm/objects/Refractor.js +3 -0
  133. package/examples/jsm/objects/Sky.js +5 -3
  134. package/examples/jsm/objects/Water.js +5 -2
  135. package/examples/jsm/objects/Water2.js +3 -0
  136. package/examples/jsm/physics/AmmoPhysics.js +21 -0
  137. package/examples/jsm/physics/RapierPhysics.js +21 -0
  138. package/examples/jsm/postprocessing/BokehPass.js +3 -2
  139. package/examples/jsm/postprocessing/GTAOPass.js +572 -0
  140. package/examples/jsm/postprocessing/LUTPass.js +2 -1
  141. package/examples/jsm/postprocessing/OutputPass.js +3 -0
  142. package/examples/jsm/postprocessing/Pass.js +14 -3
  143. package/examples/jsm/postprocessing/SAOPass.js +0 -1
  144. package/examples/jsm/postprocessing/SMAAPass.js +0 -2
  145. package/examples/jsm/postprocessing/TAARenderPass.js +1 -2
  146. package/examples/jsm/renderers/CSS3DRenderer.js +3 -9
  147. package/examples/jsm/renderers/SVGRenderer.js +9 -6
  148. package/examples/jsm/renderers/common/Animation.js +10 -21
  149. package/examples/jsm/renderers/common/Backend.js +19 -3
  150. package/examples/jsm/renderers/common/Background.js +20 -22
  151. package/examples/jsm/renderers/common/Bindings.js +31 -22
  152. package/examples/jsm/renderers/common/ChainMap.js +3 -3
  153. package/examples/jsm/renderers/common/Color4.js +37 -0
  154. package/examples/jsm/renderers/common/Geometries.js +4 -4
  155. package/examples/jsm/renderers/common/Info.js +12 -2
  156. package/examples/jsm/renderers/common/Pipelines.js +3 -51
  157. package/examples/jsm/renderers/common/PostProcessing.js +25 -0
  158. package/examples/jsm/renderers/common/RenderContext.js +1 -1
  159. package/examples/jsm/renderers/common/RenderContexts.js +1 -1
  160. package/examples/jsm/renderers/common/RenderObject.js +21 -2
  161. package/examples/jsm/renderers/common/RenderObjects.js +5 -3
  162. package/examples/jsm/renderers/common/Renderer.js +137 -37
  163. package/examples/jsm/renderers/common/StorageTexture.js +1 -0
  164. package/examples/jsm/renderers/common/Textures.js +8 -37
  165. package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +10 -2
  166. package/examples/jsm/renderers/common/nodes/NodeUniformsGroup.js +44 -0
  167. package/examples/jsm/renderers/common/nodes/Nodes.js +121 -19
  168. package/examples/jsm/renderers/webgl/WebGLBackend.js +366 -67
  169. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +183 -38
  170. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +92 -5
  171. package/examples/jsm/renderers/webgl/utils/WebGLCapabilities.js +36 -0
  172. package/examples/jsm/renderers/webgl/utils/WebGLExtensions.js +11 -1
  173. package/examples/jsm/renderers/webgl/utils/WebGLState.js +14 -2
  174. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +71 -2
  175. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +42 -0
  176. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +1 -1
  177. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +33 -3
  178. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +4 -14
  179. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +188 -137
  180. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +1 -1
  181. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +241 -90
  182. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -10
  183. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +11 -3
  184. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +2 -3
  185. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +88 -6
  186. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +2 -0
  187. package/examples/jsm/shaders/AfterimageShader.js +2 -0
  188. package/examples/jsm/shaders/BasicShader.js +2 -0
  189. package/examples/jsm/shaders/BlendShader.js +2 -0
  190. package/examples/jsm/shaders/BokehShader.js +2 -0
  191. package/examples/jsm/shaders/BokehShader2.js +4 -0
  192. package/examples/jsm/shaders/BrightnessContrastShader.js +2 -0
  193. package/examples/jsm/shaders/ColorCorrectionShader.js +2 -0
  194. package/examples/jsm/shaders/DOFMipMapShader.js +2 -0
  195. package/examples/jsm/shaders/DepthLimitedBlurShader.js +5 -0
  196. package/examples/jsm/shaders/FXAAShader.js +135 -133
  197. package/examples/jsm/shaders/FilmShader.js +1 -1
  198. package/examples/jsm/shaders/FocusShader.js +2 -0
  199. package/examples/jsm/shaders/FreiChenShader.js +2 -0
  200. package/examples/jsm/shaders/GTAOShader.js +424 -0
  201. package/examples/jsm/shaders/GodRaysShader.js +8 -0
  202. package/examples/jsm/shaders/HalftoneShader.js +2 -0
  203. package/examples/jsm/shaders/HorizontalTiltShiftShader.js +2 -0
  204. package/examples/jsm/shaders/HueSaturationShader.js +2 -0
  205. package/examples/jsm/shaders/KaleidoShader.js +2 -0
  206. package/examples/jsm/shaders/LuminosityHighPassShader.js +2 -0
  207. package/examples/jsm/shaders/LuminosityShader.js +2 -0
  208. package/examples/jsm/shaders/MMDToonShader.js +2 -0
  209. package/examples/jsm/shaders/MirrorShader.js +2 -0
  210. package/examples/jsm/shaders/NormalMapShader.js +2 -0
  211. package/examples/jsm/shaders/OutputShader.js +8 -5
  212. package/examples/jsm/shaders/PoissonDenoiseShader.js +226 -0
  213. package/examples/jsm/shaders/SAOShader.js +7 -3
  214. package/examples/jsm/shaders/SMAAShader.js +6 -0
  215. package/examples/jsm/shaders/SSAOShader.js +8 -3
  216. package/examples/jsm/shaders/SSRShader.js +6 -0
  217. package/examples/jsm/shaders/SobelOperatorShader.js +2 -0
  218. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +2 -0
  219. package/examples/jsm/shaders/TechnicolorShader.js +2 -0
  220. package/examples/jsm/shaders/TriangleBlurShader.js +2 -0
  221. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -0
  222. package/examples/jsm/shaders/VelocityShader.js +2 -0
  223. package/examples/jsm/shaders/VerticalTiltShiftShader.js +2 -0
  224. package/examples/jsm/shaders/WaterRefractionShader.js +2 -0
  225. package/examples/jsm/transpiler/AST.js +270 -0
  226. package/examples/jsm/transpiler/GLSLDecoder.js +941 -0
  227. package/examples/jsm/transpiler/ShaderToyDecoder.js +49 -0
  228. package/examples/jsm/transpiler/TSLEncoder.js +715 -0
  229. package/examples/jsm/transpiler/Transpiler.js +18 -0
  230. package/examples/jsm/utils/SortUtils.js +158 -0
  231. package/examples/jsm/utils/TextureUtils.js +33 -21
  232. package/examples/jsm/webxr/ARButton.js +14 -0
  233. package/examples/jsm/webxr/VRButton.js +24 -9
  234. package/examples/jsm/webxr/XRButton.js +27 -11
  235. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  236. package/package.json +8 -6
  237. package/src/Three.js +1 -0
  238. package/src/constants.js +8 -1
  239. package/src/core/BufferAttribute.js +21 -2
  240. package/src/core/InterleavedBuffer.js +21 -1
  241. package/src/core/Object3D.js +60 -12
  242. package/src/core/UniformsGroup.js +7 -1
  243. package/src/extras/PMREMGenerator.js +7 -1
  244. package/src/extras/curves/LineCurve3.js +4 -0
  245. package/src/loaders/AudioLoader.js +1 -1
  246. package/src/loaders/BufferGeometryLoader.js +0 -7
  247. package/src/loaders/ImageBitmapLoader.js +25 -1
  248. package/src/loaders/MaterialLoader.js +10 -2
  249. package/src/loaders/ObjectLoader.js +49 -0
  250. package/src/materials/Material.js +27 -13
  251. package/src/materials/ShaderMaterial.js +2 -1
  252. package/src/math/Box3.js +35 -18
  253. package/src/math/ColorManagement.js +0 -16
  254. package/src/math/Quaternion.js +5 -4
  255. package/src/math/Sphere.js +2 -0
  256. package/src/math/Triangle.js +17 -5
  257. package/src/math/Vector3.js +11 -12
  258. package/src/objects/BatchedMesh.js +1020 -0
  259. package/src/objects/Skeleton.js +1 -3
  260. package/src/objects/SkinnedMesh.js +6 -7
  261. package/src/renderers/WebGL3DRenderTarget.js +2 -2
  262. package/src/renderers/WebGLArrayRenderTarget.js +2 -2
  263. package/src/renderers/WebGLRenderer.js +165 -43
  264. package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +8 -0
  265. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +19 -0
  266. package/src/renderers/shaders/ShaderChunk/batching_vertex.glsl.js +5 -0
  267. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -2
  268. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +0 -5
  269. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +31 -4
  270. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  271. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +9 -4
  272. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +8 -6
  273. package/src/renderers/shaders/ShaderChunk/project_vertex.glsl.js +6 -0
  274. package/src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl.js +9 -17
  275. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +84 -0
  276. package/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js +6 -0
  277. package/src/renderers/shaders/ShaderChunk.js +4 -0
  278. package/src/renderers/shaders/ShaderLib/depth.glsl.js +2 -0
  279. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +2 -0
  280. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +2 -0
  281. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -0
  282. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +3 -0
  283. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +2 -0
  284. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -0
  285. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -2
  286. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +2 -0
  287. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +3 -0
  288. package/src/renderers/webgl/WebGLAttributes.js +39 -5
  289. package/src/renderers/webgl/WebGLBufferRenderer.js +31 -0
  290. package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
  291. package/src/renderers/webgl/WebGLExtensions.js +1 -0
  292. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +31 -0
  293. package/src/renderers/webgl/WebGLLights.js +11 -2
  294. package/src/renderers/webgl/WebGLProgram.js +100 -51
  295. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  296. package/src/renderers/webgl/WebGLShadowMap.js +35 -0
  297. package/src/renderers/webgl/WebGLState.js +25 -4
  298. package/src/renderers/webgl/WebGLTextures.js +7 -11
  299. package/src/renderers/webgl/WebGLUniforms.js +11 -1
  300. package/src/renderers/webgl/WebGLUniformsGroups.js +72 -93
  301. package/src/renderers/webxr/WebXRManager.js +16 -0
  302. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +0 -76
  303. package/examples/jsm/nodes/accessors/LineMaterialNode.js +0 -29
@@ -0,0 +1,1020 @@
1
+ import { BufferAttribute } from '../core/BufferAttribute.js';
2
+ import { BufferGeometry } from '../core/BufferGeometry.js';
3
+ import { DataTexture } from '../textures/DataTexture.js';
4
+ import { FloatType } from '../constants.js';
5
+ import { Matrix4 } from '../math/Matrix4.js';
6
+ import { Mesh } from './Mesh.js';
7
+ import { RGBAFormat } from '../constants.js';
8
+ import { Box3 } from '../math/Box3.js';
9
+ import { Sphere } from '../math/Sphere.js';
10
+ import { Frustum } from '../math/Frustum.js';
11
+ import { WebGLCoordinateSystem } from '../constants.js';
12
+ import { WebGPUCoordinateSystem } from '../constants.js';
13
+ import { Vector3 } from '../math/Vector3.js';
14
+
15
+ function sortOpaque( a, b ) {
16
+
17
+ return a.z - b.z;
18
+
19
+ }
20
+
21
+ function sortTransparent( a, b ) {
22
+
23
+ return b.z - a.z;
24
+
25
+ }
26
+
27
+ class MultiDrawRenderList {
28
+
29
+ constructor() {
30
+
31
+ this.index = 0;
32
+ this.pool = [];
33
+ this.list = [];
34
+
35
+ }
36
+
37
+ push( drawRange, z ) {
38
+
39
+ const pool = this.pool;
40
+ const list = this.list;
41
+ if ( this.index >= pool.length ) {
42
+
43
+ pool.push( {
44
+
45
+ start: - 1,
46
+ count: - 1,
47
+ z: - 1,
48
+
49
+ } );
50
+
51
+ }
52
+
53
+ const item = pool[ this.index ];
54
+ list.push( item );
55
+ this.index ++;
56
+
57
+ item.start = drawRange.start;
58
+ item.count = drawRange.count;
59
+ item.z = z;
60
+
61
+ }
62
+
63
+ reset() {
64
+
65
+ this.list.length = 0;
66
+ this.index = 0;
67
+
68
+ }
69
+
70
+ }
71
+
72
+ const ID_ATTR_NAME = 'batchId';
73
+ const _matrix = /*@__PURE__*/ new Matrix4();
74
+ const _invMatrixWorld = /*@__PURE__*/ new Matrix4();
75
+ const _identityMatrix = /*@__PURE__*/ new Matrix4();
76
+ const _projScreenMatrix = /*@__PURE__*/ new Matrix4();
77
+ const _frustum = /*@__PURE__*/ new Frustum();
78
+ const _box = /*@__PURE__*/ new Box3();
79
+ const _sphere = /*@__PURE__*/ new Sphere();
80
+ const _vector = /*@__PURE__*/ new Vector3();
81
+ const _renderList = /*@__PURE__*/ new MultiDrawRenderList();
82
+ const _mesh = /*@__PURE__*/ new Mesh();
83
+ const _batchIntersects = [];
84
+
85
+ // @TODO: SkinnedMesh support?
86
+ // @TODO: geometry.groups support?
87
+ // @TODO: geometry.drawRange support?
88
+ // @TODO: geometry.morphAttributes support?
89
+ // @TODO: Support uniform parameter per geometry
90
+ // @TODO: Add an "optimize" function to pack geometry and remove data gaps
91
+
92
+ // copies data from attribute "src" into "target" starting at "targetOffset"
93
+ function copyAttributeData( src, target, targetOffset = 0 ) {
94
+
95
+ const itemSize = target.itemSize;
96
+ if ( src.isInterleavedBufferAttribute || src.array.constructor !== target.array.constructor ) {
97
+
98
+ // use the component getters and setters if the array data cannot
99
+ // be copied directly
100
+ const vertexCount = src.count;
101
+ for ( let i = 0; i < vertexCount; i ++ ) {
102
+
103
+ for ( let c = 0; c < itemSize; c ++ ) {
104
+
105
+ target.setComponent( i + targetOffset, c, src.getComponent( i, c ) );
106
+
107
+ }
108
+
109
+ }
110
+
111
+ } else {
112
+
113
+ // faster copy approach using typed array set function
114
+ target.array.set( src.array, targetOffset * itemSize );
115
+
116
+ }
117
+
118
+ target.needsUpdate = true;
119
+
120
+ }
121
+
122
+ class BatchedMesh extends Mesh {
123
+
124
+ get maxGeometryCount() {
125
+
126
+ return this._maxGeometryCount;
127
+
128
+ }
129
+
130
+ constructor( maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material ) {
131
+
132
+ super( new BufferGeometry(), material );
133
+
134
+ this.isBatchedMesh = true;
135
+ this.perObjectFrustumCulled = true;
136
+ this.sortObjects = true;
137
+ this.boundingBox = null;
138
+ this.boundingSphere = null;
139
+ this.customSort = null;
140
+
141
+ this._drawRanges = [];
142
+ this._reservedRanges = [];
143
+
144
+ this._visibility = [];
145
+ this._active = [];
146
+ this._bounds = [];
147
+
148
+ this._maxGeometryCount = maxGeometryCount;
149
+ this._maxVertexCount = maxVertexCount;
150
+ this._maxIndexCount = maxIndexCount;
151
+
152
+ this._geometryInitialized = false;
153
+ this._geometryCount = 0;
154
+ this._multiDrawCounts = new Int32Array( maxGeometryCount );
155
+ this._multiDrawStarts = new Int32Array( maxGeometryCount );
156
+ this._multiDrawCount = 0;
157
+ this._visibilityChanged = true;
158
+
159
+ // Local matrix per geometry by using data texture
160
+ this._matricesTexture = null;
161
+
162
+ this._initMatricesTexture();
163
+
164
+ }
165
+
166
+ _initMatricesTexture() {
167
+
168
+ // layout (1 matrix = 4 pixels)
169
+ // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
170
+ // with 8x8 pixel texture max 16 matrices * 4 pixels = (8 * 8)
171
+ // 16x16 pixel texture max 64 matrices * 4 pixels = (16 * 16)
172
+ // 32x32 pixel texture max 256 matrices * 4 pixels = (32 * 32)
173
+ // 64x64 pixel texture max 1024 matrices * 4 pixels = (64 * 64)
174
+
175
+ let size = Math.sqrt( this._maxGeometryCount * 4 ); // 4 pixels needed for 1 matrix
176
+ size = Math.ceil( size / 4 ) * 4;
177
+ size = Math.max( size, 4 );
178
+
179
+ const matricesArray = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
180
+ const matricesTexture = new DataTexture( matricesArray, size, size, RGBAFormat, FloatType );
181
+
182
+ this._matricesTexture = matricesTexture;
183
+
184
+ }
185
+
186
+ _initializeGeometry( reference ) {
187
+
188
+ const geometry = this.geometry;
189
+ const maxVertexCount = this._maxVertexCount;
190
+ const maxGeometryCount = this._maxGeometryCount;
191
+ const maxIndexCount = this._maxIndexCount;
192
+ if ( this._geometryInitialized === false ) {
193
+
194
+ for ( const attributeName in reference.attributes ) {
195
+
196
+ const srcAttribute = reference.getAttribute( attributeName );
197
+ const { array, itemSize, normalized } = srcAttribute;
198
+
199
+ const dstArray = new array.constructor( maxVertexCount * itemSize );
200
+ const dstAttribute = new srcAttribute.constructor( dstArray, itemSize, normalized );
201
+ dstAttribute.setUsage( srcAttribute.usage );
202
+
203
+ geometry.setAttribute( attributeName, dstAttribute );
204
+
205
+ }
206
+
207
+ if ( reference.getIndex() !== null ) {
208
+
209
+ const indexArray = maxVertexCount > 65536
210
+ ? new Uint32Array( maxIndexCount )
211
+ : new Uint16Array( maxIndexCount );
212
+
213
+ geometry.setIndex( new BufferAttribute( indexArray, 1 ) );
214
+
215
+ }
216
+
217
+ const idArray = maxGeometryCount > 65536
218
+ ? new Uint32Array( maxVertexCount )
219
+ : new Uint16Array( maxVertexCount );
220
+ geometry.setAttribute( ID_ATTR_NAME, new BufferAttribute( idArray, 1 ) );
221
+
222
+ this._geometryInitialized = true;
223
+
224
+ }
225
+
226
+ }
227
+
228
+ // Make sure the geometry is compatible with the existing combined geometry atributes
229
+ _validateGeometry( geometry ) {
230
+
231
+ // check that the geometry doesn't have a version of our reserved id attribute
232
+ if ( geometry.getAttribute( ID_ATTR_NAME ) ) {
233
+
234
+ throw new Error( `BatchedMesh: Geometry cannot use attribute "${ ID_ATTR_NAME }"` );
235
+
236
+ }
237
+
238
+ // check to ensure the geometries are using consistent attributes and indices
239
+ const batchGeometry = this.geometry;
240
+ if ( Boolean( geometry.getIndex() ) !== Boolean( batchGeometry.getIndex() ) ) {
241
+
242
+ throw new Error( 'BatchedMesh: All geometries must consistently have "index".' );
243
+
244
+ }
245
+
246
+ for ( const attributeName in batchGeometry.attributes ) {
247
+
248
+ if ( attributeName === ID_ATTR_NAME ) {
249
+
250
+ continue;
251
+
252
+ }
253
+
254
+ if ( ! geometry.hasAttribute( attributeName ) ) {
255
+
256
+ throw new Error( `BatchedMesh: Added geometry missing "${ attributeName }". All geometries must have consistent attributes.` );
257
+
258
+ }
259
+
260
+ const srcAttribute = geometry.getAttribute( attributeName );
261
+ const dstAttribute = batchGeometry.getAttribute( attributeName );
262
+ if ( srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized ) {
263
+
264
+ throw new Error( 'BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );
265
+
266
+ }
267
+
268
+ }
269
+
270
+ }
271
+
272
+ setCustomSort( func ) {
273
+
274
+ this.customSort = func;
275
+ return this;
276
+
277
+ }
278
+
279
+ computeBoundingBox() {
280
+
281
+ if ( this.boundingBox === null ) {
282
+
283
+ this.boundingBox = new Box3();
284
+
285
+ }
286
+
287
+ const geometryCount = this._geometryCount;
288
+ const boundingBox = this.boundingBox;
289
+ const active = this._active;
290
+
291
+ boundingBox.makeEmpty();
292
+ for ( let i = 0; i < geometryCount; i ++ ) {
293
+
294
+ if ( active[ i ] === false ) continue;
295
+
296
+ this.getMatrixAt( i, _matrix );
297
+ this.getBoundingBoxAt( i, _box ).applyMatrix4( _matrix );
298
+ boundingBox.union( _box );
299
+
300
+ }
301
+
302
+ }
303
+
304
+ computeBoundingSphere() {
305
+
306
+ if ( this.boundingSphere === null ) {
307
+
308
+ this.boundingSphere = new Sphere();
309
+
310
+ }
311
+
312
+ const geometryCount = this._geometryCount;
313
+ const boundingSphere = this.boundingSphere;
314
+ const active = this._active;
315
+
316
+ boundingSphere.makeEmpty();
317
+ for ( let i = 0; i < geometryCount; i ++ ) {
318
+
319
+ if ( active[ i ] === false ) continue;
320
+
321
+ this.getMatrixAt( i, _matrix );
322
+ this.getBoundingSphereAt( i, _sphere ).applyMatrix4( _matrix );
323
+ boundingSphere.union( _sphere );
324
+
325
+ }
326
+
327
+ }
328
+
329
+ addGeometry( geometry, vertexCount = - 1, indexCount = - 1 ) {
330
+
331
+ this._initializeGeometry( geometry );
332
+
333
+ this._validateGeometry( geometry );
334
+
335
+ // ensure we're not over geometry
336
+ if ( this._geometryCount >= this._maxGeometryCount ) {
337
+
338
+ throw new Error( 'BatchedMesh: Maximum geometry count reached.' );
339
+
340
+ }
341
+
342
+ // get the necessary range fo the geometry
343
+ const reservedRange = {
344
+ vertexStart: - 1,
345
+ vertexCount: - 1,
346
+ indexStart: - 1,
347
+ indexCount: - 1,
348
+ };
349
+
350
+ let lastRange = null;
351
+ const reservedRanges = this._reservedRanges;
352
+ const drawRanges = this._drawRanges;
353
+ const bounds = this._bounds;
354
+ if ( this._geometryCount !== 0 ) {
355
+
356
+ lastRange = reservedRanges[ reservedRanges.length - 1 ];
357
+
358
+ }
359
+
360
+ if ( vertexCount === - 1 ) {
361
+
362
+ reservedRange.vertexCount = geometry.getAttribute( 'position' ).count;
363
+
364
+ } else {
365
+
366
+ reservedRange.vertexCount = vertexCount;
367
+
368
+ }
369
+
370
+ if ( lastRange === null ) {
371
+
372
+ reservedRange.vertexStart = 0;
373
+
374
+ } else {
375
+
376
+ reservedRange.vertexStart = lastRange.vertexStart + lastRange.vertexCount;
377
+
378
+ }
379
+
380
+ const index = geometry.getIndex();
381
+ const hasIndex = index !== null;
382
+ if ( hasIndex ) {
383
+
384
+ if ( indexCount === - 1 ) {
385
+
386
+ reservedRange.indexCount = index.count;
387
+
388
+ } else {
389
+
390
+ reservedRange.indexCount = indexCount;
391
+
392
+ }
393
+
394
+ if ( lastRange === null ) {
395
+
396
+ reservedRange.indexStart = 0;
397
+
398
+ } else {
399
+
400
+ reservedRange.indexStart = lastRange.indexStart + lastRange.indexCount;
401
+
402
+ }
403
+
404
+ }
405
+
406
+ if (
407
+ reservedRange.indexStart !== - 1 &&
408
+ reservedRange.indexStart + reservedRange.indexCount > this._maxIndexCount ||
409
+ reservedRange.vertexStart + reservedRange.vertexCount > this._maxVertexCount
410
+ ) {
411
+
412
+ throw new Error( 'BatchedMesh: Reserved space request exceeds the maximum buffer size.' );
413
+
414
+ }
415
+
416
+ const visibility = this._visibility;
417
+ const active = this._active;
418
+ const matricesTexture = this._matricesTexture;
419
+ const matricesArray = this._matricesTexture.image.data;
420
+
421
+ // push new visibility states
422
+ visibility.push( true );
423
+ active.push( true );
424
+
425
+ // update id
426
+ const geometryId = this._geometryCount;
427
+ this._geometryCount ++;
428
+
429
+ // initialize matrix information
430
+ _identityMatrix.toArray( matricesArray, geometryId * 16 );
431
+ matricesTexture.needsUpdate = true;
432
+
433
+ // add the reserved range and draw range objects
434
+ reservedRanges.push( reservedRange );
435
+ drawRanges.push( {
436
+ start: hasIndex ? reservedRange.indexStart : reservedRange.vertexStart,
437
+ count: - 1
438
+ } );
439
+ bounds.push( {
440
+ boxInitialized: false,
441
+ box: new Box3(),
442
+
443
+ sphereInitialized: false,
444
+ sphere: new Sphere()
445
+ } );
446
+
447
+ // set the id for the geometry
448
+ const idAttribute = this.geometry.getAttribute( ID_ATTR_NAME );
449
+ for ( let i = 0; i < reservedRange.vertexCount; i ++ ) {
450
+
451
+ idAttribute.setX( reservedRange.vertexStart + i, geometryId );
452
+
453
+ }
454
+
455
+ idAttribute.needsUpdate = true;
456
+
457
+ // update the geometry
458
+ this.setGeometryAt( geometryId, geometry );
459
+
460
+ return geometryId;
461
+
462
+ }
463
+
464
+ setGeometryAt( id, geometry ) {
465
+
466
+ if ( id >= this._geometryCount ) {
467
+
468
+ throw new Error( 'BatchedMesh: Maximum geometry count reached.' );
469
+
470
+ }
471
+
472
+ this._validateGeometry( geometry );
473
+
474
+ const batchGeometry = this.geometry;
475
+ const hasIndex = batchGeometry.getIndex() !== null;
476
+ const dstIndex = batchGeometry.getIndex();
477
+ const srcIndex = geometry.getIndex();
478
+ const reservedRange = this._reservedRanges[ id ];
479
+ if (
480
+ hasIndex &&
481
+ srcIndex.count > reservedRange.indexCount ||
482
+ geometry.attributes.position.count > reservedRange.vertexCount
483
+ ) {
484
+
485
+ throw new Error( 'BatchedMesh: Reserved space not large enough for provided geometry.' );
486
+
487
+ }
488
+
489
+ // copy geometry over
490
+ const vertexStart = reservedRange.vertexStart;
491
+ const vertexCount = reservedRange.vertexCount;
492
+ for ( const attributeName in batchGeometry.attributes ) {
493
+
494
+ if ( attributeName === ID_ATTR_NAME ) {
495
+
496
+ continue;
497
+
498
+ }
499
+
500
+ // copy attribute data
501
+ const srcAttribute = geometry.getAttribute( attributeName );
502
+ const dstAttribute = batchGeometry.getAttribute( attributeName );
503
+ copyAttributeData( srcAttribute, dstAttribute, vertexStart );
504
+
505
+ // fill the rest in with zeroes
506
+ const itemSize = srcAttribute.itemSize;
507
+ for ( let i = srcAttribute.count, l = vertexCount; i < l; i ++ ) {
508
+
509
+ const index = vertexStart + i;
510
+ for ( let c = 0; c < itemSize; c ++ ) {
511
+
512
+ dstAttribute.setComponent( index, c, 0 );
513
+
514
+ }
515
+
516
+ }
517
+
518
+ dstAttribute.needsUpdate = true;
519
+
520
+ }
521
+
522
+ // copy index
523
+ if ( hasIndex ) {
524
+
525
+ const indexStart = reservedRange.indexStart;
526
+
527
+ // copy index data over
528
+ for ( let i = 0; i < srcIndex.count; i ++ ) {
529
+
530
+ dstIndex.setX( indexStart + i, vertexStart + srcIndex.getX( i ) );
531
+
532
+ }
533
+
534
+ // fill the rest in with zeroes
535
+ for ( let i = srcIndex.count, l = reservedRange.indexCount; i < l; i ++ ) {
536
+
537
+ dstIndex.setX( indexStart + i, vertexStart );
538
+
539
+ }
540
+
541
+ dstIndex.needsUpdate = true;
542
+
543
+ }
544
+
545
+ // store the bounding boxes
546
+ const bound = this._bounds[ id ];
547
+ if ( geometry.boundingBox !== null ) {
548
+
549
+ bound.box.copy( geometry.boundingBox );
550
+ bound.boxInitialized = true;
551
+
552
+ } else {
553
+
554
+ bound.boxInitialized = false;
555
+
556
+ }
557
+
558
+ if ( geometry.boundingSphere !== null ) {
559
+
560
+ bound.sphere.copy( geometry.boundingSphere );
561
+ bound.sphereInitialized = true;
562
+
563
+ } else {
564
+
565
+ bound.sphereInitialized = false;
566
+
567
+ }
568
+
569
+ // set drawRange count
570
+ const drawRange = this._drawRanges[ id ];
571
+ const posAttr = geometry.getAttribute( 'position' );
572
+ drawRange.count = hasIndex ? srcIndex.count : posAttr.count;
573
+ this._visibilityChanged = true;
574
+
575
+ return id;
576
+
577
+ }
578
+
579
+ deleteGeometry( geometryId ) {
580
+
581
+ // Note: User needs to call optimize() afterward to pack the data.
582
+
583
+ const active = this._active;
584
+ if ( geometryId >= active.length || active[ geometryId ] === false ) {
585
+
586
+ return this;
587
+
588
+ }
589
+
590
+ active[ geometryId ] = false;
591
+ this._visibilityChanged = true;
592
+
593
+ return this;
594
+
595
+ }
596
+
597
+ // get bounding box and compute it if it doesn't exist
598
+ getBoundingBoxAt( id, target ) {
599
+
600
+ const active = this._active;
601
+ if ( active[ id ] === false ) {
602
+
603
+ return this;
604
+
605
+ }
606
+
607
+ // compute bounding box
608
+ const bound = this._bounds[ id ];
609
+ const box = bound.box;
610
+ const geometry = this.geometry;
611
+ if ( bound.boxInitialized === false ) {
612
+
613
+ box.makeEmpty();
614
+
615
+ const index = geometry.index;
616
+ const position = geometry.attributes.position;
617
+ const drawRange = this._drawRanges[ id ];
618
+ for ( let i = drawRange.start, l = drawRange.start + drawRange.count; i < l; i ++ ) {
619
+
620
+ let iv = i;
621
+ if ( index ) {
622
+
623
+ iv = index.getX( iv );
624
+
625
+ }
626
+
627
+ box.expandByPoint( _vector.fromBufferAttribute( position, iv ) );
628
+
629
+ }
630
+
631
+ bound.boxInitialized = true;
632
+
633
+ }
634
+
635
+ target.copy( box );
636
+ return target;
637
+
638
+ }
639
+
640
+ // get bounding sphere and compute it if it doesn't exist
641
+ getBoundingSphereAt( id, target ) {
642
+
643
+ const active = this._active;
644
+ if ( active[ id ] === false ) {
645
+
646
+ return this;
647
+
648
+ }
649
+
650
+ // compute bounding sphere
651
+ const bound = this._bounds[ id ];
652
+ const sphere = bound.sphere;
653
+ const geometry = this.geometry;
654
+ if ( bound.sphereInitialized === false ) {
655
+
656
+ sphere.makeEmpty();
657
+
658
+ this.getBoundingBoxAt( id, _box );
659
+ _box.getCenter( sphere.center );
660
+
661
+ const index = geometry.index;
662
+ const position = geometry.attributes.position;
663
+ const drawRange = this._drawRanges[ id ];
664
+
665
+ let maxRadiusSq = 0;
666
+ for ( let i = drawRange.start, l = drawRange.start + drawRange.count; i < l; i ++ ) {
667
+
668
+ let iv = i;
669
+ if ( index ) {
670
+
671
+ iv = index.getX( iv );
672
+
673
+ }
674
+
675
+ _vector.fromBufferAttribute( position, iv );
676
+ maxRadiusSq = Math.max( maxRadiusSq, sphere.center.distanceToSquared( _vector ) );
677
+
678
+ }
679
+
680
+ sphere.radius = Math.sqrt( maxRadiusSq );
681
+ bound.sphereInitialized = true;
682
+
683
+ }
684
+
685
+ target.copy( sphere );
686
+ return target;
687
+
688
+ }
689
+
690
+ setMatrixAt( geometryId, matrix ) {
691
+
692
+ // @TODO: Map geometryId to index of the arrays because
693
+ // optimize() can make geometryId mismatch the index
694
+
695
+ const active = this._active;
696
+ const matricesTexture = this._matricesTexture;
697
+ const matricesArray = this._matricesTexture.image.data;
698
+ const geometryCount = this._geometryCount;
699
+ if ( geometryId >= geometryCount || active[ geometryId ] === false ) {
700
+
701
+ return this;
702
+
703
+ }
704
+
705
+ matrix.toArray( matricesArray, geometryId * 16 );
706
+ matricesTexture.needsUpdate = true;
707
+
708
+ return this;
709
+
710
+ }
711
+
712
+ getMatrixAt( geometryId, matrix ) {
713
+
714
+ const active = this._active;
715
+ const matricesArray = this._matricesTexture.image.data;
716
+ const geometryCount = this._geometryCount;
717
+ if ( geometryId >= geometryCount || active[ geometryId ] === false ) {
718
+
719
+ return null;
720
+
721
+ }
722
+
723
+ return matrix.fromArray( matricesArray, geometryId * 16 );
724
+
725
+ }
726
+
727
+ setVisibleAt( geometryId, value ) {
728
+
729
+ const visibility = this._visibility;
730
+ const active = this._active;
731
+ const geometryCount = this._geometryCount;
732
+
733
+ // if the geometry is out of range, not active, or visibility state
734
+ // does not change then return early
735
+ if (
736
+ geometryId >= geometryCount ||
737
+ active[ geometryId ] === false ||
738
+ visibility[ geometryId ] === value
739
+ ) {
740
+
741
+ return this;
742
+
743
+ }
744
+
745
+ visibility[ geometryId ] = value;
746
+ this._visibilityChanged = true;
747
+
748
+ return this;
749
+
750
+ }
751
+
752
+ getVisibleAt( geometryId ) {
753
+
754
+ const visibility = this._visibility;
755
+ const active = this._active;
756
+ const geometryCount = this._geometryCount;
757
+
758
+ // return early if the geometry is out of range or not active
759
+ if ( geometryId >= geometryCount || active[ geometryId ] === false ) {
760
+
761
+ return false;
762
+
763
+ }
764
+
765
+ return visibility[ geometryId ];
766
+
767
+ }
768
+
769
+ raycast( raycaster, intersects ) {
770
+
771
+ const visibility = this._visibility;
772
+ const active = this._active;
773
+ const drawRanges = this._drawRanges;
774
+ const geometryCount = this._geometryCount;
775
+ const matrixWorld = this.matrixWorld;
776
+ const batchGeometry = this.geometry;
777
+
778
+ // iterate over each geometry
779
+ _mesh.material = this.material;
780
+ _mesh.geometry.index = batchGeometry.index;
781
+ _mesh.geometry.attributes = batchGeometry.attributes;
782
+ if ( _mesh.geometry.boundingBox === null ) {
783
+
784
+ _mesh.geometry.boundingBox = new Box3();
785
+
786
+ }
787
+
788
+ if ( _mesh.geometry.boundingSphere === null ) {
789
+
790
+ _mesh.geometry.boundingSphere = new Sphere();
791
+
792
+ }
793
+
794
+ for ( let i = 0; i < geometryCount; i ++ ) {
795
+
796
+ if ( ! visibility[ i ] || ! active[ i ] ) {
797
+
798
+ continue;
799
+
800
+ }
801
+
802
+ const drawRange = drawRanges[ i ];
803
+ _mesh.geometry.setDrawRange( drawRange.start, drawRange.count );
804
+
805
+ // ge the intersects
806
+ this.getMatrixAt( i, _mesh.matrixWorld ).premultiply( matrixWorld );
807
+ this.getBoundingBoxAt( i, _mesh.geometry.boundingBox );
808
+ this.getBoundingSphereAt( i, _mesh.geometry.boundingSphere );
809
+ _mesh.raycast( raycaster, _batchIntersects );
810
+
811
+ // add batch id to the intersects
812
+ for ( let j = 0, l = _batchIntersects.length; j < l; j ++ ) {
813
+
814
+ const intersect = _batchIntersects[ j ];
815
+ intersect.object = this;
816
+ intersect.batchId = i;
817
+ intersects.push( intersect );
818
+
819
+ }
820
+
821
+ _batchIntersects.length = 0;
822
+
823
+ }
824
+
825
+ _mesh.material = null;
826
+ _mesh.geometry.index = null;
827
+ _mesh.geometry.attributes = {};
828
+ _mesh.geometry.setDrawRange( 0, Infinity );
829
+
830
+ }
831
+
832
+ copy( source ) {
833
+
834
+ super.copy( source );
835
+
836
+ this.geometry = source.geometry.clone();
837
+ this.perObjectFrustumCulled = source.perObjectFrustumCulled;
838
+ this.sortObjects = source.sortObjects;
839
+ this.boundingBox = source.boundingBox !== null ? source.boundingBox.clone() : null;
840
+ this.boundingSphere = source.boundingSphere !== null ? source.boundingSphere.clone() : null;
841
+
842
+ this._drawRanges = source._drawRanges.map( range => ( { ...range } ) );
843
+ this._reservedRanges = source._reservedRanges.map( range => ( { ...range } ) );
844
+
845
+ this._visibility = source._visibility.slice();
846
+ this._active = source._active.slice();
847
+ this._bounds = source._bounds.map( bound => ( {
848
+ boxInitialized: bound.boxInitialized,
849
+ box: bound.box.clone(),
850
+
851
+ sphereInitialized: bound.sphereInitialized,
852
+ sphere: bound.sphere.clone()
853
+ } ) );
854
+
855
+ this._maxGeometryCount = source._maxGeometryCount;
856
+ this._maxVertexCount = source._maxVertexCount;
857
+ this._maxIndexCount = source._maxIndexCount;
858
+
859
+ this._geometryInitialized = source._geometryInitialized;
860
+ this._geometryCount = source._geometryCount;
861
+ this._multiDrawCounts = source._multiDrawCounts.slice();
862
+ this._multiDrawStarts = source._multiDrawStarts.slice();
863
+
864
+ this._matricesTexture = source._matricesTexture.clone();
865
+ this._matricesTexture.image.data = this._matricesTexture.image.slice();
866
+
867
+ return this;
868
+
869
+ }
870
+
871
+ dispose() {
872
+
873
+ // Assuming the geometry is not shared with other meshes
874
+ this.geometry.dispose();
875
+
876
+ this._matricesTexture.dispose();
877
+ this._matricesTexture = null;
878
+ return this;
879
+
880
+ }
881
+
882
+ onBeforeRender( renderer, scene, camera, geometry, material/*, _group*/ ) {
883
+
884
+ // if visibility has not changed and frustum culling and object sorting is not required
885
+ // then skip iterating over all items
886
+ if ( ! this._visibilityChanged && ! this.perObjectFrustumCulled && ! this.sortObjects ) {
887
+
888
+ return;
889
+
890
+ }
891
+
892
+ // the indexed version of the multi draw function requires specifying the start
893
+ // offset in bytes.
894
+ const index = geometry.getIndex();
895
+ const bytesPerElement = index === null ? 1 : index.array.BYTES_PER_ELEMENT;
896
+
897
+ const visibility = this._visibility;
898
+ const multiDrawStarts = this._multiDrawStarts;
899
+ const multiDrawCounts = this._multiDrawCounts;
900
+ const drawRanges = this._drawRanges;
901
+ const perObjectFrustumCulled = this.perObjectFrustumCulled;
902
+
903
+ // prepare the frustum in the local frame
904
+ if ( perObjectFrustumCulled ) {
905
+
906
+ _projScreenMatrix
907
+ .multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse )
908
+ .multiply( this.matrixWorld );
909
+ _frustum.setFromProjectionMatrix(
910
+ _projScreenMatrix,
911
+ renderer.isWebGPURenderer ? WebGPUCoordinateSystem : WebGLCoordinateSystem
912
+ );
913
+
914
+ }
915
+
916
+ let count = 0;
917
+ if ( this.sortObjects ) {
918
+
919
+ // get the camera position in the local frame
920
+ _invMatrixWorld.copy( this.matrixWorld ).invert();
921
+ _vector.setFromMatrixPosition( camera.matrixWorld ).applyMatrix4( _invMatrixWorld );
922
+
923
+ for ( let i = 0, l = visibility.length; i < l; i ++ ) {
924
+
925
+ if ( visibility[ i ] ) {
926
+
927
+ // get the bounds in world space
928
+ this.getMatrixAt( i, _matrix );
929
+ this.getBoundingSphereAt( i, _sphere ).applyMatrix4( _matrix );
930
+
931
+ // determine whether the batched geometry is within the frustum
932
+ let culled = false;
933
+ if ( perObjectFrustumCulled ) {
934
+
935
+ culled = ! _frustum.intersectsSphere( _sphere );
936
+
937
+ }
938
+
939
+ if ( ! culled ) {
940
+
941
+ // get the distance from camera used for sorting
942
+ const z = _vector.distanceTo( _sphere.center );
943
+ _renderList.push( drawRanges[ i ], z );
944
+
945
+ }
946
+
947
+ }
948
+
949
+ }
950
+
951
+ // Sort the draw ranges and prep for rendering
952
+ const list = _renderList.list;
953
+ const customSort = this.customSort;
954
+ if ( customSort === null ) {
955
+
956
+ list.sort( material.transparent ? sortTransparent : sortOpaque );
957
+
958
+ } else {
959
+
960
+ customSort.call( this, list, camera );
961
+
962
+ }
963
+
964
+ for ( let i = 0, l = list.length; i < l; i ++ ) {
965
+
966
+ const item = list[ i ];
967
+ multiDrawStarts[ count ] = item.start * bytesPerElement;
968
+ multiDrawCounts[ count ] = item.count;
969
+ count ++;
970
+
971
+ }
972
+
973
+ _renderList.reset();
974
+
975
+ } else {
976
+
977
+ for ( let i = 0, l = visibility.length; i < l; i ++ ) {
978
+
979
+ if ( visibility[ i ] ) {
980
+
981
+ // determine whether the batched geometry is within the frustum
982
+ let culled = false;
983
+ if ( perObjectFrustumCulled ) {
984
+
985
+ // get the bounds in world space
986
+ this.getMatrixAt( i, _matrix );
987
+ this.getBoundingSphereAt( i, _sphere ).applyMatrix4( _matrix );
988
+ culled = ! _frustum.intersectsSphere( _sphere );
989
+
990
+ }
991
+
992
+ if ( ! culled ) {
993
+
994
+ const range = drawRanges[ i ];
995
+ multiDrawStarts[ count ] = range.start * bytesPerElement;
996
+ multiDrawCounts[ count ] = range.count;
997
+ count ++;
998
+
999
+ }
1000
+
1001
+ }
1002
+
1003
+ }
1004
+
1005
+ }
1006
+
1007
+ this._multiDrawCount = count;
1008
+ this._visibilityChanged = false;
1009
+
1010
+ }
1011
+
1012
+ onBeforeShadow( renderer, object, camera, shadowCamera, geometry, depthMaterial/* , group */ ) {
1013
+
1014
+ this.onBeforeRender( renderer, null, shadowCamera, geometry, depthMaterial );
1015
+
1016
+ }
1017
+
1018
+ }
1019
+
1020
+ export { BatchedMesh };