@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
@@ -1,197 +1,198 @@
1
- import { VM_OP, vm_decode_op, vm_decode_width, vm_operation_width } from "../isa/ParticleVMISA.js";
2
-
3
- /** @type {string} */
4
- export const PARTICLE_PASS_DEDUP_CONSTANTS = "dedup_constants";
5
-
6
- /**
7
- * Point every `LOAD_CONST` at the first copy of the value it loads, and drop the pool words that
8
- * nothing reads any more.
9
- *
10
- * `LOAD_CONST` is the only instruction that reads the constant pool, and it reads a *run* — `base`
11
- * from the operand and as many words as the instruction is wide. So two loads of the same value are
12
- * the same instruction only when they name the same base, and when they do not, every pass
13
- * downstream is looking at two different things:
14
- *
15
- * LOAD_CONST.1 r1, c0 LOAD_CONST.1 r1, c0
16
- * MUL.1 r2, r0, r1 MUL.1 r2, r0, r1
17
- * LOAD_CONST.1 r3, c1 LOAD_CONST.1 r3, c0
18
- * MUL.1 r4, r0, r3 MUL.1 r4, r0, r3
19
- * ADD.1 r5, r2, r4 ADD.1 r5, r2, r4
20
- *
21
- * With `c0` and `c1` holding the same number those two programs compute the same thing, but only the
22
- * right-hand one collapses: subexpression sharing folds the second load, copy propagation rewrites
23
- * the second `MUL` to read the first load's register, sharing then folds the two identical `MUL`s,
24
- * and dead code removes what is left. Seven instructions become five and six registers become four.
25
- * The left-hand one does not move at all. Canonicalizing the base is what makes the two the same
26
- * program, so this pass buys nothing on its own and everything through the passes after it.
27
- *
28
- * ## Where the duplicates come from
29
- *
30
- * Not from the node-graph compiler: {@link ../isa/ParticleAssembler.js}'s `constant` already scans
31
- * the whole pool for a matching run before appending, so a graph lowers to a pool with no duplicate
32
- * runs and no dead words — measured on the starter effect and on `simplex3`/`curl3`/`curl4` graphs,
33
- * every one of which comes out with nothing for this pass to find.
34
- *
35
- * They come from the other frontends:
36
- *
37
- * - **hand-written assembly**, where `.const c0 3` / `.const c1 3` is laid out exactly as typed,
38
- * because the indices are the author's to choose and the parser will not renumber them;
39
- * - **the optimizer itself**, whose folds intern new literals and whose lane-peeling speculation
40
- * runs the whole pipeline twice against one shared pool — so the literals belonging to the run
41
- * that lost are still sitting in it;
42
- * - **`f32` rounding**, since the pool is built as doubles and only becomes a `Float32Array` at the
43
- * end: two values that `constant` saw as distinct can land on the same float.
44
- *
45
- * ## Two halves, one switch
46
- *
47
- * The pass proper is the operand rewrite above: per section, and it never touches the pool, which is
48
- * what makes it safe when both sections share one. Compacting the pool needs to see every reference
49
- * in the program at once, so it is a step of
50
- * {@link ./optimize_particle_program.js optimize_compiled_particle_program} rather than a pass, and
51
- * it runs under this same switch — the rewrite is what makes words dead and the compaction is the
52
- * only thing that shows it, so a caller turning one off wants the other off too. A caller using the
53
- * per-section entry point gets the rewrite alone; there is no pool for it to compact.
54
- *
55
- * ## What must not change
56
- *
57
- * Runs are compared as `f32` **bit patterns**, not as numbers. That keeps `-0` out of `+0` — the two
58
- * are a visible difference the moment anything divides by one — and keeps two `NaN`s with different
59
- * payloads apart, which costs nothing since neither is a literal any frontend emits. Comparing the
60
- * bits the pool will actually hold, rather than the doubles it holds on the way there, is also what
61
- * catches the rounding case above.
62
- */
63
-
64
- /** Scratch for reading a value's `f32` bits. Module-level because this runs per pool word. */
65
- const F32_SCRATCH = new Float32Array(1);
66
-
67
- /** @type {Uint32Array} the same four bytes, as an integer */
68
- const U32_SCRATCH = new Uint32Array(F32_SCRATCH.buffer);
69
-
70
- /**
71
- * @param {number} value
72
- * @returns {number} the bits `value` has once the pool is a `Float32Array`
73
- */
74
- function f32_bits(value) {
75
- F32_SCRATCH[0] = value;
76
-
77
- return U32_SCRATCH[0];
78
- }
79
-
80
- /**
81
- * @param {ArrayLike<number>} constants
82
- * @param {number} base
83
- * @param {number} span
84
- * @returns {string} an identity for the run of values at `base`, distinct for every distinct run
85
- */
86
- function run_key(constants, base, span) {
87
- let key = `${span}`;
88
-
89
- for (let i = 0; i < span; i++) {
90
- key += `:${f32_bits(constants[base + i])}`;
91
- }
92
-
93
- return key;
94
- }
95
-
96
- /**
97
- * The span of pool words an instruction reads, or 0 when it is not a `LOAD_CONST`.
98
- *
99
- * @param {ArrayLike<number>} words the five words of one instruction
100
- * @returns {number}
101
- */
102
- function constant_span(words) {
103
- const op = vm_decode_op(words[0]);
104
-
105
- if (op !== VM_OP.LOAD_CONST) {
106
- return 0;
107
- }
108
-
109
- return vm_operation_width(op, vm_decode_width(words[0]));
110
- }
111
-
112
- /**
113
- * Every `(base, span)` a section loads from the pool.
114
- *
115
- * @param {ArrayLike<ArrayLike<number>>} instructions five-word tuples
116
- * @param {function(number, number, number): void} visit `(index, base, span)`
117
- */
118
- export function visit_particle_constant_reads(instructions, visit) {
119
- for (let index = 0; index < instructions.length; index++) {
120
- const words = instructions[index];
121
- const span = constant_span(words);
122
-
123
- if (span > 0) {
124
- visit(index, words[2], span);
125
- }
126
- }
127
- }
128
-
129
- /**
130
- * @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
131
- */
132
- export function pass_dedup_constants(instructions, context) {
133
- const constants = context.constants;
134
-
135
- if (constants === undefined || constants.length === 0) {
136
- return null;
137
- }
138
-
139
- /** @type {Array<{index: number, base: number, span: number}>} */
140
- const reads = [];
141
-
142
- /** @type {Set<number>} only the spans something actually loads are worth indexing */
143
- const spans = new Set();
144
-
145
- // One walk rather than one per question: this pass sits in the sweep loop and a `curl3` effect
146
- // is four thousand instructions, so decoding them all twice per invocation was most of what it
147
- // cost — and on a pool the assembler built there is nothing at the end of it to find.
148
- visit_particle_constant_reads(instructions, (index, base, span) => {
149
- if (base < 0 || base + span > constants.length) {
150
- // Out of the pool: a malformed program, which `validate` reports and this pass leaves
151
- // exactly as it found it rather than rewriting into a different kind of wrong.
152
- return;
153
- }
154
-
155
- reads.push({ index, base, span });
156
- spans.add(span);
157
- });
158
-
159
- if (reads.length === 0) {
160
- return null;
161
- }
162
-
163
- /** @type {Map<string, number>} run identity -> the first base holding it */
164
- const earliest = new Map();
165
-
166
- for (const span of spans) {
167
- for (let base = 0; base + span <= constants.length; base++) {
168
- const key = run_key(constants, base, span);
169
-
170
- // ascending, and only the first wins: the canonical base for a run is the earliest one,
171
- // which is a fixed point — running this pass again moves nothing — and monotonically
172
- // decreasing, so it cannot ping-pong with anything in the sweep it sits in.
173
- if (!earliest.has(key)) {
174
- earliest.set(key, base);
175
- }
176
- }
177
- }
178
-
179
- /** @type {number[][]|null} */
180
- let out = null;
181
-
182
- for (const read of reads) {
183
- const canonical = earliest.get(run_key(constants, read.base, read.span));
184
-
185
- if (canonical === undefined || canonical === read.base) {
186
- continue;
187
- }
188
-
189
- if (out === null) {
190
- out = instructions.map(words => Array.from(words));
191
- }
192
-
193
- out[read.index][2] = canonical;
194
- }
195
-
196
- return out;
197
- }
1
+ import { VM_OP, vm_decode_op, vm_decode_width, vm_operation_width } from "../isa/ParticleVMISA.js";
2
+
3
+ /** @type {string} */
4
+ export const PARTICLE_PASS_DEDUP_CONSTANTS = "dedup_constants";
5
+
6
+ /**
7
+ * Point every `LOAD_CONST` at the first copy of the value it loads, and drop the pool words that
8
+ * nothing reads any more.
9
+ *
10
+ * `LOAD_CONST` is the only instruction that reads the constant pool, and it reads a *run* — `base`
11
+ * from the operand and as many words as the instruction is wide. So two loads of the same value are
12
+ * the same instruction only when they name the same base, and when they do not, every pass
13
+ * downstream is looking at two different things:
14
+ *
15
+ * LOAD_CONST.1 r1, c0 LOAD_CONST.1 r1, c0
16
+ * MUL.1 r2, r0, r1 MUL.1 r2, r0, r1
17
+ * LOAD_CONST.1 r3, c1 LOAD_CONST.1 r3, c0
18
+ * MUL.1 r4, r0, r3 MUL.1 r4, r0, r3
19
+ * ADD.1 r5, r2, r4 ADD.1 r5, r2, r4
20
+ *
21
+ * With `c0` and `c1` holding the same number those two programs compute the same thing, but only the
22
+ * right-hand one collapses: subexpression sharing folds the second load, copy propagation rewrites
23
+ * the second `MUL` to read the first load's register, sharing then folds the two identical `MUL`s,
24
+ * and dead code removes what is left. Seven instructions become five and six registers become four.
25
+ * The left-hand one does not move at all. Canonicalizing the base is what makes the two the same
26
+ * program, so this pass buys nothing on its own and everything through the passes after it.
27
+ *
28
+ * ## Where the duplicates come from
29
+ *
30
+ * Not from the node-graph compiler: {@link ../isa/ParticleAssembler.js}'s `constant` already scans
31
+ * the whole pool for a matching run before appending, so a graph lowers to a pool with no duplicate
32
+ * runs and no dead words — measured on the starter effect and on `simplex3`/`curl3`/`curl4` graphs,
33
+ * every one of which comes out with nothing for this pass to find.
34
+ *
35
+ * They come from the other frontends:
36
+ *
37
+ * - **hand-written assembly**, where `.const c0 3` / `.const c1 3` is laid out exactly as typed,
38
+ * because the indices are the author's to choose and the parser will not renumber them;
39
+ * - **the optimizer itself**, whose folds intern new literals and whose lane-peeling speculation
40
+ * runs the whole pipeline twice against one shared pool — so the literals belonging to the run
41
+ * that lost are still sitting in it;
42
+ * - **`f32` rounding**, since the pool is built as doubles and only becomes a `Float32Array` at the
43
+ * end: two values that `constant` saw as distinct can land on the same float.
44
+ *
45
+ * ## Two halves, one switch
46
+ *
47
+ * The pass proper is the operand rewrite above: per section, and it never touches the pool, which is
48
+ * what makes it safe when both sections share one. Compacting the pool needs to see every reference
49
+ * in the program at once, so it is a step of
50
+ * {@link ./optimize_particle_program.js optimize_particle_program} rather than a pass, and
51
+ * it runs under this same switch — the rewrite is what makes words dead and the compaction is the
52
+ * only thing that shows it, so a caller turning one off wants the other off too. A caller using the
53
+ * per-section entry point gets the rewrite alone; there is no pool for it to compact.
54
+ *
55
+ * ## What must not change
56
+ *
57
+ * Runs are compared as `f32` **bit patterns**, not as numbers. That keeps `-0` out of `+0` — the two
58
+ * are a visible difference the moment anything divides by one — and keeps two `NaN`s with different
59
+ * payloads apart, which costs nothing since neither is a literal any frontend emits. Comparing the
60
+ * bits the pool will actually hold, rather than the doubles it holds on the way there, is also what
61
+ * catches the rounding case above.
62
+ */
63
+
64
+ /** Scratch for reading a value's `f32` bits. Module-level because this runs per pool word. */
65
+ const F32_SCRATCH = new Float32Array(1);
66
+
67
+ /** @type {Uint32Array} the same four bytes, as an integer */
68
+ const U32_SCRATCH = new Uint32Array(F32_SCRATCH.buffer);
69
+
70
+ /**
71
+ * @param {number} value
72
+ * @returns {number} the bits `value` has once the pool is a `Float32Array`
73
+ */
74
+ function f32_bits(value) {
75
+ F32_SCRATCH[0] = value;
76
+
77
+ return U32_SCRATCH[0];
78
+ }
79
+
80
+ /**
81
+ * @param {ArrayLike<number>} constants
82
+ * @param {number} base
83
+ * @param {number} span
84
+ * @returns {string} an identity for the run of values at `base`, distinct for every distinct run
85
+ */
86
+ function run_key(constants, base, span) {
87
+ let key = `${span}`;
88
+
89
+ for (let i = 0; i < span; i++) {
90
+ key += `:${f32_bits(constants[base + i])}`;
91
+ }
92
+
93
+ return key;
94
+ }
95
+
96
+ /**
97
+ * The span of pool words an instruction reads, or 0 when it is not a `LOAD_CONST`.
98
+ *
99
+ * @param {ArrayLike<number>} words the five words of one instruction
100
+ * @returns {number}
101
+ */
102
+ function constant_span(words) {
103
+ const op = vm_decode_op(words[0]);
104
+
105
+ if (op !== VM_OP.LOAD_CONST) {
106
+ return 0;
107
+ }
108
+
109
+ return vm_operation_width(op, vm_decode_width(words[0]));
110
+ }
111
+
112
+ /**
113
+ * Every `(base, span)` a section loads from the pool. A `LOAD_CONST` is the one instruction that
114
+ * reads it, and its pool index is its first source word.
115
+ *
116
+ * @param {ArrayLike<ArrayLike<number>>} instructions four-word tuples
117
+ * @param {function(number, number, number): void} visit `(index, base, span)`
118
+ */
119
+ export function visit_particle_constant_reads(instructions, visit) {
120
+ for (let index = 0; index < instructions.length; index++) {
121
+ const words = instructions[index];
122
+ const span = constant_span(words);
123
+
124
+ if (span > 0) {
125
+ visit(index, words[1], span);
126
+ }
127
+ }
128
+ }
129
+
130
+ /**
131
+ * @type {import("./optimize_particle_program.js").ParticleOptimizerPass}
132
+ */
133
+ export function pass_dedup_constants(instructions, context) {
134
+ const constants = context.constants;
135
+
136
+ if (constants === undefined || constants.length === 0) {
137
+ return null;
138
+ }
139
+
140
+ /** @type {Array<{index: number, base: number, span: number}>} */
141
+ const reads = [];
142
+
143
+ /** @type {Set<number>} only the spans something actually loads are worth indexing */
144
+ const spans = new Set();
145
+
146
+ // One walk rather than one per question: this pass sits in the sweep loop and a `curl3` effect
147
+ // is four thousand instructions, so decoding them all twice per invocation was most of what it
148
+ // cost — and on a pool the assembler built there is nothing at the end of it to find.
149
+ visit_particle_constant_reads(instructions, (index, base, span) => {
150
+ if (base < 0 || base + span > constants.length) {
151
+ // Out of the pool: a malformed program, which `validate` reports and this pass leaves
152
+ // exactly as it found it rather than rewriting into a different kind of wrong.
153
+ return;
154
+ }
155
+
156
+ reads.push({ index, base, span });
157
+ spans.add(span);
158
+ });
159
+
160
+ if (reads.length === 0) {
161
+ return null;
162
+ }
163
+
164
+ /** @type {Map<string, number>} run identity -> the first base holding it */
165
+ const earliest = new Map();
166
+
167
+ for (const span of spans) {
168
+ for (let base = 0; base + span <= constants.length; base++) {
169
+ const key = run_key(constants, base, span);
170
+
171
+ // ascending, and only the first wins: the canonical base for a run is the earliest one,
172
+ // which is a fixed point — running this pass again moves nothing — and monotonically
173
+ // decreasing, so it cannot ping-pong with anything in the sweep it sits in.
174
+ if (!earliest.has(key)) {
175
+ earliest.set(key, base);
176
+ }
177
+ }
178
+ }
179
+
180
+ /** @type {number[][]|null} */
181
+ let out = null;
182
+
183
+ for (const read of reads) {
184
+ const canonical = earliest.get(run_key(constants, read.base, read.span));
185
+
186
+ if (canonical === undefined || canonical === read.base) {
187
+ continue;
188
+ }
189
+
190
+ if (out === null) {
191
+ out = instructions.map(words => Array.from(words));
192
+ }
193
+
194
+ out[read.index][1] = canonical;
195
+ }
196
+
197
+ return out;
198
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"pass_eliminate_dead_code.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.js"],"names":[],"mappings":"AAmDo5B,2JAAiP;AAjDroC,qBAAqB;AACrB,sCADW,MAAM,CACkC"}
1
+ {"version":3,"file":"pass_eliminate_dead_code.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.js"],"names":[],"mappings":"AAmD8jF,2JAAqP;AAjDnzF,qBAAqB;AACrB,sCADW,MAAM,CACkC"}
@@ -1,4 +1,23 @@
1
1
  export function pass_fold_constants(instructions: number[][], context: import("./optimize_particle_program.js").ParticleOptimizerContext): number[][];
