@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
@@ -3,9 +3,24 @@ import {
3
3
  PARTICLE_VM_MAX_INSTRUCTIONS,
4
4
  } from "../ParticleConstants.js";
5
5
  import {
6
+ VM_DEST,
7
+ VM_DST_MASK,
8
+ VM_DST_SHIFT,
9
+ VM_ISA,
10
+ VM_KIND,
11
+ VM_KIND_BITS,
12
+ VM_KIND_MASK,
13
+ VM_KIND_SHIFT,
14
+ VM_MAX_WIDTH,
6
15
  VM_OP,
7
- vm_decode_op,
8
- vm_decode_width,
16
+ VM_OP_MASK,
17
+ VM_OPERAND_BASE_MASK,
18
+ VM_OPERAND_SWIZZLE_SHIFT,
19
+ VM_SWIZZLE_IDENTITY,
20
+ VM_WIDTH,
21
+ VM_WIDTH_MASK,
22
+ VM_WIDTH_SHIFT,
23
+ vm_dest_width,
9
24
  vm_operation_width,
10
25
  } from "../isa/ParticleVMISA.js";
11
26
 
@@ -38,6 +53,73 @@ export function u32_to_unit_f32(u) {
38
53
  return (u >>> 8) * (1 / 16777216);
39
54
  }
40
55
 
