@woosh/meep-engine 3.16.0 → 3.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  4. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  7. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  10. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  11. package/editor/view/node-graph/NodeGraphView.js +84 -8
  12. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  15. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  16. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  17. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  20. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  22. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  25. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  27. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  28. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  29. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  30. package/editor/view/particles/effect/particle-editor.css +123 -35
  31. package/package.json +1 -1
  32. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  34. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  35. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  37. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  38. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  39. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  40. package/src/core/graph/csr/CSRGraph.js +14 -6
  41. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  44. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  47. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  50. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  53. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  55. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  56. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  57. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  59. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  62. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  65. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  68. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  71. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  74. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  77. package/src/engine/animation/AnimationUtils.js +246 -246
  78. package/src/engine/animation/Animations.js +74 -74
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  80. package/src/engine/ecs/EventType.d.ts +0 -1
  81. package/src/engine/ecs/EventType.js +1 -26
  82. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  85. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  86. package/src/engine/ecs/parent/EntityNode.js +4 -9
  87. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  89. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  93. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  95. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  96. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  97. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  98. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  99. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  100. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  101. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  102. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  103. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  104. package/src/engine/graphics3/LightSystem.js +4 -8
  105. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/MeshSystem.js +9 -19
  107. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  109. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  111. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  112. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  113. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  114. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  115. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  116. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  117. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  118. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  119. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  120. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  121. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  122. package/src/shade/playground/particle_editor/README.md +43 -2
  123. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  124. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  125. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  126. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  127. package/src/shade/renderer/Renderer.js +13 -1
  128. package/src/shade/renderer/particles/DESIGN.md +104 -19
  129. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  130. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  132. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  133. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  134. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  135. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  136. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  137. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  138. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  139. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  140. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  141. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  142. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  143. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  144. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  145. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  146. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  148. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  149. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  151. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  153. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  155. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  157. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  159. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  161. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  162. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  163. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  164. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  165. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  166. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  168. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  169. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  170. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  171. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  172. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  174. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  175. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  177. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  178. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  179. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  180. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  181. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  182. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  183. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  185. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  186. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/graph_particles.js +105 -262
  188. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  189. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  190. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  191. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  192. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  193. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  194. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  196. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  197. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  198. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  199. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  200. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  202. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  203. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  205. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  206. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  207. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  208. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  209. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  210. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  211. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  212. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  213. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  214. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  215. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  216. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  217. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  218. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  219. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  220. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  221. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  222. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  223. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  224. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  225. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  226. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  227. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  228. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  229. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  230. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  235. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  236. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  237. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  238. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  239. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  240. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  241. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  242. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  244. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  245. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  246. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  247. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  248. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  250. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  251. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  252. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  253. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  254. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  255. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  256. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  257. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  258. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  259. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  261. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  262. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  263. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  264. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  265. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  266. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  267. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  268. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  270. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  271. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  272. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  273. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  274. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  275. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  276. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  277. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  278. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  279. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  280. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  281. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  282. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  283. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  285. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  286. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  287. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  288. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  289. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  291. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
  292. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
  293. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  294. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  295. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  296. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  297. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  298. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  299. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  300. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  302. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  303. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  305. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  306. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  307. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  308. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  309. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  310. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  311. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  312. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  314. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  315. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  317. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  318. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  320. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  321. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  323. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  324. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  325. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  326. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  327. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  328. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  329. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  330. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  331. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  332. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  333. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  334. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  335. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  336. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  337. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  338. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  339. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  340. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  341. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  342. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  343. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  344. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  345. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  346. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  347. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  348. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  349. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  350. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  351. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  352. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  353. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  354. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  355. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  356. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  357. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  374. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  375. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  376. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  377. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  378. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  379. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  380. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  381. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  382. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  383. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  384. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  385. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  386. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  387. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  388. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  389. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  390. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  391. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  392. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  393. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  394. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  395. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  396. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  397. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  398. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  399. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  400. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  401. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  402. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  403. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  404. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  405. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  406. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  407. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  408. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  409. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  410. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
