@woosh/meep-engine 3.14.6 → 3.16.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 (1089) hide show
  1. package/editor/Editor.js +7 -7
  2. package/editor/actions/concrete/TransformModifyAction.d.ts +4 -4
  3. package/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
  4. package/editor/actions/concrete/TransformModifyAction.js +4 -4
  5. package/editor/camera/camera_framing.js +7 -7
  6. package/editor/ecs/component/editors/ecs/Transform64Editor.d.ts +20 -0
  7. package/editor/ecs/component/editors/ecs/Transform64Editor.d.ts.map +1 -0
  8. package/editor/ecs/component/editors/ecs/Transform64Editor.js +70 -0
  9. package/editor/ecs/component/prototypeObjectEditor.js +2 -2
  10. package/editor/ecs/component/registerEngineComponentEditors.js +3 -3
  11. package/editor/particles/effect/ParticleEffectDocument.d.ts +396 -0
  12. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -0
  13. package/editor/particles/effect/ParticleEffectDocument.js +989 -0
  14. package/editor/particles/effect/ParticleReferenceSimulation.d.ts +113 -0
  15. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -0
  16. package/editor/particles/effect/ParticleReferenceSimulation.js +377 -0
  17. package/editor/particles/effect/actions/ParticleGroupDefineAction.d.ts +35 -0
  18. package/editor/particles/effect/actions/ParticleGroupDefineAction.d.ts.map +1 -0
  19. package/editor/particles/effect/actions/ParticleGroupDefineAction.js +45 -0
  20. package/editor/particles/effect/make_starter_particle_effect.d.ts +23 -0
  21. package/editor/particles/effect/make_starter_particle_effect.d.ts.map +1 -0
  22. package/editor/particles/effect/make_starter_particle_effect.js +177 -0
  23. package/editor/persistence/buildNewSceneDataset.d.ts.map +1 -1
  24. package/editor/persistence/buildNewSceneDataset.js +10 -8
  25. package/editor/process/symbolic/AudioEmitterSymbolicDisplay.js +67 -67
  26. package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
  27. package/editor/process/symbolic/GridPositionSymbolicDisplay.js +6 -6
  28. package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
  29. package/editor/process/symbolic/ParticleEmitterSymbolicDisplay.d.ts.map +1 -1
  30. package/editor/process/symbolic/ParticleEmitterSymbolicDisplay.js +6 -3
  31. package/editor/process/symbolic/PositionedMarkerSymbolicDisplay.js +6 -6
  32. package/editor/selection/editor_pick.js +130 -130
  33. package/editor/templates/entity_templates.js +7 -7
  34. package/editor/tools/TransformToolV2.d.ts +3 -3
  35. package/editor/tools/TransformToolV2.d.ts.map +1 -1
  36. package/editor/tools/TransformToolV2.js +58 -25
  37. package/editor/tools/paint/TerrainHeightPaintTool.d.ts.map +1 -1
  38. package/editor/tools/paint/TerrainHeightPaintTool.js +11 -9
  39. package/editor/tools/v2/GizmoNode.js +2 -2
  40. package/editor/tools/v2/TransformControls.d.ts +3 -3
  41. package/editor/tools/v2/TransformControls.d.ts.map +1 -1
  42. package/editor/tools/v2/TransformControls.js +1003 -971
  43. package/editor/tools/v2/handle/gizmo_drag_plane.d.ts.map +1 -1
  44. package/editor/tools/v2/handle/gizmo_drag_plane.js +6 -1
  45. package/editor/view/ecs/components/common/AutoCanvasView.js +17 -0
  46. package/editor/view/node-graph/NodeGraphEditorView.d.ts +143 -2
  47. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  48. package/editor/view/node-graph/NodeGraphEditorView.js +358 -6
  49. package/editor/view/node-graph/NodeGraphMinimapView.d.ts +120 -0
  50. package/editor/view/node-graph/NodeGraphMinimapView.d.ts.map +1 -0
  51. package/editor/view/node-graph/NodeGraphMinimapView.js +859 -0
  52. package/editor/view/node-graph/NodeGraphPaletteView.d.ts +112 -0
  53. package/editor/view/node-graph/NodeGraphPaletteView.d.ts.map +1 -0
  54. package/editor/view/node-graph/NodeGraphPaletteView.js +352 -0
  55. package/editor/view/node-graph/NodeGraphSearchMenuView.d.ts +76 -0
  56. package/editor/view/node-graph/NodeGraphSearchMenuView.d.ts.map +1 -0
  57. package/editor/view/node-graph/NodeGraphSearchMenuView.js +247 -0
  58. package/editor/view/node-graph/NodeGraphView.d.ts +147 -5
  59. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  60. package/editor/view/node-graph/NodeGraphView.js +809 -76
  61. package/editor/view/node-graph/NodeIconView.d.ts +33 -0
  62. package/editor/view/node-graph/NodeIconView.d.ts.map +1 -0
  63. package/editor/view/node-graph/NodeIconView.js +54 -0
  64. package/editor/view/node-graph/NodeView.d.ts +71 -1
  65. package/editor/view/node-graph/NodeView.d.ts.map +1 -1
  66. package/editor/view/node-graph/NodeView.js +318 -17
  67. package/editor/view/node-graph/PortView.d.ts +41 -1
  68. package/editor/view/node-graph/PortView.d.ts.map +1 -1
  69. package/editor/view/node-graph/PortView.js +121 -69
  70. package/editor/view/node-graph/actions/ConnectionDeleteAction.d.ts +16 -3
  71. package/editor/view/node-graph/actions/ConnectionDeleteAction.d.ts.map +1 -1
  72. package/editor/view/node-graph/actions/ConnectionDeleteAction.js +29 -3
  73. package/editor/view/node-graph/actions/NodeCreateAction.d.ts +65 -0
  74. package/editor/view/node-graph/actions/NodeCreateAction.d.ts.map +1 -0
  75. package/editor/view/node-graph/actions/NodeCreateAction.js +108 -0
  76. package/editor/view/node-graph/actions/NodeDeleteAction.d.ts +6 -0
  77. package/editor/view/node-graph/actions/NodeDeleteAction.d.ts.map +1 -1
  78. package/editor/view/node-graph/actions/NodeDeleteAction.js +24 -2
  79. package/editor/view/node-graph/connection_wire_geometry.d.ts +34 -0
  80. package/editor/view/node-graph/connection_wire_geometry.d.ts.map +1 -1
  81. package/editor/view/node-graph/connection_wire_geometry.js +79 -3
  82. package/editor/view/node-graph/node-graph.css +678 -0
  83. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts +37 -0
  84. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -0
  85. package/editor/view/particles/effect/ParticleCodeEditorView.js +479 -0
  86. package/editor/view/particles/effect/ParticleEffectEditorView.d.ts +61 -0
  87. package/editor/view/particles/effect/ParticleEffectEditorView.d.ts.map +1 -0
  88. package/editor/view/particles/effect/ParticleEffectEditorView.js +223 -0
  89. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts +25 -0
  90. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -0
  91. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +606 -0
  92. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +156 -0
  93. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -0
  94. package/editor/view/particles/effect/ParticleGraphEditorView.js +1636 -0
  95. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts +22 -0
  96. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -0
  97. package/editor/view/particles/effect/ParticleNodeParametersView.js +520 -0
  98. package/editor/view/particles/effect/ParticlePreviewView.d.ts +52 -0
  99. package/editor/view/particles/effect/ParticlePreviewView.d.ts.map +1 -0
  100. package/editor/view/particles/effect/ParticlePreviewView.js +533 -0
  101. package/editor/view/particles/effect/particle-editor.css +556 -0
  102. package/editor/view/prepareMeshLibrary.d.ts.map +1 -1
  103. package/editor/view/prepareMeshLibrary.js +8 -4
  104. package/package.json +1 -1
  105. package/samples/engine/first-scene/main.js +152 -152
  106. package/samples/generation/generators/mir_generator_place_bases.js +3 -3
  107. package/src/core/assert.d.ts +28 -24
  108. package/src/core/assert.d.ts.map +1 -1
  109. package/src/core/assert.js +34 -26
  110. package/src/core/geom/3d/shape/PosedShape3D.d.ts +17 -0
  111. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  112. package/src/core/geom/3d/shape/PosedShape3D.js +34 -2
  113. package/src/core/graph/format/graphviz/graphviz_escape_html_label.d.ts +17 -0
  114. package/src/core/graph/format/graphviz/graphviz_escape_html_label.d.ts.map +1 -0
  115. package/src/core/graph/format/graphviz/graphviz_escape_html_label.js +25 -0
  116. package/src/core/graph/format/graphviz/graphviz_escape_quoted.d.ts +16 -0
  117. package/src/core/graph/format/graphviz/graphviz_escape_quoted.d.ts.map +1 -0
  118. package/src/core/graph/format/graphviz/graphviz_escape_quoted.js +24 -0
  119. package/src/core/model/node-graph/NodeGraph.d.ts +12 -0
  120. package/src/core/model/node-graph/NodeGraph.d.ts.map +1 -1
  121. package/src/core/model/node-graph/NodeGraph.js +21 -6
  122. package/src/core/model/node-graph/node/NodeDescription.d.ts +36 -0
  123. package/src/core/model/node-graph/node/NodeDescription.d.ts.map +1 -1
  124. package/src/core/model/node-graph/node/NodeDescription.js +41 -0
  125. package/src/core/model/node-graph/visual/ConnectionVisualData.d.ts +119 -0
  126. package/src/core/model/node-graph/visual/ConnectionVisualData.d.ts.map +1 -0
  127. package/src/core/model/node-graph/visual/ConnectionVisualData.js +317 -0
  128. package/src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.d.ts +4 -0
  129. package/src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.d.ts.map +1 -1
  130. package/src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.js +125 -22
  131. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts +91 -2
  132. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts.map +1 -1
  133. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +164 -113
  134. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts +162 -0
  135. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +1 -0
  136. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.js +288 -0
  137. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +109 -0
  138. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -0
  139. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +141 -0
  140. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +149 -0
  141. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -0
  142. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +175 -0
  143. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +137 -0
  144. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -0
  145. package/src/core/model/node-graph/visual/layout/RouteGrid.js +242 -0
  146. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +114 -0
  147. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -0
  148. package/src/core/model/node-graph/visual/layout/RouteSearch.js +300 -0
  149. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +86 -0
  150. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -0
  151. package/src/core/model/node-graph/visual/layout/RouteSet.js +168 -0
  152. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts +48 -0
  153. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +1 -0
  154. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +555 -0
  155. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts +34 -0
  156. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +1 -0
  157. package/src/core/model/node-graph/visual/layout/layout_assign_layers.js +202 -0
  158. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts +34 -0
  159. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +1 -0
  160. package/src/core/model/node-graph/visual/layout/layout_break_cycles.js +254 -0
  161. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts +29 -0
  162. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -0
  163. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +184 -0
  164. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +29 -0
  165. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -0
  166. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +95 -0
  167. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +56 -0
  168. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -0
  169. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +131 -0
  170. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +36 -0
  171. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -0
  172. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +415 -0
  173. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts +21 -0
  174. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +1 -0
  175. package/src/core/model/node-graph/visual/layout/layout_orient_links.js +49 -0
  176. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +41 -0
  177. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -0
  178. package/src/core/model/node-graph/visual/layout/route_connections.js +309 -0
  179. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +33 -0
  180. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -0
  181. package/src/core/model/node-graph/visual/layout/route_grid_build.js +237 -0
  182. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +25 -0
  183. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -0
  184. package/src/core/model/node-graph/visual/layout/route_nudge.js +220 -0
  185. package/src/core/model/node-graph/visual/layout/route_to_spline.d.ts +29 -0
  186. package/src/core/model/node-graph/visual/layout/route_to_spline.d.ts.map +1 -0
  187. package/src/core/model/node-graph/visual/layout/route_to_spline.js +120 -0
  188. package/src/engine/EngineHarness.d.ts.map +1 -1
  189. package/src/engine/EngineHarness.js +593 -586
  190. package/src/engine/EntityCreator.js +116 -116
  191. package/src/engine/achievements/AchievementManager.js +437 -437
  192. package/src/engine/animation/AnimatedActions.js +111 -111
  193. package/src/engine/animation/AnimationUtils.d.ts.map +1 -1
  194. package/src/engine/animation/AnimationUtils.js +246 -234
  195. package/src/engine/animation/Animations.d.ts +1 -0
  196. package/src/engine/animation/Animations.d.ts.map +1 -1
  197. package/src/engine/animation/Animations.js +13 -5
  198. package/src/engine/animation/clip/bind_property_writer.d.ts.map +1 -1
  199. package/src/engine/animation/clip/bind_property_writer.js +12 -5
  200. package/src/engine/animation/curve/binding/BoundTransform64Writer.d.ts +29 -0
  201. package/src/engine/animation/curve/binding/BoundTransform64Writer.d.ts.map +1 -0
  202. package/src/engine/animation/curve/binding/BoundTransform64Writer.js +80 -0
  203. package/src/engine/animation/removeEntityWithMeshParticlesEffect.js +4 -4
  204. package/src/engine/asset/loaders/gltf_test_fixtures.d.ts.map +1 -1
  205. package/src/engine/asset/loaders/gltf_test_fixtures.js +5 -4
  206. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +12 -12
  207. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  208. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +77 -44
  209. package/src/engine/control/first-person/abilities/LedgeGrab.js +1 -1
  210. package/src/engine/control/first-person/abilities/Mantle.js +1 -1
  211. package/src/engine/control/first-person/abilities/Slide.js +1 -1
  212. package/src/engine/control/first-person/collision/KinematicMover.d.ts +5 -9
  213. package/src/engine/control/first-person/collision/KinematicMover.d.ts.map +1 -1
  214. package/src/engine/control/first-person/collision/KinematicMover.js +59 -29
  215. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +2 -2
  216. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
  217. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +7 -7
  218. package/src/engine/ecs/EventType.d.ts +1 -0
  219. package/src/engine/ecs/EventType.js +35 -10
  220. package/src/engine/ecs/dynamic_actions/actions/definition/SendRequestActionDescription.d.ts.map +1 -1
  221. package/src/engine/ecs/dynamic_actions/actions/definition/SendRequestActionDescription.js +12 -4
  222. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts +4 -4
  223. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
  224. package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +10 -11
  225. package/src/engine/ecs/grid/pick.js +1 -1
  226. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.d.ts +1 -1
  227. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +13 -13
  228. package/src/engine/ecs/gui/hud/testHudEdgeStick.js +3 -3
  229. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts +10 -10
  230. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +1 -1
  231. package/src/engine/ecs/ik/InverseKinematicsSystem.js +8 -8
  232. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts.map +1 -1
  233. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +120 -97
  234. package/src/engine/ecs/ik/ik_bone_chain.d.ts +16 -5
  235. package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +1 -1
  236. package/src/engine/ecs/ik/ik_bone_chain.js +16 -4
  237. package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts +7 -3
  238. package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts.map +1 -1
  239. package/src/engine/ecs/ik/ik_probe_terrain_contact.js +20 -16
  240. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +18 -0
  241. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -0
  242. package/src/engine/ecs/ik/ik_write_local_rotation.js +30 -0
  243. package/src/engine/ecs/parent/EntityNode.d.ts +24 -6
  244. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  245. package/src/engine/ecs/parent/EntityNode.js +54 -42
  246. package/src/engine/ecs/parent/EntityNodeFlags.d.ts +0 -1
  247. package/src/engine/ecs/parent/EntityNodeFlags.js +7 -8
  248. package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
  249. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  250. package/src/engine/ecs/speaker/VoiceSystem.js +4 -4
  251. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  252. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +2 -0
  253. package/src/engine/ecs/terrain/ecs/Terrain.d.ts +5 -2
  254. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  255. package/src/engine/ecs/terrain/ecs/Terrain.js +7 -4
  256. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +3 -3
  257. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts +7 -7
  258. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  259. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +84 -36
  260. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +513 -0
  261. package/src/engine/ecs/transform/Transform64.d.ts +48 -11
  262. package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
  263. package/src/engine/ecs/transform/Transform64.js +54 -15
  264. package/src/engine/ecs/transform/Transform64SerializationAdapter.d.ts +37 -0
  265. package/src/engine/ecs/transform/Transform64SerializationAdapter.d.ts.map +1 -0
  266. package/src/engine/ecs/transform/Transform64SerializationAdapter.js +75 -0
  267. package/src/engine/ecs/transform/__probe.d.ts +4 -0
  268. package/src/engine/ecs/transform/__probe.d.ts.map +1 -0
  269. package/src/engine/ecs/transform/t64_allocation_probe.d.ts +31 -0
  270. package/src/engine/ecs/transform/t64_allocation_probe.d.ts.map +1 -0
  271. package/src/engine/ecs/transform/t64_allocation_probe.js +78 -0
  272. package/src/engine/ecs/transform/t64_announce_change.d.ts +33 -0
  273. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -0
  274. package/src/engine/ecs/transform/t64_announce_change.js +39 -0
  275. package/src/engine/ecs/transform/t64_equals_components.d.ts +30 -0
  276. package/src/engine/ecs/transform/t64_equals_components.d.ts.map +1 -0
  277. package/src/engine/ecs/transform/t64_equals_components.js +59 -0
  278. package/src/engine/ecs/transform/t64_read_rotation.d.ts +13 -0
  279. package/src/engine/ecs/transform/t64_read_rotation.d.ts.map +1 -0
  280. package/src/engine/ecs/transform/t64_read_rotation.js +16 -0
  281. package/src/engine/ecs/transform/t64_read_translation.d.ts +14 -0
  282. package/src/engine/ecs/transform/t64_read_translation.d.ts.map +1 -0
  283. package/src/engine/ecs/transform/t64_read_translation.js +17 -0
  284. package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts +5 -5
  285. package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts.map +1 -1
  286. package/src/engine/ecs/transform-attachment/TransformAttachment.js +4 -4
  287. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts +10 -10
  288. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  289. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +71 -20
  290. package/src/engine/graphics/debug/createDebugLabel.js +3 -3
  291. package/src/engine/graphics/ecs/camera/pp/PerfectPanner.d.ts.map +1 -1
  292. package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +5 -4
  293. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  294. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +8 -3
  295. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +6 -6
  296. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  297. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +25 -13
  298. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraLanderSystem.js +1 -1
  299. package/src/engine/graphics/ecs/mesh/setMesh.js +2 -2
  300. package/src/engine/graphics/ecs/path/entity/EntityPath.d.ts.map +1 -1
  301. package/src/engine/graphics/ecs/path/entity/EntityPath.js +21 -7
  302. package/src/engine/graphics/ecs/path/entity/EntityPathMarkerDefinition.d.ts +4 -4
  303. package/src/engine/graphics/ecs/path/entity/EntityPathMarkerDefinition.d.ts.map +1 -1
  304. package/src/engine/graphics/ecs/path/entity/EntityPathMarkerDefinition.js +4 -4
  305. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts +2 -2
  306. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  307. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +145 -135
  308. package/src/engine/graphics/geometry/MikkT/Build4RuleGroups.js +2 -2
  309. package/src/engine/graphics/geometry/MikkT/DegenEpilogue.js +1 -1
  310. package/src/engine/graphics/geometry/MikkT/DegenPrologue.js +1 -1
  311. package/src/engine/graphics/geometry/MikkT/EvalTspace.js +1 -1
  312. package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +3 -3
  313. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +659 -0
  314. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +21 -5
  315. package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts +45 -0
  316. package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts.map +1 -1
  317. package/src/engine/graphics/render/frame_graph/FrameGraph.js +282 -60
  318. package/src/engine/graphics/render/frame_graph/FramePassBuilder.d.ts.map +1 -1
  319. package/src/engine/graphics/render/frame_graph/FramePassBuilder.js +20 -9
  320. package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts +12 -0
  321. package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts.map +1 -1
  322. package/src/engine/graphics/render/frame_graph/FramePassNode.js +13 -0
  323. package/src/engine/graphics/render/frame_graph/FramePassResources.d.ts.map +1 -1
  324. package/src/engine/graphics/render/frame_graph/FramePassResources.js +5 -0
  325. package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts +19 -1
  326. package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts.map +1 -1
  327. package/src/engine/graphics/render/frame_graph/ResourceEntry.js +23 -1
  328. package/src/engine/graphics/render/frame_graph/backend/void/VoidRenderContext.d.ts +15 -1
  329. package/src/engine/graphics/render/frame_graph/backend/void/VoidRenderContext.d.ts.map +1 -1
  330. package/src/engine/graphics/render/frame_graph/backend/void/VoidRenderContext.js +33 -16
  331. package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.d.ts.map +1 -1
  332. package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.js +19 -1
  333. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +6 -6
  334. package/src/engine/graphics3/CameraSystem.d.ts +6 -6
  335. package/src/engine/graphics3/CameraSystem.d.ts.map +1 -1
  336. package/src/engine/graphics3/CameraSystem.js +170 -170
  337. package/src/engine/graphics3/DecalSystem.d.ts +6 -6
  338. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  339. package/src/engine/graphics3/DecalSystem.js +449 -449
  340. package/src/engine/graphics3/LightSystem.d.ts +6 -6
  341. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  342. package/src/engine/graphics3/LightSystem.js +234 -221
  343. package/src/engine/graphics3/MeshSystem.d.ts +6 -6
  344. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  345. package/src/engine/graphics3/MeshSystem.js +53 -22
  346. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +20 -15
  347. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -1
  348. package/src/engine/graphics3/ParticipatingMediaSystem.js +198 -184
  349. package/src/engine/graphics3/ParticleEmitterSystem.d.ts +6 -6
  350. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  351. package/src/engine/graphics3/ParticleEmitterSystem.js +310 -289
  352. package/src/engine/graphics3/PickingSystem.d.ts +6 -6
  353. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
  354. package/src/engine/graphics3/PickingSystem.js +273 -273
  355. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -6
  356. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  357. package/src/engine/graphics3/ShadedGeometrySystem.js +180 -169
  358. package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -1
  359. package/src/engine/graphics3/TerrainSystem.js +565 -566
  360. package/src/engine/graphics3/Trail3DSystem.d.ts +6 -6
  361. package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
  362. package/src/engine/graphics3/Trail3DSystem.js +221 -221
  363. package/src/engine/graphics3/camera_sync_from_transform.d.ts +2 -2
  364. package/src/engine/graphics3/camera_sync_from_transform.d.ts.map +1 -1
  365. package/src/engine/graphics3/camera_sync_from_transform.js +2 -1
  366. package/src/engine/graphics3/debug/gizmo_view_from_camera.js +4 -4
  367. package/src/engine/graphics3/particles/GPUParticularRenderer.d.ts +6 -0
  368. package/src/engine/graphics3/particles/GPUParticularRenderer.d.ts.map +1 -1
  369. package/src/engine/graphics3/particles/GPUParticularRenderer.js +82 -53
  370. package/src/engine/graphics3/particles/particle_gpu_records.d.ts +12 -8
  371. package/src/engine/graphics3/particles/particle_gpu_records.d.ts.map +1 -1
  372. package/src/engine/graphics3/particles/particle_gpu_records.js +53 -45
  373. package/src/engine/graphics3/preview/make_model_preview_scene.js +1 -1
  374. package/src/engine/graphics3/shade_camera_projection_ray.js +4 -4
  375. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts.map +1 -1
  376. package/src/engine/graphics3/shade_node_to_entity_composition.js +88 -84
  377. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts +7 -7
  378. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
  379. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +8 -8
  380. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +9 -8
  381. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  382. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +29 -8
  383. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +2 -2
  384. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.d.ts.map +1 -1
  385. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +35 -21
  386. package/src/engine/intelligence/behavior/util/RotationBehavior.js +5 -5
  387. package/src/engine/intelligence/mcts/StateNode.js +1 -1
  388. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +7 -7
  389. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
  390. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +14 -15
  391. package/src/engine/interpolation/pose_interpoland.d.ts +2 -2
  392. package/src/engine/interpolation/pose_interpoland.js +4 -4
  393. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts +4 -4
  394. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
  395. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +39 -14
  396. package/src/engine/network/adapters/TransformReplicationAdapter.d.ts +7 -7
  397. package/src/engine/network/adapters/TransformReplicationAdapter.d.ts.map +1 -1
  398. package/src/engine/network/adapters/TransformReplicationAdapter.js +19 -20
  399. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +48 -0
  400. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  401. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +246 -3
  402. package/src/engine/network/replication/Replicator.d.ts +5 -3
  403. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  404. package/src/engine/network/replication/Replicator.js +65 -16
  405. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -3
  406. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  407. package/src/engine/physics/ccd/linear_sweep.js +9 -3
  408. package/src/engine/physics/constraint/solve_constraints.js +10 -10
  409. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +8 -8
  410. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -1
  411. package/src/engine/physics/ecs/ColliderObserverSystem.js +6 -6
  412. package/src/engine/physics/ecs/PhysicsSystem.d.ts +22 -32
  413. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  414. package/src/engine/physics/ecs/PhysicsSystem.js +2337 -2310
  415. package/src/engine/physics/ecs/find_non_finite_physics_state.js +6 -6
  416. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +7 -7
  417. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
  418. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +16 -8
  419. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +4 -4
  420. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -1
  421. package/src/engine/physics/fluid/ecs/FluidSystem.js +6 -6
  422. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts +2 -2
  423. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.d.ts.map +1 -1
  424. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +4 -4
  425. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +7 -7
  426. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +4 -4
  427. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +7 -7
  428. package/src/engine/physics/inertia/world_inverse_inertia.js +1 -1
  429. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
  430. package/src/engine/physics/integration/integrate_position.js +13 -12
  431. package/src/engine/physics/inverse_kinematics/fabrik/fabrik_solve.d.ts.map +1 -1
  432. package/src/engine/physics/inverse_kinematics/fabrik/fabrik_solve.js +23 -5
  433. package/src/engine/physics/narrowphase/compute_penetration.js +18 -14
  434. package/src/engine/physics/narrowphase/convex_convex_manifold.js +2 -2
  435. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +9 -9
  436. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  437. package/src/engine/physics/narrowphase/narrowphase_step.js +95 -68
  438. package/src/engine/physics/narrowphase/refine_ray_concave.js +1 -1
  439. package/src/engine/physics/narrowphase/refine_ray_hit.js +3 -3
  440. package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -1
  441. package/src/engine/physics/queries/overlap_shape.js +19 -7
  442. package/src/engine/physics/queries/raycast.js +3 -3
  443. package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
  444. package/src/engine/physics/queries/shape_cast.js +628 -620
  445. package/src/engine/physics/solver/solve_contacts.js +10 -10
  446. package/src/engine/physics/vehicle/RaycastVehicle.d.ts +6 -5
  447. package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
  448. package/src/engine/physics/vehicle/RaycastVehicle.js +10 -5
  449. package/src/engine/sound/ecs/SoundListenerSystem.d.ts +16 -4
  450. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  451. package/src/engine/sound/ecs/SoundListenerSystem.js +70 -11
  452. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +7 -7
  453. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -1
  454. package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +343 -338
  455. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +2 -2
  456. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -1
  457. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +356 -345
  458. package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts +23 -2
  459. package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts.map +1 -1
  460. package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +174 -140
  461. package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.d.ts +6 -6
  462. package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.d.ts.map +1 -1
  463. package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.js +185 -184
  464. package/src/engine/sound/material/detector/terrain/TerrainSoundMaterialSurfaceDetector.js +1 -1
  465. package/src/engine/sound/simulation/core/AcousticRegionIndex.d.ts +2 -1
  466. package/src/engine/sound/simulation/core/AcousticRegionIndex.d.ts.map +1 -1
  467. package/src/engine/sound/simulation/core/AcousticRegionIndex.js +4 -3
  468. package/src/engine/sound/simulation/core/AcousticVolumeRegion.d.ts +3 -2
  469. package/src/engine/sound/simulation/core/AcousticVolumeRegion.d.ts.map +1 -1
  470. package/src/engine/sound/simulation/core/AcousticVolumeRegion.js +6 -4
  471. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +10 -6
  472. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  473. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +32 -7
  474. package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.d.ts +7 -7
  475. package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.d.ts.map +1 -1
  476. package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.js +6 -6
  477. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
  478. package/src/engine/sound/sopra/runtime/EventInstance.js +8 -2
  479. package/src/format/scene/gltf/gltf_component_type.d.ts.map +1 -1
  480. package/src/format/scene/gltf/gltf_component_type.js +3 -1
  481. package/src/format/texture/ktx2/ktx2_read.d.ts.map +1 -1
  482. package/src/format/texture/ktx2/ktx2_read.js +2 -1
  483. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.d.ts.map +1 -1
  484. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +8 -1
  485. package/src/generation/markers/GridCellActionPlaceMarker.d.ts +4 -4
  486. package/src/generation/markers/GridCellActionPlaceMarker.d.ts.map +1 -1
  487. package/src/generation/markers/GridCellActionPlaceMarker.js +16 -6
  488. package/src/generation/markers/MarkerNode.d.ts +3 -3
  489. package/src/generation/markers/MarkerNode.d.ts.map +1 -1
  490. package/src/generation/markers/MarkerNode.js +3 -3
  491. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts +4 -4
  492. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts.map +1 -1
  493. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +7 -7
  494. package/src/generation/markers/actions/MarkerNodeActionImaginary.d.ts.map +1 -1
  495. package/src/generation/markers/actions/MarkerNodeActionImaginary.js +20 -2
  496. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +1 -1
  497. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.d.ts.map +1 -1
  498. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.js +13 -3
  499. package/src/generation/markers/transform/MarkerNodeTransformRotateRandom.d.ts.map +1 -1
  500. package/src/generation/markers/transform/MarkerNodeTransformRotateRandom.js +11 -1
  501. package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.d.ts.map +1 -1
  502. package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.js +8 -4
  503. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.d.ts.map +1 -1
  504. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +13 -5
  505. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.d.ts.map +1 -1
  506. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js +8 -2
  507. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.d.ts.map +1 -1
  508. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.js +16 -2
  509. package/src/shade/RENDERER_CONTRACT.md +584 -580
  510. package/src/shade/device/graph/BufferResourceDescriptor.d.ts.map +1 -1
  511. package/src/shade/device/graph/BufferResourceDescriptor.js +193 -184
  512. package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
  513. package/src/shade/device/graph/TextureResourceDescriptor.js +12 -0
  514. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  515. package/src/shade/device/mock/SoftwareGPUDevice.js +8 -0
  516. package/src/shade/playground/avboit/README.md +117 -0
  517. package/src/shade/playground/avboit/index.html +215 -0
  518. package/src/shade/playground/avboit/main.d.ts +2 -0
  519. package/src/shade/playground/avboit/main.d.ts.map +1 -0
  520. package/src/shade/playground/avboit/main.js +875 -0
  521. package/src/shade/playground/basis_textures/main.js +1 -1
  522. package/src/shade/playground/ground_seam/main.js +1 -1
  523. package/src/shade/playground/particle_editor/README.md +175 -0
  524. package/src/shade/playground/particle_editor/index.html +76 -0
  525. package/src/shade/playground/particle_editor/main.d.ts +2 -0
  526. package/src/shade/playground/particle_editor/main.d.ts.map +1 -0
  527. package/src/shade/playground/particle_editor/main.js +139 -0
  528. package/src/shade/playground/particle_system/README.md +92 -62
  529. package/src/shade/playground/particle_system/index.html +67 -21
  530. package/src/shade/playground/particle_system/main.js +247 -102
  531. package/src/shade/{renderer/particles → playground/particle_system}/particle_prototype.d.ts +21 -18
  532. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -0
  533. package/src/shade/{renderer/particles → playground/particle_system}/particle_prototype.js +197 -181
  534. package/src/shade/playground/particle_system/particle_scene.d.ts +136 -20
  535. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
  536. package/src/shade/playground/particle_system/particle_scene.js +487 -670
  537. package/src/shade/playground/skinned_blas_refit/sweep_views.js +2 -2
  538. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
  539. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +2 -1
  540. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  541. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +2 -1
  542. package/src/shade/playground/sponza_path_trace/main.js +1 -1
  543. package/src/shade/playground/volumetrics_froxel/main.js +917 -917
  544. package/src/shade/playground/volumetrics_froxel/measure.js +559 -559
  545. package/src/shade/renderer/Renderer.d.ts +44 -0
  546. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  547. package/src/shade/renderer/Renderer.js +169 -36
  548. package/src/shade/renderer/ShadeTransparencyMode.d.ts +13 -0
  549. package/src/shade/renderer/ShadeTransparencyMode.d.ts.map +1 -0
  550. package/src/shade/renderer/ShadeTransparencyMode.js +30 -0
  551. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  552. package/src/shade/renderer/atmosphere/GPUSky.js +4 -2
  553. package/src/shade/renderer/buffer/graph_read_buffer.d.ts.map +1 -1
  554. package/src/shade/renderer/buffer/graph_read_buffer.js +8 -1
  555. package/src/shade/renderer/buffer/table/GPUTypedTable.js +1 -1
  556. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +30 -0
  557. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
  558. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +84 -0
  559. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +27 -0
  560. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +1 -0
  561. package/src/shade/renderer/buffer/table/gpu_database_words.d.ts +24 -0
  562. package/src/shade/renderer/buffer/table/gpu_database_words.d.ts.map +1 -0
  563. package/src/shade/renderer/buffer/table/gpu_database_words.js +92 -0
  564. package/src/shade/renderer/camera/Camera.d.ts +2 -2
  565. package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
  566. package/src/shade/renderer/camera/Camera.js +11 -5
  567. package/src/shade/renderer/camera/GPUCameraContext.d.ts.map +1 -1
  568. package/src/shade/renderer/camera/GPUCameraContext.js +2 -1
  569. package/src/shade/renderer/camera/OrbitalCameraController.d.ts +3 -3
  570. package/src/shade/renderer/camera/OrbitalCameraController.d.ts.map +1 -1
  571. package/src/shade/renderer/camera/OrbitalCameraController.js +31 -16
  572. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +2 -2
  573. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  574. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +4 -3
  575. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +10 -5
  576. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +1 -1
  577. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +8 -4
  578. package/src/shade/renderer/extension/FrameContext.d.ts.map +1 -1
  579. package/src/shade/renderer/extension/FrameContext.js +5 -0
  580. package/src/shade/renderer/extension/FrameRecord.d.ts +16 -0
  581. package/src/shade/renderer/extension/FrameRecord.d.ts.map +1 -1
  582. package/src/shade/renderer/extension/FrameRecord.js +31 -0
  583. package/src/shade/renderer/extension/GBufferTextures.d.ts +11 -0
  584. package/src/shade/renderer/extension/GBufferTextures.d.ts.map +1 -1
  585. package/src/shade/renderer/extension/GBufferTextures.js +14 -0
  586. package/src/shade/renderer/geometry/attribute/gpu_vertex_buffer_layout_from_spec.js +1 -1
  587. package/src/shade/renderer/geometry/util/geometry_stripify.js +6 -6
  588. package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.js +8 -8
  589. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
  590. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +14 -5
  591. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
  592. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +17 -9
  593. package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts +2 -1
  594. package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts.map +1 -1
  595. package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.js +4 -1
  596. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts +2 -1
  597. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
  598. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +11 -1
  599. package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.d.ts +1 -1
  600. package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.d.ts.map +1 -1
  601. package/src/shade/renderer/global_illumination/probe/octahedral/graph_lpv_shade.js +4 -2
  602. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
  603. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +5 -1
  604. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  605. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +35 -11
  606. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  607. package/src/shade/renderer/particles/DESIGN.md +271 -112
  608. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +251 -86
  609. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  610. package/src/shade/renderer/particles/GPUParticleSystem.js +822 -146
  611. package/src/shade/renderer/particles/ParticleConstants.d.ts +96 -3
  612. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  613. package/src/shade/renderer/particles/ParticleConstants.js +103 -4
  614. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +5 -4
  615. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  616. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +11 -15
  617. package/src/shade/renderer/particles/coherence/shader_particle_bucket.d.ts +2 -2
  618. package/src/shade/renderer/particles/coherence/shader_particle_bucket.d.ts.map +1 -1
  619. package/src/shade/renderer/particles/coherence/shader_particle_bucket.js +20 -15
  620. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts +7 -8
  621. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts.map +1 -1
  622. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.js +7 -17
  623. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts +56 -0
  624. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts.map +1 -0
  625. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.js +68 -0
  626. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts +39 -0
  627. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts.map +1 -0
  628. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.js +52 -0
  629. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +83 -0
  630. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -0
  631. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +166 -0
  632. package/src/shade/renderer/particles/data/chunk_particle_emitter.d.ts +21 -5
  633. package/src/shade/renderer/particles/data/chunk_particle_emitter.d.ts.map +1 -1
  634. package/src/shade/renderer/particles/data/chunk_particle_emitter.js +44 -85
  635. package/src/shade/renderer/particles/data/particle_header.d.ts +62 -0
  636. package/src/shade/renderer/particles/data/particle_header.d.ts.map +1 -0
  637. package/src/shade/renderer/particles/data/particle_header.js +103 -0
  638. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +179 -0
  639. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts.map +1 -0
  640. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -0
  641. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +120 -1
  642. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  643. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +90 -1
  644. package/src/shade/renderer/particles/graph/ParticleNodeGroup.d.ts +283 -0
  645. package/src/shade/renderer/particles/graph/ParticleNodeGroup.d.ts.map +1 -0
  646. package/src/shade/renderer/particles/graph/ParticleNodeGroup.js +419 -0
  647. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +44 -2
  648. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  649. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +476 -40
  650. package/src/shade/renderer/particles/graph/ParticleValueType.d.ts +188 -0
  651. package/src/shade/renderer/particles/graph/ParticleValueType.d.ts.map +1 -0
  652. package/src/shade/renderer/particles/graph/ParticleValueType.js +287 -0
  653. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts +16 -9
  654. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  655. package/src/shade/renderer/particles/graph/compile_particle_graph.js +464 -205
  656. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts +11 -0
  657. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -0
  658. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +213 -0
  659. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts +27 -0
  660. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -0
  661. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +75 -0
  662. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts +83 -0
  663. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -0
  664. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +319 -0
  665. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts +22 -0
  666. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -0
  667. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +517 -0
  668. package/src/shade/renderer/particles/graph/groups/particle_groups_utility.d.ts +70 -0
  669. package/src/shade/renderer/particles/graph/groups/particle_groups_utility.d.ts.map +1 -0
  670. package/src/shade/renderer/particles/graph/groups/particle_groups_utility.js +161 -0
  671. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts +8 -0
  672. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -0
  673. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +159 -0
  674. package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts +88 -0
  675. package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts.map +1 -0
  676. package/src/shade/renderer/particles/graph/infer_particle_graph_types.js +234 -0
  677. package/src/shade/renderer/particles/graph/make_particle_group.d.ts +98 -0
  678. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -0
  679. package/src/shade/renderer/particles/graph/make_particle_group.js +427 -0
  680. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts +11 -4
  681. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts.map +1 -1
  682. package/src/shade/renderer/particles/graph/particle_graph_authoring.js +121 -108
  683. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +38 -0
  684. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -0
  685. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +25 -0
  686. package/src/shade/renderer/particles/graph/particle_graph_distributions.d.ts +29 -0
  687. package/src/shade/renderer/particles/graph/particle_graph_distributions.d.ts.map +1 -0
  688. package/src/shade/renderer/particles/graph/particle_graph_distributions.js +170 -0
  689. package/src/shade/renderer/particles/graph/particle_graph_json.d.ts +87 -0
  690. package/src/shade/renderer/particles/graph/particle_graph_json.d.ts.map +1 -0
  691. package/src/shade/renderer/particles/graph/particle_graph_json.js +196 -0
  692. package/src/shade/renderer/particles/graph/particle_group_json.d.ts +86 -0
  693. package/src/shade/renderer/particles/graph/particle_group_json.d.ts.map +1 -0
  694. package/src/shade/renderer/particles/graph/particle_group_json.js +182 -0
  695. package/src/shade/renderer/particles/graph/particle_group_library.d.ts +33 -0
  696. package/src/shade/renderer/particles/graph/particle_group_library.d.ts.map +1 -0
  697. package/src/shade/renderer/particles/graph/particle_group_library.js +75 -0
  698. package/src/shade/renderer/particles/graph/particle_node_library.d.ts +37 -0
  699. package/src/shade/renderer/particles/graph/particle_node_library.d.ts.map +1 -0
  700. package/src/shade/renderer/particles/graph/particle_node_library.js +64 -0
  701. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +146 -0
  702. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -0
  703. package/src/shade/renderer/particles/graph/particle_node_parameters.js +234 -0
  704. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts +30 -0
  705. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -0
  706. package/src/shade/renderer/particles/graph/particle_node_presentation.js +286 -0
  707. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +66 -0
  708. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -0
  709. package/src/shade/renderer/particles/graph/validate_particle_graph.js +439 -0
  710. package/src/shade/renderer/particles/graph_particles.d.ts +143 -68
  711. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  712. package/src/shade/renderer/particles/graph_particles.js +424 -71
  713. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +107 -0
  714. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -0
  715. package/src/shade/renderer/particles/graph_particles_avboit.js +312 -0
  716. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +41 -8
  717. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  718. package/src/shade/renderer/particles/isa/InstructionStream.js +111 -33
  719. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts +13 -10
  720. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts.map +1 -1
  721. package/src/shade/renderer/particles/isa/ParticleAssembler.js +30 -26
  722. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +27 -15
  723. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  724. package/src/shade/renderer/particles/isa/ParticleProgram.js +139 -34
  725. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +117 -9
  726. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  727. package/src/shade/renderer/particles/isa/ParticleVMISA.js +296 -37
  728. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +149 -0
  729. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -0
  730. package/src/shade/renderer/particles/isa/particle_assembly.js +999 -0
  731. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +25 -3
  732. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  733. package/src/shade/renderer/particles/layout/ParticleLayout.js +33 -5
  734. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +160 -0
  735. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -0
  736. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +478 -0
  737. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +291 -0
  738. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -0
  739. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +647 -0
  740. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +95 -0
  741. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -0
  742. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +213 -0
  743. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +16 -0
  744. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -0
  745. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +223 -0
  746. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +121 -0
  747. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -0
  748. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +206 -0
  749. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +11 -0
  750. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -0
  751. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +197 -0
  752. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts +4 -0
  753. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -0
  754. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.js +51 -0
  755. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +4 -0
  756. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -0
  757. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +561 -0
  758. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts +4 -0
  759. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -0
  760. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +72 -0
  761. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts +4 -0
  762. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -0
  763. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +86 -0
  764. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts +4 -0
  765. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -0
  766. package/src/shade/renderer/particles/optimizer/pass_peephole.js +271 -0
  767. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts +4 -0
  768. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -0
  769. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +268 -0
  770. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts +4 -0
  771. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -0
  772. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +151 -0
  773. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +131 -0
  774. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -0
  775. package/src/shade/renderer/particles/particle_test_fixtures.js +203 -0
  776. package/src/shade/renderer/particles/runtime/Emitter.d.ts +219 -0
  777. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +1 -0
  778. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +128 -60
  779. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  780. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +286 -117
  781. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +264 -0
  782. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -0
  783. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +404 -0
  784. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +49 -15
  785. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +1 -1
  786. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +51 -18
  787. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
  788. package/src/shade/renderer/particles/runtime/ProgramArena.js +72 -32
  789. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +4 -4
  790. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  791. package/src/shade/renderer/particles/runtime/create_particle_effect.js +4 -4
  792. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +15 -0
  793. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +1 -0
  794. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts +17 -0
  795. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts.map +1 -0
  796. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +75 -0
  797. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts +20 -0
  798. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -0
  799. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +94 -0
  800. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +15 -5
  801. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +1 -1
  802. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts +1 -2
  803. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts.map +1 -1
  804. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js +1 -2
  805. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts +11 -0
  806. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts.map +1 -0
  807. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.js +13 -0
  808. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_age.d.ts +17 -0
  809. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_age.d.ts.map +1 -0
  810. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_age.js +22 -0
  811. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts +14 -0
  812. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts.map +1 -0
  813. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.js +23 -0
  814. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +1 -1
  815. package/src/shade/renderer/particles/shaders/chunk_particle_scene_view_depth.d.ts +18 -0
  816. package/src/shade/renderer/particles/shaders/chunk_particle_scene_view_depth.d.ts.map +1 -0
  817. package/src/shade/renderer/particles/shaders/chunk_particle_scene_view_depth.js +24 -0
  818. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts +26 -0
  819. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts.map +1 -0
  820. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.js +59 -0
  821. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts +14 -0
  822. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -0
  823. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +153 -0
  824. package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.d.ts +3 -0
  825. package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.d.ts.map +1 -0
  826. package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.js +124 -0
  827. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts +19 -0
  828. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -0
  829. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +147 -0
  830. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -8
  831. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  832. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +72 -37
  833. package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.d.ts +5 -0
  834. package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.d.ts.map +1 -0
  835. package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.js +216 -0
  836. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  837. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +7 -3
  838. package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
  839. package/src/shade/renderer/particles/shaders/shader_particle_render.js +132 -197
  840. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  841. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +78 -24
  842. package/src/shade/renderer/particles/shaders/shader_particle_spawn_commands.d.ts +26 -0
  843. package/src/shade/renderer/particles/shaders/shader_particle_spawn_commands.d.ts.map +1 -0
  844. package/src/shade/renderer/particles/shaders/shader_particle_spawn_commands.js +66 -0
  845. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts +1 -1
  846. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
  847. package/src/shade/renderer/particles/sort/shader_particle_sort.js +21 -36
  848. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +2 -2
  849. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  850. package/src/shade/renderer/particles/vm/ParticleVMReference.js +100 -90
  851. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  852. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +270 -138
  853. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts +9 -0
  854. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  855. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +26 -0
  856. package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts +1 -2
  857. package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts.map +1 -1
  858. package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.js +0 -3
  859. package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +1 -1
  860. package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +1 -1
  861. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  862. package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
  863. package/src/shade/renderer/postprocess/nss/NSS.js +3 -2
  864. package/src/shade/renderer/postprocess/nss/generate_NSS_WEIGHTS_ACTUAL.js +3 -2
  865. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts +7 -2
  866. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  867. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -1
  868. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +1 -1
  869. package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts +3 -0
  870. package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +1 -0
  871. package/src/shade/renderer/rasterize/{native/oit → forward}/FORWARD_VERTEX_SHADER_STRUCT.js +4 -4
  872. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts +3 -0
  873. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +1 -0
  874. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.js +17 -0
  875. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.d.ts +1 -1
  876. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -0
  877. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.js +16 -16
  878. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.d.ts +1 -1
  879. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -0
  880. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.js +17 -17
  881. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.d.ts +1 -1
  882. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +1 -0
  883. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.js +2 -2
  884. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts +3 -0
  885. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -0
  886. package/src/shade/renderer/rasterize/{native/oit → forward}/vertex_shader_chunk.js +4 -4
  887. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts +27 -0
  888. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts.map +1 -0
  889. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.js +27 -0
  890. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +87 -0
  891. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -0
  892. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +61 -0
  893. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts +107 -0
  894. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts.map +1 -0
  895. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.js +120 -0
  896. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +642 -0
  897. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +534 -0
  898. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts +15 -0
  899. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts.map +1 -0
  900. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.js +33 -0
  901. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts +20 -0
  902. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts.map +1 -0
  903. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.js +38 -0
  904. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts +45 -0
  905. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -0
  906. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +139 -0
  907. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts +37 -0
  908. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts.map +1 -0
  909. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.js +73 -0
  910. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts +9 -0
  911. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts.map +1 -0
  912. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.js +17 -0
  913. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts +11 -0
  914. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts.map +1 -0
  915. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.js +18 -0
  916. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts +9 -0
  917. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts.map +1 -0
  918. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.js +17 -0
  919. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts +9 -0
  920. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts.map +1 -0
  921. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.js +17 -0
  922. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts +15 -0
  923. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts.map +1 -0
  924. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.js +25 -0
  925. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts +17 -0
  926. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts.map +1 -0
  927. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.js +35 -0
  928. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts +11 -0
  929. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts.map +1 -0
  930. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.js +21 -0
  931. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts +9 -0
  932. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts.map +1 -0
  933. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.js +26 -0
  934. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts +11 -0
  935. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts.map +1 -0
  936. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.js +22 -0
  937. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts +10 -0
  938. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts.map +1 -0
  939. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.js +21 -0
  940. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts +10 -0
  941. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts.map +1 -0
  942. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.js +32 -0
  943. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.d.ts +18 -0
  944. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.d.ts.map +1 -0
  945. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js +58 -0
  946. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts +20 -0
  947. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts.map +1 -0
  948. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.js +27 -0
  949. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts +10 -0
  950. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts.map +1 -0
  951. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.js +18 -0
  952. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts +9 -0
  953. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts.map +1 -0
  954. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.js +21 -0
  955. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts +9 -0
  956. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts.map +1 -0
  957. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.js +23 -0
  958. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts +13 -0
  959. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts.map +1 -0
  960. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.js +27 -0
  961. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts +22 -0
  962. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts.map +1 -0
  963. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.js +38 -0
  964. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +141 -0
  965. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -0
  966. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +994 -0
  967. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts +8 -0
  968. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts.map +1 -0
  969. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.js +135 -0
  970. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts +3 -0
  971. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +1 -0
  972. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.js +101 -0
  973. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts +3 -0
  974. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +1 -0
  975. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +96 -0
  976. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts +3 -0
  977. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts.map +1 -0
  978. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js +83 -0
  979. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts +9 -0
  980. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts.map +1 -0
  981. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.js +119 -0
  982. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts +3 -0
  983. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts.map +1 -0
  984. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js +87 -0
  985. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts +15 -0
  986. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -0
  987. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +202 -0
  988. package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts +22 -0
  989. package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts.map +1 -0
  990. package/src/shade/renderer/rasterize/native/material_draw_indirect.js +69 -0
  991. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  992. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +665 -722
  993. package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +3 -3
  994. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +4 -4
  995. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +4 -4
  996. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts +7 -2
  997. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  998. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +16 -2
  999. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts +3 -3
  1000. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts.map +1 -1
  1001. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js +29 -23
  1002. package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.d.ts +2 -2
  1003. package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.d.ts.map +1 -1
  1004. package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.js +3 -3
  1005. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts +4 -4
  1006. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts.map +1 -1
  1007. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.js +2 -2
  1008. package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.d.ts +2 -2
  1009. package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.d.ts.map +1 -1
  1010. package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.js +2 -2
  1011. package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.d.ts +7 -7
  1012. package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.d.ts.map +1 -1
  1013. package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.js +79 -71
  1014. package/src/shade/renderer/shader/chunk/math/chunk_lower_bound_branchless.d.ts.map +1 -1
  1015. package/src/shade/renderer/shader/chunk/math/chunk_lower_bound_branchless.js +3 -1
  1016. package/src/shade/renderer/shader/chunk/random/chunk_hash_to_float01.d.ts +13 -3
  1017. package/src/shade/renderer/shader/chunk/random/chunk_hash_to_float01.d.ts.map +1 -1
  1018. package/src/shade/renderer/shader/chunk/random/chunk_hash_to_float01.js +15 -5
  1019. package/src/shade/renderer/shader/chunk/random/chunk_random_uint.d.ts +8 -0
  1020. package/src/shade/renderer/shader/chunk/random/chunk_random_uint.d.ts.map +1 -1
  1021. package/src/shade/renderer/shader/chunk/random/chunk_random_uint.js +15 -5
  1022. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg.d.ts +7 -0
  1023. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg.d.ts.map +1 -1
  1024. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg.js +17 -7
  1025. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_advance.d.ts +17 -0
  1026. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_advance.d.ts.map +1 -0
  1027. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_advance.js +26 -0
  1028. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_output.d.ts +15 -0
  1029. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_output.d.ts.map +1 -0
  1030. package/src/shade/renderer/shader/chunk/random/pcg/chunk_pcg_output.js +26 -0
  1031. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
  1032. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +8 -2
  1033. package/src/shade/renderer/shadow/map/PointLightShadowmap.d.ts.map +1 -1
  1034. package/src/shade/renderer/shadow/map/PointLightShadowmap.js +7 -2
  1035. package/src/shade/renderer/shadow/map/SpotLightShadowmap.d.ts.map +1 -1
  1036. package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +3 -15
  1037. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.d.ts.map +1 -1
  1038. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +10 -4
  1039. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.d.ts.map +1 -1
  1040. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.js +7 -2
  1041. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +2 -2
  1042. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +3 -3
  1043. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  1044. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +3 -3
  1045. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  1046. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +66 -5
  1047. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  1048. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +35 -4
  1049. package/src/view/minimap/Minimap.d.ts.map +1 -1
  1050. package/src/view/minimap/Minimap.js +227 -225
  1051. package/src/view/minimap/MinimapCanvasView.js +3 -3
  1052. package/src/view/minimap/MinimapMarker.d.ts +45 -0
  1053. package/src/view/minimap/MinimapMarker.d.ts.map +1 -0
  1054. package/src/view/minimap/MinimapMarker.js +80 -0
  1055. package/src/view/minimap/MinimapMarkerCollection.d.ts +6 -5
  1056. package/src/view/minimap/MinimapMarkerCollection.d.ts.map +1 -1
  1057. package/src/view/minimap/MinimapMarkerCollection.js +6 -6
  1058. package/src/view/minimap/MinimapMarkerSerializationAdapter.d.ts +19 -0
  1059. package/src/view/minimap/MinimapMarkerSerializationAdapter.d.ts.map +1 -0
  1060. package/src/view/minimap/MinimapMarkerSerializationAdapter.js +42 -0
  1061. package/src/view/minimap/dom/MinimapCameraView.d.ts +1 -1
  1062. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  1063. package/src/view/minimap/dom/MinimapCameraView.js +23 -4
  1064. package/src/view/minimap/dom/MinimapMarkerView.js +3 -3
  1065. package/src/view/minimap/gl/MarkerGL.js +3 -3
  1066. package/src/view/util/DomLayoutFrame.d.ts +53 -0
  1067. package/src/view/util/DomLayoutFrame.d.ts.map +1 -0
  1068. package/src/view/util/DomLayoutFrame.js +122 -0
  1069. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.js +0 -19
  1070. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.js +0 -241
  1071. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.js +0 -40
  1072. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.js +0 -28
  1073. package/src/engine/ecs/util/hideEntityGracefully.js +0 -196
  1074. package/src/shade/renderer/particles/cull/chunk_particle_cull.js +0 -38
  1075. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.js +0 -214
  1076. package/src/shade/renderer/particles/particle_prototype.d.ts.map +0 -1
  1077. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.js +0 -86
  1078. package/src/shade/renderer/particles/runtime/spawn_request_encoding.js +0 -52
  1079. package/src/shade/renderer/particles/shaders/chunk_particle_context.js +0 -58
  1080. package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts +0 -3
  1081. package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +0 -1
  1082. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts +0 -3
  1083. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +0 -1
  1084. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.js +0 -17
  1085. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +0 -1
  1086. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +0 -1
  1087. package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.d.ts.map +0 -1
  1088. package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts +0 -3
  1089. package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts.map +0 -1