56
+ // --- the opcode rules as dense tables ------------------------------------------------------------
57
+ //
58
+ // The editor's preview runs this executor for every live particle every frame, so its speed is that
59
+ // preview's frame rate, and a few thousand instructions a particle leave no room for a map lookup an
60
+ // instruction. Everything the loop needs to know about an opcode is read out of the ISA once, here,
61
+ // into arrays indexed by opcode number; the ISA stays the one place the rules are written.
62
+
63
+ /** One past the largest opcode number. @type {number} */
64
+ const OP_COUNT = VM_OP_MASK + 1;
65
+
66
+ /** `1` where the opcode is defined. @type {Uint8Array} */
67
+ const OP_DEFINED = new Uint8Array(OP_COUNT);
68
+
69
+ /** The lane count the opcode always operates on, or `-1` where the instruction's width field says. @type {Int8Array} */
70
+ const OP_WIDTH = new Int8Array(OP_COUNT);
71
+
72
+ /** The lanes the opcode always writes, or `-1` for as many as it operates on. @type {Int8Array} */
73
+ const OP_DEST = new Int8Array(OP_COUNT);
74
+
75
+ /** Bit `n` set where source slot `n` is read one lane whatever the width. @type {Uint8Array} */
76
+ const OP_SCALAR = new Uint8Array(OP_COUNT);
77
+
78
+ for (const [op, meta] of VM_ISA) {
79
+ OP_DEFINED[op] = 1;
80
+ OP_WIDTH[op] = meta.width === VM_WIDTH.VARIABLE ? -1 : vm_operation_width(op, 0);
81
+ OP_DEST[op] = meta.dest === VM_DEST.WIDTH ? -1 : vm_dest_width(op, 0);
82
+
83
+ for (const slot of meta.scalar_operands) {
84
+ OP_SCALAR[op] |= 1 << slot;
85
+ }
86
+ }
87
+
88
+ // --- module-local copies of what the loop reads per instruction ----------------------------------
89
+ //
90
+ // An imported binding is a live lookup on every read under some module loaders (vitest's among
91
+ // them), and the loop below reads a dozen of them per instruction. Copied once here, they are plain
92
+ // constants to the JIT, and the opcode switch can be a jump table.
93
+
94
+ const {
95
+ ABS, ACOS, ADD, ASIN, ATAN2, CLAMP, CMP_EQ, CMP_GE, CMP_GT, CMP_LE, CMP_LT, COS, CROSS, CURVE,
96
+ DISTANCE, DIV, DOT, EXP, FLOOR, FRACT, HALT, KILL, LENGTH, LOAD_ATTR, LOAD_BUILTIN, LOAD_CONST,
97
+ LOG, MAD, MAX, MIN, MIX, MOV, MUL, NEG, NOP, NORMALIZE, POW, RANDOM, RSQRT, SELECT, SIN,
98
+ SMOOTHSTEP, SQRT, STEP, STORE_ATTR, SUB, TAN,
99
+ } = VM_OP;
100
+ const KIND_REG = VM_KIND.REG;
101
+ const KIND_IMM = VM_KIND.IMM;
102
+ const OPCODE_MASK = VM_OP_MASK;
103
+ const WIDTH_SHIFT = VM_WIDTH_SHIFT;
104
+ const WIDTH_MASK = VM_WIDTH_MASK;
105
+ const DST_SHIFT = VM_DST_SHIFT;
106
+ const DST_MASK = VM_DST_MASK;
107
+ const KIND_SHIFT = VM_KIND_SHIFT;
108
+ const KIND_BITS = VM_KIND_BITS;
109
+ const KIND_MASK = VM_KIND_MASK;
110
+ const OPERAND_BASE_MASK = VM_OPERAND_BASE_MASK;
111
+ const OPERAND_SWIZZLE_SHIFT = VM_OPERAND_SWIZZLE_SHIFT;
112
+ const SWIZZLE_IDENTITY = VM_SWIZZLE_IDENTITY;
113
+ const INSTRUCTION_WORDS = PARTICLE_VM_INSTRUCTION_WORDS;
114
+ const MAX_INSTRUCTIONS = PARTICLE_VM_MAX_INSTRUCTIONS;
115
+ const MAX_WIDTH = VM_MAX_WIDTH;
116
+
117
+ /** Scratch for reading a literal's bits as the `f32` they are. */
118
+ const LITERAL_F32 = new Float32Array(1);
119
+
120
+ /** @type {Uint32Array} the same four bytes */
121
+ const LITERAL_U32 = new Uint32Array(LITERAL_F32.buffer);
122
+
41
123
  /**
42
124
  * Execute one section of a particle program against a single particle record.
43
125
  *
@@ -45,7 +127,10 @@ export function u32_to_unit_f32(u) {
45
127
  * particle asked to be destroyed and the advanced RNG state so the caller can persist it.
46
128
  *
47
129
  * This is the CPU reference semantics — the WGSL interpreter is written to match it exactly, and the
48
- * parity spec cross-checks them.
130
+ * parity spec cross-checks them. The shape is the interpreter's: every source is resolved, lane by
131
+ * lane as far as the opcode reads it, before the opcode runs, and the destination is written after,
132
+ * so a source may overlap the destination in any way and still mean what it held before the
133
+ * instruction.
49
134
  *
50
135
  * @param {object} params
51
136
  * @param {Uint32Array} params.words instruction words for the section (SPAWN or UPDATE)
@@ -81,228 +166,264 @@ export function execute_particle_vm({
81
166
  return u32_to_unit_f32(r.value);
82
167
  };
83
168
 
84
- const instruction_count = Math.min(words.length / PARTICLE_VM_INSTRUCTION_WORDS, PARTICLE_VM_MAX_INSTRUCTIONS);
169
+ // The three resolved sources and the result, one f32 per lane. Only the lanes an opcode reads
170
+ // are resolved and only the lanes it writes are stored, so nothing here is ever cleared.
171
+ const a = new Float32Array(MAX_WIDTH);
172
+ const b = new Float32Array(MAX_WIDTH);
173
+ const c = new Float32Array(MAX_WIDTH);
174
+ const d = new Float32Array(MAX_WIDTH);
175
+
176
+ /**
177
+ * Resolve a source by the kind its word carries: a register run read through its swizzle, or
178
+ * the one `f32` a literal is in every lane. The only place the kinds are read; every opcode
179
+ * below sees a value, so no opcode has a tagged mode of its own.
180
+ *
181
+ * @param {Float32Array} into
182
+ * @param {number} kind
183
+ * @param {number} word
184
+ * @param {number} lanes
185
+ */
186
+ const gather = (into, kind, word, lanes) => {
187
+ if (kind === KIND_REG) {
188
+ const base = word & OPERAND_BASE_MASK;
189
+ const pattern = ((word >>> OPERAND_SWIZZLE_SHIFT) & 0xff) ^ SWIZZLE_IDENTITY;
190
+
191
+ for (let i = 0; i < lanes; i++) {
192
+ into[i] = reg[base + ((pattern >>> (2 * i)) & 3)];
193
+ }
194
+ } else if (kind === KIND_IMM) {
195
+ LITERAL_U32[0] = word;
196
+ const value = LITERAL_F32[0];
197
+
198
+ for (let i = 0; i < lanes; i++) {
199
+ into[i] = value;
200
+ }
201
+ }
202
+ };
203
+
204
+ const instruction_count = Math.min(words.length / INSTRUCTION_WORDS, MAX_INSTRUCTIONS);
85
205
 
