@woosh/meep-engine 3.16.0 → 3.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  4. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  7. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  10. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  11. package/editor/view/node-graph/NodeGraphView.js +84 -8
  12. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  15. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  16. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  17. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  20. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  22. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  25. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  27. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  28. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  29. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  30. package/editor/view/particles/effect/particle-editor.css +123 -35
  31. package/package.json +1 -1
  32. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  34. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  35. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  37. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  38. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  39. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  40. package/src/core/graph/csr/CSRGraph.js +14 -6
  41. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  44. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  47. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  50. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  53. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  55. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  56. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  57. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  59. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  62. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  65. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  68. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  71. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  74. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  77. package/src/engine/animation/AnimationUtils.js +246 -246
  78. package/src/engine/animation/Animations.js +74 -74
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  80. package/src/engine/ecs/EventType.d.ts +0 -1
  81. package/src/engine/ecs/EventType.js +1 -26
  82. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  85. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  86. package/src/engine/ecs/parent/EntityNode.js +4 -9
  87. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  89. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  93. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  95. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  96. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  97. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  98. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  99. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  100. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  101. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  102. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  103. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  104. package/src/engine/graphics3/LightSystem.js +4 -8
  105. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/MeshSystem.js +9 -19
  107. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  109. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  111. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  112. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  113. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  114. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  115. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  116. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  117. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  118. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  119. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  120. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  121. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  122. package/src/shade/playground/particle_editor/README.md +43 -2
  123. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  124. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  125. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  126. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  127. package/src/shade/renderer/Renderer.js +13 -1
  128. package/src/shade/renderer/particles/DESIGN.md +104 -19
  129. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  130. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  132. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  133. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  134. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  135. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  136. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  137. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  138. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  139. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  140. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  141. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  142. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  143. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  144. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  145. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  146. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  148. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  149. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  151. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  153. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  155. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  157. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  159. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  161. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  162. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  163. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  164. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  165. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  166. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  168. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  169. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  170. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  171. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  172. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  174. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  175. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  177. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  178. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  179. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  180. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  181. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  182. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  183. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  185. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  186. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/graph_particles.js +105 -262
  188. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  189. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  190. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  191. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  192. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  193. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  194. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  196. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  197. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  198. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  199. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  200. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  202. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  203. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  205. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  206. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  207. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  208. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  209. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  210. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  211. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  212. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  213. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  214. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  215. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  216. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  217. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  218. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  219. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  220. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  221. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  222. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  223. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  224. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  225. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  226. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  227. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  228. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  229. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  230. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  235. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  236. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  237. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  238. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  239. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  240. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  241. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  242. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  244. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  245. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  246. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  247. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  248. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  250. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  251. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  252. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  253. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  254. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  255. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  256. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  257. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  258. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  259. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  261. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  262. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  263. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  264. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  265. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  266. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  267. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  268. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  270. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  271. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  272. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  273. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  274. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  275. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  276. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  277. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  278. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  279. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  280. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  281. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  282. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  283. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  285. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  286. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  287. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  288. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  289. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  291. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
  292. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
  293. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  294. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  295. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  296. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  297. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  298. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  299. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  300. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  302. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  303. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  305. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  306. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  307. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  308. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  309. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  310. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  311. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  312. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  314. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  315. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  317. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  318. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  320. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  321. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  323. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  324. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  325. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  326. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  327. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  328. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  329. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  330. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  331. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  332. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  333. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  334. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  335. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  336. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  337. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  338. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  339. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  340. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  341. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  342. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  343. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  344. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  345. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  346. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  347. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  348. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  349. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  350. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  351. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  352. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  353. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  354. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  355. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  356. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  357. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  374. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  375. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  376. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  377. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  378. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  379. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  380. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  381. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  382. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  383. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  384. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  385. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  386. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  387. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  388. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  389. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  390. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  391. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  392. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  393. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  394. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  395. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  396. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  397. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  398. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  399. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  400. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  401. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  402. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  403. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  404. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  405. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  406. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  407. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  408. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  409. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  410. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Simplex noise whose gradients turn with `alpha`, with its exact derivative, and no period.