@@ -0,0 +1,1636 @@
1
+ import { Color } from "../../../../src/core/color/Color.js";
2
+ import { PortDirection } from "../../../../src/core/model/node-graph/node/PortDirection.js";
3
+ import { ActionProcessor } from "../../../../src/core/process/undo/ActionProcessor.js";
4
+ import { infer_particle_graph_types } from "../../../../src/shade/renderer/particles/graph/infer_particle_graph_types.js";
5
+ import { particle_group_from_nodes } from "../../../../src/shade/renderer/particles/graph/make_particle_group.js";
6
+ import {
7
+ particle_group_descriptions,
8
+ } from "../../../../src/shade/renderer/particles/graph/particle_group_json.js";
9
+ import {
10
+ is_particle_group_description,
11
+ } from "../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js";
12
+ import {
13
+ particle_node_default_parameters,
14
+ particle_node_parameters,
15
+ } from "../../../../src/shade/renderer/particles/graph/particle_node_parameters.js";
16
+ import {
17
+ PARTICLE_NODE_REGISTRY,
18
+ PARTICLE_VALUE_TYPE,
19
+ } from "../../../../src/shade/renderer/particles/graph/ParticleNodeRegistry.js";
20
+ import {
21
+ particle_library_descriptions,
22
+ } from "../../../../src/shade/renderer/particles/graph/particle_node_library.js";
23
+ import {
24
+ PARTICLE_TYPE_COLOR,
25
+ PARTICLE_TYPE_F32,
26
+ PARTICLE_TYPE_VEC2,
27
+ PARTICLE_TYPE_VEC3,
28
+ PARTICLE_TYPE_VEC4,
29
+ } from "../../../../src/shade/renderer/particles/graph/ParticleValueType.js";
30
+ import KeyboardDevice from "../../../../src/engine/input/devices/KeyboardDevice.js";
31
+ import { KeyCodes } from "../../../../src/engine/input/devices/KeyCodes.js";
32
+ import LabelView from "../../../../src/view/common/LabelView.js";
33
+ import EmptyView from "../../../../src/view/elements/EmptyView.js";
34
+ import View from "../../../../src/view/View.js";
35
+ import { NodeGraphCamera } from "../../node-graph/NodeGraphCamera.js";
36
+ import { NodeGraphEditorView } from "../../node-graph/NodeGraphEditorView.js";
37
+ import { NodeCreateAction } from "../../node-graph/actions/NodeCreateAction.js";
38
+ import { NodeDeleteAction } from "../../node-graph/actions/NodeDeleteAction.js";
39
+ import { ConnectionCreateAction } from "../../node-graph/actions/ConnectionCreateAction.js";
40
+ import { NodesMoveAction } from "../../node-graph/actions/NodesMoveAction.js";
41
+ import { SelectionSetAction } from "../../node-graph/actions/SelectionSetAction.js";
42
+ import { ParticleGroupDefineAction } from "../../../particles/effect/actions/ParticleGroupDefineAction.js";
43
+ import { ParticleNodeParametersView } from "./ParticleNodeParametersView.js";
44
+
45
+ /**
46
+ * The graph layer of the particle editor: the two phases of an effect's simulation, authored as
47
+ * node graphs.
48
+ *
49
+ * Built *with* the node-graph editor rather than in it. Everything particle-specific arrives
50
+ * through the seams the base offers — the node library the canvas's add-node menu offers, a
51
+ * parameter-view factory that draws vector, enum, attribute and swizzle controls, and a problems
52
+ * list fed by the document's own compile. The base is left knowing nothing about particles.
53
+ *
54
+ * ## Adding a node
55
+ *
56
+ * On the canvas, where the node is going. Right-click and the library opens under the cursor with
57
+ * the caret in a search field; type a few letters and press Enter and the node lands at the point
58
+ * that was clicked. Drop a wire on open canvas and the same menu opens, narrowed to the types that
59
+ * have a port to take it, and picking one wires it up as it arrives.
60
+ *
61
+ * There is no palette down the side any more. It was a fine list and a bad way to add a node: every
62
+ * node cost a trip to the edge of the window and back, and the node arrived in the middle of the
63
+ * view rather than where it was wanted.
64
+ *
65
+ * ## Groups
66
+ *
67
+ * A {@link ../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js group} is a node made
68
+ * of nodes, and double-clicking one opens it: the canvas shows the group's own graph and the toolbar
69
+ * grows a breadcrumb back out. Groups nest, so the breadcrumb does. The groups shipped with the
70
+ * editor are locked — one body shared by every instance in every effect — and open read-only.
71
+ *
72
+ * ## Two phases, two graphs
73
+ *
74
+ * INIT runs once when a particle is spawned, UPDATE once per frame per live particle. They are
75
+ * separate graphs with separate cameras and separate selections, and switching between them is a
76
+ * matter of which one is visible — both stay built, so a phase comes back exactly where it was
77
+ * rather than reset to the origin.
78
+ *
79
+ * ## What is undoable
80
+ *
81
+ * Everything that touches a graph, through the {@link ActionProcessor} the host supplies. Adding a
82
+ * node from the menu, wiring, moving, deleting, and every parameter edit inside a node all land
83
+ * on one timeline, so a host editor's global undo covers particle authoring without knowing it
84
+ * exists.
85
+ */
86
+
87
+ /** Height of the phase / action toolbar, px. @type {number} */
88
+ const TOOLBAR_HEIGHT = 32;
89
+
90
+ /** Height of the problems strip along the bottom, px. @type {number} */
91
+ const PROBLEMS_HEIGHT = 96;
92
+
93
+ /**
94
+ * One colour per type a value can have, and one for a port whose value is not known — nothing
95
+ * wired into it yet, or a parameter that does not describe a width.
96
+ *
97
+ * Every port in the library is declared with the one value type; which value it carries is
98
+ * resolved per node by `infer_particle_graph_types`, and that is what a port is coloured by and a
99
+ * wire drawn in. A wire meeting a port of another colour is a conversion, which is the point: a
100
+ * `vec4` literal feeding a `vec3` add shows as a pink wire into an amber port.
101
+ *
102
+ * Unresolved is registered rather than left to the default because the default exists for a type
103
+ * nobody has thought about, and this one has been.
104
+ *
105
+ * A colour is a `vec4` and gets a colour of its own anyway. Nothing is converted where the two
106
+ * meet — they are the same four lanes — so the change of hue along a wire is not a warning about
107
+ * anything; it is where a raw vector starts being used as a colour, or a colour stops being one,
108
+ * which is the thing a semantic type exists to make visible.
109
+ *
110
+ * @type {Map<number, Color>} data type id -> colour
111
+ */
112
+ const PARTICLE_TYPE_COLORS = new Map([
113
+ [PARTICLE_VALUE_TYPE.id, new Color(0.58, 0.62, 0.68)],
114
+ [PARTICLE_TYPE_F32.id, new Color(0.55, 0.80, 1.0)],
115
+ [PARTICLE_TYPE_VEC2.id, new Color(0.55, 0.88, 0.50)],
116
+ [PARTICLE_TYPE_VEC3.id, new Color(1.0, 0.78, 0.35)],
117
+ [PARTICLE_TYPE_VEC4.id, new Color(0.95, 0.55, 0.80)],
118
+ [PARTICLE_TYPE_COLOR.id, new Color(0.72, 0.60, 0.98)],
119
+ ]);
120
+
121
+ /**
122
+ * The categories the add-node menu groups the library into, in the order they are offered. A node
123
+ * type not named here falls into "other", so the library gaining a type never hides it.
124
+ *
125
+ * @type {Array<{name: string, types: string[]}>}
126
+ */
127
+ const PALETTE_CATEGORIES = [
128
+ { name: "sources", types: ["const", "color", "builtin", "attribute", "random", "curve"] },
129
+ { name: "output", types: ["setAttribute", "kill"] },
130
+ { name: "arithmetic", types: ["add", "sub", "mul", "div", "mad", "scale", "min", "max", "pow", "step", "mix", "clamp", "smoothstep", "remap", "oneMinus"] },
131
+ { name: "math", types: ["neg", "abs", "floor", "fract", "round", "ceil", "sqrt", "sin", "cos", "exp", "log"] },
132
+ { name: "vector", types: ["vec2", "vec3", "vec4", "decompose2", "decompose3", "decompose4", "swizzle", "dot", "cross", "length", "normalize", "distance", "angleBetween2", "angleBetween3"] },
133
+ { name: "logic", types: ["compare", "select"] },
134
+ { name: "rotation", types: ["quatFromAxisAngle", "quatLookRotation", "quatRotate"] },
135
+ { name: "sampling", types: ["sampleSphereSurface", "sampleSphereVolume"] },
136
+ { name: "noise", types: ["simplex3", "simplex4", "curl3", "curl4"] },
137
+ ];
138
+
139
+ /**
140
+ * Whether a port could take a value of a given type, for the menu that finishes a dropped wire.
141
+ *
142
+ * Every port in the library declares the one {@link PARTICLE_VALUE_TYPE} — including a group's, so
143
+ * that a wire may be dragged between any two ports and the graph model never refuses one on a type
144
+ * it does not decide. What a particle node reads is decided by what is wired into it, so for a stock
145
+ * type the answer is always yes, and what the menu is really filtering by is which side the wire came
146
+ * out of. That is the useful filter anyway: a wire out of an output cannot be finished by a `const`.
147
+ *
148
+ * A group *declares* what each of its ports is, separately from the port, and there the answer means
149
+ * something. A value goes in if the shapes match, if it is a scalar (which broadcasts), or if the
150
+ * port is wider (the missing lanes read zero). A port narrower than the value is left out: offering
151
+ * `cross` for a `vec4` would be offering to drop a lane. A group port declared with no type at all
152
+ * takes the shape of what arrives, and so takes anything.
153
+ *
154
+ * @param {Port} port
155
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleValueType.js").ParticleValueType|null} dataType
156
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleNodeDescription.js").ParticleNodeDescription} description
157
+ * @returns {boolean}
158
+ */
159
+ function particle_port_accepts(port, dataType, description) {
160
+ if (dataType === null || dataType.isParticleValueType !== true) {
161
+ return true;
162
+ }
163
+
164
+ const declared = description.group?.portType(port.name, port.direction) ?? null;
165
+
166
+ if (declared === null) {
167
+ return true;
168
+ }
169
+
170
+ return dataType.is_scalar || declared.components >= dataType.components;
171
+ }
172
+
173
+ export class ParticleGraphEditorView extends View {
174
+ /**
175
+ * @type {Array<{id: string, label: string, editor: NodeGraphEditorView, toggle: View}>}
176
+ */
177
+ #phases = [];
178
+
179
+ /**
180
+ * @type {string}
181
+ */
182
+ #active = "init";
183
+
184
+ /**
185
+ * @type {EmptyView}
186
+ */
187
+ #problems;
188
+
189
+ /**
190
+ * @type {EmptyView}
191
+ */
192
+ #body;
193
+
194
+ /**
195
+ * @type {EmptyView}
196
+ */
197
+ #toolbar;
198
+
199
+ /**
200
+ * The breadcrumb back out of whatever groups are open, and empty while none is.
201
+ * @type {EmptyView}
202
+ */
203
+ #trail;
204
+
205
+ /**
206
+ * The two commands whose availability depends on what is selected. See {@link #refreshCommands}.
207
+ * @type {View}
208
+ */
209
+ #group_button;
210
+
211
+ /**
212
+ * @type {View}
213
+ */
214
+ #ungroup_button;
215
+
216
+ /**
217
+ * The groups currently open, outermost first, each with the canvas showing it. Empty means the
218
+ * phase graphs are what is on screen.
219
+ *
220
+ * @type {Array<{group: import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup, editor: NodeGraphEditorView}>}
221
+ */
222
+ #open_groups = [];
223
+
224
+ /**
225
+ * Phases whose camera has not yet been pointed at their contents. A graph that has just been
226
+ * arranged for the first time is somewhere in particular, and it is not the origin.
227
+ * Discharged by {@link #frameIfNeeded}.
228
+ * @type {Set<string>}
229
+ */
230
+ #needs_framing = new Set();
231
+
232
+ /**
233
+ * The last compile's diagnostics, kept so a node view that appears after them can still be
234
+ * marked. Nodes arrive from an undo as readily as from the menu.
235
+ * @type {Array<{scope: string, node: number, severity: string}>}
236
+ */
237
+ #diagnostics = [];
238
+
239
+ /**
240
+ * The resolved types of each phase's graph, by phase id, as of the last change to the effect.
241
+ * Filled on demand — see {@link #typesOf} — and emptied whenever the effect changes, since any
242
+ * edit may retype ports far from itself.
243
+ * @type {Map<string, import("../../../../src/shade/renderer/particles/graph/infer_particle_graph_types.js").ParticleGraphTypes>}
244
+ */
245
+ #types = new Map();
246
+
247
+ /**
248
+ * The resolved types of each open group's body, by group. See {@link #groupTypes}.
249
+ * @type {Map<import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup, import("../../../../src/shade/renderer/particles/graph/infer_particle_graph_types.js").ParticleGraphTypes>}
250
+ */
251
+ #group_types = new Map();
252
+
253
+ /**
254
+ * @param {object} options
255
+ * @param {import("../../../particles/effect/ParticleEffectDocument.js").ParticleEffectDocument} options.effect
256
+ * @param {ActionProcessor} [options.actionProcessor] shared with a host editor for a single undo
257
+ * timeline across the whole application
258
+ */
259
+ constructor({ effect, actionProcessor = new ActionProcessor({}) }) {
260
+ super();
261
+
262
+ this.el = document.createElement('div');
263
+
264
+ this.addClass('ui-particle-graph-editor');
265
+
266
+ /**
267
+ * @type {import("../../../particles/effect/ParticleEffectDocument.js").ParticleEffectDocument}
268
+ */
269
+ this.effect = effect;
270
+
271
+ /**
272
+ * @type {ActionProcessor}
273
+ */
274
+ this.actionProcessor = actionProcessor;
275
+
276
+ this.#toolbar = new EmptyView({ classList: ['toolbar'] });
277
+ this.#body = new EmptyView({ classList: ['body'] });
278
+ this.#problems = new EmptyView({ classList: ['problems'] });
279
+
280
+ for (const phase of [{ id: "init", label: "INIT" }, { id: "update", label: "UPDATE" }]) {
281
+ this.#phases.push(this.#buildPhase(phase.id, phase.label));
282
+ }
283
+
284
+ this.addChild(this.#toolbar);
285
+ this.addChild(this.#body);
286
+ this.addChild(this.#problems);
287
+
288
+ this.#buildToolbar();
289
+
290
+ this.setPhase(this.#active);
291
+
292
+ this.#refreshCommands();
293
+
294
+ // Before anything else downstream of a change: a node cannot be drawn until every canvas
295
+ // knows how big its type is, and a group the author just made is a type nothing has seen.
296
+ this.bindSignal(effect.on.changed, this.#ensureGroupPrototypes, this);
297
+
298
+ this.#ensureGroupPrototypes();
299
+
300
+ this.bindSignal(effect.on.changed, this.refreshProblems, this);
301
+ this.on.linked.add(this.refreshProblems, this);
302
+
303
+ // a port's type follows the graph, so every change is a chance for every port to differ
304
+ this.bindSignal(effect.on.changed, this.#refreshTypes, this);
305
+
306
+ this.bindSignal(this.size.onChanged, this.layout, this);
307
+ this.on.linked.add(this.layout, this);
308
+
309
+ this.#bindShortcuts();
310
+ }
311
+
312
+ /**
313
+ * `Ctrl+G` groups the selection and `Ctrl+Shift+G` opens one back up.
314
+ *
315
+ * On this view rather than on a canvas, because it is this view that owns both commands and
316
+ * because a keystroke has to reach them whichever canvas happens to be on screen. The canvases
317
+ * do not stop key events, so one typed over a graph arrives here.
318
+ */
319
+ #bindShortcuts() {
320
+ this.el.setAttribute('tabindex', '-1');
321
+
322
+ const keyboard = new KeyboardDevice(this.el);
323
+
324
+ keyboard.on.down.add(event => {
325
+ if (!event.ctrlKey || event.keyCode !== KeyCodes.g) {
326
+ return;
327
+ }
328
+
329
+ const target = event.target;
330
+
331
+ if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
332
+ // typing into a field — a node's parameter, the search box, a group's name
333
+ return;
334
+ }
335
+
336
+ event.preventDefault();
337
+ event.stopPropagation();
338
+
339
+ const done = event.shiftKey ? this.ungroupSelection() : this.groupSelection();
340
+
341
+ done.catch(e => console.error(event.shiftKey ? "could not ungroup" : "could not group", e));
342
+ });
343
+
344
+ this.on.linked.add(keyboard.start, keyboard);
345
+ this.on.unlinked.add(keyboard.stop, keyboard);
346
+ }
347
+
348
+ /**
349
+ * @param {string} id
350
+ * @param {string} label
351
+ * @returns {{id: string, label: string, editor: NodeGraphEditorView, toggle: View}}
352
+ */
353
+ #buildPhase(id, label) {
354
+ const effect = this.effect;
355
+
356
+ const visual = effect[`${id}_visual`];
357
+
358
+ for (const [type_id, color] of PARTICLE_TYPE_COLORS) {
359
+ visual.addDataColor(type_id, color);
360
+ }
361
+
362
+ // A graph nobody has placed yet — a new effect, or one loaded from a file with no positions
363
+ // — would otherwise open as a stack of nodes on top of each other at the origin. Checked
364
+ // before the editor is built, because building it gives every node visual data at 0,0 and
365
+ // there is then no way to tell "not placed" from "placed at the origin".
366
+ const unplaced = visual.nodes.size === 0 && effect[id].getNodes().length > 0;
367
+
368
+ const editor = this.#buildCanvas({
369
+ graph: effect[id],
370
+ visual,
371
+ types: () => this.#typesOf(id),
372
+ });
373
+
374
+ editor.addClass(`phase-${id}`);
375
+
376
+ if (unplaced) {
377
+ editor.layout();
378
+
379
+ // the camera cannot be pointed at the result yet, see #frameIfNeeded
380
+ this.#needs_framing.add(id);
381
+ }
382
+
383
+ this.bindSignal(editor.on.arranged, () => this.#frameIfNeeded());
384
+
385
+ this.#body.addChild(editor);
386
+
387
+ // A node's marker cannot be applied off the document's change signal: that fires before the
388
+ // graph view has built the node's view, because this view's bindings are linked before its
389
+ // children's. The graph view says when the view exists, which is the only moment that works
390
+ // — for a node the canvas menu just added and for one an undo brings back alike.
391
+ this.bindSignal(editor.graphView.on.nodeViewAdded, node => this.#markNode(id, node.id));
392
+
393
+ // Two phases, two maps, one opinion about whether a map is wanted. Folding one away and
394
+ // finding the other still open on the next phase switch would read as the fold not having
395
+ // worked. Setting a value it already holds announces nothing, so this settles rather than
396
+ // loops.
397
+ this.bindSignal(editor.minimap.collapsed.onChanged, collapsed => {
398
+ for (const phase of this.#phases) {
399
+ phase.editor.minimap.collapsed.set(collapsed);
400
+ }
401
+ });
402
+
403
+ const toggle = new EmptyView({ classList: ['phase-toggle'] });
404
+
405
+ toggle.addChild(new LabelView(label, { classList: ['label'] }));
406
+ toggle.el.addEventListener('click', () => this.setPhase(id));
407
+
408
+ this.#toolbar.addChild(toggle);
409
+
410
+ return { id, label, editor, toggle };
411
+ }
412
+
413
+ /**
414
+ * One canvas over one graph, with everything particle-specific wired into the base's seams.
415
+ *
416
+ * Shared between the two phase graphs and the body of every group that gets opened, because they
417
+ * differ in exactly two things — which graph, and whether it can be edited — and everything else
418
+ * about how a particle graph is drawn and added to should not be written twice.
419
+ *
420
+ * @param {object} options
421
+ * @param {NodeGraph} options.graph
422
+ * @param {NodeGraphVisualData} options.visual
423
+ * @param {function():import("../../../../src/shade/renderer/particles/graph/infer_particle_graph_types.js").ParticleGraphTypes} options.types
424
+ * @param {boolean} [options.readOnly]
425
+ * @returns {NodeGraphEditorView}
426
+ */
427
+ #buildCanvas({ graph, visual, types, readOnly = false }) {
428
+ const effect = this.effect;
429
+
430
+ for (const [type_id, color] of PARTICLE_TYPE_COLORS) {
431
+ visual.addDataColor(type_id, color);
432
+ }
433
+
434
+ const editor = new NodeGraphEditorView({
435
+ graph,
436
+ nodeRegistry: PARTICLE_NODE_REGISTRY,
437
+ visual,
438
+ camera: new NodeGraphCamera(),
439
+ actionProcessor: this.actionProcessor,
440
+ readOnly,
441
+ library: {
442
+ // The menu heads each *run* of one category, so the order it is handed decides the
443
+ // order it shows; sorting here keeps that decision on the particle side of the seam.
444
+ descriptions: () => [...particle_library_descriptions(), ...effect.groups.map(g => g.description)]
445
+ .sort((a, b) => category_rank(a.name) - category_rank(b.name)),
446
+ categoryOf: description => category_of(description.name),
447
+ describe: description => description.help,
448
+ accepts: particle_port_accepts,
449
+ parametersOf: description => this.#defaultParameters(description),
450
+ },
451
+ parameterViewFactory: ({ node, commit }) => {
452
+ // A group's configuration is its wiring, and its boundary blocks are its edge:
453
+ // neither declares a parameter, and neither is in the schema to be asked about. A
454
+ // node with no parameters gets no container at all, rather than an empty one.
455
+ if (is_particle_group_description(node.description)) {
456
+ return null;
457
+ }
458
+
459
+ if (particle_node_parameters(node.description.name).length === 0) {
460
+ return null;
461
+ }
462
+
463
+ return new ParticleNodeParametersView({ effect, node, commit });
464
+ },
465
+ // What a port carries on this node: its output's type, or for an input the type the
466
+ // node reads it as — which is what an empty port is waiting for. Unknown falls back to
467
+ // the declared type, and its colour.
468
+ portDataType: endpoint => {
469
+ const resolved = types();
470
+
471
+ const type = endpoint.port.direction === PortDirection.Out
472
+ ? resolved.output(endpoint.instance.id, endpoint.port.name)
473
+ : resolved.input(endpoint.instance.id, endpoint.port.name);
474
+
475
+ return type ?? endpoint.port.dataType;
476
+ },
477
+ });
478
+
479
+ // Before anything is drawn on it: a canvas cannot build a node until its registry knows how
480
+ // big the type is, and the types this document made are in no shared registry.
481
+ this.#generateGroupPrototypes(editor);
482
+
483
+ // what the commands apply to is what is selected, and that is per canvas
484
+ for (const signal of [editor.selection.nodes.on.added, editor.selection.nodes.on.removed]) {
485
+ editor.bindSignal(signal, () => this.#refreshCommands());
486
+ }
487
+
488
+ // Double-click a group to open it. Bound on the canvas rather than on this view, so that
489
+ // closing a group takes its bindings with it — and bindings are linked before children, so
490
+ // this is in place before the graph view builds the first node.
491
+ editor.bindSignal(editor.graphView.on.nodeViewAdded, (node, nodeView) => {
492
+ if (node.description.isParticleGroupBoundaryDescription === true) {
493
+ nodeView.addClass('is-group-boundary');
494
+
495
+ return;
496
+ }
497
+
498
+ if (node.description.isParticleGroupNodeDescription !== true) {
499
+ return;
500
+ }
501
+
502
+ nodeView.addClass('is-group');
503
+
504
+ nodeView.el.addEventListener('dblclick', event => {
505
+ event.preventDefault();
506
+ event.stopPropagation();
507
+
508
+ this.openGroup(node.description.group);
509
+ });
510
+ });
511
+
512
+ return editor;
513
+ }
514
+
515
+ /**
516
+ * The parameters a node of this type should arrive with.
517
+ *
518
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleNodeDescription.js").ParticleNodeDescription} description
519
+ * @returns {object}
520
+ */
521
+ #defaultParameters(description) {
522
+ if (is_particle_group_description(description)) {
523
+ return {};
524
+ }
525
+
526
+ return particle_node_default_parameters(description.name, { layout: this.#layoutOrNothing() });
527
+ }
528
+
529
+ /**
530
+ * Give every canvas a box for every node type this document carries of its own.
531
+ *
532
+ * A canvas generates the box it draws a node in from the registry it was built with, and throws
533
+ * when it cannot find one — which is the right behaviour, since the alternative is a node drawn
534
+ * at nothing by nothing. A group an author has just made is a type that registry has never seen,
535
+ * so it is told here, on every change, for every canvas.
536
+ *
537
+ * Cheap and idempotent: a registry generates a box from port and parameter counts and keys it by
538
+ * the description's id, so telling it twice about the same type costs an arithmetic pass.
539
+ */
540
+ #ensureGroupPrototypes() {
541
+ for (const canvas of [...this.#phases.map(phase => phase.editor), ...this.#open_groups.map(open => open.editor)]) {
542
+ this.#generateGroupPrototypes(canvas);
543
+ }
544
+ }
545
+
546
+ /**
547
+ * The same, for one canvas — which is what a canvas built after the fact needs, and there is no
548
+ * change to hang it off: a group's body is opened, not announced.
549
+ *
550
+ * @param {NodeGraphEditorView} canvas
551
+ */
552
+ #generateGroupPrototypes(canvas) {
553
+ for (const group of this.effect.groups) {
554
+ for (const description of particle_group_descriptions(group)) {
555
+ canvas.visualRegistry.generate(description);
556
+ }
557
+ }
558
+ }
559
+
560
+ #buildToolbar() {
561
+ this.#trail = new EmptyView({ classList: ['group-trail'] });
562
+
563
+ this.#toolbar.addChild(this.#trail);
564
+
565
+ this.#toolbar.addChild(new EmptyView({ classList: ['spacer'] }));
566
+
567
+ this.#group_button = this.#buildButton("Group", () => {
568
+ this.groupSelection().catch(e => console.error("could not group the selection", e));
569
+ });
570
+
571
+ this.#ungroup_button = this.#buildButton("Ungroup", () => {
572
+ this.ungroupSelection().catch(e => console.error("could not ungroup", e));
573
+ });
574
+
575
+ this.#toolbar.addChild(this.#group_button);
576
+ this.#toolbar.addChild(this.#ungroup_button);
577
+
578
+ // The auto-layouter moves every node, which is a big enough change to an author's
579
+ // arrangement that it belongs behind a button rather than happening on its own — and behind
580
+ // an undo, which is what {@link arrange} adds over calling the layouter directly.
581
+ this.#toolbar.addChild(this.#buildButton("Arrange", () => this.arrange()));
582
+ }
583
+
584
+ /**
585
+ * Say whether each command applies to what is selected right now, and why not when it does not.
586
+ *
587
+ * Grouping can be refused for a reason that is not obvious from looking at the canvas — a
588
+ * selection something outside it runs in the middle of cannot become one node — and a button that
589
+ * looked available and then did nothing would be the worst of both. So the reason is worked out
590
+ * up front and shown on the button, which is where an author will look for it.
591
+ *
592
+ * Cheap: the check is a walk downstream from the selection, over a graph with tens of nodes in
593
+ * it, run when the selection changes.
594
+ */
595
+ #refreshCommands() {
596
+ const editor = this.activeEditor();
597
+
598
+ const selected = editor.selection.nodes.asArray();
599
+
600
+ const grouping = this.#whyNotGroup(editor, selected);
601
+
602
+ this.#group_button.setClass('disabled', grouping !== null);
603
+ this.#group_button.el.setAttribute('title', grouping ?? "make one node out of the selection (Ctrl+G)");
604
+
605
+ const groups = selected
606
+ .map(id => editor.graph.getNode(id))
607
+ .filter(node => node?.description.isParticleGroupNodeDescription === true);
608
+
609
+ const ungrouping = editor.readOnly
610
+ ? "this group is locked"
611
+ : (groups.length === 0 ? "select a group node" : null);
612
+
613
+ this.#ungroup_button.setClass('disabled', ungrouping !== null);
614
+ this.#ungroup_button.el.setAttribute('title', ungrouping ?? "put back what the group is made of (Ctrl+Shift+G)");
615
+ }
616
+
617
+ /**
618
+ * Why the selection cannot be grouped, or `null` when it can.
619
+ *
620
+ * @param {NodeGraphEditorView} editor
621
+ * @param {number[]} selected
622
+ * @returns {string|null}
623
+ */
624
+ #whyNotGroup(editor, selected) {
625
+ if (editor.readOnly) {
626
+ return "this group is locked";
627
+ }
628
+
629
+ if (selected.length === 0) {
630
+ return "select something to group";
631
+ }
632
+
633
+ try {
634
+ // built and thrown away: the question "could this be grouped" and the answer "here is the
635
+ // group" are the same work, and doing it twice is cheaper than two ways of being wrong
636
+ particle_group_from_nodes({
637
+ graph: editor.graph,
638
+ nodes: selected,
639
+ name: "__probe",
640
+ });
641
+ } catch (e) {
642
+ return e.message;
643
+ }
644
+
645
+ return null;
646
+ }
647
+
648
+ /**
649
+ * Turn what is selected into a group, and put the group where the selection was.
650
+ *
651
+ * The one gesture that makes a graph smaller. Which wires become ports, what they are called and
652
+ * what type they are is worked out from the selection — see
653
+ * {@link ../../../../src/shade/renderer/particles/graph/make_particle_group.js} — so a group
654
+ * arrives finished rather than as a form to fill in, and its face is the author's to change
655
+ * afterwards.
656
+ *
657
+ * Everything it does is one step on the timeline: the nodes leaving, the group type appearing,
658
+ * the node that replaces them, and every wire re-made around it. An undo that left a type behind
659
+ * in the add-node menu would be an undo that did not undo.
660
+ *
661
+ * @returns {Promise<NodeInstance|null>} the node that replaced the selection, or null when there
662
+ * was nothing selected to group
663
+ */
664
+ async groupSelection() {
665
+ const editor = this.activeEditor();
666
+
667
+ if (editor.readOnly) {
668
+ throw new Error("This group is locked, so what is inside it cannot be re-grouped.");
669
+ }
670
+
671
+ const selected = editor.selection.nodes.asArray().slice();
672
+
673
+ if (selected.length === 0) {
674
+ return null;
675
+ }
676
+
677
+ const graph = editor.graph;
678
+ const visual = editor.visual;
679
+
680
+ const { group, inputs, outputs } = particle_group_from_nodes({
681
+ graph,
682
+ visual,
683
+ visualRegistry: editor.visualRegistry,
684
+ layout: this.#layoutOrNothing(),
685
+ nodes: selected,
686
+ name: this.effect.unusedGroupName(),
687
+ label: `Group ${this.effect.groups.length + 1}`,
688
+ help: "a group made from a selection",
689
+ icon: PARTICLE_GROUP_ICON,
690
+ });
691
+
692
+ const centre = centroid(visual, selected);
693
+
694
+ const create = new NodeCreateAction(
695
+ graph, visual, editor.visualRegistry, group.description, centre.x, centre.y
696
+ );
697
+
698
+ this.actionProcessor.mark('group');
699
+
700
+ // The group is defined before the node that uses it is created: creating one needs a box to
701
+ // draw it in, and that is generated when the document announces the type.
702
+ await this.actionProcessor.doMany([
703
+ new SelectionSetAction(editor.selection, [], []),
704
+ ...selected.map(id => new NodeDeleteAction(graph, visual, id)),
705
+ new ParticleGroupDefineAction(this.effect, group),
706
+ create,
707
+ ]);
708
+
709
+ const node = create.node;
710
+
711
+ const wires = [];
712
+
713
+ for (const entry of inputs) {
714
+ const port = group.description.findPortByNameAndDirection(entry.port, PortDirection.In);
715
+
716
+ wires.push(new ConnectionCreateAction(graph, entry.from.node, entry.from.port, node.id, port.id));
717
+ }
718
+
719
+ for (const entry of outputs) {
720
+ const port = group.description.findPortByNameAndDirection(entry.port, PortDirection.Out);
721
+
722
+ for (const target of entry.to) {
723
+ wires.push(new ConnectionCreateAction(graph, node.id, port.id, target.node, target.port));
724
+ }
725
+ }
726
+
727
+ // and what is selected afterwards is the thing the author just made
728
+ wires.push(new SelectionSetAction(editor.selection, [node.id], []));
729
+
730
+ await this.actionProcessor.doMany(wires);
731
+
732
+ return node;
733
+ }
734
+
735
+ /**
736
+ * Replace every selected group node with the nodes it is made of.
737
+ *
738
+ * The way out of a grouping made by mistake, and the way in to a library group an author wants to
739
+ * change one use of: the definition is not touched, only this instance. What lands in the graph
740
+ * is what compilation would have inlined anyway.
741
+ *
742
+ * @returns {Promise<NodeInstance[]>} the nodes that replaced them; empty when nothing applied
743
+ */
744
+ async ungroupSelection() {
745
+ const editor = this.activeEditor();
746
+
747
+ if (editor.readOnly) {
748
+ throw new Error("This group is locked, so what is inside it cannot be changed.");
749
+ }
750
+
751
+ const selected = editor.selection.nodes.asArray()
752
+ .map(id => editor.graph.getNode(id))
753
+ .filter(node => node !== undefined && node.description.isParticleGroupNodeDescription === true);
754
+
755
+ if (selected.length === 0) {
756
+ return [];
757
+ }
758
+
759
+ this.actionProcessor.mark('ungroup');
760
+
761
+ const opened = [];
762
+
763
+ for (const node of selected) {
764
+ opened.push(...await this.#ungroup(editor, node));
765
+ }
766
+
767
+ await this.actionProcessor.do(new SelectionSetAction(
768
+ editor.selection,
769
+ opened.map(node => node.id),
770
+ []
771
+ ));
772
+
773
+ return opened;
774
+ }
775
+
776
+ /**
777
+ * One group node, replaced by a copy of its body.
778
+ *
779
+ * Built out of the same actions every other edit is, rather than as a bespoke reversible splice:
780
+ * the nodes arrive through {@link NodeCreateAction}, the wires through
781
+ * {@link ConnectionCreateAction}, and the group node leaves through {@link NodeDeleteAction}, so
782
+ * undo already knows what to do with all of it.
783
+ *
784
+ * @param {NodeGraphEditorView} editor
785
+ * @param {NodeInstance} node the group instance
786
+ * @returns {Promise<NodeInstance[]>}
787
+ */
788
+ async #ungroup(editor, node) {
789
+ const graph = editor.graph;
790
+ const visual = editor.visual;
791
+
792
+ const group = node.description.group;
793
+ const body = group.graph;
794
+
795
+ const placed = visual.getNode(node.id)?.dimensions.position;
796
+
797
+ // Where the body sits inside the group, so what comes out of it lands around where the node
798
+ // was rather than at the origin.
799
+ const origin = body_origin(group);
800
+
801
+ /** @type {Map<number, NodeCreateAction>} body node id -> the action that recreates it */
802
+ const created = new Map();
803
+
804
+ for (const inner of body.getNodes()) {
805
+ if (inner === group.inputNode || inner === group.outputNode) {
806
+ continue;
807
+ }
808
+
809
+ const at = group.visual.getNode(inner.id)?.dimensions.position;
810
+
811
+ created.set(inner.id, new NodeCreateAction(
812
+ graph,
813
+ visual,
814
+ editor.visualRegistry,
815
+ inner.description,
816
+ (placed?.x ?? 0) + (at === undefined ? 0 : at.x - origin.x),
817
+ (placed?.y ?? 0) + (at === undefined ? 0 : at.y - origin.y),
818
+ clone_parameters(inner.parameters)
819
+ ));
820
+ }
821
+
822
+ await this.actionProcessor.doMany(Array.from(created.values()));
823
+
824
+ // What the group node was wired to, read before it goes.
825
+ const sources = new Map();
826
+ const targets = new Map();
827
+
828
+ for (const connection of node.inConnections) {
829
+ sources.set(connection.target.port.name, {
830
+ node: connection.source.instance.id,
831
+ port: connection.source.port.id,
832
+ });
833
+ }
834
+
835
+ for (const connection of node.outConnections) {
836
+ const listed = targets.get(connection.source.port.name) ?? [];
837
+
838
+ listed.push({ node: connection.target.instance.id, port: connection.target.port.id });
839
+
840
+ targets.set(connection.source.port.name, listed);
841
+ }
842
+
843
+ const wires = [];
844
+
845
+ for (const connection of body.getConnections()) {
846
+ const from = connection.source;
847
+ const to = connection.target;
848
+
849
+ const from_boundary = from.instance === group.inputNode;
850
+ const to_boundary = to.instance === group.outputNode;
851
+
852
+ if (from_boundary && to_boundary) {
853
+ const source = sources.get(from.port.name);
854
+
855
+ if (source !== undefined) {
856
+ for (const target of targets.get(to.port.name) ?? []) {
857
+ wires.push(new ConnectionCreateAction(
858
+ graph, source.node, source.port, target.node, target.port
859
+ ));
860
+ }
861
+ }
862
+
863
+ continue;
864
+ }
865
+
866
+ if (from_boundary) {
867
+ const source = sources.get(from.port.name);
868
+
869
+ if (source !== undefined) {
870
+ wires.push(new ConnectionCreateAction(
871
+ graph, source.node, source.port, created.get(to.instance.id).node.id, to.port.id
872
+ ));
873
+ }
874
+
875
+ continue;
876
+ }
877
+
878
+ if (to_boundary) {
879
+ for (const target of targets.get(to.port.name) ?? []) {
880
+ wires.push(new ConnectionCreateAction(
881
+ graph, created.get(from.instance.id).node.id, from.port.id, target.node, target.port
882
+ ));
883
+ }
884
+
885
+ continue;
886
+ }
887
+
888
+ wires.push(new ConnectionCreateAction(
889
+ graph,
890
+ created.get(from.instance.id).node.id, from.port.id,
891
+ created.get(to.instance.id).node.id, to.port.id
892
+ ));
893
+ }
894
+
895
+ // last: deleting the group node takes its own wires with it, and the ones above replace them
896
+ await this.actionProcessor.doMany([...wires, new NodeDeleteAction(graph, visual, node.id)]);
897
+
898
+ return Array.from(created.values()).map(action => action.node);
899
+ }
900
+
901
+ /**
902
+ * The effect's attribute schema, or nothing when the declarations do not make one.
903
+ *
904
+ * @returns {import("../../../../src/shade/renderer/particles/layout/ParticleLayout.js").ParticleLayout|undefined}
905
+ */
906
+ #layoutOrNothing() {
907
+ try {
908
+ return this.effect.buildLayout();
909
+ } catch (e) {
910
+ // a broken attribute schema types the attribute reads as unknown, and nothing else
911
+ return undefined;
912
+ }
913
+ }
914
+
915
+ /**
916
+ * Show the body of a group instead of the graph that holds it.
917
+ *
918
+ * Every instance of a group shares one body, so this is the group's own graph and not a copy of
919
+ * it — which is the point, and is why the ones shipped with the editor are locked: an edit inside
920
+ * an unlocked group is an edit to every instance of it in every effect. A locked one opens
921
+ * read-only, and is worth opening anyway to read.
922
+ *
923
+ * Groups nest, so this stacks: opening one from inside another pushes onto the trail rather than
924
+ * replacing it.
925
+ *
926
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup} group
927
+ * @returns {void}
928
+ */
929
+ openGroup(group) {
930
+ const unplaced = group.visual.nodes.size === 0;
931
+
932
+ const editor = this.#buildCanvas({
933
+ graph: group.graph,
934
+ visual: group.visual,
935
+ types: () => this.#groupTypes(group),
936
+ readOnly: group.locked,
937
+ });
938
+
939
+ editor.addClass('group-body');
940
+
941
+ this.#open_groups.push({ group, editor });
942
+
943
+ // An editable group's body is not part of the document, so nothing in the effect's change
944
+ // signal says when its types have moved. Its own graph does.
945
+ for (const signal of [
946
+ group.graph.on.nodeAdded,
947
+ group.graph.on.nodeRemoved,
948
+ group.graph.on.connectionAdded,
949
+ group.graph.on.connectionRemoved,
950
+ ]) {
951
+ editor.bindSignal(signal, () => {
952
+ this.#group_types.delete(group);
953
+
954
+ editor.graphView.refreshPortTypes();
955
+ });
956
+ }
957
+
958
+ this.#body.addChild(editor);
959
+
960
+ if (unplaced) {
961
+ // A group's body is built in code and has never been arranged, so the first time anybody
962
+ // looks at one is the moment to do it. The result is kept on the definition, so the
963
+ // second look is where the first one left it.
964
+ editor.layout();
965
+
966
+ // bound on the canvas rather than on this view, so closing the group takes the binding
967
+ // with it rather than leaving one pointed at a canvas nobody will draw again
968
+ editor.bindSignal(editor.on.arranged, final => {
969
+ if (final) {
970
+ editor.cameraContainAll();
971
+ }
972
+ });
973
+ }
974
+
975
+ this.#showActive();
976
+ this.layout();
977
+
978
+ if (!editor.isArrangementProvisional()) {
979
+ editor.cameraContainAll();
980
+ }
981
+ }
982
+
983
+ /**
984
+ * Leave the innermost open group. Harmless when none is open.
985
+ * @returns {void}
986
+ */
987
+ closeGroup() {
988
+ this.openGroupDepth(this.#open_groups.length - 1);
989
+ }
990
+
991
+ /**
992
+ * Go back to a particular depth in the trail: 0 is the phase graph, 1 the outermost group.
993
+ *
994
+ * @param {number} depth
995
+ * @returns {void}
996
+ */
997
+ openGroupDepth(depth) {
998
+ const target = Math.max(0, Math.min(depth, this.#open_groups.length));
999
+
1000
+ for (const closing of this.#open_groups.splice(target)) {
1001
+ this.#body.removeChild(closing.editor);
1002
+ }
1003
+
1004
+ this.#showActive();
1005
+ this.layout();
1006
+ }
1007
+
1008
+ /**
1009
+ * The groups currently open, outermost first.
1010
+ *
1011
+ * @returns {import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup[]}
1012
+ */
1013
+ openGroups() {
1014
+ return this.#open_groups.map(entry => entry.group);
1015
+ }
1016
+
1017
+ /**
1018
+ * Re-run the automatic layout over the graph on screen, as one undoable step.
1019
+ *
1020
+ * It moves every node in the graph, which makes it the most destructive thing on the toolbar:
1021
+ * an author who does not like the result has lost an arrangement they may have spent a while on.
1022
+ * So the positions before and after are recorded and pushed as a {@link NodesMoveAction}, the
1023
+ * same action a drag lands on the timeline.
1024
+ *
1025
+ * Inside a locked group it does nothing: an arrangement is a change to the group's definition
1026
+ * like any other, and a locked group's definition is not the author's to change.
1027
+ */
1028
+ arrange() {
1029
+ const editor = this.activeEditor();
1030
+
1031
+ if (editor.readOnly) {
1032
+ return;
1033
+ }
1034
+
1035
+ const open = this.#open_groups[this.#open_groups.length - 1];
1036
+
1037
+ const graph = open === undefined ? this.effect[this.#active] : open.group.graph;
1038
+ const visual = open === undefined ? this.effect[`${this.#active}_visual`] : open.group.visual;
1039
+
1040
+ /** @type {{visual: NodeVisualData, from: Vector2}[]} */
1041
+ const before = [];
1042
+
1043
+ for (const node of graph.getNodes()) {
1044
+ const node_visual = visual.getNode(node.id);
1045
+
1046
+ if (node_visual !== undefined) {
1047
+ before.push({ visual: node_visual, from: node_visual.dimensions.position.clone() });
1048
+ }
1049
+ }
1050
+
1051
+ editor.layout();
1052
+
1053
+ const moved = before.filter(entry => !entry.visual.dimensions.position.equals(entry.from));
1054
+
1055
+ if (moved.length === 0) {
1056
+ return;
1057
+ }
1058
+
1059
+ // the nodes are already where the layouter put them; the action records the net change so
1060
+ // the whole arrange lands on the timeline as one entry
1061
+ this.actionProcessor.mark('arrange');
1062
+ this.actionProcessor.do(new NodesMoveAction(moved.map(entry => ({
1063
+ visual: entry.visual,
1064
+ from: entry.from,
1065
+ to: entry.visual.dimensions.position.clone()
1066
+ }))));
1067
+ }
1068
+
1069
+ /**
1070
+ * @param {string} label
1071
+ * @param {function()} action
1072
+ * @returns {View}
1073
+ */
1074
+ #buildButton(label, action) {
1075
+ const button = new EmptyView({ classList: ['toolbar-button'] });
1076
+
1077
+ button.addChild(new LabelView(label));
1078
+
1079
+ button.el.addEventListener('click', () => {
1080
+ if (button.el.classList.contains('disabled')) {
1081
+ // the title says why, and doing nothing is what "disabled" means
1082
+ return;
1083
+ }
1084
+
1085
+ action();
1086
+ });
1087
+
1088
+ return button;
1089
+ }
1090
+
1091
+ /**
1092
+ * Add a node of the given type to the phase being edited, seeded with the defaults its type
1093
+ * declares — so what lands in the graph is a node that compiles rather than one to repair.
1094
+ *
1095
+ * @param {ParticleNodeDescription} description
1096
+ * @param {object} [options] position, see {@link NodeGraphEditorView#addNode}
1097
+ * @returns {Promise<NodeInstance>} the new node, once the action timeline has applied the add
1098
+ */
1099
+ async addNode(description, options = {}) {
1100
+ const editor = this.activeEditor();
1101
+
1102
+ if (editor.readOnly) {
1103
+ // the canvas on screen is a locked group's body, which is not the author's to add to
1104
+ throw new Error(
1105
+ `Cannot add a '${description.name}': `
1106
+ + `the group '${this.#open_groups[this.#open_groups.length - 1].group.name}' is locked.`
1107
+ );
1108
+ }
1109
+
1110
+ return editor.addNode(description, {
1111
+ ...options,
1112
+ parameters: this.#defaultParameters(description),
1113
+ });
1114
+ }
1115
+
1116
+ /**
1117
+ * The resolved types of one group's body, computed on first use and kept.
1118
+ *
1119
+ * A group's body does not change while an effect is being edited — the shipped ones are locked,
1120
+ * and an unlocked one changing is a change to the group rather than to the effect — so unlike a
1121
+ * phase's types these are not thrown away when the document changes. They are keyed on the group
1122
+ * itself, so two effects open on the same group share one answer.
1123
+ *
1124
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup} group
1125
+ * @returns {import("../../../../src/shade/renderer/particles/graph/infer_particle_graph_types.js").ParticleGraphTypes}
1126
+ */
1127
+ #groupTypes(group) {
1128
+ let types = this.#group_types.get(group);
1129
+
1130
+ if (types === undefined) {
1131
+ // No layout: a group has no effect and so no attribute schema of its own. A group that
1132
+ // reads an attribute types that read as unknown, which is honest — what it reads depends
1133
+ // on the effect it is placed in.
1134
+ types = infer_particle_graph_types(group.graph);
1135
+
1136
+ this.#group_types.set(group, types);
1137
+ }
1138
+
1139
+ return types;
1140
+ }
1141
+
1142
+ /**
1143
+ * The resolved types of one phase's graph, computed on first use since the effect last changed.
1144
+ *
1145
+ * @param {string} id `"init"` or `"update"`
1146
+ * @returns {import("../../../../src/shade/renderer/particles/graph/infer_particle_graph_types.js").ParticleGraphTypes}
1147
+ */
1148
+ #typesOf(id) {
1149
+ let types = this.#types.get(id);
1150
+
1151
+ if (types === undefined) {
1152
+ types = infer_particle_graph_types(this.effect[id], { layout: this.#layoutOrNothing() });
1153
+
1154
+ this.#types.set(id, types);
1155
+ }
1156
+
1157
+ return types;
1158
+ }
1159
+
1160
+ /**
1161
+ * Forget the resolved types and have every port in both phases ask again.
1162
+ *
1163
+ * The open groups are asked too. Their own types have not changed — a group's body is not part
1164
+ * of the document — but a group editor's ports are drawn by the same path, and one left showing
1165
+ * the colours it had before a rebuild would be the only stale thing on screen.
1166
+ */
1167
+ #refreshTypes() {
1168
+ this.#types.clear();
1169
+
1170
+ for (const phase of this.#phases) {
1171
+ phase.editor.graphView.refreshPortTypes();
1172
+ }
1173
+
1174
+ for (const open of this.#open_groups) {
1175
+ open.editor.graphView.refreshPortTypes();
1176
+ }
1177
+ }
1178
+
1179
+ /**
1180
+ * The canvas an edit would land on: the innermost open group, or the phase being edited.
1181
+ *
1182
+ * @returns {NodeGraphEditorView}
1183
+ */
1184
+ activeEditor() {
1185
+ const open = this.#open_groups[this.#open_groups.length - 1];
1186
+
1187
+ return open === undefined
1188
+ ? this.#phases.find(phase => phase.id === this.#active).editor
1189
+ : open.editor;
1190
+ }
1191
+
1192
+ /**
1193
+ * @returns {string} `"init"` or `"update"`
1194
+ */
1195
+ activePhase() {
1196
+ return this.#active;
1197
+ }
1198
+
1199
+ /**
1200
+ * Show one phase. Both stay built, so the one being left keeps its camera and its selection.
1201
+ * @param {string} id `"init"` or `"update"`
1202
+ */
1203
+ setPhase(id) {
1204
+ this.#active = id;
1205
+
1206
+ // A group is opened from a graph, so leaving that graph leaves the group. Coming back to
1207
+ // find somebody else's group still open would be the phase switch not having happened.
1208
+ for (const closing of this.#open_groups.splice(0)) {
1209
+ this.#body.removeChild(closing.editor);
1210
+ }
1211
+
1212
+ for (const phase of this.#phases) {
1213
+ phase.toggle.setClass('active', phase.id === id);
1214
+ }
1215
+
1216
+ this.#showActive();
1217
+
1218
+ this.layout();
1219
+ this.refreshProblems();
1220
+ }
1221
+
1222
+ /**
1223
+ * Show exactly one canvas — the innermost open group, or the active phase — and redraw the trail
1224
+ * back out to it.
1225
+ */
1226
+ #showActive() {
1227
+ const active = this.activeEditor();
1228
+
1229
+ for (const phase of this.#phases) {
1230
+ phase.editor.visible = phase.editor === active;
1231
+ }
1232
+
1233
+ for (const open of this.#open_groups) {
1234
+ open.editor.visible = open.editor === active;
1235
+ }
1236
+
1237
+ this.#refreshCommands();
1238
+
1239
+ this.#trail.removeAllChildren();
1240
+
1241
+ if (this.#open_groups.length === 0) {
1242
+ // nothing to find the way back from
1243
+ return;
1244
+ }
1245
+
1246
+ const crumb = (label, depth, group) => {
1247
+ const view = new EmptyView({ classList: ['crumb'] });
1248
+
1249
+ const current = depth === this.#open_groups.length;
1250
+
1251
+ if (current && group !== undefined && !group.locked) {
1252
+ // The group an author is inside, and made: its name is the one thing about it that
1253
+ // wants changing the moment it exists, so it is a field rather than a word.
1254
+ view.addChild(this.#buildGroupNameField(group));
1255
+ } else {
1256
+ // `name` rather than `label`: LabelView puts `label` on every one of its elements,
1257
+ // so the crumb's name and its "locked" tag would be indistinguishable by class
1258
+ view.addChild(new LabelView(label, { classList: ['name'] }));
1259
+ }
1260
+
1261
+ if (group?.locked === true) {
1262
+ view.addChild(new LabelView("locked", { classList: ['locked'] }));
1263
+ }
1264
+
1265
+ view.setClass('current', current);
1266
+
1267
+ view.el.addEventListener('click', event => {
1268
+ if (event.target instanceof HTMLInputElement) {
1269
+ // renaming the group is not asking to leave it
1270
+ return;
1271
+ }
1272
+
1273
+ this.openGroupDepth(depth);
1274
+ });
1275
+
1276
+ this.#trail.addChild(view);
1277
+ };
1278
+
1279
+ crumb(this.#active.toUpperCase(), 0, undefined);
1280
+
1281
+ this.#open_groups.forEach((open, index) => crumb(open.group.label, index + 1, open.group));
1282
+ }
1283
+
1284
+ /**
1285
+ * The field that renames the group being edited.
1286
+ *
1287
+ * What it changes is the *label* — what a person reads. The group's name is an address: it is
1288
+ * what a saved graph holds and what a node is resolved by, and renaming that would mean
1289
+ * rewriting every node that used it. Groups an author makes are numbered rather than named, and
1290
+ * this is what makes that all right.
1291
+ *
1292
+ * Committed when the field is left or Enter is pressed, not per keystroke: a rename that fires
1293
+ * on every letter would put a dozen entries on the undo timeline for one edit.
1294
+ *
1295
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup} group
1296
+ * @returns {View}
1297
+ */
1298
+ #buildGroupNameField(group) {
1299
+ const field = document.createElement('input');
1300
+
1301
+ field.setAttribute('type', 'text');
1302
+ field.setAttribute('spellcheck', 'false');
1303
+ field.classList.add('name', 'rename');
1304
+ field.value = group.label;
1305
+
1306
+ field.addEventListener('change', () => this.renameGroup(group, field.value));
1307
+
1308
+ field.addEventListener('keydown', event => {
1309
+ if (event.key === "Enter") {
1310
+ field.blur();
1311
+ }
1312
+ });
1313
+
1314
+ // typing a name is not a graph shortcut, and Delete in here must not delete the selection
1315
+ field.addEventListener('keydown', event => event.stopPropagation());
1316
+
1317
+ return new EmptyView({ el: field });
1318
+ }
1319
+
1320
+ /**
1321
+ * Call a group something else.
1322
+ *
1323
+ * Reaches every node already on screen that is an instance of it: a canvas is not rebuilt for a
1324
+ * word, and one left showing the old name would be the only stale thing in the window.
1325
+ *
1326
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup} group
1327
+ * @param {string} label
1328
+ * @returns {void}
1329
+ */
1330
+ renameGroup(group, label) {
1331
+ const wanted = label.trim();
1332
+
1333
+ if (wanted === "" || wanted === group.label) {
1334
+ return;
1335
+ }
1336
+
1337
+ group.label = wanted;
1338
+ group.description.display_label = wanted;
1339
+
1340
+ for (const canvas of [...this.#phases.map(phase => phase.editor), ...this.#open_groups.map(open => open.editor)]) {
1341
+ for (const nodeView of canvas.graphView.nodeViews.values()) {
1342
+ if (nodeView.node.description === group.description) {
1343
+ nodeView.refreshLabel();
1344
+ }
1345
+ }
1346
+ }
1347
+
1348
+ this.effect.touch();
1349
+ }
1350
+
1351
+ /**
1352
+ * Rebuild the problems strip from a fresh compile of the effect.
1353
+ *
1354
+ * Everything is listed, whichever phase it belongs to, because a problem in the phase an author
1355
+ * is not looking at is exactly the one they would otherwise hunt for. Nodes carrying a problem
1356
+ * are marked in the graph as well.
1357
+ */
1358
+ refreshProblems() {
1359
+ // The graph's own problems, not the running program's: with the code layer authoritative the
1360
+ // graphs are not compiled at all, and a panel that then said "no problems" about a graph
1361
+ // with a dangling input in plain sight would be lying about the thing it is showing.
1362
+ const diagnostics = this.effect.graphDiagnostics();
1363
+
1364
+ this.#diagnostics = diagnostics;
1365
+
1366
+ this.#problems.removeAllChildren();
1367
+
1368
+ if (diagnostics.length === 0) {
1369
+ this.#problems.addChild(new LabelView("No problems.", { classList: ['none'] }));
1370
+ }
1371
+
1372
+ for (const diagnostic of diagnostics) {
1373
+ const entry = new EmptyView({ classList: ['problem', diagnostic.severity] });
1374
+
1375
+ const where = diagnostic.node >= 0
1376
+ ? `${diagnostic.scope}: node ${diagnostic.node}`
1377
+ : diagnostic.scope;
1378
+
1379
+ entry.addChild(new LabelView(where, { classList: ['where'] }));
1380
+ entry.addChild(new LabelView(diagnostic.message, { classList: ['message'] }));
1381
+
1382
+ if (diagnostic.node >= 0) {
1383
+ entry.el.addEventListener('click', () => this.revealNode(diagnostic.scope, diagnostic.node));
1384
+ }
1385
+
1386
+ this.#problems.addChild(entry);
1387
+ }
1388
+
1389
+ this.#markProblemNodes(diagnostics);
1390
+ }
1391
+
1392
+ /**
1393
+ * Put a class on the view of every node a diagnostic names, so the graph shows where the
1394
+ * problems are and not only the list below it.
1395
+ *
1396
+ * @param {Array<{scope: string, node: number, severity: string}>} diagnostics
1397
+ */
1398
+ #markProblemNodes(diagnostics) {
1399
+ for (const phase of this.#phases) {
1400
+ for (const node_id of phase.editor.graphView.nodeViews.keys()) {
1401
+ this.#markNode(phase.id, node_id, diagnostics);
1402
+ }
1403
+ }
1404
+ }
1405
+
1406
+ /**
1407
+ * Mark one node from the diagnostics in hand.
1408
+ *
1409
+ * @param {string} phase_id
1410
+ * @param {number} node_id
1411
+ * @param {Array<{scope: string, node: number, severity: string}>} [diagnostics]
1412
+ */
1413
+ #markNode(phase_id, node_id, diagnostics = this.#diagnostics) {
1414
+ const phase = this.#phases.find(candidate => candidate.id === phase_id);
1415
+ const nodeView = phase?.editor.graphView.nodeViews.get(node_id);
1416
+
1417
+ if (nodeView === undefined) {
1418
+ return;
1419
+ }
1420
+
1421
+ let severity;
1422
+
1423
+ for (const diagnostic of diagnostics) {
1424
+ if (diagnostic.scope !== phase_id || diagnostic.node !== node_id) {
1425
+ continue;
1426
+ }
1427
+
1428
+ // an error outranks a warning on the same node
1429
+ if (diagnostic.severity === "error" || severity === undefined) {
1430
+ severity = diagnostic.severity;
1431
+ }
1432
+ }
1433
+
1434
+ nodeView.setClass('has-error', severity === "error");
1435
+ nodeView.setClass('has-warning', severity === "warning");
1436
+ }
1437
+
1438
+ /**
1439
+ * Switch to the phase a node is in and centre the view on it.
1440
+ *
1441
+ * @param {string} phase_id `"init"` or `"update"`
1442
+ * @param {number} node_id
1443
+ */
1444
+ revealNode(phase_id, node_id) {
1445
+ const phase = this.#phases.find(candidate => candidate.id === phase_id);
1446
+
1447
+ if (phase === undefined) {
1448
+ return;
1449
+ }
1450
+
1451
+ this.setPhase(phase_id);
1452
+
1453
+ const visual = this.effect[`${phase_id}_visual`].getNode(node_id);
1454
+
1455
+ if (visual === undefined) {
1456
+ return;
1457
+ }
1458
+
1459
+ const camera = phase.editor.camera;
1460
+ const scale = camera.scale.getValue();
1461
+
1462
+ camera.position.set(
1463
+ visual.dimensions.position.x + visual.dimensions.size.x / 2 - (phase.editor.size.x / 2) / scale,
1464
+ visual.dimensions.position.y + visual.dimensions.size.y / 2 - (phase.editor.size.y / 2) / scale
1465
+ );
1466
+
1467
+ phase.editor.selection.nodes.reset();
1468
+ phase.editor.selection.nodes.add(node_id);
1469
+ }
1470
+
1471
+ /**
1472
+ * The add-node menu of the canvas currently on screen — a test's way in, and a host's way to
1473
+ * open it from a menu of its own.
1474
+ *
1475
+ * @returns {import("../../node-graph/NodeGraphSearchMenuView.js").NodeGraphSearchMenuView|null}
1476
+ */
1477
+ searchMenu() {
1478
+ return this.activeEditor().searchMenu;
1479
+ }
1480
+
1481
+ layout() {
1482
+ const width = this.size.x;
1483
+ const height = this.size.y;
1484
+
1485
+ const body_height = Math.max(0, height - TOOLBAR_HEIGHT - PROBLEMS_HEIGHT);
1486
+
1487
+ this.#toolbar.position.set(0, 0);
1488
+ this.#toolbar.size.set(width, TOOLBAR_HEIGHT);
1489
+
1490
+ this.#body.position.set(0, TOOLBAR_HEIGHT);
1491
+ this.#body.size.set(width, body_height);
1492
+
1493
+ // Every canvas takes the whole body — the phases, and any group opened over them — because
1494
+ // exactly one of them is visible at a time.
1495
+ for (const canvas of [...this.#phases.map(phase => phase.editor), ...this.#open_groups.map(open => open.editor)]) {
1496
+ canvas.position.set(0, 0);
1497
+ canvas.size.set(width, body_height);
1498
+ }
1499
+
1500
+ this.#problems.position.set(0, TOOLBAR_HEIGHT + body_height);
1501
+ this.#problems.size.set(width, PROBLEMS_HEIGHT);
1502
+
1503
+ this.#frameIfNeeded();
1504
+ }
1505
+
1506
+ /**
1507
+ * Point the camera of any phase arranged for the first time at what the arranging produced.
1508
+ *
1509
+ * Two things have to have happened, and they arrive in either order — hence trying from both
1510
+ * ends. The editor needs a size, or there is no viewport to fit a graph into. And its
1511
+ * arrangement has to be the final one: a graph arranged before its nodes were drawn is arranged
1512
+ * again from their real sizes, and a camera aimed at the first attempt is aimed at where the
1513
+ * nodes were about to stop being.
1514
+ */
1515
+ #frameIfNeeded() {
1516
+ for (const phase of this.#phases) {
1517
+ if (!this.#needs_framing.has(phase.id)) {
1518
+ continue;
1519
+ }
1520
+
1521
+ const editor = phase.editor;
1522
+
1523
+ if (editor.size.x <= 0 || editor.size.y <= 0) {
1524
+ continue;
1525
+ }
1526
+
1527
+ if (editor.isArrangementProvisional()) {
1528
+ continue;
1529
+ }
1530
+
1531
+ this.#needs_framing.delete(phase.id);
1532
+
1533
+ editor.cameraContainAll();
1534
+ }
1535
+ }
1536
+ }
1537
+
1538
+ /**
1539
+ * The glyph a group made out of a selection carries: a box with a smaller box inside it, which is
1540
+ * what one is.
1541
+ *
1542
+ * @type {string}
1543
+ */
1544
+ const PARTICLE_GROUP_ICON = "M4 5h16v14H4z M9 10h6v4H9z";
1545
+
1546
+ /**
1547
+ * The middle of a set of nodes, in graph space, so a group lands where the thing it replaced was.
1548
+ *
1549
+ * @param {NodeGraphVisualData} visual
1550
+ * @param {number[]} nodes
1551
+ * @returns {{x: number, y: number}}
1552
+ */
1553
+ function centroid(visual, nodes) {
1554
+ let x = 0;
1555
+ let y = 0;
1556
+ let counted = 0;
1557
+
1558
+ for (const id of nodes) {
1559
+ const placed = visual.getNode(id);
1560
+
1561
+ if (placed === undefined) {
1562
+ continue;
1563
+ }
1564
+
1565
+ x += placed.dimensions.position.x;
1566
+ y += placed.dimensions.position.y;
1567
+
1568
+ counted++;
1569
+ }
1570
+
1571
+ return counted === 0 ? { x: 0, y: 0 } : { x: x / counted, y: y / counted };
1572
+ }
1573
+
1574
+ /**
1575
+ * The top-left corner of a group's body, so what comes out of an ungrouping keeps its arrangement
1576
+ * relative to where the group node was rather than jumping to wherever the body happens to sit.
1577
+ *
1578
+ * @param {import("../../../../src/shade/renderer/particles/graph/ParticleNodeGroup.js").ParticleNodeGroup} group
1579
+ * @returns {{x: number, y: number}}
1580
+ */
1581
+ function body_origin(group) {
1582
+ let x = Infinity;
1583
+ let y = Infinity;
1584
+
1585
+ for (const node of group.graph.getNodes()) {
1586
+ const placed = group.visual.getNode(node.id);
1587
+
1588
+ if (placed === undefined) {
1589
+ continue;
1590
+ }
1591
+
1592
+ x = Math.min(x, placed.dimensions.position.x);
1593
+ y = Math.min(y, placed.dimensions.position.y);
1594
+ }
1595
+
1596
+ return Number.isFinite(x) ? { x, y } : { x: 0, y: 0 };
1597
+ }
1598
+
1599
+ /**
1600
+ * A node's parameters, deep enough that the copy and the original cannot write through to each
1601
+ * other — an ungrouped node must not share an array with the group's definition.
1602
+ *
1603
+ * @param {object} parameters
1604
+ * @returns {object}
1605
+ */
1606
+ function clone_parameters(parameters) {
1607
+ const result = {};
1608
+
1609
+ for (const key of Object.keys(parameters)) {
1610
+ const value = parameters[key];
1611
+
1612
+ result[key] = Array.isArray(value) ? value.slice() : value;
1613
+ }
1614
+
1615
+ return result;
1616
+ }
1617
+
1618
+ /**
1619
+ * @param {string} type node type name
1620
+ * @returns {string}
1621
+ */
1622
+ function category_of(type) {
1623
+ const index = category_rank(type);
1624
+
1625
+ return index === PALETTE_CATEGORIES.length ? "other" : PALETTE_CATEGORIES[index].name;
1626
+ }
1627
+
1628
+ /**
1629
+ * @param {string} type node type name
1630
+ * @returns {number} index into {@link PALETTE_CATEGORIES}, or its length for an uncategorised type
1631
+ */
1632
+ function category_rank(type) {
1633
+ const index = PALETTE_CATEGORIES.findIndex(candidate => candidate.types.includes(type));
1634
+
1635
+ return index === -1 ? PALETTE_CATEGORIES.length : index;
1636
+ }