86
206
  for (let pc = 0; pc < instruction_count; pc++) {
87
- const base = pc * PARTICLE_VM_INSTRUCTION_WORDS;
207
+ const base = pc * INSTRUCTION_WORDS;
88
208
  const word0 = words[base];
89
- const op = vm_decode_op(word0);
90
- const dst = words[base + 1];
91
- const s0 = words[base + 2];
92
- const s1 = words[base + 3];
93
- const s2 = words[base + 4];
209
+ const op = word0 & OPCODE_MASK;
210
+
211
+ if (OP_DEFINED[op] === 0) {
212
+ throw new Error(`ParticleVMReference: unhandled opcode ${op} at pc ${pc}`);
213
+ }
94
214
 
95
215
  /** Lanes this instruction spans. Fixed-width opcodes ignore the encoded field. */
96
- const w = vm_operation_width(op, vm_decode_width(word0));
216
+ const fixed_width = OP_WIDTH[op];
217
+ const w = fixed_width < 0 ? (word0 >>> WIDTH_SHIFT) & WIDTH_MASK : fixed_width;
218
+ const dst = (word0 >>> DST_SHIFT) & DST_MASK;
219
+ const kinds = word0 >>> KIND_SHIFT;
220
+ const scalar = OP_SCALAR[op];
221
+ const s0 = words[base + 1];
222
+ const s1 = words[base + 2];
223
+ const s2 = words[base + 3];
97
224
 
98
- // Register operands are slot indices; lane `i` of an operand is slot `base + i`.
99
- const d = dst;
100
- const a = s0;
101
- const b = s1;
102
- const c = s2;
225
+ gather(a, kinds & KIND_MASK, s0, (scalar & 1) !== 0 ? 1 : w);
226
+ gather(b, (kinds >>> KIND_BITS) & KIND_MASK, s1, (scalar & 2) !== 0 ? 1 : w);
227
+ gather(c, (kinds >>> (2 * KIND_BITS)) & KIND_MASK, s2, (scalar & 4) !== 0 ? 1 : w);
103
228
 
104
229
  switch (op) {
105
- case VM_OP.HALT:
230
+ case HALT:
106
231
  return { killed, rng_state: state };
107
- case VM_OP.NOP:
232
+ case NOP:
108
233
  break;
109
234
 
110
- case VM_OP.MOV:
111
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i];
235
+ case MOV:
236
+ for (let i = 0; i < w; i++) d[i] = a[i];
112
237
  break;
113
238
 
114
- case VM_OP.LOAD_CONST: {
115
- // The pool is addressed by word, so the operand is where the value starts, not
116
- // which vec4 slot holds it.
117
- for (let i = 0; i < w; i++) reg[d + i] = constants[s0 + i];
239
+ case LOAD_CONST:
240
+ // The pool is addressed by word, so the operand is where the value starts.
241
+ for (let i = 0; i < w; i++) d[i] = constants[s0 + i];
118
242
  break;
119
- }
120
243
 
121
- case VM_OP.LOAD_ATTR: {
244
+ case LOAD_ATTR:
122
245
  // Lanes past the attribute's component count read zero — a one-component attribute
123
246
  // asked for at width 3 is (x, 0, 0), which is what widening it costs: nothing.
124
- const off = s0; const comp = s1;
125
- for (let i = 0; i < w; i++) reg[d + i] = i < comp ? record_f32[off + i] : 0;
247
+ for (let i = 0; i < w; i++) d[i] = i < s1 ? record_f32[s0 + i] : 0;
126
248
  break;
127
- }
128
249
 
129
- case VM_OP.STORE_ATTR: {
130
- const off = s0; const comp = s1; const src = dst;
131
- for (let i = 0; i < comp; i++) record_f32[off + i] = reg[src + i];
250
+ case STORE_ATTR:
251
+ for (let i = 0; i < s2; i++) record_f32[s1 + i] = a[i];
132
252
  break;
133
- }
134
253
 
135
- case VM_OP.LOAD_BUILTIN: {
254
+ case LOAD_BUILTIN: {
136
255
  const v = builtins[s0] ?? [0, 0, 0, 0];
137
- for (let i = 0; i < w; i++) reg[d + i] = v[i] ?? 0;
256
+ for (let i = 0; i < w; i++) d[i] = v[i] ?? 0;
138
257
  break;
139
258
  }
140
259
 
141
- case VM_OP.KILL:
142
- if (reg[dst] > 0) killed = true;
260
+ case KILL:
261
+ if (a[0] > 0) killed = true;
143
262
  break;
144
263
 
145
- case VM_OP.ADD:
146
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] + reg[b + i];
147
- break;
148
- case VM_OP.SUB:
149
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] - reg[b + i];
264
+ case ADD:
265
+ for (let i = 0; i < w; i++) d[i] = a[i] + b[i];
150
266
  break;