3
+ *
4
+ * `psrdnoise3` with the wrap deleted, which is what the missing `if` costs — see the note at the top
5
+ * of this file. It still repeats every 289 cells, because that is the hash's modulus rather than a
6
+ * choice; "non-periodic" here means only that it does not tile to a period you name.
7
+ *
8
+ * @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
9
+ */
10
+ export const PARTICLE_GROUP_SRDNOISE_3: import("../ParticleNodeGroup.js").ParticleNodeGroup;
11
+ /**
12
+ * The same field, tiling to a period you give it.
13
+ *
14
+ * Any whole period up to 289 works on each axis independently; an axis at or below zero does not
15
+ * wrap, and all three at zero is {@link PARTICLE_GROUP_SRDNOISE_3} computed the long way — use that
16
+ * node instead, it is the cheaper one. 289 is a hard ceiling, being the hash's modulus: a longer
17
+ * period does not tile, it repeats inside itself.
18
+ *
19
+ * @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
20
+ */
21
+ export const PARTICLE_GROUP_PSRDNOISE_3: import("../ParticleNodeGroup.js").ParticleNodeGroup;
22
+ //# sourceMappingURL=particle_groups_psrdnoise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"particle_groups_psrdnoise.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js"],"names":[],"mappings":"AAwbA;;;;;;;;GAQG;AACH,wCAFU,OAAO,yBAAyB,EAAE,iBAAiB,CA4BxD;AAEL;;;;;;;;;GASG;AACH,yCAFU,OAAO,yBAAyB,EAAE,iBAAiB,CA+BxD"}
@@ -0,0 +1,517 @@
1
+ import { ParticleGroupBuilder } from "../ParticleGroupBuilder.js";
2
+ import { PARTICLE_TYPE_F32, PARTICLE_TYPE_VEC3 } from "../ParticleValueType.js";
3
+
4
+ /**
5
+ * psrdnoise: simplex noise with rotating gradients, an exact derivative, and an optional period.
6
+ *
7
+ * The engine already has this as a shader chunk — see
8
+ * {@link ../../../shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js} — and this is the same function
9
+ * for the particle VM, transcribed from the same source. Three things separate it from the
10
+ * {@link ./particle_groups_noise.js simplex noise} already here, and each of them is a reason to
11
+ * spend the instructions:
12
+ *
13
+ * - **The gradient comes out with the value.** `w³·(g·x)` differentiates by the product rule into
14
+ * things already computed, so the derivative is a handful of multiply-adds rather than three more
15
+ * evaluations. A curl built on this needs *two* samples where {@link ./particle_groups_noise.js
16
+ * curl3} needs twelve, which is the difference between a curl an UPDATE graph can afford and one
17
+ * it cannot.
18
+ * - **The gradients are a spiral, not a table.** Classic simplex noise picks each corner's gradient
19
+ * out of a small fixed set, and the set's directions show up in the field as faint preferred axes.
20
+ * Here the hash is read as a point on a Fibonacci spiral over the unit sphere: 289 directions, no
21
+ * axis favoured.
22
+ * - **`alpha` turns the gradients.** Animate it and the field swirls in place instead of sliding
23
+ * past — flow noise, which is a different thing from noise sampled at a moving point.
24
+ *
25
+ * psrdnoise (c) 2021 Stefan Gustavson and Ian McEwan. Published under the MIT license.
26
+ * @see https://github.com/stegu/psrdnoise/
27
+ *
28
+ * ## What the VM's lack of control flow costs, and what it does not
29
+ *
30
+ * The shader has two branches and neither survives here, but only one of them was worth anything.
31
+ *
32
+ * `alpha == 0` takes a shortcut in the shader that skips the rotation. The general path *is* that
33
+ * shortcut when `alpha` is zero — `cos(0)` is 1 and `sin(0)` is 0, so the gradient comes out the
34
+ * spiral point unchanged — so it is written once, always, and is exactly right either way. The
35
+ * shortcut only ever bought speed, and only when a whole warp agreed on it; here there are no warps
36
+ * and no branches for them to agree about.
37
+ *
38
+ * The per-axis wrap, `if (period.x > 0.0)`, becomes arithmetic. Multiplying by `1/period` — with the
39
+ * reciprocal set to **zero** where no period was asked for — makes the wrap `v - floor(v·0)·p`,
40
+ * which is `v`. So it always runs, does nothing when it is not wanted, and has no divide by zero to
41
+ * guard: the reciprocal is built once, up front, out of a comparison against zero.
42
+ *
43
+ * The outer `if (any(period > 0.0))`, which skips the whole wrap, has no branchless equivalent worth
44
+ * having. It becomes a *second node*: {@link PARTICLE_GROUP_SRDNOISE_3} is this function with the
45
+ * wrap deleted, exactly as `chunk_srdnoise3` is. That is the adaptation the missing control flow
46
+ * actually forces, and it is the one upstream made for the same reason.
47
+ *
48
+ * ## Why it is written transposed, and where it stops being
49
+ *
50
+ * The four corners' lattice coordinates are carried as three `vec4`s — all four x coordinates, then
51
+ * all four y, then all four z — rather than as four `vec3`s. That is the layout the hash wants (one
52
+ * permutation of four corners at once, not four of one), and the layout the wrap wants too: skewing,
53
+ * unskewing and wrapping are all element-wise in it, so each is three `vec4` instructions instead of
54
+ * four `vec3` ones plus the shuffling between.
55
+ *
56
+ * The corner *offsets* are the other way round, one corner at a time, because that half is a sum
57
+ * over corners and holding four of everything through it is what would put this over the register
58
+ * file. Same reasoning as the note on the subject in {@link ./particle_groups_noise.js}.
59
+ *
60
+ * The periodic node needs one more turn of that screw, and it is not about *when* things are built —
61
+ * the compiler emits a value where it is first read, not where it was written down — but about
62
+ * whether they are built **twice**. Skewing is element-wise in the transposed layout, so each of the
63
+ * three wrapped lattice axes wants two of the three wrapped texture axes, and computing the three
64
+ * texture axes once and sharing them keeps twelve registers alive across the whole wrap. Computing
65
+ * each one where it is used, six times for three distinct values, keeps two alive instead of three
66
+ * and gives every one of them a live range a few instructions long. That trade — a third again as
67
+ * much arithmetic for eight slots — is the difference between a node that compiles and a node that
68
+ * reports it has run out of registers, which is the only exchange rate that matters at 48 slots.
69
+ */
70
+
71
+ /**
72
+ * The permutation polynomial's modulus: 17², and the period every psrdnoise field has whether or not
73
+ * one was asked for.
74
+ * @type {number}
75
+ */
76
+ const PERMUTE_MODULUS = 289;
77
+
78
+ /**
79
+ * How much a corner's ramp is scaled to fill `[-1, 1]`. Upstream's number, and it applies to the
80
+ * derivative as well as to the value.
81
+ * @type {number}
82
+ */
83
+ const NOISE_SCALE = 39.5;
84
+
85
+ /**
86
+ * The squared radius of a corner's support: far enough that the four corners cover the cell between
87
+ * them, near enough that no corner outside it ever reaches in.
88
+ * @type {number}
89
+ */
90
+ const CORNER_SUPPORT = 0.5;
91
+
92
+ /**
93
+ * `x mod 289`, without a modulo opcode: `x - floor(x / 289) * 289`.
94
+ *
95
+ * Divided rather than multiplied by a reciprocal, unlike the `mod289` in
96
+ * {@link ./particle_groups_noise.js}. It costs the same — one instruction, and 289 is then the same
97
+ * interned word both times — and a divide is correctly rounded where `x * fround(1/289)` rounds
98
+ * twice. The result decides which gradient a corner is handed, so the cheaper spelling would be
99
+ * paying in the one currency this function cannot spend.
100
+ *
101
+ * @param {ParticleGroupBuilder} g
102
+ * @param {*} x
103
+ * @returns {*}
104
+ */
105
+ function mod289(g, x) {
106
+ return g.sub(x, g.mul(g.floor(g.div(x, g.f(PERMUTE_MODULUS))), g.f(PERMUTE_MODULUS)));
107
+ }
108
+
109
+ /**
110
+ * The permutation: `(34x + 10)x mod 289`, over four corners at once.
111
+ *
112
+ * A bijection on `[0, 289)` rather than merely a hash — no two lattice coordinates collide, so no
113
+ * two corners of a cell are handed the same gradient. Its input is reduced first, which is what
114
+ * keeps `(34x + 10)x` inside the range an `f32` holds exactly.
115
+ *
116
+ * @param {ParticleGroupBuilder} g
117
+ * @param {*} x
118
+ * @returns {*}
119
+ */
120
+ function permute(g, x) {
121
+ const reduced = mod289(g, x);
122
+
123
+ return mod289(g, g.mul(g.mad(reduced, g.f(34), g.f(10)), reduced));
124
+ }
125
+
126
+ /**
127
+ * Texture space to psrdnoise's simplex space: `(y + z, z + x, x + y)`.
128
+ *
129
+ * The lattice this generates is axis-aligned with the space being sampled rather than skewed away
130
+ * from it, which is the whole reason a rectangular period can be imposed on this noise at all.
131
+ *
132
+ * @param {ParticleGroupBuilder} g
133
+ * @param {*} v a `vec3`
134
+ * @returns {*} a `vec3`
135
+ */
136
+ function skew(g, v) {
137
+ return g.vec3(
138
+ g.add(g.y(v), g.z(v)),
139
+ g.add(g.z(v), g.x(v)),
140
+ g.add(g.x(v), g.y(v))
141
+ );
142
+ }
143
+
144
+ /**
145
+ * Simplex space back to texture space: `0.5 * (y + z - x, z + x - y, x + y - z)`, the inverse of
146
+ * {@link skew}. Its inputs here are always integers and the factor is a power of two, so it is
147
+ * exact.
148
+ *
149
+ * @param {ParticleGroupBuilder} g
150
+ * @param {*} i a `vec3`
151
+ * @returns {*} a `vec3`
152
+ */
153
+ function unskew(g, i) {
154
+ const half = axis => g.mul(axis, g.f(0.5));
155
+
156
+ return g.vec3(
157
+ half(g.sub(g.add(g.y(i), g.z(i)), g.x(i))),
158
+ half(g.sub(g.add(g.z(i), g.x(i)), g.y(i))),
159
+ half(g.sub(g.add(g.x(i), g.y(i)), g.z(i)))
160
+ );
161
+ }
162
+
163
+ /**
164
+ * Where the sample point is, in terms of the simplex it falls in.
165
+ *
166
+ * `i0` is the base corner of the skewed cell, and `o1` and `o2` are the two steps from it to the
167
+ * second and third corners — the point's coordinates inside the cell, rank-ordered, since the
168
+ * descending order of the fractional parts is the order the tetrahedron's corners are walked in. The
169
+ * fourth corner is always `i0 + 1`.
170
+ *
171
+ * The same three steps are then carried in texture space as well, unskewed. `base` is where the
172
+ * cell's own corner sits, `step1` and `step2` are how far the second and third are from it, and the
173
+ * fourth is half a unit along every axis whatever the cell is. Both halves are wanted: the lattice
174
+ * coordinates are what gets hashed, and the texture-space ones are what the corner offsets and the
175
+ * wrap are measured in. Carrying them as a base and two steps rather than as four positions is what
176
+ * keeps this to nine registers instead of twelve.
177
+ *
178
+ * @param {ParticleGroupBuilder} g
179
+ * @param {*} x the sample point, a `vec3`
180
+ * @returns {{i0: *, o1: *, o2: *, base: *, step1: *, step2: *, offset: function(number):*}}
181
+ */
182
+ function simplex_of(g, x) {
183
+ const uvw = skew(g, x);
184
+
185
+ const i0 = g.floor(uvw);
186
+ const f0 = g.sub(uvw, i0);
187
+
188
+ const gt_ = g.step(g.swz(f0, "xyx"), g.swz(f0, "yzz"));
189
+ const lt_ = g.sub(g.f(1), gt_);
190
+
191
+ const gt = g.vec3(g.z(lt_), g.x(gt_), g.y(gt_));
192
+ const lt = g.vec3(g.x(lt_), g.y(lt_), g.z(gt_));
193
+
194
+ const o1 = g.min(gt, lt);
195
+ const o2 = g.max(gt, lt);
196
+
197
+ const base = unskew(g, i0);
198
+ const step1 = unskew(g, o1);
199
+ const step2 = unskew(g, o2);
200
+
201
+ // The vector from the cell's own corner to the point, which every corner offset is that minus
202
+ // the corner's own step. Taken here so that `x` and `base` both die before the hash begins.
203
+ const from_base = g.sub(x, base);
204
+
205
+ return {
206
+ i0,
207
+ o1,
208
+ o2,
209
+ base,
210
+ step1,
211
+ step2,
212
+
213
+ /**
214
+ * The vector from one corner to the sample point.
215
+ *
216
+ * Four separate values, each read once, so only one is ever live: what is shared between
217
+ * them — `from_base` — is three registers rather than twelve.
218
+ *
219
+ * @param {number} corner 0 to 3
220
+ * @returns {*} a `vec3`
221
+ */
222
+ offset: corner => [
223
+ () => from_base,
224
+ () => g.sub(from_base, step1),
225
+ () => g.sub(from_base, step2),
226
+ () => g.sub(from_base, g.f(0.5)),
227
+ ][corner](),
228
+ };
229
+ }
230
+
231
+ /**
232
+ * One axis of the four corners' lattice coordinates, as a `vec4`: `i0`, `i0 + o1`, `i0 + o2` and
233
+ * `i0 + 1`, all in one lane of the cell.
234
+ *
235
+ * @param {ParticleGroupBuilder} g
236
+ * @param {{i0: *, o1: *, o2: *}} simplex
237
+ * @param {string} axis `"x"`, `"y"` or `"z"`
238
+ * @returns {*} a `vec4`
239
+ */
240
+ function lattice_axis(g, simplex, axis) {
241
+ const steps = g.vec4(g.f(0), g.swz(simplex.o1, axis), g.swz(simplex.o2, axis), g.f(1));
242
+
243
+ return g.add(g.swz(simplex.i0, axis), steps);
244
+ }
245
+
246
+ /**
247
+ * One axis of the four corners' positions in *texture* space, as a `vec4`, wrapped to that axis's
248
+ * period.
249
+ *
250
+ * The wrap has to happen here rather than in simplex space, because it is here that the period is a
251
+ * rectangle. `reciprocal` is `1/period` where a period was asked for and zero where it was not,
252
+ * which is what makes one expression cover both: `v - floor(v·0)·p` is `v`.
253
+ *
254
+ * @param {ParticleGroupBuilder} g
255
+ * @param {{base: *, step1: *, step2: *}} simplex
256
+ * @param {*} period a `vec3`
257
+ * @param {*} reciprocal a `vec3`
258
+ * @param {string} axis
259
+ * @returns {*} a `vec4`
260
+ */
261
+ function wrapped_texture_axis(g, simplex, period, reciprocal, axis) {
262
+ const corners = g.vec4(
263
+ g.f(0),
264
+ g.swz(simplex.step1, axis),
265
+ g.swz(simplex.step2, axis),
266
+ // the fourth corner is `i0 + 1` in simplex space, which unskews to half a unit along every
267
+ // axis — a constant, whatever cell this is
268
+ g.f(0.5)
269
+ );
270
+
271
+ const v = g.add(g.swz(simplex.base, axis), corners);
272
+
273
+ return g.sub(v, g.mul(g.floor(g.mul(v, g.swz(reciprocal, axis))), g.swz(period, axis)));
274
+ }
275
+
276
+ /**
277
+ * One axis of the four corners' lattice coordinates after the wrap: the wrapped texture-space
278
+ * corners, skewed back.
279
+ *
280
+ * Skewing is element-wise in this layout — the x of `skew(v)` is `v.y + v.z` — so one axis of the
281
+ * answer wants two axes of the input, and this builds both of them rather than being handed all
282
+ * three. Two axes alive instead of three is four registers, and the third would have to stay alive
283
+ * across a permutation to be worth keeping. The `+ 0.5` under the floor is a round-to-nearest: the
284
+ * wrap leaves a corner a hair off the integer it should be, and truncating would drop it into the
285
+ * neighbouring cell.
286
+ *
287
+ * Only the hash inputs move. The offsets the kernel sums are measured from the *unwrapped* corners,
288
+ * which is what keeps the field continuous across the seam.
289
+ *
290
+ * @param {ParticleGroupBuilder} g
291
+ * @param {{base: *, step1: *, step2: *}} simplex
292
+ * @param {*} period
293
+ * @param {*} reciprocal
294
+ * @param {string} axis
295
+ * @returns {*} a `vec4`
296
+ */
297
+ function wrapped_lattice_axis(g, simplex, period, reciprocal, axis) {
298
+ const [first, second] = { x: ["y", "z"], y: ["z", "x"], z: ["x", "y"] }[axis];
299
+
300
+ const sum = g.add(
301
+ wrapped_texture_axis(g, simplex, period, reciprocal, first),
302
+ wrapped_texture_axis(g, simplex, period, reciprocal, second)
303
+ );
304
+
305
+ return g.floor(g.add(sum, g.f(0.5)));
306
+ }
307
+
308
+ /**
309
+ * `1/period` per axis, and zero on an axis with no period — see {@link wrapped_texture_axis}.
310
+ *
311
+ * `max(period, 1)` only keeps the divide honest on the axes whose answer is about to be multiplied
312
+ * by zero anyway; the comparison is what decides.
313
+ *
314
+ * @param {ParticleGroupBuilder} g
315
+ * @param {*} period a `vec3`
316
+ * @returns {*} a `vec3`
317
+ */
318
+ function period_reciprocal(g, period) {
319
+ return g.div(g.op("compare", [period, g.f(0)], { op: "gt" }), g.max(period, g.f(1)));
320
+ }
321
+
322
+ /**
323
+ * One corner's gradient, read off its hash.
324
+ *
325
+ * The hash is a position on a Fibonacci spiral over the unit sphere — `theta` around it, `sz` up —
326
+ * and `alpha` then turns that point by that many radians about a pseudo-random axis orthogonal to
327
+ * it, which `psi` picks out. `p` is the spiral point and `q` the orthogonal direction, so the two
328
+ * span the plane of the rotation and the answer is `cos(alpha)·p + sin(alpha)·q`.
329
+ *
330
+ * At `alpha == 0` that is `p` exactly, which is why there is no branch — see the note at the top of
331
+ * this file.
332
+ *
333
+ * @param {ParticleGroupBuilder} g
334
+ * @param {*} hash one corner's hashed index, a scalar in `[0, 289)`
335
+ * @param {{sin: *, cos: *}} rotation `alpha`'s sine and cosine, taken once for all four corners
336
+ * @returns {*} a `vec3` unit gradient
337
+ */
338
+ function corner_gradient(g, hash, rotation) {
339
+ // 2*pi / the golden ratio: the spiral's turn per step
340
+ const theta = g.mul(hash, g.f(3.883222077));
341
+ // the point's height on the sphere, 1 - (hash + 0.5) * 2/289
342
+ const sz = g.mad(hash, g.f(-0.006920415), g.f(0.996539792));
343
+ // 10*pi/289 — a rotation phase chosen not to correlate with theta
344
+ const psi = g.mul(hash, g.f(0.108705628));
345
+
346
+ const ct = g.cos(theta);
347
+ const st = g.sin(theta);
348
+
349
+ // the spiral point's radius off the axis
350
+ const radius = g.sqrt(g.sub(g.f(1), g.mul(sz, sz)));
351
+
352
+ const sp = g.sin(psi);
353
+ const cp = g.cos(psi);
354
+
355
+ const px = g.mul(ct, radius);
356
+ const py = g.mul(st, radius);
357
+ const pz = sz;
358
+
359
+ const ctp = g.sub(g.mul(st, sp), g.mul(ct, cp));
360
+
361
+ const qx = g.mix(g.mul(ctp, st), sp, sz);
362
+ const qy = g.mix(g.neg(g.mul(ctp, ct)), cp, sz);
363
+ const qz = g.neg(g.add(g.mul(py, cp), g.mul(px, sp)));
364
+
365
+ return g.vec3(
366
+ g.mad(rotation.cos, px, g.mul(rotation.sin, qx)),
367
+ g.mad(rotation.cos, py, g.mul(rotation.sin, qy)),
368
+ g.mad(rotation.cos, pz, g.mul(rotation.sin, qz))
369
+ );
370
+ }
371
+
372
+ /**
373
+ * The sum over corners: the noise value and its exact first derivative.
374
+ *
375
+ * Each corner contributes `w³·(g·x)`, where `w` is a radial falloff that reaches zero at the edge of
376
+ * that corner's support. The derivative is that product differentiated — `d(w³) = 3w²·dw` and
377
+ * `dw = -2x` — which is why it costs multiply-adds and no transcendentals at all: everything in it
378
+ * was computed for the value.
379
+ *
380
+ * `axis_of` is asked for z, then y, then x, and one at a time: the hash folds one axis in between
381
+ * each permutation, so an axis built up front would sit in registers waiting through work that does
382
+ * not need it. See the note about the transposed layout at the top of this file.
383
+ *
384
+ * @param {ParticleGroupBuilder} g
385
+ * @param {function(string):*} axis_of one axis of the four corners' lattice coordinates, as a `vec4`
386
+ * @param {function(number):*} offset_of the vector from corner `k` to the sample point
387
+ * @param {*} alpha
388
+ * @returns {{value: *, gradient: *}}
389
+ */
390
+ function psrdnoise_kernel(g, axis_of, offset_of, alpha) {
391
+ // One value per corner. Folding one axis in between each permutation is what makes three
392
+ // coordinates a single hash rather than three independent ones.
393
+ let hash = permute(g, axis_of("z"));
394
+
395
+ hash = permute(g, g.add(hash, axis_of("y")));
396
+ hash = permute(g, g.add(hash, axis_of("x")));
397
+
398
+ // `alpha` is the same for every corner, so its sine and cosine are taken once.
399
+ const rotation = { sin: g.sin(alpha), cos: g.cos(alpha) };
400
+
401
+ let value = null;
402
+ let gradient = null;
403
+
404
+ ["x", "y", "z", "w"].forEach((lane, corner) => {
405
+ const direction = corner_gradient(g, g.swz(hash, lane), rotation);
406
+
407
+ const offset = offset_of(corner);
408
+
409
+ const w = g.max(g.sub(g.f(CORNER_SUPPORT), g.dot(offset, offset)), g.f(0));
410
+ const w2 = g.mul(w, w);
411
+ const w3 = g.mul(w2, w);
412
+
413
+ const ramp = g.dot(direction, offset);
414
+
415
+ const contribution = g.mul(w3, ramp);
416
+
417
+ const slope = g.add(
418
+ g.scale(direction, w3),
419
+ g.scale(offset, g.mul(g.mul(g.f(-6), w2), ramp))
420
+ );
421
+
422
+ value = value === null ? contribution : g.add(value, contribution);
423
+ gradient = gradient === null ? slope : g.add(gradient, slope);
424
+ });
425
+
426
+ return {
427
+ value: g.mul(value, g.f(NOISE_SCALE)),
428
+ gradient: g.scale(gradient, g.f(NOISE_SCALE)),
429
+ };
430
+ }
431
+
432
+ /**
433
+ * What both nodes produce.
434
+ * @type {Array<{name: string, type: import("../ParticleValueType.js").ParticleValueType}>}
435
+ */
436
+ const NOISE_OUTPUTS = [
437
+ { name: "out", type: PARTICLE_TYPE_F32 },
438
+ { name: "gradient", type: PARTICLE_TYPE_VEC3 },
439
+ ];
440
+
441
+ /**
442
+ * Simplex noise whose gradients turn with `alpha`, with its exact derivative, and no period.
443
+ *
444
+ * `psrdnoise3` with the wrap deleted, which is what the missing `if` costs — see the note at the top
445
+ * of this file. It still repeats every 289 cells, because that is the hash's modulus rather than a
446
+ * choice; "non-periodic" here means only that it does not tile to a period you name.
447
+ *
448
+ * @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
449
+ */
450
+ export const PARTICLE_GROUP_SRDNOISE_3 = (() => {
451
+ const g = new ParticleGroupBuilder({
452
+ name: "srdnoise3",
453
+ label: "Flow Noise 3D",
454
+ icon: "M4 13c3-6 6 4 9-2s5-4 7-6 M4 20c3-6 6 4 9-2s5-4 7-6",
455
+ help: "noise whose gradients turn with alpha, plus its exact derivative — read both and it is most of the register file",
456
+ inputs: [
457
+ { name: "p", type: PARTICLE_TYPE_VEC3 },
458
+ { name: "alpha", type: PARTICLE_TYPE_F32 },
459
+ ],
460
+ outputs: NOISE_OUTPUTS,
461
+ });
462
+
463
+ const simplex = simplex_of(g, g.in.p);
464
+
465
+ const noise = psrdnoise_kernel(
466
+ g,
467
+ axis => lattice_axis(g, simplex, axis),
468
+ corner => simplex.offset(corner),
469
+ g.in.alpha
470
+ );
471
+
472
+ g.out("out", noise.value);
473
+ g.out("gradient", noise.gradient);
474
+
475
+ return g.build();
476
+ })();
477
+
478
+ /**
479
+ * The same field, tiling to a period you give it.
480
+ *
481
+ * Any whole period up to 289 works on each axis independently; an axis at or below zero does not
482
+ * wrap, and all three at zero is {@link PARTICLE_GROUP_SRDNOISE_3} computed the long way — use that
483
+ * node instead, it is the cheaper one. 289 is a hard ceiling, being the hash's modulus: a longer
484
+ * period does not tile, it repeats inside itself.
485
+ *
486
+ * @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
487
+ */
488
+ export const PARTICLE_GROUP_PSRDNOISE_3 = (() => {
489
+ const g = new ParticleGroupBuilder({
490
+ name: "psrdnoise3",
491
+ label: "Tiling Flow Noise 3D",
492
+ icon: "M3 4h18v16H3z M6 11c2-4 4 3 6-1s3-3 6-4",
493
+ help: "flow noise that tiles to a whole period, per axis — expensive, and the wrap is not free",
494
+ inputs: [
495
+ { name: "p", type: PARTICLE_TYPE_VEC3 },
496
+ { name: "period", type: PARTICLE_TYPE_VEC3 },
497
+ { name: "alpha", type: PARTICLE_TYPE_F32 },
498
+ ],
499
+ outputs: NOISE_OUTPUTS,
500
+ });
501
+
502
+ const simplex = simplex_of(g, g.in.p);
503
+
504
+ const reciprocal = period_reciprocal(g, g.in.period);
505
+
506
+ const noise = psrdnoise_kernel(
507
+ g,
508
+ axis => wrapped_lattice_axis(g, simplex, g.in.period, reciprocal, axis),
509
+ corner => simplex.offset(corner),
510
+ g.in.alpha
511
+ );
512
+
513
+ g.out("out", noise.value);
514
+ g.out("gradient", noise.gradient);
515
+
516
+ return g.build();
517
+ })();
@@ -1 +1 @@
1
- {"version":3,"file":"simplex_reference.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/particles/graph/groups/simplex_reference.js"],"names":[],"mappings":"AA+EA;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,GACN,MAAM,CA2ElB"}
1
+ {"version":3,"file":"simplex_reference.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/particles/graph/groups/simplex_reference.js"],"names":[],"mappings":"AAyGA;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,GACN,MAAM,CA2ElB"}