@plastic-software/three 0.167.3 → 0.174.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 (748) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/build/three.cjs +36277 -24023
  4. package/build/three.core.js +48830 -0
  5. package/build/three.core.min.js +6 -0
  6. package/build/three.module.js +10175 -46743
  7. package/build/three.module.min.js +2 -2
  8. package/build/three.tsl.js +550 -0
  9. package/build/three.tsl.min.js +6 -0
  10. package/build/three.webgpu.js +44348 -50670
  11. package/build/three.webgpu.min.js +2 -2
  12. package/build/three.webgpu.nodes.js +70301 -0
  13. package/build/three.webgpu.nodes.min.js +6 -0
  14. package/examples/jsm/Addons.js +3 -15
  15. package/examples/jsm/animation/AnimationClipCreator.js +1 -1
  16. package/examples/jsm/animation/CCDIKSolver.js +61 -11
  17. package/examples/jsm/capabilities/WebGL.js +27 -21
  18. package/examples/jsm/capabilities/WebGPU.js +1 -10
  19. package/examples/jsm/controls/ArcballControls.js +262 -231
  20. package/examples/jsm/controls/DragControls.js +1 -1
  21. package/examples/jsm/controls/FirstPersonControls.js +175 -163
  22. package/examples/jsm/controls/FlyControls.js +194 -188
  23. package/examples/jsm/controls/OrbitControls.js +801 -777
  24. package/examples/jsm/controls/PointerLockControls.js +26 -20
  25. package/examples/jsm/controls/TrackballControls.js +469 -448
  26. package/examples/jsm/controls/TransformControls.js +119 -68
  27. package/examples/jsm/csm/CSM.js +2 -2
  28. package/examples/jsm/csm/CSMFrustum.js +7 -4
  29. package/examples/jsm/csm/CSMHelper.js +2 -0
  30. package/examples/jsm/csm/CSMShadowNode.js +442 -0
  31. package/examples/jsm/curves/NURBSCurve.js +33 -2
  32. package/examples/jsm/curves/NURBSUtils.js +3 -0
  33. package/examples/jsm/effects/AnaglyphEffect.js +6 -13
  34. package/examples/jsm/effects/OutlineEffect.js +1 -1
  35. package/examples/jsm/effects/ParallaxBarrierEffect.js +17 -11
  36. package/examples/jsm/effects/StereoEffect.js +6 -1
  37. package/examples/jsm/exporters/DRACOExporter.js +4 -2
  38. package/examples/jsm/exporters/EXRExporter.js +19 -11
  39. package/examples/jsm/exporters/GLTFExporter.js +181 -109
  40. package/examples/jsm/exporters/KTX2Exporter.js +54 -23
  41. package/examples/jsm/exporters/OBJExporter.js +5 -1
  42. package/examples/jsm/exporters/PLYExporter.js +11 -9
  43. package/examples/jsm/exporters/USDZExporter.js +50 -11
  44. package/examples/jsm/geometries/DecalGeometry.js +73 -21
  45. package/examples/jsm/geometries/TextGeometry.js +1 -12
  46. package/examples/jsm/helpers/LightProbeHelper.js +43 -44
  47. package/examples/jsm/helpers/LightProbeHelperGPU.js +65 -0
  48. package/examples/jsm/helpers/TextureHelperGPU.js +185 -0
  49. package/examples/jsm/helpers/VertexNormalsHelper.js +2 -0
  50. package/examples/jsm/interactive/HTMLMesh.js +1 -0
  51. package/examples/jsm/interactive/InteractiveGroup.js +108 -51
  52. package/examples/jsm/interactive/SelectionHelper.js +3 -1
  53. package/examples/jsm/libs/basis/basis_transcoder.js +8 -10
  54. package/examples/jsm/libs/basis/basis_transcoder.wasm +0 -0
  55. package/examples/jsm/libs/demuxer_mp4.js +109 -0
  56. package/examples/jsm/libs/ktx-parse.module.js +1 -1
  57. package/examples/jsm/lighting/TiledLighting.js +18 -0
  58. package/examples/jsm/lights/LightProbeGenerator.js +26 -12
  59. package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
  60. package/examples/jsm/lines/LineGeometry.js +25 -0
  61. package/examples/jsm/lines/LineMaterial.js +0 -1
  62. package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
  63. package/examples/jsm/lines/webgpu/Line2.js +2 -1
  64. package/examples/jsm/lines/webgpu/LineSegments2.js +16 -21
  65. package/examples/jsm/lines/webgpu/Wireframe.js +57 -0
  66. package/examples/jsm/loaders/3DMLoader.js +1 -0
  67. package/examples/jsm/loaders/3MFLoader.js +104 -2
  68. package/examples/jsm/loaders/BVHLoader.js +1 -1
  69. package/examples/jsm/loaders/ColladaLoader.js +15 -12
  70. package/examples/jsm/loaders/DDSLoader.js +42 -0
  71. package/examples/jsm/loaders/DRACOLoader.js +3 -1
  72. package/examples/jsm/loaders/FBXLoader.js +71 -22
  73. package/examples/jsm/loaders/GCodeLoader.js +4 -2
  74. package/examples/jsm/loaders/GLTFLoader.js +29 -14
  75. package/examples/jsm/loaders/KTX2Loader.js +160 -58
  76. package/examples/jsm/loaders/KTXLoader.js +4 -4
  77. package/examples/jsm/loaders/LDrawLoader.js +22 -136
  78. package/examples/jsm/loaders/LottieLoader.js +2 -1
  79. package/examples/jsm/loaders/MTLLoader.js +27 -7
  80. package/examples/jsm/loaders/MaterialXLoader.js +40 -14
  81. package/examples/jsm/loaders/NRRDLoader.js +1 -1
  82. package/examples/jsm/loaders/OBJLoader.js +5 -3
  83. package/examples/jsm/loaders/PCDLoader.js +14 -13
  84. package/examples/jsm/loaders/PDBLoader.js +3 -2
  85. package/examples/jsm/loaders/PLYLoader.js +15 -12
  86. package/examples/jsm/loaders/PVRLoader.js +1 -1
  87. package/examples/jsm/loaders/STLLoader.js +3 -2
  88. package/examples/jsm/loaders/SVGLoader.js +2 -2
  89. package/examples/jsm/loaders/TDSLoader.js +17 -18
  90. package/examples/jsm/loaders/VRMLLoader.js +17 -17
  91. package/examples/jsm/loaders/VTKLoader.js +4 -3
  92. package/examples/jsm/loaders/XYZLoader.js +3 -2
  93. package/examples/jsm/loaders/lwo/IFFParser.js +4 -4
  94. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
  95. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
  96. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  97. package/examples/jsm/math/ColorSpaces.js +76 -0
  98. package/examples/jsm/math/ConvexHull.js +1 -1
  99. package/examples/jsm/math/OBB.js +17 -0
  100. package/examples/jsm/misc/GPUComputationRenderer.js +6 -7
  101. package/examples/jsm/misc/ProgressiveLightMap.js +54 -41
  102. package/examples/jsm/misc/ProgressiveLightMapGPU.js +294 -0
  103. package/examples/jsm/misc/Timer.js +27 -12
  104. package/examples/jsm/misc/Volume.js +28 -18
  105. package/examples/jsm/misc/VolumeSlice.js +19 -16
  106. package/examples/jsm/modifiers/CurveModifier.js +10 -8
  107. package/examples/jsm/modifiers/CurveModifierGPU.js +235 -0
  108. package/examples/jsm/modifiers/SimplifyModifier.js +2 -2
  109. package/examples/jsm/objects/GroundedSkybox.js +4 -4
  110. package/examples/jsm/objects/LensflareMesh.js +324 -0
  111. package/examples/jsm/objects/Reflector.js +5 -2
  112. package/examples/jsm/objects/Sky.js +2 -2
  113. package/examples/jsm/objects/SkyMesh.js +14 -14
  114. package/examples/jsm/objects/Water2.js +1 -1
  115. package/examples/jsm/objects/Water2Mesh.js +11 -9
  116. package/examples/jsm/objects/WaterMesh.js +38 -33
  117. package/examples/jsm/physics/JoltPhysics.js +8 -8
  118. package/examples/jsm/physics/RapierPhysics.js +5 -5
  119. package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
  120. package/examples/jsm/postprocessing/BloomPass.js +2 -2
  121. package/examples/jsm/postprocessing/EffectComposer.js +1 -2
  122. package/examples/jsm/postprocessing/OutlinePass.js +37 -51
  123. package/examples/jsm/postprocessing/OutputPass.js +2 -0
  124. package/examples/jsm/postprocessing/SAOPass.js +1 -2
  125. package/examples/jsm/postprocessing/SMAAPass.js +1 -3
  126. package/examples/jsm/postprocessing/SSAARenderPass.js +3 -1
  127. package/examples/jsm/postprocessing/SSAOPass.js +2 -4
  128. package/examples/jsm/postprocessing/SSRPass.js +8 -4
  129. package/examples/jsm/postprocessing/UnrealBloomPass.js +2 -2
  130. package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
  131. package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
  132. package/examples/jsm/renderers/SVGRenderer.js +6 -4
  133. package/examples/jsm/shaders/BokehShader2.js +1 -1
  134. package/examples/jsm/shaders/FXAAShader.js +225 -224
  135. package/examples/jsm/shaders/GodRaysShader.js +3 -3
  136. package/examples/jsm/shaders/OutputShader.js +6 -2
  137. package/examples/jsm/shaders/SobelOperatorShader.js +1 -1
  138. package/examples/jsm/transpiler/AST.js +12 -2
  139. package/examples/jsm/transpiler/GLSLDecoder.js +77 -31
  140. package/examples/jsm/transpiler/ShaderToyDecoder.js +3 -3
  141. package/examples/jsm/transpiler/TSLEncoder.js +96 -21
  142. package/examples/jsm/tsl/display/AfterImageNode.js +243 -0
  143. package/examples/jsm/tsl/display/AnaglyphPassNode.js +106 -0
  144. package/examples/jsm/tsl/display/AnamorphicNode.js +257 -0
  145. package/{src/nodes/display/BleachBypassNode.js → examples/jsm/tsl/display/BleachBypass.js} +11 -6
  146. package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +252 -67
  147. package/examples/jsm/tsl/display/DenoiseNode.js +332 -0
  148. package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +92 -14
  149. package/examples/jsm/tsl/display/DotScreenNode.js +103 -0
  150. package/examples/jsm/tsl/display/FXAANode.js +364 -0
  151. package/examples/jsm/tsl/display/FilmNode.js +100 -0
  152. package/examples/jsm/tsl/display/GTAONode.js +521 -0
  153. package/examples/jsm/tsl/display/GaussianBlurNode.js +393 -0
  154. package/examples/jsm/tsl/display/LensflareNode.js +278 -0
  155. package/examples/jsm/tsl/display/Lut3DNode.js +108 -0
  156. package/examples/jsm/tsl/display/MotionBlur.js +33 -0
  157. package/examples/jsm/tsl/display/OutlineNode.js +750 -0
  158. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +88 -0
  159. package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +160 -28
  160. package/examples/jsm/tsl/display/RGBShiftNode.js +95 -0
  161. package/examples/jsm/tsl/display/SMAANode.js +767 -0
  162. package/examples/jsm/tsl/display/SSAAPassNode.js +357 -0
  163. package/examples/jsm/tsl/display/SSRNode.js +538 -0
  164. package/examples/jsm/tsl/display/Sepia.js +24 -0
  165. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +66 -20
  166. package/examples/jsm/tsl/display/StereoCompositePassNode.js +184 -0
  167. package/examples/jsm/tsl/display/StereoPassNode.js +119 -0
  168. package/examples/jsm/tsl/display/TRAAPassNode.js +451 -0
  169. package/examples/jsm/tsl/display/TransitionNode.js +140 -0
  170. package/examples/jsm/tsl/display/hashBlur.js +34 -0
  171. package/examples/jsm/tsl/lighting/TiledLightsNode.js +395 -0
  172. package/examples/jsm/tsl/math/Bayer.js +18 -0
  173. package/examples/jsm/tsl/utils/Raymarching.js +65 -0
  174. package/examples/jsm/utils/BufferGeometryUtils.js +2 -2
  175. package/examples/jsm/utils/CameraUtils.js +4 -1
  176. package/examples/jsm/utils/GeometryCompressionUtils.js +38 -123
  177. package/examples/jsm/utils/GeometryUtils.js +22 -19
  178. package/examples/jsm/utils/SceneOptimizer.js +410 -0
  179. package/examples/jsm/utils/SceneUtils.js +2 -2
  180. package/examples/jsm/utils/ShadowMapViewer.js +3 -8
  181. package/examples/jsm/utils/ShadowMapViewerGPU.js +201 -0
  182. package/examples/jsm/utils/SkeletonUtils.js +84 -66
  183. package/examples/jsm/utils/UVsDebug.js +1 -1
  184. package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +1 -0
  185. package/examples/jsm/utils/WebGPUTextureUtils.js +64 -0
  186. package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
  187. package/examples/jsm/webxr/Text2D.js +6 -6
  188. package/examples/jsm/webxr/XRControllerModelFactory.js +7 -2
  189. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  190. package/package.json +14 -9
  191. package/src/Three.Core.js +182 -0
  192. package/src/Three.Legacy.js +0 -21
  193. package/src/Three.TSL.js +543 -0
  194. package/src/Three.WebGPU.Nodes.js +23 -0
  195. package/src/Three.WebGPU.js +13 -184
  196. package/src/Three.js +1 -176
  197. package/src/animation/AnimationClip.js +2 -2
  198. package/src/animation/AnimationObjectGroup.js +2 -2
  199. package/src/animation/AnimationUtils.js +1 -1
  200. package/src/animation/PropertyBinding.js +2 -2
  201. package/src/audio/Audio.js +379 -2
  202. package/src/audio/AudioAnalyser.js +58 -1
  203. package/src/audio/AudioContext.js +15 -0
  204. package/src/audio/AudioListener.js +76 -0
  205. package/src/audio/PositionalAudio.js +107 -0
  206. package/src/cameras/ArrayCamera.js +29 -0
  207. package/src/cameras/Camera.js +47 -0
  208. package/src/cameras/CubeCamera.js +66 -0
  209. package/src/cameras/OrthographicCamera.js +109 -0
  210. package/src/cameras/PerspectiveCamera.js +173 -34
  211. package/src/cameras/StereoCamera.js +48 -2
  212. package/src/constants.js +6 -6
  213. package/src/core/BufferAttribute.js +4 -9
  214. package/src/core/BufferGeometry.js +48 -8
  215. package/src/core/Clock.js +1 -1
  216. package/src/core/EventDispatcher.js +52 -8
  217. package/src/core/InterleavedBuffer.js +4 -13
  218. package/src/core/Object3D.js +573 -3
  219. package/src/core/RenderTarget.js +22 -4
  220. package/src/core/RenderTarget3D.js +22 -0
  221. package/src/core/RenderTargetArray.js +22 -0
  222. package/src/extras/Controls.js +104 -0
  223. package/src/extras/DataUtils.js +48 -8
  224. package/src/extras/Earcut.js +18 -7
  225. package/src/extras/ImageUtils.js +18 -11
  226. package/src/extras/PMREMGenerator.js +40 -9
  227. package/src/extras/ShapeUtils.js +24 -2
  228. package/src/extras/TextureUtils.js +96 -10
  229. package/src/extras/core/Curve.js +153 -53
  230. package/src/extras/core/CurvePath.js +63 -22
  231. package/src/extras/core/Interpolations.js +29 -3
  232. package/src/extras/core/Path.js +134 -1
  233. package/src/extras/core/Shape.js +66 -3
  234. package/src/extras/core/ShapePath.js +76 -0
  235. package/src/extras/curves/ArcCurve.js +22 -0
  236. package/src/extras/curves/CatmullRomCurve3.js +89 -18
  237. package/src/extras/curves/CubicBezierCurve.js +67 -0
  238. package/src/extras/curves/CubicBezierCurve3.js +50 -0
  239. package/src/extras/curves/EllipseCurve.js +102 -0
  240. package/src/extras/curves/LineCurve.js +36 -0
  241. package/src/extras/curves/LineCurve3.js +36 -0
  242. package/src/extras/curves/QuadraticBezierCurve.js +59 -0
  243. package/src/extras/curves/QuadraticBezierCurve3.js +43 -0
  244. package/src/extras/curves/SplineCurve.js +48 -0
  245. package/src/geometries/BoxGeometry.js +38 -0
  246. package/src/geometries/CapsuleGeometry.js +34 -0
  247. package/src/geometries/CircleGeometry.js +40 -0
  248. package/src/geometries/ConeGeometry.js +38 -0
  249. package/src/geometries/CylinderGeometry.js +50 -4
  250. package/src/geometries/DodecahedronGeometry.js +32 -0
  251. package/src/geometries/EdgesGeometry.js +30 -2
  252. package/src/geometries/ExtrudeGeometry.js +52 -0
  253. package/src/geometries/IcosahedronGeometry.js +32 -0
  254. package/src/geometries/LatheGeometry.js +43 -3
  255. package/src/geometries/OctahedronGeometry.js +32 -0
  256. package/src/geometries/PlaneGeometry.js +34 -0
  257. package/src/geometries/PolyhedronGeometry.js +29 -0
  258. package/src/geometries/RingGeometry.js +36 -0
  259. package/src/geometries/ShapeGeometry.js +37 -0
  260. package/src/geometries/SphereGeometry.js +37 -0
  261. package/src/geometries/TetrahedronGeometry.js +32 -0
  262. package/src/geometries/TorusGeometry.js +35 -0
  263. package/src/geometries/TorusKnotGeometry.js +38 -0
  264. package/src/geometries/TubeGeometry.js +49 -0
  265. package/src/geometries/WireframeGeometry.js +32 -0
  266. package/src/helpers/ArrowHelper.js +60 -3
  267. package/src/helpers/AxesHelper.js +28 -0
  268. package/src/helpers/Box3Helper.js +28 -0
  269. package/src/helpers/BoxHelper.js +43 -7
  270. package/src/helpers/CameraHelper.js +61 -18
  271. package/src/helpers/DirectionalLightHelper.js +52 -0
  272. package/src/helpers/GridHelper.js +26 -0
  273. package/src/helpers/HemisphereLightHelper.js +39 -0
  274. package/src/helpers/PlaneHelper.js +33 -0
  275. package/src/helpers/PointLightHelper.js +43 -0
  276. package/src/helpers/PolarGridHelper.js +30 -0
  277. package/src/helpers/SkeletonHelper.js +39 -2
  278. package/src/helpers/SpotLightHelper.js +40 -0
  279. package/src/lights/AmbientLight.js +25 -0
  280. package/src/lights/DirectionalLight.js +57 -0
  281. package/src/lights/DirectionalLightShadow.js +15 -0
  282. package/src/lights/HemisphereLight.js +32 -0
  283. package/src/lights/Light.js +36 -0
  284. package/src/lights/LightProbe.js +43 -0
  285. package/src/lights/LightShadow.js +159 -0
  286. package/src/lights/PointLight.js +59 -0
  287. package/src/lights/PointLightShadow.js +21 -0
  288. package/src/lights/RectAreaLight.js +59 -0
  289. package/src/lights/SpotLight.js +102 -0
  290. package/src/lights/SpotLightShadow.js +24 -2
  291. package/src/lights/webgpu/IESSpotLight.js +21 -0
  292. package/src/loaders/Loader.js +132 -0
  293. package/src/loaders/MaterialLoader.js +7 -1
  294. package/src/loaders/nodes/NodeLoader.js +189 -0
  295. package/src/loaders/nodes/NodeMaterialLoader.js +108 -0
  296. package/src/loaders/nodes/NodeObjectLoader.js +151 -0
  297. package/src/materials/LineDashedMaterial.js +0 -1
  298. package/src/materials/Material.js +469 -7
  299. package/src/materials/MeshPhongMaterial.js +1 -1
  300. package/src/materials/MeshPhysicalMaterial.js +2 -2
  301. package/src/materials/MeshStandardMaterial.js +2 -2
  302. package/src/{nodes/materials → materials/nodes}/Line2NodeMaterial.js +192 -82
  303. package/src/materials/nodes/LineBasicNodeMaterial.js +46 -0
  304. package/src/materials/nodes/LineDashedNodeMaterial.js +132 -0
  305. package/src/materials/nodes/MeshBasicNodeMaterial.js +133 -0
  306. package/src/materials/nodes/MeshLambertNodeMaterial.js +82 -0
  307. package/src/materials/nodes/MeshMatcapNodeMaterial.js +77 -0
  308. package/src/materials/nodes/MeshNormalNodeMaterial.js +67 -0
  309. package/src/materials/nodes/MeshPhongNodeMaterial.js +141 -0
  310. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +517 -0
  311. package/src/materials/nodes/MeshSSSNodeMaterial.js +175 -0
  312. package/src/materials/nodes/MeshStandardNodeMaterial.js +186 -0
  313. package/src/materials/nodes/MeshToonNodeMaterial.js +66 -0
  314. package/src/materials/nodes/NodeMaterial.js +1180 -0
  315. package/src/{nodes/materials/Materials.js → materials/nodes/NodeMaterials.js} +3 -2
  316. package/src/materials/nodes/PointsNodeMaterial.js +153 -0
  317. package/src/materials/nodes/ShadowNodeMaterial.js +67 -0
  318. package/src/materials/nodes/SpriteNodeMaterial.js +198 -0
  319. package/src/materials/nodes/VolumeNodeMaterial.js +72 -0
  320. package/src/materials/nodes/manager/NodeMaterialObserver.js +509 -0
  321. package/src/math/Box2.js +177 -0
  322. package/src/math/Box3.js +243 -0
  323. package/src/math/Color.js +343 -0
  324. package/src/math/ColorManagement.js +143 -102
  325. package/src/math/Cylindrical.js +65 -6
  326. package/src/math/Euler.js +137 -4
  327. package/src/math/Frustum.js +83 -0
  328. package/src/math/Interpolant.js +87 -8
  329. package/src/math/Line3.js +96 -2
  330. package/src/math/MathUtils.js +182 -19
  331. package/src/math/Matrix2.js +70 -0
  332. package/src/math/Matrix3.js +229 -4
  333. package/src/math/Matrix4.js +368 -3
  334. package/src/math/Plane.js +164 -2
  335. package/src/math/Quaternion.js +265 -9
  336. package/src/math/Ray.js +160 -0
  337. package/src/math/Sphere.js +147 -0
  338. package/src/math/Spherical.js +73 -11
  339. package/src/math/SphericalHarmonics3.js +112 -14
  340. package/src/math/Triangle.js +230 -2
  341. package/src/math/Vector2.js +396 -10
  342. package/src/math/Vector3.js +550 -13
  343. package/src/math/Vector4.js +415 -9
  344. package/src/math/interpolants/CubicInterpolant.js +10 -1
  345. package/src/math/interpolants/DiscreteInterpolant.js +10 -2
  346. package/src/math/interpolants/LinearInterpolant.js +13 -0
  347. package/src/math/interpolants/QuaternionLinearInterpolant.js +10 -1
  348. package/src/nodes/Nodes.js +84 -166
  349. package/src/nodes/TSL.js +167 -0
  350. package/src/nodes/accessors/AccessorsUtils.js +39 -10
  351. package/src/nodes/accessors/Arrays.js +68 -0
  352. package/src/nodes/accessors/BatchNode.js +93 -26
  353. package/src/nodes/accessors/Bitangent.js +54 -0
  354. package/src/nodes/accessors/BufferAttributeNode.js +189 -11
  355. package/src/nodes/accessors/BufferNode.js +70 -5
  356. package/src/nodes/accessors/BuiltinNode.js +63 -0
  357. package/src/nodes/accessors/Camera.js +129 -0
  358. package/src/nodes/accessors/ClippingNode.js +152 -43
  359. package/src/nodes/accessors/CubeTextureNode.js +76 -13
  360. package/src/nodes/accessors/InstanceNode.js +118 -35
  361. package/src/nodes/accessors/InstancedMeshNode.js +50 -0
  362. package/src/nodes/accessors/Lights.js +129 -0
  363. package/src/nodes/accessors/MaterialNode.js +394 -58
  364. package/src/nodes/accessors/MaterialProperties.js +57 -1
  365. package/src/nodes/accessors/MaterialReferenceNode.js +60 -18
  366. package/src/nodes/accessors/ModelNode.js +159 -12
  367. package/src/nodes/accessors/ModelViewProjectionNode.js +10 -36
  368. package/src/nodes/accessors/MorphNode.js +60 -13
  369. package/src/nodes/accessors/Normal.js +156 -0
  370. package/src/nodes/accessors/Object3DNode.js +154 -35
  371. package/src/nodes/accessors/PointUVNode.js +35 -6
  372. package/src/nodes/accessors/Position.js +64 -0
  373. package/src/nodes/accessors/ReferenceBaseNode.js +357 -0
  374. package/src/nodes/accessors/ReferenceNode.js +243 -6
  375. package/src/nodes/accessors/ReflectVector.js +36 -0
  376. package/src/nodes/accessors/RendererReferenceNode.js +57 -7
  377. package/src/nodes/accessors/SceneNode.js +98 -6
  378. package/src/nodes/accessors/SkinningNode.js +214 -21
  379. package/src/nodes/accessors/StorageBufferNode.js +288 -28
  380. package/src/nodes/accessors/StorageTextureNode.js +139 -12
  381. package/src/nodes/accessors/Tangent.js +62 -0
  382. package/src/nodes/accessors/Texture3DNode.js +98 -12
  383. package/src/nodes/accessors/{TextureBicubicNode.js → TextureBicubic.js} +14 -34
  384. package/src/nodes/accessors/TextureNode.js +347 -34
  385. package/src/nodes/accessors/TextureSizeNode.js +51 -9
  386. package/src/nodes/accessors/UV.js +11 -0
  387. package/src/nodes/accessors/UniformArrayNode.js +241 -32
  388. package/src/nodes/accessors/UserDataNode.js +55 -7
  389. package/src/nodes/accessors/VelocityNode.js +223 -0
  390. package/src/nodes/accessors/VertexColorNode.js +45 -6
  391. package/src/nodes/code/CodeNode.js +108 -8
  392. package/src/nodes/code/ExpressionNode.js +38 -7
  393. package/src/nodes/code/FunctionCallNode.js +62 -11
  394. package/src/nodes/code/FunctionNode.js +54 -24
  395. package/src/nodes/code/ScriptableNode.js +241 -17
  396. package/src/nodes/code/ScriptableValueNode.js +93 -8
  397. package/src/nodes/core/ArrayNode.js +142 -0
  398. package/src/nodes/core/AssignNode.js +60 -12
  399. package/src/nodes/core/AttributeNode.js +55 -22
  400. package/src/nodes/core/BypassNode.js +59 -11
  401. package/src/nodes/core/CacheNode.js +64 -10
  402. package/src/nodes/core/ConstNode.js +38 -3
  403. package/src/nodes/core/ContextNode.js +87 -12
  404. package/src/nodes/core/IndexNode.js +102 -10
  405. package/src/nodes/core/InputNode.js +55 -3
  406. package/src/nodes/core/LightingModel.js +65 -5
  407. package/src/nodes/core/MRTNode.js +81 -7
  408. package/src/nodes/core/Node.js +368 -50
  409. package/src/nodes/core/NodeAttribute.js +38 -0
  410. package/src/nodes/core/NodeBuilder.js +1317 -83
  411. package/src/nodes/core/NodeCache.js +41 -2
  412. package/src/nodes/core/NodeCode.js +31 -0
  413. package/src/nodes/core/NodeFrame.js +123 -2
  414. package/src/nodes/core/NodeFunction.js +46 -0
  415. package/src/nodes/core/NodeFunctionInput.js +44 -0
  416. package/src/nodes/core/NodeParser.js +11 -0
  417. package/src/nodes/core/NodeUniform.js +52 -0
  418. package/src/nodes/core/NodeUtils.js +226 -6
  419. package/src/nodes/core/NodeVar.js +47 -1
  420. package/src/nodes/core/NodeVarying.js +28 -0
  421. package/src/nodes/core/OutputStructNode.js +61 -17
  422. package/src/nodes/core/ParameterNode.js +34 -4
  423. package/src/nodes/core/PropertyNode.js +296 -32
  424. package/src/nodes/core/StackNode.js +108 -8
  425. package/src/nodes/core/StructNode.js +120 -0
  426. package/src/nodes/core/StructType.js +13 -0
  427. package/src/nodes/core/StructTypeNode.js +116 -9
  428. package/src/nodes/core/TempNode.js +37 -7
  429. package/src/nodes/core/UniformGroupNode.js +98 -17
  430. package/src/nodes/core/UniformNode.js +72 -4
  431. package/src/nodes/core/VarNode.js +170 -13
  432. package/src/nodes/core/VaryingNode.js +109 -8
  433. package/src/nodes/core/constants.js +40 -0
  434. package/src/nodes/display/BlendModes.js +193 -0
  435. package/src/nodes/display/BumpMapNode.js +47 -10
  436. package/src/nodes/display/ColorAdjustment.js +141 -0
  437. package/src/nodes/display/ColorSpaceFunctions.js +54 -0
  438. package/src/nodes/display/ColorSpaceNode.js +147 -68
  439. package/src/nodes/display/FrontFacingNode.js +39 -6
  440. package/src/nodes/display/NormalMapNode.js +55 -13
  441. package/src/nodes/display/PassNode.js +420 -19
  442. package/src/nodes/display/PosterizeNode.js +40 -7
  443. package/src/nodes/display/RenderOutputNode.js +81 -13
  444. package/src/nodes/display/ScreenNode.js +286 -0
  445. package/src/nodes/display/ToneMappingFunctions.js +242 -0
  446. package/src/nodes/display/ToneMappingNode.js +68 -175
  447. package/src/nodes/display/ToonOutlinePassNode.js +183 -0
  448. package/src/nodes/display/ViewportDepthNode.js +210 -36
  449. package/src/nodes/display/ViewportDepthTextureNode.js +32 -9
  450. package/src/nodes/display/ViewportSharedTextureNode.js +32 -9
  451. package/src/nodes/display/ViewportTextureNode.js +68 -11
  452. package/src/nodes/fog/Fog.js +113 -0
  453. package/src/nodes/functions/BSDF/BRDF_GGX.js +4 -4
  454. package/src/nodes/functions/BSDF/BRDF_Lambert.js +2 -2
  455. package/src/nodes/functions/BSDF/BRDF_Sheen.js +6 -6
  456. package/src/nodes/functions/BSDF/DFGApprox.js +2 -2
  457. package/src/nodes/functions/BSDF/D_GGX.js +2 -2
  458. package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +3 -3
  459. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  460. package/src/nodes/functions/BSDF/F_Schlick.js +2 -2
  461. package/src/nodes/functions/BSDF/LTC.js +50 -6
  462. package/src/nodes/functions/BSDF/Schlick_to_F0.js +2 -2
  463. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +2 -2
  464. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
  465. package/src/nodes/functions/BasicLightingModel.js +27 -6
  466. package/src/nodes/functions/PhongLightingModel.js +38 -8
  467. package/src/nodes/functions/PhysicalLightingModel.js +215 -51
  468. package/src/nodes/functions/ShadowMaskModel.js +24 -1
  469. package/src/nodes/functions/ToonLightingModel.js +24 -5
  470. package/src/nodes/functions/VolumetricLightingModel.js +183 -0
  471. package/src/nodes/functions/material/getAlphaHashThreshold.js +68 -0
  472. package/src/nodes/functions/material/getGeometryRoughness.js +10 -4
  473. package/src/nodes/functions/material/getParallaxCorrectNormal.js +37 -0
  474. package/src/nodes/functions/material/getRoughness.js +2 -2
  475. package/src/nodes/functions/material/getShIrradianceAt.js +28 -0
  476. package/src/nodes/geometry/RangeNode.js +62 -7
  477. package/src/nodes/gpgpu/AtomicFunctionNode.js +280 -0
  478. package/src/nodes/gpgpu/BarrierNode.js +89 -0
  479. package/src/nodes/gpgpu/ComputeBuiltinNode.js +227 -0
  480. package/src/nodes/gpgpu/ComputeNode.js +124 -9
  481. package/src/nodes/gpgpu/WorkgroupInfoNode.js +208 -0
  482. package/src/nodes/lighting/AONode.js +24 -3
  483. package/src/nodes/lighting/AmbientLightNode.js +16 -8
  484. package/src/nodes/lighting/AnalyticLightNode.js +151 -231
  485. package/src/nodes/lighting/BasicEnvironmentNode.js +25 -3
  486. package/src/nodes/lighting/BasicLightMapNode.js +25 -5
  487. package/src/nodes/lighting/DirectionalLightNode.js +19 -20
  488. package/src/nodes/lighting/EnvironmentNode.js +34 -17
  489. package/src/nodes/lighting/HemisphereLightNode.js +42 -11
  490. package/src/nodes/lighting/IESSpotLightNode.js +18 -9
  491. package/src/nodes/lighting/IrradianceNode.js +23 -3
  492. package/src/nodes/lighting/LightProbeNode.js +29 -36
  493. package/src/nodes/lighting/LightUtils.js +12 -4
  494. package/src/nodes/lighting/LightingContextNode.js +70 -21
  495. package/src/nodes/lighting/LightingNode.js +22 -9
  496. package/src/nodes/lighting/LightsNode.js +309 -86
  497. package/src/nodes/lighting/PointLightNode.js +66 -32
  498. package/src/nodes/lighting/PointShadowNode.js +306 -0
  499. package/src/nodes/lighting/RectAreaLightNode.js +61 -25
  500. package/src/nodes/lighting/ShadowBaseNode.js +92 -0
  501. package/src/nodes/lighting/ShadowNode.js +812 -0
  502. package/src/nodes/lighting/SpotLightNode.js +73 -31
  503. package/src/nodes/materialx/MaterialXNodes.js +2 -2
  504. package/src/nodes/materialx/lib/mx_hsv.js +27 -22
  505. package/src/nodes/materialx/lib/mx_noise.js +70 -70
  506. package/src/nodes/materialx/lib/mx_transform_color.js +2 -2
  507. package/src/nodes/math/ConditionalNode.js +230 -0
  508. package/src/nodes/math/Hash.js +21 -0
  509. package/src/nodes/math/MathNode.js +812 -131
  510. package/src/nodes/math/MathUtils.js +47 -8
  511. package/src/nodes/math/OperatorNode.js +410 -66
  512. package/src/nodes/math/TriNoise3D.js +32 -32
  513. package/src/nodes/parsers/GLSLNodeFunction.js +16 -0
  514. package/src/nodes/parsers/GLSLNodeParser.js +11 -0
  515. package/src/nodes/pmrem/PMREMNode.js +188 -28
  516. package/src/nodes/pmrem/PMREMUtils.js +24 -24
  517. package/src/nodes/procedural/Checker.js +22 -0
  518. package/src/nodes/shapes/Shapes.js +32 -0
  519. package/src/nodes/tsl/TSLBase.js +31 -0
  520. package/src/nodes/{shadernode/ShaderNode.js → tsl/TSLCore.js} +114 -98
  521. package/src/nodes/utils/ArrayElementNode.js +45 -5
  522. package/src/nodes/utils/ConvertNode.js +39 -4
  523. package/src/nodes/utils/CubeMapNode.js +88 -8
  524. package/src/nodes/utils/Discard.js +24 -0
  525. package/src/nodes/utils/EquirectUVNode.js +39 -7
  526. package/src/nodes/utils/FlipNode.js +106 -0
  527. package/src/nodes/utils/FunctionOverloadingNode.js +61 -6
  528. package/src/nodes/utils/JoinNode.js +31 -3
  529. package/src/nodes/utils/LoopNode.js +95 -9
  530. package/src/nodes/utils/MatcapUVNode.js +27 -8
  531. package/src/nodes/utils/MaxMipLevelNode.js +57 -6
  532. package/src/nodes/utils/MemberNode.js +68 -0
  533. package/src/nodes/utils/Oscillators.js +41 -0
  534. package/src/nodes/utils/Packing.js +21 -0
  535. package/src/nodes/utils/PostProcessingUtils.js +95 -0
  536. package/src/nodes/utils/RTTNode.js +141 -9
  537. package/src/nodes/utils/ReflectorNode.js +295 -21
  538. package/src/nodes/utils/RemapNode.js +93 -10
  539. package/src/nodes/utils/RotateNode.js +48 -13
  540. package/src/nodes/utils/SetNode.js +50 -4
  541. package/src/nodes/utils/SplitNode.js +62 -6
  542. package/src/nodes/utils/SpriteSheetUVNode.js +56 -7
  543. package/src/nodes/utils/SpriteUtils.js +21 -5
  544. package/src/nodes/utils/StorageArrayElementNode.js +64 -12
  545. package/src/nodes/utils/Timer.js +73 -0
  546. package/src/nodes/utils/TriplanarTexturesNode.js +96 -10
  547. package/src/nodes/utils/UVUtils.js +27 -9
  548. package/src/nodes/utils/ViewportUtils.js +16 -4
  549. package/src/objects/BatchedMesh.js +808 -281
  550. package/src/objects/Bone.js +24 -0
  551. package/src/objects/ClippingGroup.js +68 -0
  552. package/src/objects/Group.js +24 -0
  553. package/src/objects/InstancedMesh.js +120 -2
  554. package/src/objects/LOD.js +120 -5
  555. package/src/objects/Line.js +89 -6
  556. package/src/objects/LineLoop.js +20 -0
  557. package/src/objects/LineSegments.js +18 -0
  558. package/src/objects/Mesh.js +82 -23
  559. package/src/objects/Points.js +62 -0
  560. package/src/objects/Skeleton.js +107 -2
  561. package/src/objects/SkinnedMesh.js +99 -5
  562. package/src/objects/Sprite.js +54 -0
  563. package/src/renderers/WebGLRenderer.js +274 -157
  564. package/src/renderers/common/Animation.js +109 -12
  565. package/src/renderers/common/Attributes.js +40 -0
  566. package/src/renderers/common/Backend.js +504 -44
  567. package/src/renderers/common/Background.js +67 -9
  568. package/src/renderers/common/BindGroup.js +45 -1
  569. package/src/renderers/common/Binding.js +35 -0
  570. package/src/renderers/common/Bindings.js +136 -19
  571. package/src/renderers/common/Buffer.js +49 -0
  572. package/src/renderers/common/BufferUtils.js +25 -0
  573. package/src/renderers/common/BundleGroup.js +83 -0
  574. package/src/renderers/common/ChainMap.js +45 -6
  575. package/src/renderers/common/ClippingContext.js +175 -80
  576. package/src/renderers/common/Color4.js +40 -0
  577. package/src/renderers/common/ComputePipeline.js +24 -0
  578. package/src/renderers/common/Constants.js +2 -1
  579. package/src/renderers/common/CubeRenderTarget.js +22 -3
  580. package/src/renderers/common/DataMap.js +37 -1
  581. package/src/renderers/common/Geometries.js +111 -14
  582. package/src/renderers/common/IndirectStorageBufferAttribute.js +38 -0
  583. package/src/renderers/common/Info.js +78 -35
  584. package/src/renderers/common/Lighting.js +73 -0
  585. package/src/renderers/common/Pipeline.js +22 -0
  586. package/src/renderers/common/Pipelines.js +148 -5
  587. package/src/renderers/common/PostProcessing.js +112 -11
  588. package/src/renderers/common/ProgrammableStage.js +60 -2
  589. package/src/renderers/common/QuadMesh.js +56 -5
  590. package/src/renderers/common/RenderBundle.js +14 -8
  591. package/src/renderers/common/RenderBundles.js +39 -10
  592. package/src/renderers/common/RenderContext.js +205 -7
  593. package/src/renderers/common/RenderContexts.js +59 -6
  594. package/src/renderers/common/RenderList.js +230 -21
  595. package/src/renderers/common/RenderLists.js +45 -6
  596. package/src/renderers/common/RenderObject.js +552 -41
  597. package/src/renderers/common/RenderObjects.js +118 -9
  598. package/src/renderers/common/RenderPipeline.js +24 -0
  599. package/src/renderers/common/Renderer.js +1537 -239
  600. package/src/renderers/common/RendererUtils.js +191 -0
  601. package/src/renderers/common/SampledTexture.js +132 -3
  602. package/src/renderers/common/Sampler.js +30 -0
  603. package/src/renderers/common/StorageBuffer.js +24 -0
  604. package/src/renderers/common/StorageBufferAttribute.js +31 -2
  605. package/src/renderers/common/StorageInstancedBufferAttribute.js +31 -2
  606. package/src/renderers/common/StorageTexture.js +38 -0
  607. package/src/renderers/common/Textures.js +142 -32
  608. package/src/renderers/common/TimestampQueryPool.js +98 -0
  609. package/src/renderers/common/Uniform.js +225 -3
  610. package/src/renderers/common/UniformBuffer.js +19 -0
  611. package/src/renderers/common/UniformsGroup.js +157 -6
  612. package/src/renderers/common/XRManager.js +1185 -0
  613. package/src/renderers/common/XRRenderTarget.js +74 -0
  614. package/src/renderers/common/extras/PMREMGenerator.js +211 -53
  615. package/src/renderers/common/nodes/NodeBuilderState.js +100 -6
  616. package/src/renderers/common/nodes/NodeLibrary.js +194 -0
  617. package/src/renderers/common/nodes/NodeSampledTexture.js +92 -4
  618. package/src/renderers/common/nodes/NodeSampler.js +28 -0
  619. package/src/renderers/common/nodes/NodeStorageBuffer.js +37 -3
  620. package/src/renderers/common/nodes/NodeUniform.js +285 -2
  621. package/src/renderers/common/nodes/NodeUniformBuffer.js +29 -0
  622. package/src/renderers/common/nodes/NodeUniformsGroup.js +31 -18
  623. package/src/renderers/common/nodes/Nodes.js +390 -70
  624. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  625. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  626. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +2 -2
  627. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  628. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +2 -2
  629. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +7 -7
  630. package/src/renderers/shaders/ShaderLib/points.glsl.js +2 -0
  631. package/src/renderers/shaders/ShaderLib/sprite.glsl.js +2 -4
  632. package/src/renderers/webgl/WebGLAttributes.js +45 -14
  633. package/src/renderers/webgl/WebGLBackground.js +24 -1
  634. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  635. package/src/renderers/webgl/WebGLCapabilities.js +2 -0
  636. package/src/renderers/webgl/WebGLGeometries.js +0 -28
  637. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  638. package/src/renderers/webgl/WebGLProgram.js +27 -29
  639. package/src/renderers/webgl/WebGLPrograms.js +24 -16
  640. package/src/renderers/webgl/WebGLState.js +68 -11
  641. package/src/renderers/webgl/WebGLTextures.js +49 -10
  642. package/src/renderers/webgl-fallback/WebGLBackend.js +1055 -238
  643. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +5 -10
  644. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +425 -48
  645. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +64 -1
  646. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +28 -0
  647. package/src/renderers/webgl-fallback/utils/WebGLExtensions.js +45 -0
  648. package/src/renderers/webgl-fallback/utils/WebGLState.js +419 -14
  649. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +281 -59
  650. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +367 -0
  651. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +43 -0
  652. package/src/renderers/webgpu/WebGPUBackend.js +816 -236
  653. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +78 -0
  654. package/src/renderers/webgpu/WebGPURenderer.js +45 -6
  655. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +63 -0
  656. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +97 -0
  657. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +954 -147
  658. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +29 -4
  659. package/src/renderers/webgpu/nodes/WGSLNodeParser.js +11 -0
  660. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +147 -31
  661. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +213 -31
  662. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +146 -28
  663. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +161 -7
  664. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +333 -50
  665. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +287 -0
  666. package/src/renderers/webgpu/utils/WebGPUUtils.js +131 -3
  667. package/src/renderers/webxr/WebXRDepthSensing.js +1 -1
  668. package/src/renderers/webxr/WebXRManager.js +54 -32
  669. package/src/scenes/Fog.js +60 -0
  670. package/src/scenes/FogExp2.js +51 -0
  671. package/src/scenes/Scene.js +87 -0
  672. package/src/textures/Data3DTexture.js +2 -2
  673. package/src/textures/DepthTexture.js +2 -0
  674. package/src/textures/Source.js +2 -2
  675. package/src/textures/Texture.js +368 -5
  676. package/src/textures/VideoFrameTexture.js +35 -0
  677. package/src/utils.js +33 -1
  678. package/examples/jsm/animation/MMDAnimationHelper.js +0 -1207
  679. package/examples/jsm/animation/MMDPhysics.js +0 -1406
  680. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  681. package/examples/jsm/controls/Controls.js +0 -32
  682. package/examples/jsm/exporters/MMDExporter.js +0 -217
  683. package/examples/jsm/geometries/InstancedPointsGeometry.js +0 -174
  684. package/examples/jsm/geometries/SDFGeometryGenerator.js +0 -144
  685. package/examples/jsm/libs/mmdparser.module.js +0 -11530
  686. package/examples/jsm/loaders/LogLuvLoader.js +0 -606
  687. package/examples/jsm/loaders/MMDLoader.js +0 -2295
  688. package/examples/jsm/loaders/TiltLoader.js +0 -520
  689. package/examples/jsm/objects/InstancedPoints.js +0 -21
  690. package/examples/jsm/shaders/MMDToonShader.js +0 -134
  691. package/examples/jsm/utils/GPUStatsPanel.js +0 -95
  692. package/examples/jsm/utils/PackedPhongMaterial.js +0 -178
  693. package/src/nodes/accessors/BitangentNode.js +0 -13
  694. package/src/nodes/accessors/CameraNode.js +0 -19
  695. package/src/nodes/accessors/InstancedPointsMaterialNode.js +0 -21
  696. package/src/nodes/accessors/NormalNode.js +0 -14
  697. package/src/nodes/accessors/PositionNode.js +0 -10
  698. package/src/nodes/accessors/ReflectVectorNode.js +0 -10
  699. package/src/nodes/accessors/TangentNode.js +0 -23
  700. package/src/nodes/accessors/UVNode.js +0 -3
  701. package/src/nodes/core/NodeKeywords.js +0 -80
  702. package/src/nodes/core/UniformGroup.js +0 -13
  703. package/src/nodes/display/AfterImageNode.js +0 -152
  704. package/src/nodes/display/AnamorphicNode.js +0 -145
  705. package/src/nodes/display/BlendModeNode.js +0 -128
  706. package/src/nodes/display/ColorAdjustmentNode.js +0 -104
  707. package/src/nodes/display/DenoiseNode.js +0 -198
  708. package/src/nodes/display/DotScreenNode.js +0 -75
  709. package/src/nodes/display/FXAANode.js +0 -327
  710. package/src/nodes/display/FilmNode.js +0 -52
  711. package/src/nodes/display/GTAONode.js +0 -324
  712. package/src/nodes/display/GaussianBlurNode.js +0 -207
  713. package/src/nodes/display/Lut3DNode.js +0 -53
  714. package/src/nodes/display/RGBShiftNode.js +0 -49
  715. package/src/nodes/display/SepiaNode.js +0 -18
  716. package/src/nodes/display/TransitionNode.js +0 -76
  717. package/src/nodes/display/ViewportNode.js +0 -137
  718. package/src/nodes/fog/FogExp2Node.js +0 -34
  719. package/src/nodes/fog/FogNode.js +0 -48
  720. package/src/nodes/fog/FogRangeNode.js +0 -35
  721. package/src/nodes/lighting/LightNode.js +0 -57
  722. package/src/nodes/loaders/NodeLoader.js +0 -110
  723. package/src/nodes/loaders/NodeMaterialLoader.js +0 -60
  724. package/src/nodes/loaders/NodeObjectLoader.js +0 -71
  725. package/src/nodes/materials/InstancedPointsNodeMaterial.js +0 -162
  726. package/src/nodes/materials/LineBasicNodeMaterial.js +0 -28
  727. package/src/nodes/materials/LineDashedNodeMaterial.js +0 -55
  728. package/src/nodes/materials/MeshBasicNodeMaterial.js +0 -73
  729. package/src/nodes/materials/MeshLambertNodeMaterial.js +0 -43
  730. package/src/nodes/materials/MeshMatcapNodeMaterial.js +0 -53
  731. package/src/nodes/materials/MeshNormalNodeMaterial.js +0 -40
  732. package/src/nodes/materials/MeshPhongNodeMaterial.js +0 -74
  733. package/src/nodes/materials/MeshPhysicalNodeMaterial.js +0 -244
  734. package/src/nodes/materials/MeshSSSNodeMaterial.js +0 -84
  735. package/src/nodes/materials/MeshStandardNodeMaterial.js +0 -104
  736. package/src/nodes/materials/MeshToonNodeMaterial.js +0 -34
  737. package/src/nodes/materials/NodeMaterial.js +0 -680
  738. package/src/nodes/materials/PointsNodeMaterial.js +0 -39
  739. package/src/nodes/materials/ShadowNodeMaterial.js +0 -34
  740. package/src/nodes/materials/SpriteNodeMaterial.js +0 -90
  741. package/src/nodes/materials/VolumeNodeMaterial.js +0 -106
  742. package/src/nodes/math/CondNode.js +0 -139
  743. package/src/nodes/math/HashNode.js +0 -34
  744. package/src/nodes/procedural/CheckerNode.js +0 -42
  745. package/src/nodes/utils/DiscardNode.js +0 -28
  746. package/src/nodes/utils/OscNode.js +0 -81
  747. package/src/nodes/utils/PackingNode.js +0 -55
  748. package/src/nodes/utils/TimerNode.js +0 -94