151
- case VM_OP.MUL:
152
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] * reg[b + i];
267
+ case SUB:
268
+ for (let i = 0; i < w; i++) d[i] = a[i] - b[i];
153
269
  break;
154
- case VM_OP.DIV:
155
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] / reg[b + i];
270
+ case MUL:
271
+ for (let i = 0; i < w; i++) d[i] = a[i] * b[i];
156
272
  break;
157
- case VM_OP.MAD:
158
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] * reg[b + i] + reg[c + i];
273
+ case DIV:
274
+ for (let i = 0; i < w; i++) d[i] = a[i] / b[i];
159
275
  break;
160
- case VM_OP.MIN:
161
- for (let i = 0; i < w; i++) reg[d + i] = Math.min(reg[a + i], reg[b + i]);
276
+ case MAD:
277
+ for (let i = 0; i < w; i++) d[i] = a[i] * b[i] + c[i];
162
278
  break;
163
- case VM_OP.MAX:
164
- for (let i = 0; i < w; i++) reg[d + i] = Math.max(reg[a + i], reg[b + i]);
279
+ case MIN:
280
+ for (let i = 0; i < w; i++) d[i] = Math.min(a[i], b[i]);
165
281
  break;
166
- case VM_OP.MIX:
167
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] + (reg[b + i] - reg[a + i]) * reg[c + i];
282
+ case MAX:
283
+ for (let i = 0; i < w; i++) d[i] = Math.max(a[i], b[i]);
168
284
  break;
169
- case VM_OP.CLAMP:
170
- for (let i = 0; i < w; i++) reg[d + i] = Math.min(Math.max(reg[a + i], reg[b + i]), reg[c + i]);
285
+ case MIX:
286
+ for (let i = 0; i < w; i++) d[i] = a[i] + (b[i] - a[i]) * c[i];
171
287
  break;
172
- case VM_OP.SCALE: {
173
- const scale = reg[b];
174
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] * scale;
288
+ case CLAMP:
289
+ for (let i = 0; i < w; i++) d[i] = Math.min(Math.max(a[i], b[i]), c[i]);
175
290
  break;