2
+ /**
3
+ * One lane of an operation, in the arithmetic the reference executes it in: `f32` operands, an
4
+ * `f64` computation, and the result rounded back to `f32` — which for a single correctly-rounded
5
+ * operation is the same number an `f32` machine produces.
6
+ *
7
+ * @param {number} op
8
+ * @param {number} a
9
+ * @param {number} b
10
+ * @param {number} c
11
+ * @returns {number}
12
+ */
13
+ export function evaluate_particle_operation(op: number, a: number, b: number, c: number): number;
2
14
  /** @type {string} */
3
15
  export const PARTICLE_PASS_FOLD_CONSTANTS: string;
16
+ /**
17
+ * The opcodes whose result a known zero operand decides on its own — the ones
18
+ * `fold_multiply_by_zero` rewrites, and therefore the ones whose results the equivalence harness's
19
+ * reach mode has to follow. Stated once so the two cannot drift.
20
+ * @type {Set<number>}
21
+ */
22
+ export const PARTICLE_ZERO_ABSORBING_OPS: Set<number>;
4
23
  //# sourceMappingURL=pass_fold_constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pass_fold_constants.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_fold_constants.js"],"names":[],"mappings":"AAmDmD,sJAMnC;AArDhB,qBAAqB;AACrB,2CADW,MAAM,CAC4C"}
1
+ {"version":3,"file":"pass_fold_constants.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_fold_constants.js"],"names":[],"mappings":"AAyF4B,sJAEwD;AAuJpF;;;;;;;;;;GAUG;AACH,gDANW,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ,MAAM,CAmElB;AA9SD,qBAAqB;AACrB,2CADW,MAAM,CAC4C;AAE7D;;;;;GAKG;AACH,0CAFU,IAAI,MAAM,CAAC,CAE2C"}