@woosh/meep-engine 3.16.0 → 3.17.1

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 (431) hide show
  1. package/README.md +8 -72
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  3. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  4. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  7. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  10. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  11. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  12. package/editor/view/node-graph/NodeGraphView.js +84 -8
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  15. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  16. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  17. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  20. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  22. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  25. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  27. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  28. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  29. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  30. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  31. package/editor/view/particles/effect/particle-editor.css +123 -35
  32. package/package.json +1 -1
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  34. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  35. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  37. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  38. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  39. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  40. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  41. package/src/core/graph/csr/CSRGraph.js +14 -6
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  44. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  47. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  50. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  53. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  55. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  56. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  57. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  59. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  62. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  65. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  68. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  70. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  71. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  74. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  76. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  77. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  78. package/src/engine/animation/AnimationUtils.js +246 -246
  79. package/src/engine/animation/Animations.js +74 -74
  80. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  81. package/src/engine/ecs/EventType.d.ts +0 -1
  82. package/src/engine/ecs/EventType.js +1 -26
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  85. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  86. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  87. package/src/engine/ecs/parent/EntityNode.js +4 -9
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  89. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  93. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  95. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  96. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  97. package/src/engine/ecs/transform/t64_set_rotation_axis_angle.d.ts +25 -0
  98. package/src/engine/ecs/transform/t64_set_rotation_axis_angle.d.ts.map +1 -0
  99. package/src/engine/ecs/transform/t64_set_rotation_axis_angle.js +45 -0
  100. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  101. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  102. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  103. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  104. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  105. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  106. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  107. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/LightSystem.js +4 -8
  109. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/MeshSystem.js +9 -19
  111. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  112. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  113. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  114. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  115. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  116. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  117. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  118. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  119. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  120. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  121. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  122. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  123. package/src/engine/sound/simulation/AcousticSimulator.d.ts +11 -8
  124. package/src/engine/sound/simulation/AcousticSimulator.d.ts.map +1 -1
  125. package/src/engine/sound/simulation/AcousticSimulator.js +45 -36
  126. package/src/engine/sound/simulation/README.md +2 -2
  127. package/src/engine/sound/simulation/core/OcclusionSolver.d.ts.map +1 -1
  128. package/src/engine/sound/simulation/core/VolumeField.d.ts +9 -9
  129. package/src/engine/sound/simulation/core/VolumeField.d.ts.map +1 -1
  130. package/src/engine/sound/simulation/core/VolumeField.js +29 -13
  131. package/src/engine/sound/simulation/core/acoustic_occlusion_solve.d.ts +31 -0
  132. package/src/engine/sound/simulation/core/acoustic_occlusion_solve.d.ts.map +1 -0
  133. package/src/engine/sound/simulation/core/acoustic_occlusion_solve.js +134 -0
  134. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  135. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  136. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  137. package/src/shade/playground/particle_editor/README.md +43 -2
  138. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  139. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  140. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  141. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  142. package/src/shade/playground/volumetrics_froxel/main.js +6 -1
  143. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  144. package/src/shade/renderer/Renderer.js +13 -1
  145. package/src/shade/renderer/particles/DESIGN.md +104 -19
  146. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  147. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  148. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  149. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  150. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  151. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  152. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  153. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  154. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  155. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  157. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  158. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  159. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  160. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  161. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  162. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  163. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  164. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  165. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  166. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  168. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  169. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  170. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  171. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  172. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  174. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  175. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  176. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  177. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  178. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  179. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  180. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  181. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  182. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  183. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  185. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  186. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  187. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  188. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  189. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  190. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  191. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  192. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  193. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  194. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  196. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  197. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  198. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  199. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  200. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  202. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  203. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/graph_particles.js +105 -262
  205. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  206. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  207. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  208. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  209. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  210. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  211. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  212. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  213. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  214. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  215. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  216. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  217. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  218. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  219. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  220. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  221. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  222. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  223. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  224. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  225. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  226. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  227. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  228. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  229. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  230. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  235. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  236. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  237. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  238. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  239. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  240. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  241. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  242. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  243. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  244. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  245. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  246. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  247. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  248. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  249. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  250. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  251. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  252. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  253. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  254. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  255. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  256. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  257. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  258. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  259. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  261. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  262. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  263. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  264. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  265. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  266. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  267. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  268. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  270. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  271. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  272. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  273. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  274. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  275. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  276. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  277. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  278. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  279. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  280. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  281. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  282. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  283. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  285. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  286. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  287. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  288. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  289. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  291. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  292. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  293. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  294. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  295. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  296. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  297. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  298. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  299. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  300. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  302. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  303. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  305. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  306. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  307. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  308. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  309. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  310. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  311. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  312. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  314. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  315. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  317. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  318. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  320. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  321. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  323. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  324. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  325. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  326. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  327. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  328. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  329. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  330. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  331. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  332. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  333. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  334. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  335. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  336. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  337. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  338. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  339. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  340. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  341. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  342. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  343. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  344. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  345. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  346. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  347. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  348. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  349. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  350. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  351. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  352. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  353. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  354. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  355. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  356. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  357. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  374. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  375. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  376. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  377. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  378. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  379. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  380. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  381. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  382. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  383. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  384. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  385. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  386. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  387. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  388. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  389. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +7 -0
  390. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  391. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +7 -0
  392. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  393. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  394. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  395. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  396. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  397. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  398. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  399. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  400. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  401. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  402. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  403. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  404. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  405. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  406. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  407. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  408. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  409. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  410. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  411. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  412. package/src/engine/sound/simulation/core/OcclusionSolver.js +0 -112
  413. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  414. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  415. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  416. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  417. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  418. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  419. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  420. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  421. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  422. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  423. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +0 -89
  424. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +0 -1
  425. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  426. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  427. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  428. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  429. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  430. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  431. 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"}