176
- }
177
291
 
178
- case VM_OP.NEG:
179
- for (let i = 0; i < w; i++) reg[d + i] = -reg[a + i];
292
+ case NEG:
293
+ for (let i = 0; i < w; i++) d[i] = -a[i];
294
+ break;
295
+ case ABS:
296
+ for (let i = 0; i < w; i++) d[i] = Math.abs(a[i]);
180
297
  break;
181
- case VM_OP.ABS:
182
- for (let i = 0; i < w; i++) reg[d + i] = Math.abs(reg[a + i]);
298
+ case FLOOR:
299
+ for (let i = 0; i < w; i++) d[i] = Math.floor(a[i]);
183
300
  break;
184
- case VM_OP.FLOOR:
185
- for (let i = 0; i < w; i++) reg[d + i] = Math.floor(reg[a + i]);
301
+ case FRACT:
302
+ for (let i = 0; i < w; i++) d[i] = a[i] - Math.floor(a[i]);
186
303
  break;
187
- case VM_OP.FRACT:
188
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] - Math.floor(reg[a + i]);
304
+ case SQRT:
305
+ for (let i = 0; i < w; i++) d[i] = Math.sqrt(a[i]);
189
306
  break;
190
- case VM_OP.SQRT:
191
- for (let i = 0; i < w; i++) reg[d + i] = Math.sqrt(reg[a + i]);
307
+ case SIN:
308
+ for (let i = 0; i < w; i++) d[i] = Math.sin(a[i]);
192
309
  break;
193
- case VM_OP.SIN:
194
- for (let i = 0; i < w; i++) reg[d + i] = Math.sin(reg[a + i]);
310
+ case COS:
311
+ for (let i = 0; i < w; i++) d[i] = Math.cos(a[i]);
195
312
  break;
196
- case VM_OP.COS:
197
- for (let i = 0; i < w; i++) reg[d + i] = Math.cos(reg[a + i]);
313
+ case EXP:
314
+ for (let i = 0; i < w; i++) d[i] = Math.exp(a[i]);
198
315
  break;
199
- case VM_OP.EXP:
200
- for (let i = 0; i < w; i++) reg[d + i] = Math.exp(reg[a + i]);
316
+ case LOG:
317
+ for (let i = 0; i < w; i++) d[i] = Math.log(a[i]);
201
318
  break;
202
- case VM_OP.LOG:
203
- for (let i = 0; i < w; i++) reg[d + i] = Math.log(reg[a + i]);
319
+ case POW:
320
+ for (let i = 0; i < w; i++) d[i] = Math.pow(a[i], b[i]);
204
321
  break;
205
- case VM_OP.POW:
206
- for (let i = 0; i < w; i++) reg[d + i] = Math.pow(reg[a + i], reg[b + i]);
322
+ case STEP:
323
+ for (let i = 0; i < w; i++) d[i] = b[i] < a[i] ? 0 : 1;
207
324
  break;
208
- case VM_OP.STEP:
209
- for (let i = 0; i < w; i++) reg[d + i] = reg[b + i] < reg[a + i] ? 0 : 1;
325
+ case SMOOTHSTEP:
326
+ for (let i = 0; i < w; i++) d[i] = smoothstep(a[i], b[i], c[i]);
210
327
  break;
211
- case VM_OP.SMOOTHSTEP:
212
- for (let i = 0; i < w; i++) reg[d + i] = smoothstep(reg[a + i], reg[b + i], reg[c + i]);
328
+ // WGSL's `inverseSqrt`. Spelled as the reciprocal of a root rather than approximated,
329
+ // because the reference is the definition the hardware's estimate is measured against.
330
+ case RSQRT:
331
+ for (let i = 0; i < w; i++) d[i] = 1 / Math.sqrt(a[i]);
332
+ break;
333
+ case TAN:
334
+ for (let i = 0; i < w; i++) d[i] = Math.tan(a[i]);
335
+ break;
336
+ case ASIN:
337
+ for (let i = 0; i < w; i++) d[i] = Math.asin(a[i]);
338
+ break;
339
+ case ACOS:
340
+ for (let i = 0; i < w; i++) d[i] = Math.acos(a[i]);
341
+ break;
342
+ // `y` first, as `Math.atan2` and WGSL's `atan2` both take it.
343
+ case ATAN2:
344
+ for (let i = 0; i < w; i++) d[i] = Math.atan2(a[i], b[i]);
213
345
  break;