@@ -1,10 +1,9 @@
1
1
  import { BufferAttribute } from '../core/BufferAttribute.js';
2
2
  import { BufferGeometry } from '../core/BufferGeometry.js';
3
3
  import { DataTexture } from '../textures/DataTexture.js';
4
- import { FloatType, RedIntegerFormat, UnsignedIntType } from '../constants.js';
4
+ import { FloatType, RedIntegerFormat, UnsignedIntType, RGBAFormat } from '../constants.js';
5
5
  import { Matrix4 } from '../math/Matrix4.js';
6
6
  import { Mesh } from './Mesh.js';
7
- import { RGBAFormat } from '../constants.js';
8
7
  import { ColorManagement } from '../math/ColorManagement.js';
9
8
  import { Box3 } from '../math/Box3.js';
10
9
  import { Sphere } from '../math/Sphere.js';
@@ -12,6 +11,12 @@ import { Frustum } from '../math/Frustum.js';
12
11
  import { Vector3 } from '../math/Vector3.js';
13
12
  import { Color } from '../math/Color.js';
14
13
 
14
+ function ascIdSort( a, b ) {
15
+
16
+ return a - b;
17
+
18
+ }
19
+
15
20
  function sortOpaque( a, b ) {
16
21
 
17
22
  return a.z - b.z;
@@ -34,7 +39,7 @@ class MultiDrawRenderList {
34
39
 
35
40
  }
36
41
 
37
- push( drawRange, z, index ) {
42
+ push( start, count, z, index ) {
38
43
 
39
44
  const pool = this.pool;
40
45
  const list = this.list;
@@ -55,8 +60,8 @@ class MultiDrawRenderList {
55
60
  list.push( item );
56
61
  this.index ++;
57
62
 
58
- item.start = drawRange.start;
59
- item.count = drawRange.count;
63
+ item.start = start;
64
+ item.count = count;
60
65
  item.z = z;
61
66
  item.index = index;
62
67
 
@@ -72,10 +77,7 @@ class MultiDrawRenderList {
72
77
  }
73
78
 
74
79
  const _matrix = /*@__PURE__*/ new Matrix4();
75
- const _invMatrixWorld = /*@__PURE__*/ new Matrix4();
76
- const _identityMatrix = /*@__PURE__*/ new Matrix4();
77
80
  const _whiteColor = /*@__PURE__*/ new Color( 1, 1, 1 );
78
- const _projScreenMatrix = /*@__PURE__*/ new Matrix4();
79
81
  const _frustum = /*@__PURE__*/ new Frustum();
80
82
  const _box = /*@__PURE__*/ new Box3();
81
83
  const _sphere = /*@__PURE__*/ new Sphere();
@@ -86,13 +88,6 @@ const _renderList = /*@__PURE__*/ new MultiDrawRenderList();
86
88
  const _mesh = /*@__PURE__*/ new Mesh();
87
89
  const _batchIntersects = [];
88
90
 
89
- // @TODO: SkinnedMesh support?
90
- // @TODO: geometry.groups support?
91
- // @TODO: geometry.drawRange support?
92
- // @TODO: geometry.morphAttributes support?
93
- // @TODO: Support uniform parameter per geometry
94
- // @TODO: Add an "optimize" function to pack geometry and remove data gaps
95
-
96
91
  // copies data from attribute "src" into "target" starting at "targetOffset"
97
92
  function copyAttributeData( src, target, targetOffset = 0 ) {
98
93
 
@@ -123,44 +118,159 @@ function copyAttributeData( src, target, targetOffset = 0 ) {
123
118
 
124
119
  }
125
120
 
126
- class BatchedMesh extends Mesh {
121
+ // safely copies array contents to a potentially smaller array
122
+ function copyArrayContents( src, target ) {
127
123
 
128
- get maxInstanceCount() {
124
+ if ( src.constructor !== target.constructor ) {
129
125
 
130
- return this._maxInstanceCount;
126
+ // if arrays are of a different type (eg due to index size increasing) then data must be per-element copied
127
+ const len = Math.min( src.length, target.length );
128
+ for ( let i = 0; i < len; i ++ ) {
129
+
130
+ target[ i ] = src[ i ];
131
+
132
+ }
133
+
134
+ } else {
135
+
136
+ // if the arrays use the same data layout we can use a fast block copy
137
+ const len = Math.min( src.length, target.length );
138
+ target.set( new src.constructor( src.buffer, 0, len ) );
131
139
 
132
140
  }
133
141
 
142
+ }
143
+
144
+ /**
145
+ * A special version of a mesh with multi draw batch rendering support. Use
146
+ * this class if you have to render a large number of objects with the same
147
+ * material but with different geometries or world transformations. The usage of
148
+ * `BatchedMesh` will help you to reduce the number of draw calls and thus improve the overall
149
+ * rendering performance in your application.
150
+ *
151
+ * ```js
152
+ * const box = new THREE.BoxGeometry( 1, 1, 1 );
153
+ * const sphere = new THREE.SphereGeometry( 1, 12, 12 );
154
+ * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
155
+ *
156
+ * // initialize and add geometries into the batched mesh
157
+ * const batchedMesh = new BatchedMesh( 10, 5000, 10000, material );
158
+ * const boxGeometryId = batchedMesh.addGeometry( box );
159
+ * const sphereGeometryId = batchedMesh.addGeometry( sphere );
160
+ *
161
+ * // create instances of those geometries
162
+ * const boxInstancedId1 = batchedMesh.addInstance( boxGeometryId );
163
+ * const boxInstancedId2 = batchedMesh.addInstance( boxGeometryId );
164
+ *
165
+ * const sphereInstancedId1 = batchedMesh.addInstance( sphereGeometryId );
166
+ * const sphereInstancedId2 = batchedMesh.addInstance( sphereGeometryId );
167
+ *
168
+ * // position the geometries
169
+ * batchedMesh.setMatrixAt( boxInstancedId1, boxMatrix1 );
170
+ * batchedMesh.setMatrixAt( boxInstancedId2, boxMatrix2 );
171
+ *
172
+ * batchedMesh.setMatrixAt( sphereInstancedId1, sphereMatrix1 );
173
+ * batchedMesh.setMatrixAt( sphereInstancedId2, sphereMatrix2 );
174
+ *
175
+ * scene.add( batchedMesh );
176
+ * ```
177
+ *
178
+ * @augments Mesh
179
+ */
180
+ class BatchedMesh extends Mesh {
181
+
182
+ /**
183
+ * Constructs a new batched mesh.
184
+ *
185
+ * @param {number} maxInstanceCount - The maximum number of individual instances planned to be added and rendered.
186
+ * @param {number} maxVertexCount - The maximum number of vertices to be used by all unique geometries.
187
+ * @param {number} [maxIndexCount=maxVertexCount*2] - The maximum number of indices to be used by all unique geometries
188
+ * @param {Material|Array<Material>} [material] - The mesh material.
189
+ */
134
190
  constructor( maxInstanceCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material ) {
135
191
 
136
192
  super( new BufferGeometry(), material );
137
193
 
194
+ /**
195
+ * This flag can be used for type testing.
196
+ *
197
+ * @type {boolean}
198
+ * @readonly
199
+ * @default true
200
+ */
138
201
  this.isBatchedMesh = true;
202
+
203
+ /**
204
+ * When set ot `true`, the individual objects of a batch are frustum culled.
205
+ *
206
+ * @type {boolean}
207
+ * @default true
208
+ */
139
209
  this.perObjectFrustumCulled = true;
210
+
211
+ /**
212
+ * When set to `true`, the individual objects of a batch are sorted to improve overdraw-related artifacts.
213
+ * If the material is marked as "transparent" objects are rendered back to front and if not then they are
214
+ * rendered front to back.
215
+ *
216
+ * @type {boolean}
217
+ * @default true
218
+ */
140
219
  this.sortObjects = true;
220
+
221
+ /**
222
+ * The bounding box of the batched mesh. Can be computed via {@link BatchedMesh#computeBoundingBox}.
223
+ *
224
+ * @type {?Box3}
225
+ * @default null
226
+ */
141
227
  this.boundingBox = null;
228
+
229
+ /**
230
+ * The bounding sphere of the batched mesh. Can be computed via {@link BatchedMesh#computeBoundingSphere}.
231
+ *
232
+ * @type {?Sphere}
233
+ * @default null
234
+ */
142
235
  this.boundingSphere = null;
236
+
237
+ /**
238
+ * Takes a sort a function that is run before render. The function takes a list of instances to
239
+ * sort and a camera. The objects in the list include a "z" field to perform a depth-ordered
240
+ * sort with.
241
+ *
242
+ * @type {?Function}
243
+ * @default null
244
+ */
143
245
  this.customSort = null;
144
246
 
145
- // stores visible, active, and geometry id per object
146
- this._drawInfo = [];
247
+ // stores visible, active, and geometry id per instance and reserved buffer ranges for geometries
248
+ this._instanceInfo = [];
249
+ this._geometryInfo = [];
147
250
 
148
- // geometry information
149
- this._drawRanges = [];
150
- this._reservedRanges = [];
151
- this._bounds = [];
251
+ // instance, geometry ids that have been set as inactive, and are available to be overwritten
252
+ this._availableInstanceIds = [];
253
+ this._availableGeometryIds = [];
254
+
255
+ // used to track where the next point is that geometry should be inserted
256
+ this._nextIndexStart = 0;
257
+ this._nextVertexStart = 0;
258
+ this._geometryCount = 0;
259
+
260
+ // flags
261
+ this._visibilityChanged = true;
262
+ this._geometryInitialized = false;
152
263
 
264
+ // cached user options
153
265
  this._maxInstanceCount = maxInstanceCount;
154
266
  this._maxVertexCount = maxVertexCount;
155
267
  this._maxIndexCount = maxIndexCount;
156
268
 
157
- this._geometryInitialized = false;
158
- this._geometryCount = 0;
269
+ // buffers for multi draw
159
270
  this._multiDrawCounts = new Int32Array( maxInstanceCount );
160
271
  this._multiDrawStarts = new Int32Array( maxInstanceCount );
161
272
  this._multiDrawCount = 0;
162
273
  this._multiDrawInstances = null;
163
- this._visibilityChanged = true;
164
274
 
165
275
  // Local matrix per geometry by using data texture
166
276
  this._matricesTexture = null;
@@ -172,6 +282,54 @@ class BatchedMesh extends Mesh {
172
282
 
173
283
  }
174
284
 
285
+ /**
286
+ * The maximum number of individual instances that can be stored in the batch.
287
+ *
288
+ * @type {number}
289
+ * @readonly
290
+ */
291
+ get maxInstanceCount() {
292
+
293
+ return this._maxInstanceCount;
294
+
295
+ }
296
+
297
+ /**
298
+ * The instance count.
299
+ *
300
+ * @type {number}
301
+ * @readonly
302
+ */
303
+ get instanceCount() {
304
+
305
+ return this._instanceInfo.length - this._availableInstanceIds.length;
306
+
307
+ }
308
+
309
+ /**
310
+ * The number of unused vertices.
311
+ *
312
+ * @type {number}
313
+ * @readonly
314
+ */
315
+ get unusedVertexCount() {
316
+
317
+ return this._maxVertexCount - this._nextVertexStart;
318
+
319
+ }
320
+
321
+ /**
322
+ * The number of unused indices.
323
+ *
324
+ * @type {number}
325
+ * @readonly
326
+ */
327
+ get unusedIndexCount() {
328
+
329
+ return this._maxIndexCount - this._nextIndexStart;
330
+
331
+ }
332
+
175
333
  _initMatricesTexture() {
176
334
 
177
335
  // layout (1 matrix = 4 pixels)
@@ -261,7 +419,7 @@ class BatchedMesh extends Mesh {
261
419
  const batchGeometry = this.geometry;
262
420
  if ( Boolean( geometry.getIndex() ) !== Boolean( batchGeometry.getIndex() ) ) {
263
421
 
264
- throw new Error( 'BatchedMesh: All geometries must consistently have "index".' );
422
+ throw new Error( 'THREE.BatchedMesh: All geometries must consistently have "index".' );
265
423
 
266
424
  }
267
425
 
@@ -269,7 +427,7 @@ class BatchedMesh extends Mesh {
269
427
 
270
428
  if ( ! geometry.hasAttribute( attributeName ) ) {
271
429
 
272
- throw new Error( `BatchedMesh: Added geometry missing "${ attributeName }". All geometries must have consistent attributes.` );
430
+ throw new Error( `THREE.BatchedMesh: Added geometry missing "${ attributeName }". All geometries must have consistent attributes.` );
273
431
 
274
432
  }
275
433
 
@@ -277,7 +435,7 @@ class BatchedMesh extends Mesh {
277
435
  const dstAttribute = batchGeometry.getAttribute( attributeName );
278
436
  if ( srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized ) {
279
437
 
280
- throw new Error( 'BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );
438
+ throw new Error( 'THREE.BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );
281
439
 
282
440
  }
283
441
 
@@ -285,6 +443,45 @@ class BatchedMesh extends Mesh {
285
443
 
286
444
  }
287
445
 
446
+ /**
447
+ * Validates the instance defined by the given ID.
448
+ *
449
+ * @param {number} instanceId - The the instance to validate.
450
+ */
451
+ validateInstanceId( instanceId ) {
452
+
453
+ const instanceInfo = this._instanceInfo;
454
+ if ( instanceId < 0 || instanceId >= instanceInfo.length || instanceInfo[ instanceId ].active === false ) {
455
+
456
+ throw new Error( `THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instance is either out of range or has been deleted.` );
457
+
458
+ }
459
+
460
+ }
461
+
462
+ /**
463
+ * Validates the geometry defined by the given ID.
464
+ *
465
+ * @param {number} geometryId - The the geometry to validate.
466
+ */
467
+ validateGeometryId( geometryId ) {
468
+
469
+ const geometryInfoList = this._geometryInfo;
470
+ if ( geometryId < 0 || geometryId >= geometryInfoList.length || geometryInfoList[ geometryId ].active === false ) {
471
+
472
+ throw new Error( `THREE.BatchedMesh: Invalid geometryId ${geometryId}. Geometry is either out of range or has been deleted.` );
473
+
474
+ }
475
+
476
+ }
477
+
478
+ /**
479
+ * Takes a sort a function that is run before render. The function takes a list of instances to
480
+ * sort and a camera. The objects in the list include a "z" field to perform a depth-ordered sort with.
481
+ *
482
+ * @param {Function} func - The custom sort function.
483
+ * @return {BatchedMesh} A reference to this batched mesh.
484
+ */
288
485
  setCustomSort( func ) {
289
486
 
290
487
  this.customSort = func;
@@ -292,6 +489,11 @@ class BatchedMesh extends Mesh {
292
489
 
293
490
  }
294
491
 
492
+ /**
493
+ * Computes the bounding box, updating {@link BatchedMesh#boundingBox}.
494
+ * Bounding boxes aren't computed by default. They need to be explicitly computed,
495
+ * otherwise they are `null`.
496
+ */
295
497
  computeBoundingBox() {
296
498
 
297
499
  if ( this.boundingBox === null ) {
@@ -300,16 +502,15 @@ class BatchedMesh extends Mesh {
300
502
 
301
503
  }
302
504
 
303
- const geometryCount = this._geometryCount;
304
505
  const boundingBox = this.boundingBox;
305
- const drawInfo = this._drawInfo;
506
+ const instanceInfo = this._instanceInfo;
306
507
 
307
508
  boundingBox.makeEmpty();
308
- for ( let i = 0; i < geometryCount; i ++ ) {
509
+ for ( let i = 0, l = instanceInfo.length; i < l; i ++ ) {
309
510
 
310
- if ( drawInfo[ i ].active === false ) continue;
511
+ if ( instanceInfo[ i ].active === false ) continue;
311
512
 
312
- const geometryId = drawInfo[ i ].geometryIndex;
513
+ const geometryId = instanceInfo[ i ].geometryIndex;
313
514
  this.getMatrixAt( i, _matrix );
314
515
  this.getBoundingBoxAt( geometryId, _box ).applyMatrix4( _matrix );
315
516
  boundingBox.union( _box );
@@ -318,6 +519,11 @@ class BatchedMesh extends Mesh {
318
519
 
319
520
  }
320
521
 
522
+ /**
523
+ * Computes the bounding sphere, updating {@link BatchedMesh#boundingSphere}.
524
+ * Bounding spheres aren't computed by default. They need to be explicitly computed,
525
+ * otherwise they are `null`.
526
+ */
321
527
  computeBoundingSphere() {
322
528
 
323
529
  if ( this.boundingSphere === null ) {
@@ -327,14 +533,14 @@ class BatchedMesh extends Mesh {
327
533
  }
328
534
 
329
535
  const boundingSphere = this.boundingSphere;
330
- const drawInfo = this._drawInfo;
536
+ const instanceInfo = this._instanceInfo;
331
537
 
332
538
  boundingSphere.makeEmpty();
333
- for ( let i = 0, l = drawInfo.length; i < l; i ++ ) {
539
+ for ( let i = 0, l = instanceInfo.length; i < l; i ++ ) {
334
540
 
335
- if ( drawInfo[ i ].active === false ) continue;
541
+ if ( instanceInfo[ i ].active === false ) continue;
336
542
 
337
- const geometryId = drawInfo[ i ].geometryIndex;
543
+ const geometryId = instanceInfo[ i ].geometryIndex;
338
544
  this.getMatrixAt( i, _matrix );
339
545
  this.getBoundingSphereAt( geometryId, _sphere ).applyMatrix4( _matrix );
340
546
  boundingSphere.union( _sphere );
@@ -343,28 +549,49 @@ class BatchedMesh extends Mesh {
343
549
 
344
550
  }
345
551
 
552
+ /**
553
+ * Adds a new instance to the batch using the geometry of the given ID and returns
554
+ * a new id referring to the new instance to be used by other functions.
555
+ *
556
+ * @param {number} geometryId - The ID of a previously added geometry via {@link BatchedMesh#addGeometry}.
557
+ * @return {number} The instance ID.
558
+ */
346
559
  addInstance( geometryId ) {
347
560
 
561
+ const atCapacity = this._instanceInfo.length >= this.maxInstanceCount;
562
+
348
563
  // ensure we're not over geometry
349
- if ( this._drawInfo.length >= this._maxInstanceCount ) {
564
+ if ( atCapacity && this._availableInstanceIds.length === 0 ) {
350
565
 
351
- throw new Error( 'BatchedMesh: Maximum item count reached.' );
566
+ throw new Error( 'THREE.BatchedMesh: Maximum item count reached.' );
352
567
 
353
568
  }
354
569
 
355
- this._drawInfo.push( {
356
-
570
+ const instanceInfo = {
357
571
  visible: true,
358
572
  active: true,
359
573
  geometryIndex: geometryId,
574
+ };
575
+
576
+ let drawId = null;
577
+
578
+ // Prioritize using previously freed instance ids
579
+ if ( this._availableInstanceIds.length > 0 ) {
580
+
581
+ this._availableInstanceIds.sort( ascIdSort );
582
+
583
+ drawId = this._availableInstanceIds.shift();
584
+ this._instanceInfo[ drawId ] = instanceInfo;
585
+
586
+ } else {
360
587
 
361
- } );
588
+ drawId = this._instanceInfo.length;
589
+ this._instanceInfo.push( instanceInfo );
590
+
591
+ }
362
592
 
363
- // initialize the matrix
364
- const drawId = this._drawInfo.length - 1;
365
593
  const matricesTexture = this._matricesTexture;
366
- const matricesArray = matricesTexture.image.data;
367
- _identityMatrix.toArray( matricesArray, drawId * 16 );
594
+ _matrix.identity().toArray( matricesTexture.image.data, drawId * 16 );
368
595
  matricesTexture.needsUpdate = true;
369
596
 
370
597
  const colorsTexture = this._colorsTexture;
@@ -375,127 +602,118 @@ class BatchedMesh extends Mesh {
375
602
 
376
603
  }
377
604
 
605
+ this._visibilityChanged = true;
378
606
  return drawId;
379
607
 
380
608
  }
381
609
 
382
- addGeometry( geometry, vertexCount = - 1, indexCount = - 1 ) {
610
+ /**
611
+ * Adds the given geometry to the batch and returns the associated
612
+ * geometry id referring to it to be used in other functions.
613
+ *
614
+ * @param {BufferGeometry} geometry - The geometry to add.
615
+ * @param {number} [reservedVertexCount=-1] - Optional parameter specifying the amount of
616
+ * vertex buffer space to reserve for the added geometry. This is necessary if it is planned
617
+ * to set a new geometry at this index at a later time that is larger than the original geometry.
618
+ * Defaults to the length of the given geometry vertex buffer.
619
+ * @param {number} [reservedIndexCount=-1] - Optional parameter specifying the amount of index
620
+ * buffer space to reserve for the added geometry. This is necessary if it is planned to set a
621
+ * new geometry at this index at a later time that is larger than the original geometry. Defaults to
622
+ * the length of the given geometry index buffer.
623
+ * @return {number} The geometry ID.
624
+ */
625
+ addGeometry( geometry, reservedVertexCount = - 1, reservedIndexCount = - 1 ) {
383
626
 
384
627
  this._initializeGeometry( geometry );
385
628
 
386
629
  this._validateGeometry( geometry );
387
630
 
388
- // ensure we're not over geometry
389
- if ( this._drawInfo.length >= this._maxInstanceCount ) {
390
-
391
- throw new Error( 'BatchedMesh: Maximum item count reached.' );
392
-
393
- }
394
-
395
- // get the necessary range fo the geometry
396
- const reservedRange = {
631
+ const geometryInfo = {
632
+ // geometry information
397
633
  vertexStart: - 1,
398
634
  vertexCount: - 1,
635
+ reservedVertexCount: - 1,
636
+
399
637
  indexStart: - 1,
400
638
  indexCount: - 1,
401
- };
402
-
403
- let lastRange = null;
404
- const reservedRanges = this._reservedRanges;
405
- const drawRanges = this._drawRanges;
406
- const bounds = this._bounds;
407
- if ( this._geometryCount !== 0 ) {
408
-
409
- lastRange = reservedRanges[ reservedRanges.length - 1 ];
410
-
411
- }
412
-
413
- if ( vertexCount === - 1 ) {
414
-
415
- reservedRange.vertexCount = geometry.getAttribute( 'position' ).count;
416
-
417
- } else {
639
+ reservedIndexCount: - 1,
418
640
 
419
- reservedRange.vertexCount = vertexCount;
641
+ // draw range information
642
+ start: - 1,
643
+ count: - 1,
420
644
 
421
- }
422
-
423
- if ( lastRange === null ) {
424
-
425
- reservedRange.vertexStart = 0;
426
-
427
- } else {
428
-
429
- reservedRange.vertexStart = lastRange.vertexStart + lastRange.vertexCount;
645
+ // state
646
+ boundingBox: null,
647
+ boundingSphere: null,
648
+ active: true,
649
+ };
430
650
 
431
- }
651
+ const geometryInfoList = this._geometryInfo;
652
+ geometryInfo.vertexStart = this._nextVertexStart;
653
+ geometryInfo.reservedVertexCount = reservedVertexCount === - 1 ? geometry.getAttribute( 'position' ).count : reservedVertexCount;
432
654
 
433
655
  const index = geometry.getIndex();
434
656
  const hasIndex = index !== null;
435
657
  if ( hasIndex ) {
436
658
 
437
- if ( indexCount === - 1 ) {
659
+ geometryInfo.indexStart = this._nextIndexStart;
660
+ geometryInfo.reservedIndexCount = reservedIndexCount === - 1 ? index.count : reservedIndexCount;
438
661
 
439
- reservedRange.indexCount = index.count;
440
-
441
- } else {
442
-
443
- reservedRange.indexCount = indexCount;
662
+ }
444
663
 
445
- }
664
+ if (
665
+ geometryInfo.indexStart !== - 1 &&
666
+ geometryInfo.indexStart + geometryInfo.reservedIndexCount > this._maxIndexCount ||
667
+ geometryInfo.vertexStart + geometryInfo.reservedVertexCount > this._maxVertexCount
668
+ ) {
446
669
 
447
- if ( lastRange === null ) {
670
+ throw new Error( 'THREE.BatchedMesh: Reserved space request exceeds the maximum buffer size.' );
448
671
 
449
- reservedRange.indexStart = 0;
672
+ }
450
673
 
451
- } else {
674
+ // update id
675
+ let geometryId;
676
+ if ( this._availableGeometryIds.length > 0 ) {
452
677
 
453
- reservedRange.indexStart = lastRange.indexStart + lastRange.indexCount;
678
+ this._availableGeometryIds.sort( ascIdSort );
454
679
 
455
- }
680
+ geometryId = this._availableGeometryIds.shift();
681
+ geometryInfoList[ geometryId ] = geometryInfo;
456
682
 
457
- }
458
683
 
459
- if (
460
- reservedRange.indexStart !== - 1 &&
461
- reservedRange.indexStart + reservedRange.indexCount > this._maxIndexCount ||
462
- reservedRange.vertexStart + reservedRange.vertexCount > this._maxVertexCount
463
- ) {
684
+ } else {
464
685
 
465
- throw new Error( 'BatchedMesh: Reserved space request exceeds the maximum buffer size.' );
686
+ geometryId = this._geometryCount;
687
+ this._geometryCount ++;
688
+ geometryInfoList.push( geometryInfo );
466
689
 
467
690
  }
468
691
 
469
- // update id
470
- const geometryId = this._geometryCount;
471
- this._geometryCount ++;
472
-
473
- // add the reserved range and draw range objects
474
- reservedRanges.push( reservedRange );
475
- drawRanges.push( {
476
- start: hasIndex ? reservedRange.indexStart : reservedRange.vertexStart,
477
- count: - 1
478
- } );
479
- bounds.push( {
480
- boxInitialized: false,
481
- box: new Box3(),
482
-
483
- sphereInitialized: false,
484
- sphere: new Sphere()
485
- } );
486
-
487
692
  // update the geometry
488
693
  this.setGeometryAt( geometryId, geometry );
489
694
 
695
+ // increment the next geometry position
696
+ this._nextIndexStart = geometryInfo.indexStart + geometryInfo.reservedIndexCount;
697
+ this._nextVertexStart = geometryInfo.vertexStart + geometryInfo.reservedVertexCount;
698
+
490
699
  return geometryId;
491
700
 
492
701
  }
493
702
 
703
+ /**
704
+ * Replaces the geometry at the given ID with the provided geometry. Throws an error if there
705
+ * is not enough space reserved for geometry. Calling this will change all instances that are
706
+ * rendering that geometry.
707
+ *
708
+ * @param {number} geometryId - The ID of the geomtry that should be replaced with the given geometry.
709
+ * @param {BufferGeometry} geometry - The new geometry.
710
+ * @return {number} The geometry ID.
711
+ */
494
712
  setGeometryAt( geometryId, geometry ) {
495
713
 
496
714
  if ( geometryId >= this._geometryCount ) {
497
715
 
498
- throw new Error( 'BatchedMesh: Maximum geometry count reached.' );
716
+ throw new Error( 'THREE.BatchedMesh: Maximum geometry count reached.' );
499
717
 
500
718
  }
501
719
 
@@ -505,20 +723,22 @@ class BatchedMesh extends Mesh {
505
723
  const hasIndex = batchGeometry.getIndex() !== null;
506
724
  const dstIndex = batchGeometry.getIndex();
507
725
  const srcIndex = geometry.getIndex();
508
- const reservedRange = this._reservedRanges[ geometryId ];
726
+ const geometryInfo = this._geometryInfo[ geometryId ];
509
727
  if (
510
728
  hasIndex &&
511
- srcIndex.count > reservedRange.indexCount ||
512
- geometry.attributes.position.count > reservedRange.vertexCount
729
+ srcIndex.count > geometryInfo.reservedIndexCount ||
730
+ geometry.attributes.position.count > geometryInfo.reservedVertexCount
513
731
  ) {
514
732
 
515
- throw new Error( 'BatchedMesh: Reserved space not large enough for provided geometry.' );
733
+ throw new Error( 'THREE.BatchedMesh: Reserved space not large enough for provided geometry.' );
516
734
 
517
735
  }
518
736
 
519
- // copy geometry over
520
- const vertexStart = reservedRange.vertexStart;
521
- const vertexCount = reservedRange.vertexCount;
737
+ // copy geometry buffer data over
738
+ const vertexStart = geometryInfo.vertexStart;
739
+ const reservedVertexCount = geometryInfo.reservedVertexCount;
740
+ geometryInfo.vertexCount = geometry.getAttribute( 'position' ).count;
741
+
522
742
  for ( const attributeName in batchGeometry.attributes ) {
523
743
 
524
744
  // copy attribute data
@@ -528,7 +748,7 @@ class BatchedMesh extends Mesh {
528
748
 
529
749
  // fill the rest in with zeroes
530
750
  const itemSize = srcAttribute.itemSize;
531
- for ( let i = srcAttribute.count, l = vertexCount; i < l; i ++ ) {
751
+ for ( let i = srcAttribute.count, l = reservedVertexCount; i < l; i ++ ) {
532
752
 
533
753
  const index = vertexStart + i;
534
754
  for ( let c = 0; c < itemSize; c ++ ) {
@@ -540,14 +760,16 @@ class BatchedMesh extends Mesh {
540
760
  }
541
761
 
542
762
  dstAttribute.needsUpdate = true;
543
- dstAttribute.addUpdateRange( vertexStart * itemSize, vertexCount * itemSize );
763
+ dstAttribute.addUpdateRange( vertexStart * itemSize, reservedVertexCount * itemSize );
544
764
 
545
765
  }
546
766
 
547
767
  // copy index
548
768
  if ( hasIndex ) {
549
769
 
550
- const indexStart = reservedRange.indexStart;
770
+ const indexStart = geometryInfo.indexStart;
771
+ const reservedIndexCount = geometryInfo.reservedIndexCount;
772
+ geometryInfo.indexCount = geometry.getIndex().count;
551
773
 
552
774
  // copy index data over
553
775
  for ( let i = 0; i < srcIndex.count; i ++ ) {
@@ -557,80 +779,198 @@ class BatchedMesh extends Mesh {
557
779
  }
558
780
 
559
781
  // fill the rest in with zeroes
560
- for ( let i = srcIndex.count, l = reservedRange.indexCount; i < l; i ++ ) {
782
+ for ( let i = srcIndex.count, l = reservedIndexCount; i < l; i ++ ) {
561
783
 
562
784
  dstIndex.setX( indexStart + i, vertexStart );
563
785
 
564
786
  }
565
787
 
566
788
  dstIndex.needsUpdate = true;
567
- dstIndex.addUpdateRange( indexStart, reservedRange.indexCount );
789
+ dstIndex.addUpdateRange( indexStart, geometryInfo.reservedIndexCount );
568
790
 
569
791
  }
570
792
 
793
+ // update the draw range
794
+ geometryInfo.start = hasIndex ? geometryInfo.indexStart : geometryInfo.vertexStart;
795
+ geometryInfo.count = hasIndex ? geometryInfo.indexCount : geometryInfo.vertexCount;
796
+
571
797
  // store the bounding boxes
572
- const bound = this._bounds[ geometryId ];
798
+ geometryInfo.boundingBox = null;
573
799
  if ( geometry.boundingBox !== null ) {
574
800
 
575
- bound.box.copy( geometry.boundingBox );
576
- bound.boxInitialized = true;
801
+ geometryInfo.boundingBox = geometry.boundingBox.clone();
577
802
 
578
- } else {
803
+ }
579
804
 
580
- bound.boxInitialized = false;
805
+ geometryInfo.boundingSphere = null;
806
+ if ( geometry.boundingSphere !== null ) {
807
+
808
+ geometryInfo.boundingSphere = geometry.boundingSphere.clone();
581
809
 
582
810
  }
583
811
 
584
- if ( geometry.boundingSphere !== null ) {
812
+ this._visibilityChanged = true;
813
+ return geometryId;
585
814
 
586
- bound.sphere.copy( geometry.boundingSphere );
587
- bound.sphereInitialized = true;
815
+ }
588
816
 
589
- } else {
817
+ /**
818
+ * Deletes the geometry defined by the given ID from this batch. Any instances referencing
819
+ * this geometry will also be removed as a side effect.
820
+ *
821
+ * @param {number} geometryId - The ID of the geomtry to remove from the batch.
822
+ * @return {BatchedMesh} A reference to this batched mesh.
823
+ */
824
+ deleteGeometry( geometryId ) {
590
825
 
591
- bound.sphereInitialized = false;
826
+ const geometryInfoList = this._geometryInfo;
827
+ if ( geometryId >= geometryInfoList.length || geometryInfoList[ geometryId ].active === false ) {
828
+
829
+ return this;
592
830
 
593
831
  }
594
832
 
595
- // set drawRange count
596
- const drawRange = this._drawRanges[ geometryId ];
597
- const posAttr = geometry.getAttribute( 'position' );
598
- drawRange.count = hasIndex ? srcIndex.count : posAttr.count;
833
+ // delete any instances associated with this geometry
834
+ const instanceInfo = this._instanceInfo;
835
+ for ( let i = 0, l = instanceInfo.length; i < l; i ++ ) {
836
+
837
+ if ( instanceInfo[ i ].active && instanceInfo[ i ].geometryIndex === geometryId ) {
838
+
839
+ this.deleteInstance( i );
840
+
841
+ }
842
+
843
+ }
844
+
845
+ geometryInfoList[ geometryId ].active = false;
846
+ this._availableGeometryIds.push( geometryId );
599
847
  this._visibilityChanged = true;
600
848
 
601
- return geometryId;
849
+ return this;
602
850
 
603
851
  }
604
852
 
605
- /*
606
- deleteGeometry( geometryId ) {
853
+ /**
854
+ * Deletes an existing instance from the batch using the given ID.
855
+ *
856
+ * @param {number} instanceId - The ID of the instance to remove from the batch.
857
+ * @return {BatchedMesh} A reference to this batched mesh.
858
+ */
859
+ deleteInstance( instanceId ) {
607
860
 
608
- // TODO: delete geometry and associated instances
861
+ this.validateInstanceId( instanceId );
862
+
863
+ this._instanceInfo[ instanceId ].active = false;
864
+ this._availableInstanceIds.push( instanceId );
865
+ this._visibilityChanged = true;
866
+
867
+ return this;
609
868
 
610
869
  }
611
- */
612
870
 
613
- /*
614
- deleteInstance( instanceId ) {
871
+ /**
872
+ * Repacks the sub geometries in [name] to remove any unused space remaining from
873
+ * previously deleted geometry, freeing up space to add new geometry.
874
+ *
875
+ * @param {number} instanceId - The ID of the instance to remove from the batch.
876
+ * @return {BatchedMesh} A reference to this batched mesh.
877
+ */
878
+ optimize() {
615
879
 
616
- // Note: User needs to call optimize() afterward to pack the data.
880
+ // track the next indices to copy data to
881
+ let nextVertexStart = 0;
882
+ let nextIndexStart = 0;
617
883
 
618
- const drawInfo = this._drawInfo;
619
- if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
884
+ // Iterate over all geometry ranges in order sorted from earliest in the geometry buffer to latest
885
+ // in the geometry buffer. Because draw range objects can be reused there is no guarantee of their order.
886
+ const geometryInfoList = this._geometryInfo;
887
+ const indices = geometryInfoList
888
+ .map( ( e, i ) => i )
889
+ .sort( ( a, b ) => {
620
890
 
621
- return this;
891
+ return geometryInfoList[ a ].vertexStart - geometryInfoList[ b ].vertexStart;
622
892
 
623
- }
893
+ } );
624
894
 
625
- drawInfo[ instanceId ].active = false;
626
- this._visibilityChanged = true;
895
+ const geometry = this.geometry;
896
+ for ( let i = 0, l = geometryInfoList.length; i < l; i ++ ) {
897
+
898
+ // if a geometry range is inactive then don't copy anything
899
+ const index = indices[ i ];
900
+ const geometryInfo = geometryInfoList[ index ];
901
+ if ( geometryInfo.active === false ) {
902
+
903
+ continue;
904
+
905
+ }
906
+
907
+ // if a geometry contains an index buffer then shift it, as well
908
+ if ( geometry.index !== null ) {
909
+
910
+ if ( geometryInfo.indexStart !== nextIndexStart ) {
911
+
912
+ const { indexStart, vertexStart, reservedIndexCount } = geometryInfo;
913
+ const index = geometry.index;
914
+ const array = index.array;
915
+
916
+ // shift the index pointers based on how the vertex data will shift
917
+ // adjusting the index must happen first so the original vertex start value is available
918
+ const elementDelta = nextVertexStart - vertexStart;
919
+ for ( let j = indexStart; j < indexStart + reservedIndexCount; j ++ ) {
920
+
921
+ array[ j ] = array[ j ] + elementDelta;
922
+
923
+ }
924
+
925
+ index.array.copyWithin( nextIndexStart, indexStart, indexStart + reservedIndexCount );
926
+ index.addUpdateRange( nextIndexStart, reservedIndexCount );
927
+
928
+ geometryInfo.indexStart = nextIndexStart;
929
+
930
+ }
931
+
932
+ nextIndexStart += geometryInfo.reservedIndexCount;
933
+
934
+ }
935
+
936
+ // if a geometry needs to be moved then copy attribute data to overwrite unused space
937
+ if ( geometryInfo.vertexStart !== nextVertexStart ) {
938
+
939
+ const { vertexStart, reservedVertexCount } = geometryInfo;
940
+ const attributes = geometry.attributes;
941
+ for ( const key in attributes ) {
942
+
943
+ const attribute = attributes[ key ];
944
+ const { array, itemSize } = attribute;
945
+ array.copyWithin( nextVertexStart * itemSize, vertexStart * itemSize, ( vertexStart + reservedVertexCount ) * itemSize );
946
+ attribute.addUpdateRange( nextVertexStart * itemSize, reservedVertexCount * itemSize );
947
+
948
+ }
949
+
950
+ geometryInfo.vertexStart = nextVertexStart;
951
+
952
+ }
953
+
954
+ nextVertexStart += geometryInfo.reservedVertexCount;
955
+ geometryInfo.start = geometry.index ? geometryInfo.indexStart : geometryInfo.vertexStart;
956
+
957
+ // step the next geometry points to the shifted position
958
+ this._nextIndexStart = geometry.index ? geometryInfo.indexStart + geometryInfo.reservedIndexCount : 0;
959
+ this._nextVertexStart = geometryInfo.vertexStart + geometryInfo.reservedVertexCount;
960
+
961
+ }
627
962
 
628
963
  return this;
629
964
 
630
965
  }
631
- */
632
966
 
633
- // get bounding box and compute it if it doesn't exist
967
+ /**
968
+ * Returns the bounding box for the given geometry.
969
+ *
970
+ * @param {number} geometryId - The ID of the geometry to return the bounding box for.
971
+ * @param {Box3} target - The target object that is used to store the method's result.
972
+ * @return {Box3|null} The geometry's bounding box. Returns `null` if no geometry has been found for the given ID.
973
+ */
634
974
  getBoundingBoxAt( geometryId, target ) {
635
975
 
636
976
  if ( geometryId >= this._geometryCount ) {
@@ -640,17 +980,14 @@ class BatchedMesh extends Mesh {
640
980
  }
641
981
 
642
982
  // compute bounding box
643
- const bound = this._bounds[ geometryId ];
644
- const box = bound.box;
645
983
  const geometry = this.geometry;
646
- if ( bound.boxInitialized === false ) {
647
-
648
- box.makeEmpty();
984
+ const geometryInfo = this._geometryInfo[ geometryId ];
985
+ if ( geometryInfo.boundingBox === null ) {
649
986
 
987
+ const box = new Box3();
650
988
  const index = geometry.index;
651
989
  const position = geometry.attributes.position;
652
- const drawRange = this._drawRanges[ geometryId ];
653
- for ( let i = drawRange.start, l = drawRange.start + drawRange.count; i < l; i ++ ) {
990
+ for ( let i = geometryInfo.start, l = geometryInfo.start + geometryInfo.count; i < l; i ++ ) {
654
991
 
655
992
  let iv = i;
656
993
  if ( index ) {
@@ -663,16 +1000,22 @@ class BatchedMesh extends Mesh {
663
1000
 
664
1001
  }
665
1002
 
666
- bound.boxInitialized = true;
1003
+ geometryInfo.boundingBox = box;
667
1004
 
668
1005
  }
669
1006
 
670
- target.copy( box );
1007
+ target.copy( geometryInfo.boundingBox );
671
1008
  return target;
672
1009
 
673
1010
  }
674
1011
 
675
- // get bounding sphere and compute it if it doesn't exist
1012
+ /**
1013
+ * Returns the bounding sphere for the given geometry.
1014
+ *
1015
+ * @param {number} geometryId - The ID of the geometry to return the bounding sphere for.
1016
+ * @param {Sphere} target - The target object that is used to store the method's result.
1017
+ * @return {Sphere|null} The geometry's bounding sphere. Returns `null` if no geometry has been found for the given ID.
1018
+ */
676
1019
  getBoundingSphereAt( geometryId, target ) {
677
1020
 
678
1021
  if ( geometryId >= this._geometryCount ) {
@@ -682,22 +1025,19 @@ class BatchedMesh extends Mesh {
682
1025
  }
683
1026
 
684
1027
  // compute bounding sphere
685
- const bound = this._bounds[ geometryId ];
686
- const sphere = bound.sphere;
687
1028
  const geometry = this.geometry;
688
- if ( bound.sphereInitialized === false ) {
689
-
690
- sphere.makeEmpty();
1029
+ const geometryInfo = this._geometryInfo[ geometryId ];
1030
+ if ( geometryInfo.boundingSphere === null ) {
691
1031
 
1032
+ const sphere = new Sphere();
692
1033
  this.getBoundingBoxAt( geometryId, _box );
693
1034
  _box.getCenter( sphere.center );
694
1035
 
695
1036
  const index = geometry.index;
696
1037
  const position = geometry.attributes.position;
697
- const drawRange = this._drawRanges[ geometryId ];
698
1038
 
699
1039
  let maxRadiusSq = 0;
700
- for ( let i = drawRange.start, l = drawRange.start + drawRange.count; i < l; i ++ ) {
1040
+ for ( let i = geometryInfo.start, l = geometryInfo.start + geometryInfo.count; i < l; i ++ ) {
701
1041
 
702
1042
  let iv = i;
703
1043
  if ( index ) {
@@ -712,29 +1052,29 @@ class BatchedMesh extends Mesh {
712
1052
  }
713
1053
 
714
1054
  sphere.radius = Math.sqrt( maxRadiusSq );
715
- bound.sphereInitialized = true;
1055
+ geometryInfo.boundingSphere = sphere;
716
1056
 
717
1057
  }
718
1058
 
719
- target.copy( sphere );
1059
+ target.copy( geometryInfo.boundingSphere );
720
1060
  return target;
721
1061
 
722
1062
  }
723
1063
 
1064
+ /**
1065
+ * Sets the given local transformation matrix to the defined instance.
1066
+ * Negatively scaled matrices are not supported.
1067
+ *
1068
+ * @param {number} instanceId - The ID of an instance to set the matrix of.
1069
+ * @param {Matrix4} matrix - A 4x4 matrix representing the local transformation of a single instance.
1070
+ * @return {BatchedMesh} A reference to this batched mesh.
1071
+ */
724
1072
  setMatrixAt( instanceId, matrix ) {
725
1073
 
726
- // @TODO: Map geometryId to index of the arrays because
727
- // optimize() can make geometryId mismatch the index
1074
+ this.validateInstanceId( instanceId );
728
1075
 
729
- const drawInfo = this._drawInfo;
730
1076
  const matricesTexture = this._matricesTexture;
731
1077
  const matricesArray = this._matricesTexture.image.data;
732
- if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
733
-
734
- return this;
735
-
736
- }
737
-
738
1078
  matrix.toArray( matricesArray, instanceId * 16 );
739
1079
  matricesTexture.needsUpdate = true;
740
1080
 
@@ -742,101 +1082,289 @@ class BatchedMesh extends Mesh {
742
1082
 
743
1083
  }
744
1084
 
1085
+ /**
1086
+ * Returns the local transformation matrix of the defined instance.
1087
+ *
1088
+ * @param {number} instanceId - The ID of an instance to get the matrix of.
1089
+ * @param {Matrix4} matrix - The target object that is used to store the method's result.
1090
+ * @return {Matrix4} The instance's local transformation matrix.
1091
+ */
745
1092
  getMatrixAt( instanceId, matrix ) {
746
1093
 
747
- const drawInfo = this._drawInfo;
748
- const matricesArray = this._matricesTexture.image.data;
749
- if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
750
-
751
- return null;
752
-
753
- }
754
-
755
- return matrix.fromArray( matricesArray, instanceId * 16 );
1094
+ this.validateInstanceId( instanceId );
1095
+ return matrix.fromArray( this._matricesTexture.image.data, instanceId * 16 );
756
1096
 
757
1097
  }
758
1098
 
1099
+ /**
1100
+ * Sets the given color to the defined instance.
1101
+ *
1102
+ * @param {number} instanceId - The ID of an instance to set the color of.
1103
+ * @param {Color} color - The color to set the instance to.
1104
+ * @return {BatchedMesh} A reference to this batched mesh.
1105
+ */
759
1106
  setColorAt( instanceId, color ) {
760
1107
 
1108
+ this.validateInstanceId( instanceId );
1109
+
761
1110
  if ( this._colorsTexture === null ) {
762
1111
 
763
1112
  this._initColorsTexture();
764
1113
 
765
1114
  }
766
1115
 
767
- // @TODO: Map id to index of the arrays because
768
- // optimize() can make id mismatch the index
1116
+ color.toArray( this._colorsTexture.image.data, instanceId * 4 );
1117
+ this._colorsTexture.needsUpdate = true;
769
1118
 
770
- const colorsTexture = this._colorsTexture;
771
- const colorsArray = this._colorsTexture.image.data;
772
- const drawInfo = this._drawInfo;
773
- if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
1119
+ return this;
1120
+
1121
+ }
1122
+
1123
+ /**
1124
+ * Returns the color of the defined instance.
1125
+ *
1126
+ * @param {number} instanceId - The ID of an instance to get the color of.
1127
+ * @param {Color} color - The target object that is used to store the method's result.
1128
+ * @return {Color} The instance's color.
1129
+ */
1130
+ getColorAt( instanceId, color ) {
1131
+
1132
+ this.validateInstanceId( instanceId );
1133
+ return color.fromArray( this._colorsTexture.image.data, instanceId * 4 );
1134
+
1135
+ }
1136
+
1137
+ /**
1138
+ * Sets the visibility of the instance.
1139
+ *
1140
+ * @param {number} instanceId - The id of the instance to set the visibility of.
1141
+ * @param {boolean} visible - Whether the instance is visible or not.
1142
+ * @return {BatchedMesh} A reference to this batched mesh.
1143
+ */
1144
+ setVisibleAt( instanceId, visible ) {
1145
+
1146
+ this.validateInstanceId( instanceId );
1147
+
1148
+ if ( this._instanceInfo[ instanceId ].visible === visible ) {
774
1149
 
775
1150
  return this;
776
1151
 
777
1152
  }
778
1153
 
779
- color.toArray( colorsArray, instanceId * 4 );
780
- colorsTexture.needsUpdate = true;
1154
+ this._instanceInfo[ instanceId ].visible = visible;
1155
+ this._visibilityChanged = true;
781
1156
 
782
1157
  return this;
783
1158
 
784
1159
  }
785
1160
 
786
- getColorAt( instanceId, color ) {
1161
+ /**
1162
+ * Returns the visibility state of the defined instance.
1163
+ *
1164
+ * @param {number} instanceId - The ID of an instance to get the visibility state of.
1165
+ * @return {boolean} Whether the instance is visible or not.
1166
+ */
1167
+ getVisibleAt( instanceId ) {
787
1168
 
788
- const colorsArray = this._colorsTexture.image.data;
789
- const drawInfo = this._drawInfo;
790
- if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
1169
+ this.validateInstanceId( instanceId );
791
1170
 
792
- return null;
1171
+ return this._instanceInfo[ instanceId ].visible;
793
1172
 
794
- }
1173
+ }
1174
+
1175
+ /**
1176
+ * Sets the geometry ID of the instance at the given index.
1177
+ *
1178
+ * @param {number} instanceId - The ID of the instance to set the geometry ID of.
1179
+ * @param {number} geometryId - The geometry ID to be use by the instance.
1180
+ * @return {BatchedMesh} A reference to this batched mesh.
1181
+ */
1182
+ setGeometryIdAt( instanceId, geometryId ) {
1183
+
1184
+ this.validateInstanceId( instanceId );
1185
+ this.validateGeometryId( geometryId );
795
1186
 
796
- return color.fromArray( colorsArray, instanceId * 4 );
1187
+ this._instanceInfo[ instanceId ].geometryIndex = geometryId;
1188
+
1189
+ return this;
797
1190
 
798
1191
  }
799
1192
 
800
- setVisibleAt( instanceId, value ) {
1193
+ /**
1194
+ * Returns the geometry ID of the defined instance.
1195
+ *
1196
+ * @param {number} instanceId - The ID of an instance to get the geometry ID of.
1197
+ * @return {number} The instance's geometry ID.
1198
+ */
1199
+ getGeometryIdAt( instanceId ) {
801
1200
 
802
- // if the geometry is out of range, not active, or visibility state
803
- // does not change then return early
804
- const drawInfo = this._drawInfo;
805
- if (
806
- instanceId >= drawInfo.length ||
807
- drawInfo[ instanceId ].active === false ||
808
- drawInfo[ instanceId ].visible === value
809
- ) {
1201
+ this.validateInstanceId( instanceId );
810
1202
 
811
- return this;
1203
+ return this._instanceInfo[ instanceId ].geometryIndex;
1204
+
1205
+ }
1206
+
1207
+ /**
1208
+ * Get the range representing the subset of triangles related to the attached geometry,
1209
+ * indicating the starting offset and count, or `null` if invalid.
1210
+ *
1211
+ * @param {number} geometryId - The id of the geometry to get the range of.
1212
+ * @param {Object} [target] - The target object that is used to store the method's result.
1213
+ * @return {{
1214
+ * vertexStart:number,vertexCount:number,reservedVertexCount:number,
1215
+ * indexStart:number,indexCount:number,reservedIndexCount:number,
1216
+ * start:number,count:number
1217
+ * }} The result object with range data.
1218
+ */
1219
+ getGeometryRangeAt( geometryId, target = {} ) {
1220
+
1221
+ this.validateGeometryId( geometryId );
1222
+
1223
+ const geometryInfo = this._geometryInfo[ geometryId ];
1224
+ target.vertexStart = geometryInfo.vertexStart;
1225
+ target.vertexCount = geometryInfo.vertexCount;
1226
+ target.reservedVertexCount = geometryInfo.reservedVertexCount;
1227
+
1228
+ target.indexStart = geometryInfo.indexStart;
1229
+ target.indexCount = geometryInfo.indexCount;
1230
+ target.reservedIndexCount = geometryInfo.reservedIndexCount;
1231
+
1232
+ target.start = geometryInfo.start;
1233
+ target.count = geometryInfo.count;
1234
+
1235
+ return target;
1236
+
1237
+ }
1238
+
1239
+ /**
1240
+ * Resizes the necessary buffers to support the provided number of instances.
1241
+ * If the provided arguments shrink the number of instances but there are not enough
1242
+ * unused Ids at the end of the list then an error is thrown.
1243
+ *
1244
+ * @param {number} maxInstanceCount - The max number of individual instances that can be added and rendered by the batch.
1245
+ */
1246
+ setInstanceCount( maxInstanceCount ) {
1247
+
1248
+ // shrink the available instances as much as possible
1249
+ const availableInstanceIds = this._availableInstanceIds;
1250
+ const instanceInfo = this._instanceInfo;
1251
+ availableInstanceIds.sort( ascIdSort );
1252
+ while ( availableInstanceIds[ availableInstanceIds.length - 1 ] === instanceInfo.length ) {
1253
+
1254
+ instanceInfo.pop();
1255
+ availableInstanceIds.pop();
812
1256
 
813
1257
  }
814
1258
 
815
- drawInfo[ instanceId ].visible = value;
816
- this._visibilityChanged = true;
1259
+ // throw an error if it can't be shrunk to the desired size
1260
+ if ( maxInstanceCount < instanceInfo.length ) {
817
1261
 
818
- return this;
1262
+ throw new Error( `BatchedMesh: Instance ids outside the range ${ maxInstanceCount } are being used. Cannot shrink instance count.` );
1263
+
1264
+ }
1265
+
1266
+ // copy the multi draw counts
1267
+ const multiDrawCounts = new Int32Array( maxInstanceCount );
1268
+ const multiDrawStarts = new Int32Array( maxInstanceCount );
1269
+ copyArrayContents( this._multiDrawCounts, multiDrawCounts );
1270
+ copyArrayContents( this._multiDrawStarts, multiDrawStarts );
1271
+
1272
+ this._multiDrawCounts = multiDrawCounts;
1273
+ this._multiDrawStarts = multiDrawStarts;
1274
+ this._maxInstanceCount = maxInstanceCount;
1275
+
1276
+ // update texture data for instance sampling
1277
+ const indirectTexture = this._indirectTexture;
1278
+ const matricesTexture = this._matricesTexture;
1279
+ const colorsTexture = this._colorsTexture;
1280
+
1281
+ indirectTexture.dispose();
1282
+ this._initIndirectTexture();
1283
+ copyArrayContents( indirectTexture.image.data, this._indirectTexture.image.data );
1284
+
1285
+ matricesTexture.dispose();
1286
+ this._initMatricesTexture();
1287
+ copyArrayContents( matricesTexture.image.data, this._matricesTexture.image.data );
1288
+
1289
+ if ( colorsTexture ) {
1290
+
1291
+ colorsTexture.dispose();
1292
+ this._initColorsTexture();
1293
+ copyArrayContents( colorsTexture.image.data, this._colorsTexture.image.data );
1294
+
1295
+ }
819
1296
 
820
1297
  }
821
1298
 
822
- getVisibleAt( instanceId ) {
1299
+ /**
1300
+ * Resizes the available space in the batch's vertex and index buffer attributes to the provided sizes.
1301
+ * If the provided arguments shrink the geometry buffers but there is not enough unused space at the
1302
+ * end of the geometry attributes then an error is thrown.
1303
+ *
1304
+ * @param {number} maxVertexCount - The maximum number of vertices to be used by all unique geometries to resize to.
1305
+ * @param {number} maxIndexCount - The maximum number of indices to be used by all unique geometries to resize to.
1306
+ */
1307
+ setGeometrySize( maxVertexCount, maxIndexCount ) {
1308
+
1309
+ // Check if we can shrink to the requested vertex attribute size
1310
+ const validRanges = [ ...this._geometryInfo ].filter( info => info.active );
1311
+ const requiredVertexLength = Math.max( ...validRanges.map( range => range.vertexStart + range.reservedVertexCount ) );
1312
+ if ( requiredVertexLength > maxVertexCount ) {
823
1313
 
824
- // return early if the geometry is out of range or not active
825
- const drawInfo = this._drawInfo;
826
- if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
1314
+ throw new Error( `BatchedMesh: Geometry vertex values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
827
1315
 
828
- return false;
1316
+ }
1317
+
1318
+ // Check if we can shrink to the requested index attribute size
1319
+ if ( this.geometry.index ) {
1320
+
1321
+ const requiredIndexLength = Math.max( ...validRanges.map( range => range.indexStart + range.reservedIndexCount ) );
1322
+ if ( requiredIndexLength > maxIndexCount ) {
1323
+
1324
+ throw new Error( `BatchedMesh: Geometry index values are being used outside the range ${ maxIndexCount }. Cannot shrink further.` );
1325
+
1326
+ }
829
1327
 
830
1328
  }
831
1329
 
832
- return drawInfo[ instanceId ].visible;
1330
+ //
1331
+
1332
+ // dispose of the previous geometry
1333
+ const oldGeometry = this.geometry;
1334
+ oldGeometry.dispose();
1335
+
1336
+ // recreate the geometry needed based on the previous variant
1337
+ this._maxVertexCount = maxVertexCount;
1338
+ this._maxIndexCount = maxIndexCount;
1339
+
1340
+ if ( this._geometryInitialized ) {
1341
+
1342
+ this._geometryInitialized = false;
1343
+ this.geometry = new BufferGeometry();
1344
+ this._initializeGeometry( oldGeometry );
1345
+
1346
+ }
1347
+
1348
+ // copy data from the previous geometry
1349
+ const geometry = this.geometry;
1350
+ if ( oldGeometry.index ) {
1351
+
1352
+ copyArrayContents( oldGeometry.index.array, geometry.index.array );
1353
+
1354
+ }
1355
+
1356
+ for ( const key in oldGeometry.attributes ) {
1357
+
1358
+ copyArrayContents( oldGeometry.attributes[ key ].array, geometry.attributes[ key ].array );
1359
+
1360
+ }
833
1361
 
834
1362
  }
835
1363
 
836
1364
  raycast( raycaster, intersects ) {
837
1365
 
838
- const drawInfo = this._drawInfo;
839
- const drawRanges = this._drawRanges;
1366
+ const instanceInfo = this._instanceInfo;
1367
+ const geometryInfoList = this._geometryInfo;
840
1368
  const matrixWorld = this.matrixWorld;
841
1369
  const batchGeometry = this.geometry;
842
1370
 
@@ -856,19 +1384,19 @@ class BatchedMesh extends Mesh {
856
1384
 
857
1385
  }
858
1386
 
859
- for ( let i = 0, l = drawInfo.length; i < l; i ++ ) {
1387
+ for ( let i = 0, l = instanceInfo.length; i < l; i ++ ) {
860
1388
 
861
- if ( ! drawInfo[ i ].visible || ! drawInfo[ i ].active ) {
1389
+ if ( ! instanceInfo[ i ].visible || ! instanceInfo[ i ].active ) {
862
1390
 
863
1391
  continue;
864
1392
 
865
1393
  }
866
1394
 
867
- const geometryId = drawInfo[ i ].geometryIndex;
868
- const drawRange = drawRanges[ geometryId ];
869
- _mesh.geometry.setDrawRange( drawRange.start, drawRange.count );
1395
+ const geometryId = instanceInfo[ i ].geometryIndex;
1396
+ const geometryInfo = geometryInfoList[ geometryId ];
1397
+ _mesh.geometry.setDrawRange( geometryInfo.start, geometryInfo.count );
870
1398
 
871
- // ge the intersects
1399
+ // get the intersects
872
1400
  this.getMatrixAt( i, _mesh.matrixWorld ).premultiply( matrixWorld );
873
1401
  this.getBoundingBoxAt( geometryId, _mesh.geometry.boundingBox );
874
1402
  this.getBoundingSphereAt( geometryId, _mesh.geometry.boundingSphere );
@@ -905,17 +1433,13 @@ class BatchedMesh extends Mesh {
905
1433
  this.boundingBox = source.boundingBox !== null ? source.boundingBox.clone() : null;
906
1434
  this.boundingSphere = source.boundingSphere !== null ? source.boundingSphere.clone() : null;
907
1435
 
908
- this._drawRanges = source._drawRanges.map( range => ( { ...range } ) );
909
- this._reservedRanges = source._reservedRanges.map( range => ( { ...range } ) );
910
-
911
- this._drawInfo = source._drawInfo.map( inf => ( { ...inf } ) );
912
- this._bounds = source._bounds.map( bound => ( {
913
- boxInitialized: bound.boxInitialized,
914
- box: bound.box.clone(),
1436
+ this._geometryInfo = source._geometryInfo.map( info => ( {
1437
+ ...info,
915
1438
 
916
- sphereInitialized: bound.sphereInitialized,
917
- sphere: bound.sphere.clone()
1439
+ boundingBox: info.boundingBox !== null ? info.boundingBox.clone() : null,
1440
+ boundingSphere: info.boundingSphere !== null ? info.boundingSphere.clone() : null,
918
1441
  } ) );
1442
+ this._instanceInfo = source._instanceInfo.map( info => ( { ...info } ) );
919
1443
 
920
1444
  this._maxInstanceCount = source._maxInstanceCount;
921
1445
  this._maxVertexCount = source._maxVertexCount;
@@ -940,6 +1464,10 @@ class BatchedMesh extends Mesh {
940
1464
 
941
1465
  }
942
1466
 
1467
+ /**
1468
+ * Frees the GPU-related resources allocated by this instance. Call this
1469
+ * method whenever this instance is no longer used in your app.
1470
+ */
943
1471
  dispose() {
944
1472
 
945
1473
  // Assuming the geometry is not shared with other meshes
@@ -958,8 +1486,6 @@ class BatchedMesh extends Mesh {
958
1486
 
959
1487
  }
960
1488
 
961
- return this;
962
-
963
1489
  }
964
1490
 
965
1491
  onBeforeRender( renderer, scene, camera, geometry, material/*, _group*/ ) {
@@ -977,10 +1503,10 @@ class BatchedMesh extends Mesh {
977
1503
  const index = geometry.getIndex();
978
1504
  const bytesPerElement = index === null ? 1 : index.array.BYTES_PER_ELEMENT;
979
1505
 
980
- const drawInfo = this._drawInfo;
1506
+ const instanceInfo = this._instanceInfo;
981
1507
  const multiDrawStarts = this._multiDrawStarts;
982
1508
  const multiDrawCounts = this._multiDrawCounts;
983
- const drawRanges = this._drawRanges;
1509
+ const geometryInfoList = this._geometryInfo;
984
1510
  const perObjectFrustumCulled = this.perObjectFrustumCulled;
985
1511
  const indirectTexture = this._indirectTexture;
986
1512
  const indirectArray = indirectTexture.image.data;
@@ -988,29 +1514,29 @@ class BatchedMesh extends Mesh {
988
1514
  // prepare the frustum in the local frame
989
1515
  if ( perObjectFrustumCulled ) {
990
1516
 
991
- _projScreenMatrix
1517
+ _matrix
992
1518
  .multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse )
993
1519
  .multiply( this.matrixWorld );
994
1520
  _frustum.setFromProjectionMatrix(
995
- _projScreenMatrix,
1521
+ _matrix,
996
1522
  renderer.coordinateSystem
997
1523
  );
998
1524
 
999
1525
  }
1000
1526
 
1001
- let count = 0;
1527
+ let multiDrawCount = 0;
1002
1528
  if ( this.sortObjects ) {
1003
1529
 
1004
1530
  // get the camera position in the local frame
1005
- _invMatrixWorld.copy( this.matrixWorld ).invert();
1006
- _vector.setFromMatrixPosition( camera.matrixWorld ).applyMatrix4( _invMatrixWorld );
1007
- _forward.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ).transformDirection( _invMatrixWorld );
1531
+ _matrix.copy( this.matrixWorld ).invert();
1532
+ _vector.setFromMatrixPosition( camera.matrixWorld ).applyMatrix4( _matrix );
1533
+ _forward.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ).transformDirection( _matrix );
1008
1534
 
1009
- for ( let i = 0, l = drawInfo.length; i < l; i ++ ) {
1535
+ for ( let i = 0, l = instanceInfo.length; i < l; i ++ ) {
1010
1536
 
1011
- if ( drawInfo[ i ].visible && drawInfo[ i ].active ) {
1537
+ if ( instanceInfo[ i ].visible && instanceInfo[ i ].active ) {
1012
1538
 
1013
- const geometryId = drawInfo[ i ].geometryIndex;
1539
+ const geometryId = instanceInfo[ i ].geometryIndex;
1014
1540
 
1015
1541
  // get the bounds in world space
1016
1542
  this.getMatrixAt( i, _matrix );
@@ -1027,8 +1553,9 @@ class BatchedMesh extends Mesh {
1027
1553
  if ( ! culled ) {
1028
1554
 
1029
1555
  // get the distance from camera used for sorting
1556
+ const geometryInfo = geometryInfoList[ geometryId ];
1030
1557
  const z = _temp.subVectors( _sphere.center, _vector ).dot( _forward );
1031
- _renderList.push( drawRanges[ geometryId ], z, i );
1558
+ _renderList.push( geometryInfo.start, geometryInfo.count, z, i );
1032
1559
 
1033
1560
  }
1034
1561
 
@@ -1052,10 +1579,10 @@ class BatchedMesh extends Mesh {
1052
1579
  for ( let i = 0, l = list.length; i < l; i ++ ) {
1053
1580
 
1054
1581
  const item = list[ i ];
1055
- multiDrawStarts[ count ] = item.start * bytesPerElement;
1056
- multiDrawCounts[ count ] = item.count;
1057
- indirectArray[ count ] = item.index;
1058
- count ++;
1582
+ multiDrawStarts[ multiDrawCount ] = item.start * bytesPerElement;
1583
+ multiDrawCounts[ multiDrawCount ] = item.count;
1584
+ indirectArray[ multiDrawCount ] = item.index;
1585
+ multiDrawCount ++;
1059
1586
 
1060
1587
  }
1061
1588
 
@@ -1063,11 +1590,11 @@ class BatchedMesh extends Mesh {
1063
1590
 
1064
1591
  } else {
1065
1592
 
1066
- for ( let i = 0, l = drawInfo.length; i < l; i ++ ) {
1593
+ for ( let i = 0, l = instanceInfo.length; i < l; i ++ ) {
1067
1594
 
1068
- if ( drawInfo[ i ].visible && drawInfo[ i ].active ) {
1595
+ if ( instanceInfo[ i ].visible && instanceInfo[ i ].active ) {
1069
1596
 
1070
- const geometryId = drawInfo[ i ].geometryIndex;
1597
+ const geometryId = instanceInfo[ i ].geometryIndex;
1071
1598
 
1072
1599
  // determine whether the batched geometry is within the frustum
1073
1600
  let culled = false;
@@ -1082,11 +1609,11 @@ class BatchedMesh extends Mesh {
1082
1609
 
1083
1610
  if ( ! culled ) {
1084
1611
 
1085
- const range = drawRanges[ geometryId ];
1086
- multiDrawStarts[ count ] = range.start * bytesPerElement;
1087
- multiDrawCounts[ count ] = range.count;
1088
- indirectArray[ count ] = i;
1089
- count ++;
1612
+ const geometryInfo = geometryInfoList[ geometryId ];
1613
+ multiDrawStarts[ multiDrawCount ] = geometryInfo.start * bytesPerElement;
1614
+ multiDrawCounts[ multiDrawCount ] = geometryInfo.count;
1615
+ indirectArray[ multiDrawCount ] = i;
1616
+ multiDrawCount ++;
1090
1617
 
1091
1618
  }
1092
1619
 
@@ -1097,7 +1624,7 @@ class BatchedMesh extends Mesh {
1097
1624
  }
1098
1625
 
1099
1626
  indirectTexture.needsUpdate = true;
1100
- this._multiDrawCount = count;
1627
+ this._multiDrawCount = multiDrawCount;
1101
1628
  this._visibilityChanged = false;
1102
1629
 
1103
1630
  }