@woosh/meep-engine 3.16.0 → 3.17.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 (410) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  4. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  7. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  10. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  11. package/editor/view/node-graph/NodeGraphView.js +84 -8
  12. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  15. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  16. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  17. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  20. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  22. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  25. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  27. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  28. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  29. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  30. package/editor/view/particles/effect/particle-editor.css +123 -35
  31. package/package.json +1 -1
  32. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  34. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  35. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  37. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  38. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  39. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  40. package/src/core/graph/csr/CSRGraph.js +14 -6
  41. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  44. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  47. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  50. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  53. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  55. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  56. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  57. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  59. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  62. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  65. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  68. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  71. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  74. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  77. package/src/engine/animation/AnimationUtils.js +246 -246
  78. package/src/engine/animation/Animations.js +74 -74
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  80. package/src/engine/ecs/EventType.d.ts +0 -1
  81. package/src/engine/ecs/EventType.js +1 -26
  82. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  85. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  86. package/src/engine/ecs/parent/EntityNode.js +4 -9
  87. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  89. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  93. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  95. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  96. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  97. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  98. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  99. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  100. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  101. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  102. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  103. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  104. package/src/engine/graphics3/LightSystem.js +4 -8
  105. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/MeshSystem.js +9 -19
  107. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  109. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  111. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  112. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  113. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  114. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  115. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  116. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  117. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  118. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  119. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  120. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  121. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  122. package/src/shade/playground/particle_editor/README.md +43 -2
  123. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  124. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  125. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  126. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  127. package/src/shade/renderer/Renderer.js +13 -1
  128. package/src/shade/renderer/particles/DESIGN.md +104 -19
  129. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  130. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  132. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  133. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  134. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  135. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  136. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  137. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  138. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  139. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  140. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  141. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  142. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  143. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  144. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  145. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  146. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  148. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  149. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  151. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  153. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  155. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  157. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  159. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  161. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  162. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  163. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  164. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  165. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  166. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  168. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  169. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  170. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  171. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  172. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  174. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  175. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  177. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  178. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  179. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  180. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  181. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  182. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  183. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  185. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  186. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/graph_particles.js +105 -262
  188. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  189. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  190. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  191. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  192. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  193. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  194. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  196. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  197. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  198. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  199. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  200. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  202. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  203. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  205. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  206. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  207. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  208. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  209. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  210. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  211. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  212. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  213. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  214. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  215. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  216. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  217. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  218. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  219. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  220. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  221. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  222. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  223. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  224. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  225. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  226. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  227. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  228. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  229. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  230. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  235. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  236. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  237. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  238. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  239. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  240. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  241. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  242. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  244. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  245. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  246. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  247. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  248. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  250. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  251. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  252. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  253. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  254. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  255. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  256. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  257. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  258. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  259. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  261. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  262. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  263. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  264. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  265. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  266. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  267. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  268. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  270. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  271. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  272. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  273. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  274. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  275. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  276. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  277. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  278. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  279. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  280. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  281. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  282. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  283. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  285. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  286. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  287. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  288. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  289. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  291. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
  292. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
  293. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  294. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  295. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  296. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  297. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  298. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  299. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  300. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  302. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  303. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  305. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  306. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  307. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  308. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  309. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  310. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  311. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  312. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  314. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  315. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  317. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  318. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  320. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  321. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  323. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  324. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  325. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  326. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  327. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  328. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  329. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  330. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  331. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  332. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  333. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  334. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  335. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  336. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  337. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  338. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  339. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  340. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  341. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  342. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  343. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  344. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  345. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  346. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  347. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  348. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  349. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  350. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  351. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  352. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  353. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  354. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  355. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  356. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  357. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  374. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  375. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  376. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  377. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  378. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  379. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  380. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  381. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  382. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  383. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  384. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  385. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  386. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  387. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  388. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  389. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  390. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  391. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  392. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  393. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  394. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  395. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  396. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  397. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  398. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  399. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  400. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  401. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  402. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  403. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  404. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  405. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  406. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  407. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  408. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  409. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  410. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The bound on one lane of an operation's result, from the bounds on that lane of its sources.