214
346
 
215
- // The reductions write a single lane. Whatever wants the result wider gets an explicit
216
- // broadcast from the compiler; the implicit fill-all-four is gone.
217
- case VM_OP.DOT: {
347
+ // The reductions write a single lane; whatever wants the result wider reads it through
348
+ // an `.xxxx` swizzle.
349
+ case DOT: {
218
350
  let dp = 0;
219
- for (let i = 0; i < w; i++) dp += reg[a + i] * reg[b + i];
220
- reg[d] = dp;
351
+ for (let i = 0; i < w; i++) dp += a[i] * b[i];
352
+ d[0] = dp;
221
353
  break;
222
354
  }
223
- case VM_OP.CROSS: {
224
- // Read both sources out before writing: the destination is allowed to be one of them.
225
- const ax = reg[a], ay = reg[a + 1], az = reg[a + 2];
226
- const bx = reg[b], by = reg[b + 1], bz = reg[b + 2];
227
- reg[d] = ay * bz - az * by;
228
- reg[d + 1] = az * bx - ax * bz;
229
- reg[d + 2] = ax * by - ay * bx;
355
+ case CROSS:
356
+ d[0] = a[1] * b[2] - a[2] * b[1];
357
+ d[1] = a[2] * b[0] - a[0] * b[2];
358
+ d[2] = a[0] * b[1] - a[1] * b[0];
230
359
  // A fourth lane, if asked for, is the zero the opcode used to append.
231
- for (let i = 3; i < w; i++) reg[d + i] = 0;
360
+ d[3] = 0;
232
361
  break;
233
- }
234
- case VM_OP.LENGTH: {
362
+ case LENGTH: {
235
363
  let sum = 0;
236
- for (let i = 0; i < w; i++) sum += reg[a + i] * reg[a + i];
237
- reg[d] = Math.sqrt(sum);
364
+ for (let i = 0; i < w; i++) sum += a[i] * a[i];
365
+ d[0] = Math.sqrt(sum);
238
366
  break;
239
367
  }
240
- case VM_OP.NORMALIZE: {
368
+ case NORMALIZE: {
241
369
  let sum = 0;
242
- for (let i = 0; i < w; i++) sum += reg[a + i] * reg[a + i];
370
+ for (let i = 0; i < w; i++) sum += a[i] * a[i];
243
371
  const len = Math.sqrt(sum);
244
372
  const inv = len > 0 ? 1 / len : 0;
245
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] * inv;
373
+ for (let i = 0; i < w; i++) d[i] = a[i] * inv;
246
374
  break;
247
375
  }
248
- case VM_OP.DISTANCE: {
376
+ case DISTANCE: {
249
377
  let sum = 0;
250
378
  for (let i = 0; i < w; i++) {
251
- const e = reg[a + i] - reg[b + i];
379
+ const e = a[i] - b[i];
252
380
  sum += e * e;
253
381
  }
254
- reg[d] = Math.sqrt(sum);
255
- break;
256
- }
257
- case VM_OP.SWIZZLE: {
258
- // Selected lanes are read before any is written, so an in-place swizzle is safe.
259
- const pattern = s1;
260
- const l0 = reg[a + (pattern & 3)];
261
- const l1 = reg[a + ((pattern >> 2) & 3)];
262
- const l2 = reg[a + ((pattern >> 4) & 3)];
263
- const l3 = reg[a + ((pattern >> 6) & 3)];
264
- if (w > 0) reg[d] = l0;
265
- if (w > 1) reg[d + 1] = l1;
266
- if (w > 2) reg[d + 2] = l2;
267
- if (w > 3) reg[d + 3] = l3;
382
+ d[0] = Math.sqrt(sum);
268
383
  break;
269
384
  }
270
385
 
271
- case VM_OP.CMP_LT:
272
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] < reg[b + i] ? 1 : 0;
386
+ case CMP_LT:
387
+ for (let i = 0; i < w; i++) d[i] = a[i] < b[i] ? 1 : 0;
273
388
  break;
274
- case VM_OP.CMP_LE:
275
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] <= reg[b + i] ? 1 : 0;
389
+ case CMP_LE:
390
+ for (let i = 0; i < w; i++) d[i] = a[i] <= b[i] ? 1 : 0;
276
391
  break;
277
- case VM_OP.CMP_GT:
278
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] > reg[b + i] ? 1 : 0;
392
+ case CMP_GT:
393
+ for (let i = 0; i < w; i++) d[i] = a[i] > b[i] ? 1 : 0;
279
394
  break;
