@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,334 @@
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { uf_find, uf_union } from "../../../../../core/collection/union-find/union_find.js";
3
+ import { VM_MAX_WIDTH, VM_OP, vm_f32_bits, vm_f32_value } from "../../isa/ParticleVMISA.js";
4
+ import { particle_integer_bound_of_operation, particle_integer_bound_of_value } from "../particle_integer_bounds.js";
5
+
6
+ /**
7
+ * The value graph, with a VECTOR as the unit.
8
+ *
9
+ * There was a version of this graph in which a value was one LANE, so that every rewrite could be
10
+ * lane-exact. It was measured to be the wrong trade on this machine and retired; this is the answer
11
+ * to it, and the measurement is kept because the trade is not obvious and someone will want to take
12
+ * it again. On `curl4` the scalar graph spent 615 of its 3,182 instructions moving values between
13
+ * registers, against the pass pipeline's 79 of 2,828 — and an instruction is an instruction here, a
14
+ * `MOV` costing about what a `MAD` does.
15
+ *
16
+ * ## Why lane-exactness cost more than it bought
17
+ *
18
+ * A frontend emits every value into a RUN of consecutive registers, and every consumer reads it
19
+ * there. That satisfies the one constraint this ISA puts on an operand — all of its lanes inside one
20
+ * window of four — everywhere, by construction, for nothing. Scalarising deletes it, and then the
21
+ * lane-exact sharing it was for finishes the job: of the 1,946 runs `curl4`'s input writes, 636 have
22
+ * two of their lanes collapse into ONE VALUE under lane-level common-subexpression elimination, so
23
+ * the shape can never be one instruction again. Sharing merges lanes; merging lanes breaks runs. In a
24
+ * scalar graph those two are the same act, taken at full strength on every opportunity, and taken in
25
+ * the lift — below the level at which extraction could have priced it.
26
+ *
27
+ * So here a value is a vector of one to four lanes, which is what the machine has, and lane-level
28
+ * sharing becomes something the optimizer may CHOOSE, with the copy it costs on the bill.
29
+ *
30
+ * ## The shape
31
+ *
32
+ * A node is an operation, a width, and one operand per source — each naming a value and the swizzle
33
+ * it reads that value through, exactly as an instruction's source word does. Hash-consing over that
34
+ * is common-subexpression elimination per instruction, and it can never break a run, because it only
35
+ * ever merges two whole instructions that were already the same.
36
+ *
37
+ * Multi-output operations need no special case: `CROSS` is a node of width three the way the
38
+ * instruction is. Nor do the reductions, which are nodes of width one.
39
+ *
40
+ * `BUILD` is the one node with no instruction behind it — a vector assembled from lanes of several
41
+ * others, which is what a frontend's `vec4` constructor is and what a load of record words written by
42
+ * several different stores is. It lowers to one `MOV` per lane, and getting rid of those again is
43
+ * what the layout stage is for.
44
+ */
45
+
46
+ /**
47
+ * Node kinds with no opcode of their own. Above every {@link VM_OP} number.
48
+ * @enum {number}
49
+ */
50
+ export const PV = {
51
+ /** literals, one per lane; `imm` holds their bit patterns */
52
+ CONST: 200,
53
+ /** record words as the section found them; `imm[0]` is the first word, the width says how many */
54
+ ATTR: 201,
55
+ /** a vector assembled from one lane of each source; `patterns[i]` is the lane taken from source `i` */
56
+ BUILD: 202,
57
+ };
58
+
59
+ /**
60
+ * @typedef {object} ParticleVectorNode
61
+ * @property {number} op a {@link VM_OP} or a {@link PV}
62
+ * @property {number} width lanes the VALUE has, `1..4`
63
+ * @property {number} operand_width lanes each source is read at, which is the instruction's width
64
+ * field. The same as `width` for anything lanewise; three for a `CROSS`, and the operand's own
65
+ * width for a reduction, which reads many lanes to write one.
66
+ * @property {number[]} children the values its sources read, one per source
67
+ * @property {number[]} patterns per source, the swizzle it reads that value through — or, for
68
+ * `BUILD`, the single lane it takes
69
+ * @property {number[]} imm static fields: literal bits, a record word, a builtin id, a curve handle,
70
+ * the first draw of a `RANDOM`
71
+ */
72
+
73
+ /**
74
+ * @callback ParticleVectorRule
75
+ * @param {ParticleVectorGraph} graph
76
+ * @param {ParticleVectorNode} node the node about to be built
77
+ * @returns {number} a class to use instead, or `-1`
78
+ */
79
+
80
+ /** Commutative to the bit on every input, so their operands sort — see the scalar graph's note. */
81
+ const COMMUTATIVE = new Set([VM_OP.ADD, VM_OP.MUL]);
82
+
83
+ export class ParticleVectorGraph {
84
+ /**
85
+ * @param {object} [params]
86
+ * @param {ParticleVectorRule[]} [params.rules]
87
+ */
88
+ constructor({ rules = [], share_window = Infinity } = {}) {
89
+ /** @type {ParticleVectorRule[]} */
90
+ this.rules = rules;
91
+ /**
92
+ * How far back a value may have been computed and still be reused rather than recomputed.
93
+ *
94
+ * Sharing is not free on a machine with forty-eight registers. A value computed once and read
95
+ * a thousand instructions later occupies its run for all of them: `curl3` measures at 57
96
+ * slots with sharing unbounded and 33 with none — for 1,100 instructions either way. So the
97
+ * question is never whether to share but WHICH sharings are free, and the pass pipeline
98
+ * answers it without seeming to think about it: its common-subexpression pass can only reuse
99
+ * a value still in its register, so it takes the sharing that extends no live range and
100
+ * recomputes the rest. This is that policy with a number on it, and the number is a rung of
101
+ * the ladder in `./optimize_particle_program_vector.js` rather than a constant, because how
102
+ * much sharing a program can afford is a property of the program.
103
+ *
104
+ * @type {number}
105
+ */
106
+ this.share_window = share_window;
107
+ /** @type {ParticleVectorNode[]} */
108
+ this.nodes = [];
109
+ /** @type {Map<string, number>} */
110
+ this.interned = new Map();
111
+ /** @type {number[]} per node, the class it was created as */
112
+ this.class_of = [];
113
+ /** @type {Uint32Array} union-find over class ids */
114
+ this.parent = new Uint32Array(0);
115
+ /** @type {Map<number, number[]>} per class root, the nodes in it */
116
+ this.class_nodes = new Map();
117
+ /** @type {Map<number, number>} per class root, the magnitude bound on the integer it holds */
118
+ this.class_bound = new Map();
119
+ }
120
+
121
+ /** @returns {number} */
122
+ get size() {
123
+ return this.nodes.length;
124
+ }
125
+
126
+ /**
127
+ * @param {number} id
128
+ * @returns {number} the class root
129
+ */
130
+ find(id) {
131
+ assert.ok(id >= 0 && id < this.nodes.length, `particle vector graph: no node ${id}`);
132
+
133
+ return uf_find(this.parent, this.class_of[id]);
134
+ }
135
+
136
+ /** @param {number} id @returns {ParticleVectorNode} */
137
+ node(id) {
138
+ return this.nodes[id];
139
+ }
140
+
141
+ /** @param {number} id @returns {number[]} */
142
+ members(id) {
143
+ return this.class_nodes.get(this.find(id));
144
+ }
145
+
146
+ /** @param {number} id @returns {number} */
147
+ width_of(id) {
148
+ return this.node(this.find(id)).width;
149
+ }
150
+
151
+ /** @param {number} id @returns {number} */
152
+ bound_of(id) {
153
+ return this.class_bound.get(this.find(id)) ?? Infinity;
154
+ }
155
+
156
+ /**
157
+ * The literal a value is, lane by lane — `null` where it is not one.
158
+ *
159
+ * @param {number} id
160
+ * @returns {number[]|null}
161
+ */
162
+ constants_of(id) {
163
+ for (const member of this.members(id)) {
164
+ if (this.nodes[member].op === PV.CONST) {
165
+ return this.nodes[member].imm.map(bits => vm_f32_value(bits));
166
+ }
167
+ }
168
+
169
+ return null;
170
+ }
171
+
172
+ /**
173
+ * The literal one lane of a value is.
174
+ *
175
+ * @param {number} id
176
+ * @param {number} lane
177
+ * @returns {number|null}
178
+ */
179
+ constant_at(id, lane) {
180
+ const values = this.constants_of(id);
181
+
182
+ return values === null || lane >= values.length ? null : values[lane];
183
+ }
184
+
185
+ /**
186
+ * A vector of literals.
187
+ *
188
+ * @param {...number} values one per lane, at least one
189
+ * @returns {number} a class
190
+ */
191
+ constant(...values) {
192
+ return this.make({
193
+ op: PV.CONST,
194
+ width: values.length,
195
+ children: [],
196
+ patterns: [],
197
+ imm: values.map(value => vm_f32_bits(value)),
198
+ });
199
+ }
200
+
201
+ /**
202
+ * Build a value — or find the one that already means this, or the better one a rule knows.
203
+ *
204
+ * @param {Partial<ParticleVectorNode>} shape
205
+ * @returns {number} a class
206
+ */
207
+ make({ op, width = 1, operand_width = width, children = [], patterns = [], imm = [] }) {
208
+ assert.ok(width >= 1 && width <= VM_MAX_WIDTH, `particle vector graph: width ${width}`);
209
+
210
+ const node = {
211
+ op,
212
+ width,
213
+ operand_width,
214
+ children: children.map(child => this.find(child)),
215
+ patterns: patterns.slice(),
216
+ imm: imm.slice(),
217
+ };
218
+
219
+ // Sorting a commutative operation's operands is what makes `a + b` and `b + a` one node. The
220
+ // swizzle travels with the operand, so the pair moves together.
221
+ if (COMMUTATIVE.has(op) && node.children.length === 2
222
+ && (node.children[0] > node.children[1]
223
+ || (node.children[0] === node.children[1] && node.patterns[0] > node.patterns[1]))) {
224
+ node.children.reverse();
225
+ node.patterns.reverse();
226
+ }
227
+
228
+ for (const rule of this.rules) {
229
+ const replacement = rule(this, node);
230
+
231
+ if (replacement >= 0) {
232
+ return this.find(replacement);
233
+ }
234
+ }
235
+
236
+ const key = `${node.op}|${node.width}|${node.operand_width}`
237
+ + `|${node.children.join(",")}|${node.patterns.join(",")}|${node.imm.join(",")}`;
238
+ const existing = this.interned.get(key);
239
+
240
+ // A literal is not a live range: it costs an operand or a pool word, so it is always shared.
241
+ if (existing !== undefined && (op === PV.CONST || this.nodes.length - existing <= this.share_window)) {
242
+ return this.find(existing);
243
+ }
244
+
245
+ const id = this.nodes.length;
246
+
247
+ this.nodes.push(node);
248
+ this.class_of.push(id);
249
+ this.interned.set(key, id);
250
+ this.#grow(id);
251
+ this.class_nodes.set(id, [id]);
252
+ this.class_bound.set(id, this.#bound(node));
253
+
254
+ return id;
255
+ }
256
+
257
+ /**
258
+ * Record that a node means the same as an existing class — for a rewrite whose worth is not
259
+ * local, and which extraction should therefore be the one to take or leave.
260
+ *
261
+ * @param {number} id
262
+ * @param {number} alternative
263
+ */
264
+ add_alternative(id, alternative) {
265
+ const root = this.find(id);
266
+ const other = this.find(alternative);
267
+
268
+ if (root === other) {
269
+ return;
270
+ }
271
+
272
+ const merged = uf_union(this.parent, root, other);
273
+ const nodes = [...this.class_nodes.get(root), ...this.class_nodes.get(other)];
274
+
275
+ for (const member of nodes) {
276
+ for (const child of this.nodes[member].children) {
277
+ assert.notEqual(
278
+ uf_find(this.parent, child),
279
+ merged,
280
+ `particle vector graph: node ${member} would reach its own class ${merged}`
281
+ );
282
+ }
283
+
284
+ this.class_of[member] = merged;
285
+ }
286
+
287
+ this.class_nodes.delete(root);
288
+ this.class_nodes.delete(other);
289
+ this.class_nodes.set(merged, nodes);
290
+ this.class_bound.set(
291
+ merged,
292
+ Math.min(this.class_bound.get(root) ?? Infinity, this.class_bound.get(other) ?? Infinity)
293
+ );
294
+ }
295
+
296
+ /**
297
+ * @param {ParticleVectorNode} node
298
+ * @returns {number} the magnitude bound on the integer it holds, if it is known to hold one
299
+ */
300
+ #bound(node) {
301
+ if (node.op === PV.CONST) {
302
+ return node.imm.reduce(
303
+ (bound, bits) => Math.max(bound, particle_integer_bound_of_value(vm_f32_value(bits))),
304
+ 0
305
+ );
306
+ }
307
+
308
+ const bound = index => (node.children[index] === undefined ? Infinity : this.bound_of(node.children[index]));
309
+
310
+ // The reductions sum over every lane, so their bound is over the whole operand.
311
+ if (node.op === VM_OP.DOT) {
312
+ return particle_integer_bound_of_operation(node.op, 0, 0, 0, node.operand_width, () => [bound(0), bound(1)]);
313
+ }
314
+
315
+ return particle_integer_bound_of_operation(node.op, bound(0), bound(1), bound(2));
316
+ }
317
+
318
+ /** @param {number} wanted */
319
+ #grow(wanted) {
320
+ if (this.parent.length > wanted) {
321
+ return;
322
+ }
323
+
324
+ const grown = new Uint32Array(Math.max(16, (wanted + 1) * 2));
325
+
326
+ grown.set(this.parent);
327
+
328
+ for (let i = this.parent.length; i < grown.length; i++) {
329
+ grown[i] = i;
330
+ }
331
+
332
+ this.parent = grown;
333
+ }
334
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * What a group is, which decides how it becomes instructions.
3
+ */
4
+ export type PV_GROUP = string;
5
+ export namespace PV_GROUP {
6
+ let COMPUTE: string;
7
+ let CONSTANT: string;
8
+ let GATHER: string;
9
+ let STORE: string;
10
+ let KILL: string;
11
+ }
12
+ export type ParticleGroupOperand = {
13
+ /**
14
+ * the source slot, `0..2`
15
+ */
16
+ slot: number;
17
+ /**
18
+ * the group whose base anchors the window the operand reads, or `-1` for a
19
+ * literal
20
+ */
21
+ group: number;
22
+ /**
23
+ * per lane of the operand, its slot measured from that group's base
24
+ */
25
+ lanes: number[];
26
+ /**
27
+ * per lane of the operand, the group and the
28
+ * lane of it actually read — which is what liveness and ordering want, and stops being the same
29
+ * thing as `lanes` once the window spans a COALITION of several runs
30
+ */
31
+ reads: Array<{
32
+ group: number;
33
+ lane: number;
34
+ }>;
35
+ /**
36
+ * for a literal operand, the `f32` it holds in every lane
37
+ */
38
+ value: number;
39
+ };
40
+ export type ParticleValueGroup = {
41
+ /**
42
+ * its position in {@link ParticleValuePacking.groups }
43
+ */
44
+ index: number;
45
+ /**
46
+ * a {@link PV_GROUP }
47
+ */
48
+ kind: string;
49
+ /**
50
+ * the opcode it emits
51
+ */
52
+ op: number;
53
+ /**
54
+ * the instruction's width field
55
+ */
56
+ width: number;
57
+ /**
58
+ * slots it writes
59
+ */
60
+ span: number;
61
+ /**
62
+ * the class in each written slot; `-1` for a slot the instruction writes
63
+ * that nothing reads
64
+ */
65
+ values: number[];
66
+ /**
67
+ * static operand words by source slot, `-1` where the slot is not one
68
+ */
69
+ raw: number[];
70
+ /**
71
+ * resolved register and literal operands
72
+ */
73
+ operands: ParticleGroupOperand[];
74
+ /**
75
+ * for a gather group, where
76
+ * each lane comes from: another group's lane, or a literal when `group` is `-1`
77
+ */
78
+ gather: Array<{
79
+ group: number;
80
+ lane: number;
81
+ value: number;
82
+ }>;
83
+ /**
84
+ * for a constant group, the literal in each lane
85
+ */
86
+ constants: number[];
87
+ /**
88
+ * for a `RANDOM` group, the first draw index it takes
89
+ */
90
+ draw: number;
91
+ /**
92
+ * the coalition of runs this one is laid out inside, or `-1`
93
+ */
94
+ coalition: number;
95
+ /**
96
+ * roughly where in the section this group's work first appeared — the
97
+ * newest class it computes, or for a group with no values the newest one it reads. Classes are
98
+ * numbered as the lift meets them, so this is the order the section was written in, and it is what
99
+ * the scheduler falls back on when it has no reason to prefer one ready group over another.
100
+ */
101
+ sequence: number;
102
+ };
103
+ export type ParticleValuePacking = {
104
+ groups: ParticleValueGroup[];
105
+ /**
106
+ * per class, where it is computed
107
+ */
108
+ placement: Map<number, {
109
+ group: number;
110
+ lane: number;
111
+ }>;
112
+ /**
113
+ * per coalition, the runs the allocator lays end to end
114
+ */
115
+ coalitions: number[][];
116
+ };
117
+ //# sourceMappingURL=particle_vector_groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"particle_vector_groups.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js"],"names":[],"mappings":";;;uBAeU,MAAM;;;;;;;;;;;;UAiBF,MAAM;;;;;WACN,MAAM;;;;WAEN,MAAM,EAAE;;;;;;WACR,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;;;;WAGpC,MAAM;;;;;;WAKN,MAAM;;;;UACN,MAAM;;;;QACN,MAAM;;;;WACN,MAAM;;;;UACN,MAAM;;;;;YACN,MAAM,EAAE;;;;SAER,MAAM,EAAE;;;;cACR,oBAAoB,EAAE;;;;;YACtB,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC;;;;eAEnD,MAAM,EAAE;;;;UACR,MAAM;;;;eACN,MAAM;;;;;;;cACN,MAAM;;;YAQN,kBAAkB,EAAE;;;;eACpB,IAAI,MAAM,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;;;;gBAC1C,MAAM,EAAE,EAAE"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The shape the packer hands the lowering: one group per instruction, and where its operands read.
3
+ *
4
+ * This is the seam between choosing WHAT to compute and choosing WHERE it lives. `./particle_vector_pack.js`
5
+ * decides the first and most of the second; `./particle_vector_lower.js` schedules, colours and
6
+ * emits. Neither knows anything about the graph the values came from, which is why the seam is
7
+ * described here rather than in either of them.
8
+ *
9
+ * A group writes a RUN — `span` consecutive slots — and an operand reads a window of at most four
10
+ * consecutive slots that may cross from one run into the next when the two are in a coalition. That
11
+ * is the whole of the machine model these two files share.
12
+ */
13
+
14
+ /**
15
+ * What a group is, which decides how it becomes instructions.
16
+ * @enum {string}
17
+ */
18
+ export const PV_GROUP = {
19
+ /** one instruction writing `values`, its operands resolved from the graph */
20
+ COMPUTE: "compute",
21
+ /** a `LOAD_CONST` of a pool run; the literals are in `constants` */
22
+ CONSTANT: "constant",
23
+ /** a run assembled one lane at a time, one `MOV` per entry of `gather` */
24
+ GATHER: "gather",
25
+ /** a `STORE_ATTR`; writes no run */
26
+ STORE: "store",
27
+ /** a `KILL`; writes no run */
28
+ KILL: "kill",
29
+ };
30
+
31
+ /**
32
+ * @typedef {object} ParticleGroupOperand
33
+ * @property {number} slot the source slot, `0..2`
34
+ * @property {number} group the group whose base anchors the window the operand reads, or `-1` for a
35
+ * literal
36
+ * @property {number[]} lanes per lane of the operand, its slot measured from that group's base
37
+ * @property {Array<{group: number, lane: number}>} reads per lane of the operand, the group and the
38
+ * lane of it actually read — which is what liveness and ordering want, and stops being the same
39
+ * thing as `lanes` once the window spans a COALITION of several runs
40
+ * @property {number} value for a literal operand, the `f32` it holds in every lane
41
+ */
42
+
43
+ /**
44
+ * @typedef {object} ParticleValueGroup
45
+ * @property {number} index its position in {@link ParticleValuePacking.groups}
46
+ * @property {string} kind a {@link PV_GROUP}
47
+ * @property {number} op the opcode it emits
48
+ * @property {number} width the instruction's width field
49
+ * @property {number} span slots it writes
50
+ * @property {number[]} values the class in each written slot; `-1` for a slot the instruction writes
51
+ * that nothing reads
52
+ * @property {number[]} raw static operand words by source slot, `-1` where the slot is not one
53
+ * @property {ParticleGroupOperand[]} operands resolved register and literal operands
54
+ * @property {Array<{group: number, lane: number, value: number}>} gather for a gather group, where
55
+ * each lane comes from: another group's lane, or a literal when `group` is `-1`
56
+ * @property {number[]} constants for a constant group, the literal in each lane
57
+ * @property {number} draw for a `RANDOM` group, the first draw index it takes
58
+ * @property {number} coalition the coalition of runs this one is laid out inside, or `-1`
59
+ * @property {number} sequence roughly where in the section this group's work first appeared — the
60
+ * newest class it computes, or for a group with no values the newest one it reads. Classes are
61
+ * numbered as the lift meets them, so this is the order the section was written in, and it is what
62
+ * the scheduler falls back on when it has no reason to prefer one ready group over another.
63
+ */
64
+
65
+ /**
66
+ * @typedef {object} ParticleValuePacking
67
+ * @property {ParticleValueGroup[]} groups
68
+ * @property {Map<number, {group: number, lane: number}>} placement per class, where it is computed
69
+ * @property {number[][]} coalitions per coalition, the runs the allocator lays end to end
70
+ */
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Read one section of a compiled program into a {@link ./particle_vector_graph.js vector graph}.
3
+ *
4
+ * What a section MEANS is its final record, the kill flag it sets and the RNG state it ends on, and
5
+ * everything that draws out of that is done here: a load of a word that was stored is the stored
6
+ * value, a word put back as it was found is not stored, kills are a set, draws are a sequence that
7
+ * may be re-cut, and nothing past a `HALT` is read.
8
+ *
9
+ * What is different is the unit. The register file holds not values but PLACES IN values: slot `s`
10
+ * holds lane `l` of value `v`. Reading a run of slots then asks one question — do they all come from
11
+ * one value? If they do, the read is that value through a swizzle, which is what a source word is and
12
+ * costs nothing. If they do not, it is a `BUILD`, and the copies it costs are visible from here on
13
+ * rather than discovered at the end.
14
+ *
15
+ * That is the whole of the change, and it is why the frontend's vectors reach the other side: a
16
+ * `vec3` the compiler emitted as one instruction is read back as one value, not inferred from three.
17
+ */
18
+ /**
19
+ * @typedef {object} ParticleVectorPlace
20
+ * @property {number} value the class the slot's value belongs to
21
+ * @property {number} lane which lane of it the slot holds
22
+ */
23
+ /**
24
+ * @typedef {object} ParticleLiftedVectorSection
25
+ * @property {Array<{word: number, place: ParticleVectorPlace, origin: number}>} stores record words
26
+ * whose final contents differ from what the section found, in word order
27
+ * @property {ParticleVectorPlace[]} kills distinct kill conditions, in the order they were met
28
+ * @property {number} draw_count draws taken off the RNG
29
+ * @property {number[]} draws per draw, the class of the `RANDOM` that takes it
30
+ * @property {number[]} draw_lanes per draw, which lane of that class it is
31
+ */
32
+ /**
33
+ * @param {import("./particle_vector_graph.js").ParticleVectorGraph} graph
34
+ * @param {ArrayLike<ArrayLike<number>>} instructions four-word tuples, in program order
35
+ * @param {object} params
36
+ * @param {ArrayLike<number>} params.constants
37
+ * @param {number} params.register_slots
38
+ * @returns {ParticleLiftedVectorSection|null} `null` when the section reaches outside that file, or
39
+ * uses an opcode this lift has no model for
40
+ */
41
+ export function lift_particle_vector_section(graph: import("./particle_vector_graph.js").ParticleVectorGraph, instructions: ArrayLike<ArrayLike<number>>, { constants, register_slots }: {
42
+ constants: ArrayLike<number>;
43
+ register_slots: number;
44
+ }): ParticleLiftedVectorSection | null;
45
+ /**
46
+ * A run of places, as one source operand — or as a `BUILD` when they do not all come from one value.
47
+ *
48
+ * This is the whole of what keeping vectors buys, in one function. A frontend put a value in a run
49
+ * and its consumers read that run, so the places agree and the read is a swizzle: free. Where they do
50
+ * not agree, the copies are counted here, in the open.
51
+ *
52
+ * @param {import("./particle_vector_graph.js").ParticleVectorGraph} graph
53
+ * @param {ParticleVectorPlace[]} places one per lane read
54
+ * @returns {{value: number, pattern: number}}
55
+ */
56
+ export function read(graph: import("./particle_vector_graph.js").ParticleVectorGraph, places: ParticleVectorPlace[]): {
57
+ value: number;
58
+ pattern: number;
59
+ };
60
+ export type ParticleVectorPlace = {
61
+ /**
62
+ * the class the slot's value belongs to
63
+ */
64
+ value: number;
65
+ /**
66
+ * which lane of it the slot holds
67
+ */
68
+ lane: number;
69
+ };
70
+ export type ParticleLiftedVectorSection = {
71
+ /**
72
+ * record words
73
+ * whose final contents differ from what the section found, in word order
74
+ */
75
+ stores: Array<{
76
+ word: number;
77
+ place: ParticleVectorPlace;
78
+ origin: number;
79
+ }>;
80
+ /**
81
+ * distinct kill conditions, in the order they were met
82
+ */
83
+ kills: ParticleVectorPlace[];
84
+ /**
85
+ * draws taken off the RNG
86
+ */
87
+ draw_count: number;
88
+ /**
89
+ * per draw, the class of the `RANDOM` that takes it
90
+ */
91
+ draws: number[];
92
+ /**
93
+ * per draw, which lane of that class it is
94
+ */
95
+ draw_lanes: number[];
96
+ };
97
+ //# sourceMappingURL=particle_vector_lift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"particle_vector_lift.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AAEH;;;;;;;;GAQG;AAEH;;;;;;;;GAQG;AACH,oDARW,OAAO,4BAA4B,EAAE,mBAAmB,gBACxD,UAAU,UAAU,MAAM,CAAC,CAAC;IAEF,SAAS,EAAnC,UAAU,MAAM,CAAC;IACF,cAAc,EAA7B,MAAM;IACJ,2BAA2B,GAAC,IAAI,CAgK5C;AAED;;;;;;;;;;GAUG;AACH,4BAJW,OAAO,4BAA4B,EAAE,mBAAmB,UACxD,mBAAmB,EAAE,GACnB;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAmB5C;;;;;WAlNa,MAAM;;;;UACN,MAAM;;;;;;;YAKN,MAAM;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,mBAAmB,CAAC;QAAC,QAAQ,MAAM,CAAA;KAAC,CAAC;;;;WAEjE,mBAAmB,EAAE;;;;gBACrB,MAAM;;;;WACN,MAAM,EAAE;;;;gBACR,MAAM,EAAE"}