3
+ *
4
+ * The rules are magnitudes and nothing else — `|a * b| <= |a| * |b|` — so they say the same thing
5
+ * about a lane of an instruction and about a node of a value graph, and both callers read them from
6
+ * here rather than each keeping a copy of the table.
7
+ *
8
+ * @param {number} op
9
+ * @param {number} a bound on source 0, `Infinity` when it is unknown or absent
10
+ * @param {number} b bound on source 1
11
+ * @param {number} c bound on source 2
12
+ * @param {number} [width] lanes the operation spans — read only by the reductions
13
+ * @param {function(): number[]} [whole_operands] bounds over EVERY lane of sources 0 and 1, which is
14
+ * what a reduction sums over; never called for a lanewise operation
15
+ * @returns {number}
16
+ */
17
+ export function particle_integer_bound_of_operation(op: number, a: number, b: number, c: number, width?: number, whole_operands?: () => number[]): number;
18
+ /**
19
+ * @param {number} value
20
+ * @returns {number} the value's magnitude when it is an integer, `Infinity` otherwise
21
+ */
22
+ export function particle_integer_bound_of_value(value: number): number;
23
+ /**
24
+ * Which register slots hold an integer, and how big it can be — the one fact that makes a float
25
+ * rewrite exact.
26
+ *
27
+ * `a * b + c` as `MAD` is a different number from `MUL` then `ADD` because the pair rounds the
28
+ * product before adding it and the fused form does not. When the product is an integer below 2^24
29
+ * it needs no rounding, and the two forms are then the same number on every executor — whether the
30
+ * hardware contracts the `MAD` into an FMA or not. So the peephole can fuse those pairs without
31
+ * giving anything up, provided it can PROVE the product is that small, and this is the analysis
32
+ * that proves it.
33
+ *
34
+ * The facts come from the shapes effects are actually made of. A comparison or a `step` is 0 or 1;
35
+ * a mask built from one, `cmp * 2 - 1`, is -1 or 1; a literal is whatever it is. Those flow through
36
+ * copies, negation, `abs`, `floor`, `min`, `max`, `clamp` and `select` unchanged in kind, and
37
+ * through the arithmetic with their bounds combined. Everything else — a draw, an attribute, a
38
+ * builtin, `fract`, a division, a transcendental — is unknown. So is any value whose bound would
39
+ * pass 2^24: above it an integer may no longer be representable, and once a rounding could have
40
+ * happened nothing downstream is exact any more.
41
+ *
42
+ * ## Why the bound is a magnitude and not an interval
43
+ *
44
+ * Exactness of a product is a question about magnitudes, and `|a * b| <= |a| * |b|` is all it
45
+ * needs. An interval would prove more — that `x - floor(x / 289) * 289` is small, say, which is
46
+ * the other shape the noise library is made of — but only from a bound on `x`, which is a
47
+ * position, and there is none. That rewrite stays behind the `fuse_multiply_add` switch.
48
+ *
49
+ * The file starts zeroed on both executors, so every slot begins as the integer 0.
50
+ */
51
+ export class ParticleIntegerBounds {
52
+ /**
53
+ * @param {ArrayLike<number>} constants the shared constant pool, which `LOAD_CONST` reads
54
+ * @param {number} [slots]
55
+ */
56
+ constructor(constants: ArrayLike<number>, slots?: number);
57
+ /** @type {ArrayLike<number>} */
58
+ constants: ArrayLike<number>;
59
+ /** @type {Float64Array} per slot, the largest magnitude the integer it holds can have; `Infinity` when it is not known to hold one */
60
+ bound: Float64Array;
61
+ /**
62
+ * @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
63
+ * @param {number} [lanes] how many lanes are read; the operand's own count when left out
64
+ * @returns {number} the largest bound among the lanes read, or `Infinity`
65
+ */
66
+ bound_of_read(read: import("./particle_program_analysis.js").ParticleOperandRun, lanes?: number): number;
67
+ /**
68
+ * @param {import("./particle_program_analysis.js").ParticleOperandRun} source any operand
69
+ * @param {number} [lanes] how many lanes are read; the operand's own count when left out
70
+ * @returns {number} the bound on what it reads: a literal's own magnitude, or a run's
71
+ */
72
+ bound_of_source(source: import("./particle_program_analysis.js").ParticleOperandRun, lanes?: number): number;
73
+ /**
74
+ * Record what an instruction leaves in its destination.
75
+ *
76
+ * @param {ArrayLike<number>} words the four words of a single instruction, as they will run
77
+ */
78
+ publish(words: ArrayLike<number>): void;
79
+ /**
80
+ * @param {import("./particle_program_analysis.js").ParticleDecodedInstruction} instruction
81
+ * @param {number} span lanes the instruction writes
82
+ * @returns {number[]} the bound each written lane will hold — gathered before anything is
83
+ * written, since a source may alias the destination
84
+ */
85
+ lanes_written(instruction: import("./particle_program_analysis.js").ParticleDecodedInstruction, span: number): number[];
86
+ /**
87
+ * @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
88
+ * @param {number} lane
89
+ * @returns {number} the bound of the slot that lane reads
90
+ */
91
+ bound_of_slot(read: import("./particle_program_analysis.js").ParticleOperandRun, lane: number): number;
92
+ }
93
+ /**
94
+ * Integers up to here are exactly representable as `f32`, and so are all their sums and products
95
+ * that stay under it. Above it, integers thin out and a rounding could have happened.
96
+ *
97
+ * @type {number}
98
+ */
99
+ export const PARTICLE_EXACT_INTEGER_LIMIT: number;
100
+ //# sourceMappingURL=particle_integer_bounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"particle_integer_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_integer_bounds.js"],"names":[],"mappings":"AAmJA;;;;;;;;;;;;;;;GAeG;AACH,wDATW,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,UACN,MAAM,yBACM,MAAM,EAAE,GAElB,MAAM,CAkDlB;AAUD;;;GAGG;AACH,uDAHW,MAAM,GACJ,MAAM,CAIlB;AA/ND;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH;IACI;;;OAGG;IACH,uBAHW,UAAU,MAAM,CAAC,UACjB,MAAM,EAOhB;IAJG,gCAAgC;IAChC,WADW,UAAU,MAAM,CAAC,CACF;IAC1B,sIAAsI;IACtI,OADW,YAAY,CACa;IAGxC;;;;OAIG;IACH,oBAJW,OAAO,gCAAgC,EAAE,kBAAkB,UAC3D,MAAM,GACJ,MAAM,CAclB;IAED;;;;OAIG;IACH,wBAJW,OAAO,gCAAgC,EAAE,kBAAkB,UAC3D,MAAM,GACJ,MAAM,CAMlB;IAED;;;;OAIG;IACH,eAFW,UAAU,MAAM,CAAC,QAiB3B;IAED;;;;;OAKG;IACH,2BALW,OAAO,gCAAgC,EAAE,0BAA0B,QACnE,MAAM,GACJ,MAAM,EAAE,CAkCpB;IAED;;;;OAIG;IACH,oBAJW,OAAO,gCAAgC,EAAE,kBAAkB,QAC3D,MAAM,GACJ,MAAM,CAMlB;CACJ;AAoED;;;;;GAKG;AACH,2CAFU,MAAM,CAEoC"}
@@ -0,0 +1,236 @@
1
+ import { PARTICLE_VM_REGISTER_SLOTS } from "../ParticleConstants.js";
2
+ import { VM_KIND, VM_OP, vm_f32_value } from "../isa/ParticleVMISA.js";
3
+ import { decode_particle_instruction, particle_read_slots } from "./particle_program_analysis.js";
4
+
5
+ /**
6
+ * Which register slots hold an integer, and how big it can be — the one fact that makes a float
7
+ * rewrite exact.
8
+ *
9
+ * `a * b + c` as `MAD` is a different number from `MUL` then `ADD` because the pair rounds the
10
+ * product before adding it and the fused form does not. When the product is an integer below 2^24
11
+ * it needs no rounding, and the two forms are then the same number on every executor — whether the
12
+ * hardware contracts the `MAD` into an FMA or not. So the peephole can fuse those pairs without
13
+ * giving anything up, provided it can PROVE the product is that small, and this is the analysis
14
+ * that proves it.
15
+ *
16
+ * The facts come from the shapes effects are actually made of. A comparison or a `step` is 0 or 1;
17
+ * a mask built from one, `cmp * 2 - 1`, is -1 or 1; a literal is whatever it is. Those flow through
18
+ * copies, negation, `abs`, `floor`, `min`, `max`, `clamp` and `select` unchanged in kind, and
19
+ * through the arithmetic with their bounds combined. Everything else — a draw, an attribute, a
20
+ * builtin, `fract`, a division, a transcendental — is unknown. So is any value whose bound would
21
+ * pass 2^24: above it an integer may no longer be representable, and once a rounding could have
22
+ * happened nothing downstream is exact any more.
23
+ *
24
+ * ## Why the bound is a magnitude and not an interval
25
+ *
26
+ * Exactness of a product is a question about magnitudes, and `|a * b| <= |a| * |b|` is all it
27
+ * needs. An interval would prove more — that `x - floor(x / 289) * 289` is small, say, which is
28
+ * the other shape the noise library is made of — but only from a bound on `x`, which is a
29
+ * position, and there is none. That rewrite stays behind the `fuse_multiply_add` switch.
30
+ *
31
+ * The file starts zeroed on both executors, so every slot begins as the integer 0.
32
+ */
33
+ export class ParticleIntegerBounds {
34
+ /**
35
+ * @param {ArrayLike<number>} constants the shared constant pool, which `LOAD_CONST` reads
36
+ * @param {number} [slots]
37
+ */
38
+ constructor(constants, slots = PARTICLE_VM_REGISTER_SLOTS) {
39
+ /** @type {ArrayLike<number>} */
40
+ this.constants = constants;
41
+ /** @type {Float64Array} per slot, the largest magnitude the integer it holds can have; `Infinity` when it is not known to hold one */
42
+ this.bound = new Float64Array(slots);
43
+ }
44
+
45
+ /**
46
+ * @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
47
+ * @param {number} [lanes] how many lanes are read; the operand's own count when left out
48
+ * @returns {number} the largest bound among the lanes read, or `Infinity`
49
+ */
50
+ bound_of_read(read, lanes = read.lanes) {
51
+ let bound = 0;
52
+
53
+ for (const slot of particle_read_slots(read, lanes)) {
54
+ if (slot < 0 || slot >= this.bound.length) {
55
+ return Infinity;
56
+ }
57
+
58
+ bound = Math.max(bound, this.bound[slot]);
59
+ }
60
+
61
+ return bound;
62
+ }
63
+
64
+ /**
65
+ * @param {import("./particle_program_analysis.js").ParticleOperandRun} source any operand
66
+ * @param {number} [lanes] how many lanes are read; the operand's own count when left out
67
+ * @returns {number} the bound on what it reads: a literal's own magnitude, or a run's
68
+ */
69
+ bound_of_source(source, lanes = source.lanes) {
70
+ return source.kind === VM_KIND.IMM
71
+ ? particle_integer_bound_of_value(vm_f32_value(source.word))
72
+ : this.bound_of_read(source, lanes);
73
+ }
74
+
75
+ /**
76
+ * Record what an instruction leaves in its destination.
77
+ *
78
+ * @param {ArrayLike<number>} words the four words of a single instruction, as they will run
79
+ */
80
+ publish(words) {
81
+ const instruction = decode_particle_instruction(words);
82
+
83
+ if (instruction.write === null) {
84
+ return;
85
+ }
86
+
87
+ const { base, span } = instruction.write;
88
+ const lanes = this.lanes_written(instruction, span);
89
+
90
+ for (let lane = 0; lane < span; lane++) {
91
+ if (base + lane < this.bound.length) {
92
+ this.bound[base + lane] = lanes[lane];
93
+ }
94
+ }
95
+ }
96
+
97
+ /**
98
+ * @param {import("./particle_program_analysis.js").ParticleDecodedInstruction} instruction
99
+ * @param {number} span lanes the instruction writes
100
+ * @returns {number[]} the bound each written lane will hold — gathered before anything is
101
+ * written, since a source may alias the destination
102
+ */
103
+ lanes_written(instruction, span) {
104
+ const [a, b, c] = instruction.sources;
105
+ const per_lane = (combine) => {
106
+ const out = new Array(span);
107
+
108
+ for (let lane = 0; lane < span; lane++) {
109
+ out[lane] = capped(combine(lane));
110
+ }
111
+
112
+ return out;
113
+ };
114
+ const lane_of = (source, lane) => (source.kind === VM_KIND.IMM
115
+ ? particle_integer_bound_of_value(vm_f32_value(source.word))
116
+ : this.bound_of_slot(source, lane));
117
+
118
+ // `LOAD_CONST` is the one operation whose lanes come from somewhere other than its
119
+ // operands, so it is answered here; every other one is the scalar rule below.
120
+ if (instruction.op === VM_OP.LOAD_CONST) {
121
+ return per_lane(lane => particle_integer_bound_of_value(this.constants[instruction.words[1] + lane]));
122
+ }
123
+
124
+ return per_lane(lane => particle_integer_bound_of_operation(
125
+ instruction.op,
126
+ a === undefined ? Infinity : lane_of(a, lane),
127
+ b === undefined ? Infinity : lane_of(b, lane),
128
+ c === undefined ? Infinity : lane_of(c, lane),
129
+ instruction.operation_width,
130
+ // The reductions read every lane, so their bound is over the whole operand rather than
131
+ // over one lane of it.
132
+ () => [this.bound_of_source(a, instruction.operation_width), this.bound_of_source(b, instruction.operation_width)]
133
+ ));
134
+ }
135
+
136
+ /**
137
+ * @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
138
+ * @param {number} lane
139
+ * @returns {number} the bound of the slot that lane reads
140
+ */
141
+ bound_of_slot(read, lane) {
142
+ const slot = particle_read_slots(read, lane + 1)[lane];
143
+
144
+ return slot >= 0 && slot < this.bound.length ? this.bound[slot] : Infinity;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * The bound on one lane of an operation's result, from the bounds on that lane of its sources.
150
+ *
151
+ * The rules are magnitudes and nothing else — `|a * b| <= |a| * |b|` — so they say the same thing
152
+ * about a lane of an instruction and about a node of a value graph, and both callers read them from
153
+ * here rather than each keeping a copy of the table.
154
+ *
155
+ * @param {number} op
156
+ * @param {number} a bound on source 0, `Infinity` when it is unknown or absent
157
+ * @param {number} b bound on source 1
158
+ * @param {number} c bound on source 2
159
+ * @param {number} [width] lanes the operation spans — read only by the reductions
160
+ * @param {function(): number[]} [whole_operands] bounds over EVERY lane of sources 0 and 1, which is
161
+ * what a reduction sums over; never called for a lanewise operation
162
+ * @returns {number}
163
+ */
164
+ export function particle_integer_bound_of_operation(op, a, b, c, width = 1, whole_operands = () => [a, b]) {
165
+ switch (op) {
166
+ case VM_OP.CMP_LT:
167
+ case VM_OP.CMP_LE:
168
+ case VM_OP.CMP_GT:
169
+ case VM_OP.CMP_GE:
170
+ case VM_OP.CMP_EQ:
171
+ case VM_OP.STEP:
172
+ return 1;
173
+
174
+ case VM_OP.MOV:
175
+ case VM_OP.NEG:
176
+ case VM_OP.ABS:
177
+ case VM_OP.FLOOR:
178
+ return capped(a);
179
+
180
+ case VM_OP.MIN:
181
+ case VM_OP.MAX:
182
+ return capped(Math.max(a, b));
183
+
184
+ case VM_OP.CLAMP:
185
+ return capped(Math.max(a, b, c));
186
+
187
+ // Whichever of the two the condition picks, and the condition itself is not a value.
188
+ case VM_OP.SELECT:
189
+ return capped(Math.max(a, b));
190
+
191
+ case VM_OP.ADD:
192
+ case VM_OP.SUB:
193
+ return capped(a + b);
194
+
195
+ case VM_OP.MUL:
196
+ return capped(a * b);
197
+
198
+ case VM_OP.MAD:
199
+ return capped(a * b + c);
200
+
201
+ // Every product exact and every partial sum within the cap is what makes the sum an
202
+ // integer whatever order the hardware adds it in.
203
+ case VM_OP.DOT: {
204
+ const [whole_a, whole_b] = whole_operands();
205
+
206
+ return capped(width * whole_a * whole_b);
207
+ }
208
+
209
+ default:
210
+ return Infinity;
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Integers up to here are exactly representable as `f32`, and so are all their sums and products
216
+ * that stay under it. Above it, integers thin out and a rounding could have happened.
217
+ *
218
+ * @type {number}
219
+ */
220
+ export const PARTICLE_EXACT_INTEGER_LIMIT = 2 ** 24;
221
+
222
+ /**
223
+ * @param {number} value
224
+ * @returns {number} the value's magnitude when it is an integer, `Infinity` otherwise
225
+ */
226
+ export function particle_integer_bound_of_value(value) {
227
+ return Number.isInteger(value) ? capped(Math.abs(value)) : Infinity;
228
+ }
229
+
230
+ /**
231
+ * @param {number} bound
232
+ * @returns {number} the bound, or `Infinity` once it is past what is exact
233
+ */
234
+ function capped(bound) {
235
+ return bound <= PARTICLE_EXACT_INTEGER_LIMIT ? bound : Infinity;
236
+ }