280
- case VM_OP.CMP_GE:
281
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] >= reg[b + i] ? 1 : 0;
395
+ case CMP_GE:
396
+ for (let i = 0; i < w; i++) d[i] = a[i] >= b[i] ? 1 : 0;
282
397
  break;
283
- case VM_OP.CMP_EQ:
284
- for (let i = 0; i < w; i++) reg[d + i] = reg[a + i] === reg[b + i] ? 1 : 0;
398
+ case CMP_EQ:
399
+ for (let i = 0; i < w; i++) d[i] = a[i] === b[i] ? 1 : 0;
285
400
  break;
286
- case VM_OP.SELECT:
287
- for (let i = 0; i < w; i++) reg[d + i] = reg[c + i] > 0.5 ? reg[b + i] : reg[a + i];
401
+ case SELECT:
402
+ for (let i = 0; i < w; i++) d[i] = c[i] > 0.5 ? b[i] : a[i];
288
403
  break;
289
404
 
290
- // One draw per lane. Draw counts are part of the program's meaning — the draws are a
291
- // sequence, so one fewer moves every value after it — and with distributions gone the
292
- // count is exactly the width.
293
- case VM_OP.RANDOM:
294
- for (let i = 0; i < w; i++) reg[d + i] = draw_unit();
405
+ // One draw per lane, in lane order. Draw counts are part of the program's meaning — the
406
+ // draws are a sequence, so one fewer moves every value after it.
407
+ case RANDOM:
408
+ for (let i = 0; i < w; i++) d[i] = draw_unit();
295
409
  break;
296
410
 
297
- case VM_OP.CURVE: {
298
- const v = sampleCurve(s0, reg[b]);
299
- for (let i = 0; i < w; i++) reg[d + i] = v;
411
+ case CURVE: {
412
+ const v = sampleCurve(s0, b[0]);
413
+ for (let i = 0; i < w; i++) d[i] = v;
300
414
  break;
301
415
  }
302
416
 
303
417
  default:
304
418
  throw new Error(`ParticleVMReference: unhandled opcode ${op} at pc ${pc}`);
305
419
  }
420
+
421
+ const fixed_dest = OP_DEST[op];
422
+ const dest = fixed_dest < 0 ? w : fixed_dest;
423
+
424
+ for (let i = 0; i < dest; i++) {
425
+ reg[dst + i] = d[i];
426
+ }
306
427
  }
307
428
 
308
429
  return { killed, rng_state: state };
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_particle_vm.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/chunk_particle_vm.js"],"names":[],"mappings":"AAmXA;;;GAGG;AACH,gCAFU,SAAS,CAEqD;0BAvX9C,oCAAoC"}
1
+ {"version":3,"file":"chunk_particle_vm.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/chunk_particle_vm.js"],"names":[],"mappings":"AA6UA;;;GAGG;AACH,gCAFU,SAAS,CAEmG;0BAhV5F,oCAAoC"}