@@ -1,303 +1,303 @@
1
- import { PortDirection } from "../../../../core/model/node-graph/node/PortDirection.js";
2
- import { ParticleNodeGroup } from "./ParticleNodeGroup.js";
3
- import { get_particle_node_description, PARTICLE_NODE_OUTPUT_PORT } from "./ParticleNodeRegistry.js";
4
- import {
5
- particle_node_default_parameters,
6
- PARTICLE_NODES_WITHOUT_PARAMETERS,
7
- } from "./particle_node_parameters.js";
8
-
9
- /**
10
- * Writing a node group's body in JavaScript.
11
- *
12
- * A group like `simplex3` is two hundred nodes. Assembling that by hand — create a node, look up a
13
- * port id, create a connection, repeat — is unreadable and unreviewable, and the thing being written
14
- * is an expression, which JavaScript already spells perfectly well. So this builds the graph out of
15
- * calls: `g.mul(g.sub(x, low), scale)` creates three nodes and two wires, and reads as what it
16
- * computes.
17
- *
18
- * Every stock operation that takes no parameters of its own is a method here, taken from the library
19
- * rather than listed — a type added to it is callable the same day. The rest — `const`, `swizzle`,
20
- * `random`, `curve` and the attribute nodes — need a parameter and are reached through
21
- * {@link #op}, or through the shorthands below where there is an obvious one.
22
- *
23
- * A number where a value is expected becomes a literal, so `g.mul(v, 0.5)` is what it looks like.
24
- *
25
- * Each mention of a number is its own node, deliberately. Sharing one would be fewer instructions and
26
- * a great deal worse: a value's registers are held from where it is produced to its last reader, so a
27
- * `2.0` shared between the first line of a body and the last would pin its slots across the whole
28
- * group. The register file is the scarce thing here — see
29
- * {@link ../ParticleConstants.js PARTICLE_VM_REGISTER_SLOTS} — and the constant pool interns the
30
- * words anyway, so what the duplication costs is one `LOAD_CONST` and nothing else.
31
- *
32
- * ## What comes back
33
- *
34
- * Every call returns a **port reference** — a node and one of its output ports — which is the thing
35
- * wires are made between. Multi-output nodes (another group) hand back a map of them.
36
- */
37
- export class ParticleGroupBuilder {
38
- /**
39
- * The group being built.
40
- * @type {ParticleNodeGroup}
41
- */
42
- group;
43
-
44
- /**
45
- * The group's inputs, by name: what the body reads its arguments from.
46
- * @type {Object<string, {node: NodeInstance, port: Port}>}
47
- */
48
- in = {};
49
-
50
- /**
51
- * @param {object} options see {@link ParticleNodeGroup.create}
52
- */
53
- constructor(options) {
54
- this.group = ParticleNodeGroup.create(options);
55
-
56
- for (const port of this.group.description.inPorts) {
57
- // the input block's port of the same name: inside the group, an input is read from
58
- this.in[port.name] = {
59
- node: this.group.inputNode,
60
- port: this.group.inputNode.description.findPortByNameAndDirection(port.name, PortDirection.Out),
61
- };
62
- }
63
-
64
- for (const name of PARTICLE_NODES_WITHOUT_PARAMETERS) {
65
- if (this[name] !== undefined) {
66
- continue;
67
- }
68
-
69
- this[name] = (...args) => this.op(name, args);
70
- }
71
- }
72
-
73
- /**
74
- * Create one node of a stock type, wired to the values given.
75
- *
76
- * Arguments are matched to the type's input ports in declaration order — which is the order the
77
- * library declares its operands in, so `op("mad", [a, b, c])` is `a * b + c`. A number stands in
78
- * for a literal of that number.
79
- *
80
- * @param {string} type node type name
81
- * @param {Array<{node: NodeInstance, port: Port}|number>} [args] one per input port, in order
82
- * @param {object} [parameters] overrides on top of the type's defaults
83
- * @returns {{node: NodeInstance, port: Port}} the node's `out` port
84
- */
85
- op(type, args = [], parameters = {}) {
86
- const description = get_particle_node_description(type);
87
-
88
- const node = this.#create(description, parameters);
89
-
90
- const ports = description.inPorts;
91
-
92
- if (args.length !== ports.length) {
93
- throw new Error(
94
- `'${type}' takes ${ports.length} input${ports.length === 1 ? "" : "s"} `
95
- + `(${ports.map(port => port.name).join(", ") || "none"}), given ${args.length}.`
96
- );
97
- }
98
-
99
- ports.forEach((port, index) => this.#wire(this.#value(args[index]), node, port));
100
-
101
- return { node, port: description.findPortByNameAndDirection(PARTICLE_NODE_OUTPUT_PORT, PortDirection.Out) };
102
- }
103
-
104
- /**
105
- * Create one instance of another group, wired to the values given by name.
106
- *
107
- * How a group is built out of groups: `curl3` is twelve `simplex3`s and the arithmetic between
108
- * them, and says so.
109
- *
110
- * @param {ParticleNodeGroup} group
111
- * @param {Object<string, {node: NodeInstance, port: Port}|number>} args value per input port name
112
- * @returns {Object<string, {node: NodeInstance, port: Port}>} a reference per output port name
113
- */
114
- call(group, args = {}) {
115
- const description = group.description;
116
-
117
- const node = this.#create(description, {});
118
-
119
- for (const port of description.inPorts) {
120
- const argument = args[port.name];
121
-
122
- if (argument === undefined) {
123
- throw new Error(`Group '${group.name}' has an input '${port.name}' and nothing was given for it.`);
124
- }
125
-
126
- this.#wire(this.#value(argument), node, port);
127
- }
128
-
129
- const result = {};
130
-
131
- for (const port of description.outPorts) {
132
- result[port.name] = { node, port };
133
- }
134
-
135
- return result;
136
- }
137
-
138
- /**
139
- * A literal. One number is a scalar; several are a vector as wide as there are of them.
140
- *
141
- * @param {...number} components
142
- * @returns {{node: NodeInstance, port: Port}}
143
- */
144
- f(...components) {
145
- return this.op("const", [], { value: components.slice() });
146
- }
147
-
148
- /**
149
- * Pick and reorder lanes, spelled the way the assembly spells it.
150
- *
151
- * @param {{node: NodeInstance, port: Port}|number} value
152
- * @param {string} pattern one to four of `xyzw`
153
- * @returns {{node: NodeInstance, port: Port}}
154
- */
155
- swz(value, pattern) {
156
- const lanes = Array.from(pattern).map(lane => "xyzw".indexOf(lane));
157
-
158
- if (lanes.length === 0 || lanes.some(lane => lane === -1)) {
159
- throw new Error(`'${pattern}' is not a swizzle: one to four of x, y, z, w.`);
160
- }
161
-
162
- return this.op("swizzle", [value], { pattern: lanes });
163
- }
164
-
165
- /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
166
- x(v) {
167
- return this.swz(v, "x");
168
- }
169
-
170
- /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
171
- y(v) {
172
- return this.swz(v, "y");
173
- }
174
-
175
- /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
176
- z(v) {
177
- return this.swz(v, "z");
178
- }
179
-
180
- /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
181
- w(v) {
182
- return this.swz(v, "w");
183
- }
184
-
185
- /**
186
- * A value read as a builtin the host provides.
187
- *
188
- * @param {number} id a {@link ../isa/ParticleVMISA.js VM_BUILTIN}
189
- * @returns {{node: NodeInstance, port: Port}}
190
- */
191
- builtin(id) {
192
- return this.op("builtin", [], { id });
193
- }
194
-
195
- /**
196
- * Expose a value as one of the group's outputs.
197
- *
198
- * @param {string} name one of the group's declared output ports
199
- * @param {{node: NodeInstance, port: Port}|number} value
200
- * @returns {void}
201
- */
202
- out(name, value) {
203
- const outputNode = this.group.outputNode;
204
-
205
- const port = outputNode.description.findPortByNameAndDirection(name, PortDirection.In);
206
-
207
- if (port === undefined) {
208
- throw new Error(
209
- `Group '${this.group.name}' has no output called '${name}'. It has: `
210
- + `${this.group.outputs.map(o => o.name).join(", ") || "none"}.`
211
- );
212
- }
213
-
214
- this.#wire(this.#value(value), outputNode, port);
215
- }
216
-
217
- /**
218
- * Finish the group, having checked that it is one.
219
- *
220
- * Everything caught here is caught at the moment the library loads, which is where a broken
221
- * built-in group should fail: a group missing an output is a node whose result is nothing, and
222
- * finding that out at the far end of a compile in somebody's editor is finding it out too late.
223
- *
224
- * @returns {ParticleNodeGroup}
225
- */
226
- build() {
227
- const group = this.group;
228
-
229
- for (const port of group.outputNode.description.inPorts) {
230
- const wired = group.outputNode.getEndpoint(port.id).inConnections.length;
231
-
232
- if (wired !== 1) {
233
- throw new Error(
234
- `Group '${group.name}' output '${port.name}' has ${wired} sources; it takes exactly one.`
235
- );
236
- }
237
- }
238
-
239
- for (const node of group.graph.getNodes()) {
240
- if (node === group.inputNode || node === group.outputNode) {
241
- continue;
242
- }
243
-
244
- for (const port of node.description.inPorts) {
245
- if (node.getEndpoint(port.id).inConnections.length !== 1) {
246
- throw new Error(
247
- `Group '${group.name}': input '${port.name}' of a '${node.description.name}' `
248
- + "is not wired to exactly one source."
249
- );
250
- }
251
- }
252
- }
253
-
254
- return group;
255
- }
256
-
257
- /**
258
- * @param {ParticleNodeDescription} description
259
- * @param {object} parameters
260
- * @returns {NodeInstance}
261
- */
262
- #create(description, parameters) {
263
- const graph = this.group.graph;
264
-
265
- const node = graph.getNodeSafe(graph.createNode(description));
266
-
267
- // the type's own defaults underneath, so a body written before a type gained a parameter
268
- // still builds a node that compiles
269
- node.setParameters({
270
- ...(description.isParticleGroupNodeDescription === true
271
- ? {}
272
- : particle_node_default_parameters(description.name)),
273
- ...parameters,
274
- });
275
-
276
- return node;
277
- }
278
-
279
- /**
280
- * @param {{node: NodeInstance, port: Port}|number} value
281
- * @returns {{node: NodeInstance, port: Port}}
282
- */
283
- #value(value) {
284
- if (typeof value === "number") {
285
- return this.f(value);
286
- }
287
-
288
- if (value === undefined || value === null || value.node === undefined || value.port === undefined) {
289
- throw new Error(`Group '${this.group.name}': ${value} is not a value.`);
290
- }
291
-
292
- return value;
293
- }
294
-
295
- /**
296
- * @param {{node: NodeInstance, port: Port}} source
297
- * @param {NodeInstance} node
298
- * @param {Port} port
299
- */
300
- #wire(source, node, port) {
301
- this.group.graph.createConnection(source.node.id, source.port.id, node.id, port.id);
302
- }
303
- }
1
+ import { PortDirection } from "../../../../core/model/node-graph/node/PortDirection.js";
2
+ import { ParticleNodeGroup } from "./ParticleNodeGroup.js";
3
+ import { get_particle_node_description, PARTICLE_NODE_OUTPUT_PORT } from "./ParticleNodeRegistry.js";
4
+ import {
5
+ particle_node_default_parameters,
6
+ PARTICLE_NODES_WITHOUT_PARAMETERS,
7
+ } from "./particle_node_parameters.js";
8
+
9
+ /**
10
+ * Writing a node group's body in JavaScript.
11
+ *
12
+ * A group like `simplex3` is two hundred nodes. Assembling that by hand — create a node, look up a
13
+ * port id, create a connection, repeat — is unreadable and unreviewable, and the thing being written
14
+ * is an expression, which JavaScript already spells perfectly well. So this builds the graph out of
15
+ * calls: `g.mul(g.sub(x, low), scale)` creates three nodes and two wires, and reads as what it
16
+ * computes.
17
+ *
18
+ * Every stock operation that takes no parameters of its own is a method here, taken from the library
19
+ * rather than listed — a type added to it is callable the same day. The rest — `const`, `swizzle`,
20
+ * `random`, `curve` and the attribute nodes — need a parameter and are reached through
21
+ * {@link #op}, or through the shorthands below where there is an obvious one.
22
+ *
23
+ * A number where a value is expected becomes a literal, so `g.mul(v, 0.5)` is what it looks like.
24
+ *
25
+ * Each mention of a number is its own node, deliberately. Sharing one would be fewer instructions and
26
+ * a great deal worse: a value's registers are held from where it is produced to its last reader, so a
27
+ * `2.0` shared between the first line of a body and the last would pin its slots across the whole
28
+ * group. The fast interpreter's register file is the scarce thing here — see
29
+ * {@link ../ParticleConstants.js PARTICLE_VM_FAST_REGISTER_SLOTS} — and the constant pool interns
30
+ * the words anyway, so what the duplication costs is one `LOAD_CONST` and nothing else.
31
+ *
32
+ * ## What comes back
33
+ *
34
+ * Every call returns a **port reference** — a node and one of its output ports — which is the thing
35
+ * wires are made between. Multi-output nodes (another group) hand back a map of them.
36
+ */
37
+ export class ParticleGroupBuilder {
38
+ /**
39
+ * The group being built.
40
+ * @type {ParticleNodeGroup}
41
+ */
42
+ group;
43
+
44
+ /**
45
+ * The group's inputs, by name: what the body reads its arguments from.
46
+ * @type {Object<string, {node: NodeInstance, port: Port}>}
47
+ */
48
+ in = {};
49
+
50
+ /**
51
+ * @param {object} options see {@link ParticleNodeGroup.create}
52
+ */
53
+ constructor(options) {
54
+ this.group = ParticleNodeGroup.create(options);
55
+
56
+ for (const port of this.group.description.inPorts) {
57
+ // the input block's port of the same name: inside the group, an input is read from
58
+ this.in[port.name] = {
59
+ node: this.group.inputNode,
60
+ port: this.group.inputNode.description.findPortByNameAndDirection(port.name, PortDirection.Out),
61
+ };
62
+ }
63
+
64
+ for (const name of PARTICLE_NODES_WITHOUT_PARAMETERS) {
65
+ if (this[name] !== undefined) {
66
+ continue;
67
+ }
68
+
69
+ this[name] = (...args) => this.op(name, args);
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Create one node of a stock type, wired to the values given.
75
+ *
76
+ * Arguments are matched to the type's input ports in declaration order — which is the order the
77
+ * library declares its operands in, so `op("mad", [a, b, c])` is `a * b + c`. A number stands in
78
+ * for a literal of that number.
79
+ *
80
+ * @param {string} type node type name
81
+ * @param {Array<{node: NodeInstance, port: Port}|number>} [args] one per input port, in order
82
+ * @param {object} [parameters] overrides on top of the type's defaults
83
+ * @returns {{node: NodeInstance, port: Port}} the node's `out` port
84
+ */
85
+ op(type, args = [], parameters = {}) {
86
+ const description = get_particle_node_description(type);
87
+
88
+ const node = this.#create(description, parameters);
89
+
90
+ const ports = description.inPorts;
91
+
92
+ if (args.length !== ports.length) {
93
+ throw new Error(
94
+ `'${type}' takes ${ports.length} input${ports.length === 1 ? "" : "s"} `
95
+ + `(${ports.map(port => port.name).join(", ") || "none"}), given ${args.length}.`
96
+ );
97
+ }
98
+
99
+ ports.forEach((port, index) => this.#wire(this.#value(args[index]), node, port));
100
+
101
+ return { node, port: description.findPortByNameAndDirection(PARTICLE_NODE_OUTPUT_PORT, PortDirection.Out) };
102
+ }
103
+
104
+ /**
105
+ * Create one instance of another group, wired to the values given by name.
106
+ *
107
+ * How a group is built out of groups: `curl3` is twelve `simplex3`s and the arithmetic between
108
+ * them, and says so.
109
+ *
110
+ * @param {ParticleNodeGroup} group
111
+ * @param {Object<string, {node: NodeInstance, port: Port}|number>} args value per input port name
112
+ * @returns {Object<string, {node: NodeInstance, port: Port}>} a reference per output port name
113
+ */
114
+ call(group, args = {}) {
115
+ const description = group.description;
116
+
117
+ const node = this.#create(description, {});
118
+
119
+ for (const port of description.inPorts) {
120
+ const argument = args[port.name];
121
+
122
+ if (argument === undefined) {
123
+ throw new Error(`Group '${group.name}' has an input '${port.name}' and nothing was given for it.`);
124
+ }
125
+
126
+ this.#wire(this.#value(argument), node, port);
127
+ }
128
+
129
+ const result = {};
130
+
131
+ for (const port of description.outPorts) {
132
+ result[port.name] = { node, port };
133
+ }
134
+
135
+ return result;
136
+ }
137
+
138
+ /**
139
+ * A literal. One number is a scalar; several are a vector as wide as there are of them.
140
+ *
141
+ * @param {...number} components
142
+ * @returns {{node: NodeInstance, port: Port}}
143
+ */
144
+ f(...components) {
145
+ return this.op("const", [], { value: components.slice() });
146
+ }
147
+
148
+ /**
149
+ * Pick and reorder lanes, spelled the way the assembly spells it.
150
+ *
151
+ * @param {{node: NodeInstance, port: Port}|number} value
152
+ * @param {string} pattern one to four of `xyzw`
153
+ * @returns {{node: NodeInstance, port: Port}}
154
+ */
155
+ swz(value, pattern) {
156
+ const lanes = Array.from(pattern).map(lane => "xyzw".indexOf(lane));
157
+
158
+ if (lanes.length === 0 || lanes.some(lane => lane === -1)) {
159
+ throw new Error(`'${pattern}' is not a swizzle: one to four of x, y, z, w.`);
160
+ }
161
+
162
+ return this.op("swizzle", [value], { pattern: lanes });
163
+ }
164
+
165
+ /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
166
+ x(v) {
167
+ return this.swz(v, "x");
168
+ }
169
+
170
+ /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
171
+ y(v) {
172
+ return this.swz(v, "y");
173
+ }
174
+
175
+ /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
176
+ z(v) {
177
+ return this.swz(v, "z");
178
+ }
179
+
180
+ /** @param {{node: NodeInstance, port: Port}|number} v @returns {{node: NodeInstance, port: Port}} */
181
+ w(v) {
182
+ return this.swz(v, "w");
183
+ }
184
+
185
+ /**
186
+ * A value read as a builtin the host provides.
187
+ *
188
+ * @param {number} id a {@link ../isa/ParticleVMISA.js VM_BUILTIN}
189
+ * @returns {{node: NodeInstance, port: Port}}
190
+ */
191
+ builtin(id) {
192
+ return this.op("builtin", [], { id });
193
+ }
194
+
195
+ /**
196
+ * Expose a value as one of the group's outputs.
197
+ *
198
+ * @param {string} name one of the group's declared output ports
199
+ * @param {{node: NodeInstance, port: Port}|number} value
200
+ * @returns {void}
201
+ */
202
+ out(name, value) {
203
+ const outputNode = this.group.outputNode;
204
+
205
+ const port = outputNode.description.findPortByNameAndDirection(name, PortDirection.In);
206
+
207
+ if (port === undefined) {
208
+ throw new Error(
209
+ `Group '${this.group.name}' has no output called '${name}'. It has: `
210
+ + `${this.group.outputs.map(o => o.name).join(", ") || "none"}.`
211
+ );
212
+ }
213
+
214
+ this.#wire(this.#value(value), outputNode, port);
215
+ }
216
+
217
+ /**
218
+ * Finish the group, having checked that it is one.
219
+ *
220
+ * Everything caught here is caught at the moment the library loads, which is where a broken
221
+ * built-in group should fail: a group missing an output is a node whose result is nothing, and
222
+ * finding that out at the far end of a compile in somebody's editor is finding it out too late.
223
+ *
224
+ * @returns {ParticleNodeGroup}
225
+ */
226
+ build() {
227
+ const group = this.group;
228
+
229
+ for (const port of group.outputNode.description.inPorts) {
230
+ const wired = group.outputNode.getEndpoint(port.id).inConnections.length;
231
+
232
+ if (wired !== 1) {
233
+ throw new Error(
234
+ `Group '${group.name}' output '${port.name}' has ${wired} sources; it takes exactly one.`
235
+ );
236
+ }
237
+ }
238
+
239
+ for (const node of group.graph.getNodes()) {
240
+ if (node === group.inputNode || node === group.outputNode) {
241
+ continue;
242
+ }
243
+
244
+ for (const port of node.description.inPorts) {
245
+ if (node.getEndpoint(port.id).inConnections.length !== 1) {
246
+ throw new Error(
247
+ `Group '${group.name}': input '${port.name}' of a '${node.description.name}' `
248
+ + "is not wired to exactly one source."
249
+ );
250
+ }
251
+ }
252
+ }
253
+
254
+ return group;
255
+ }
256
+
257
+ /**
258
+ * @param {ParticleNodeDescription} description
259
+ * @param {object} parameters
260
+ * @returns {NodeInstance}
261
+ */
262
+ #create(description, parameters) {
263
+ const graph = this.group.graph;
264
+
265
+ const node = graph.getNodeSafe(graph.createNode(description));
266
+
267
+ // the type's own defaults underneath, so a body written before a type gained a parameter
268
+ // still builds a node that compiles
269
+ node.setParameters({
270
+ ...(description.isParticleGroupNodeDescription === true
271
+ ? {}
272
+ : particle_node_default_parameters(description.name)),
273
+ ...parameters,
274
+ });
275
+
276
+ return node;
277
+ }
278
+
279
+ /**
280
+ * @param {{node: NodeInstance, port: Port}|number} value
281
+ * @returns {{node: NodeInstance, port: Port}}
282
+ */
283
+ #value(value) {
284
+ if (typeof value === "number") {
285
+ return this.f(value);
286
+ }
287
+
288
+ if (value === undefined || value === null || value.node === undefined || value.port === undefined) {
289
+ throw new Error(`Group '${this.group.name}': ${value} is not a value.`);
290
+ }
291
+
292
+ return value;
293
+ }
294
+
295
+ /**
296
+ * @param {{node: NodeInstance, port: Port}} source
297
+ * @param {NodeInstance} node
298
+ * @param {Port} port
299
+ */
300
+ #wire(source, node, port) {
301
+ this.group.graph.createConnection(source.node.id, source.port.id, node.id, port.id);
302
+ }
303
+ }
@@ -145,6 +145,24 @@ export class ParticleNodeDescription extends NodeDescription {
145
145
  operation_width: number;
146
146
  type: ParticleValueType | null;
147
147
  }) => number;
148
+ /**
149
+ * Build the body this node stands for, out of stock types, given its own parameters — or `null`
150
+ * for a type that lowers itself.
151
+ *
152
+ * A {@link ./ParticleNodeGroup.js group} is one node made of many whose body is fixed when the
153
+ * group is built. Some node types are one node made of many whose body is decided by the
154
+ * *instance*: a gradient with five stops is different arithmetic from a gradient with two, so
155
+ * there is no single body to build in advance and nothing for a group to hold. Such a type
156
+ * declares this instead, and {@link ./flatten_particle_graph.js} calls it and splices the result
157
+ * in exactly as it splices a group — so everything downstream sees stock arithmetic, and
158
+ * register allocation, sub-expression sharing and the optimizer all apply to it unchanged.
159
+ *
160
+ * The group that comes back has to carry the same port names this description does: they are
161
+ * what the wires around the node are re-made against.
162
+ *
163
+ * @type {function(object):import("./ParticleNodeGroup.js").ParticleNodeGroup|null}
164
+ */
165
+ expand: (arg0: object) => import("./ParticleNodeGroup.js").ParticleNodeGroup | null;
148
166
  /**
149
167
  * A node with no output ports produces no value, so nothing can consume it; the only reason to
150
168
  * emit it is its side effect (an attribute write, a kill). Such nodes are the roots the compiler
@@ -1 +1 @@
1
- {"version":3,"file":"ParticleNodeDescription.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/graph/ParticleNodeDescription.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH;IAEI;;;;;;;;;OASG;IACH,MAFU,MAAM,CAEN;IAEV;;;;;;;;;;;;;;;OAeG;IACH,sCAFsC;QAAC,EAAE,SAAW,MAAM,KAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAC,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAC;QAAC,WAAW;gBAAS,MAAM;UAAqB;QAAC,YAAY;gBAAS,MAAM;UAAqB;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,iBAAiB;QAAC,GAAG,oBAAmB;KAAC,KAAE,IAAI,CAEtS;IAEZ;;;;;;;;;;;;;;;;;OAiBG;IACH,oBAFmB;QAAC,MAAM;gBAAS,MAAM,GAAE,oBAAkB,IAAI;UAAE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,iBAAe,SAAS,CAAA;KAAC,KAAE;QAAC,MAAM,EAAE,oBAAkB,IAAI,CAAC;QAAC,MAAM;gBAAS,MAAM,GAAE,oBAAkB,IAAI;UAAC;KAAC,CAYzM;IAEF;;;;;;;;;;;OAWG;IACH,wBAFmB;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAC;QAAC,WAAW;gBAAS,MAAM;UAAqB;QAAC,YAAY;gBAAS,MAAM;UAAqB;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,iBAAgB;KAAC,KAAE,MAAM,CAE5I;IAE1E;;;;;;;;;OASG;IACH,qBAFmB;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAC;QAAC,WAAW;gBAAS,MAAM;UAAqB;QAAC,YAAY;gBAAS,MAAM;UAAqB;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,iBAAgB;KAAC;YAAS,MAAM,GAAE,MAAM;MAEpN;IAE1B;;;;;OAKG;IACH,qBAFmB;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAA;KAAC,KAAE,MAAM,CAE1B;IAExD;;;;;OAKG;IACH,uBAEC;IAGL;;;OAGG;IACH,oCAFU,OAAO,CAE0C;CAN1D;gCA7H+B,2DAA2D"}
1
+ {"version":3,"file":"ParticleNodeDescription.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/graph/ParticleNodeDescription.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH;IAEI;;;;;;;;;OASG;IACH,MAFU,MAAM,CAEN;IAEV;;;;;;;;;;;;;;;OAeG;IACH,sCAFsC;QAAC,EAAE,SAAW,MAAM,KAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAC,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAC;QAAC,WAAW;gBAAS,MAAM;UAAqB;QAAC,YAAY;gBAAS,MAAM;UAAqB;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,iBAAiB;QAAC,GAAG,oBAAmB;KAAC,KAAE,IAAI,CAEtS;IAEZ;;;;;;;;;;;;;;;;;OAiBG;IACH,oBAFmB;QAAC,MAAM;gBAAS,MAAM,GAAE,oBAAkB,IAAI;UAAE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,iBAAe,SAAS,CAAA;KAAC,KAAE;QAAC,MAAM,EAAE,oBAAkB,IAAI,CAAC;QAAC,MAAM;gBAAS,MAAM,GAAE,oBAAkB,IAAI;UAAC;KAAC,CAYzM;IAEF;;;;;;;;;;;OAWG;IACH,wBAFmB;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAC;QAAC,WAAW;gBAAS,MAAM;UAAqB;QAAC,YAAY;gBAAS,MAAM;UAAqB;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,iBAAgB;KAAC,KAAE,MAAM,CAE5I;IAE1E;;;;;;;;;OASG;IACH,qBAFmB;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAC;QAAC,WAAW;gBAAS,MAAM;UAAqB;QAAC,YAAY;gBAAS,MAAM;UAAqB;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,iBAAgB;KAAC;YAAS,MAAM,GAAE,MAAM;MAEpN;IAE1B;;;;;OAKG;IACH,qBAFmB;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,oBAAkB,IAAI,CAAA;KAAC,KAAE,MAAM,CAE1B;IAExD;;;;;;;;;;;;;;;;OAgBG;IACH,eAFmB,MAAM,KAAE,OAAO,wBAAwB,EAAE,iBAAiB,GAAC,IAAI,CAEpE;IAEd;;;;;OAKG;IACH,uBAEC;IAGL;;;OAGG;IACH,oCAFU,OAAO,CAE0C;CAN1D;gCAhJ+B,2DAA2D"}