@woosh/meep-engine 3.16.0 → 3.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
- package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
- package/editor/particles/effect/ParticleEffectDocument.js +38 -17
- package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
- package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
- package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
- package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
- package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
- package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphView.js +84 -8
- package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
- package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
- package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
- package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
- package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
- package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
- package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
- package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
- package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
- package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
- package/editor/view/particles/effect/particle-editor.css +123 -35
- package/package.json +1 -1
- package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +10 -1
- package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
- package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
- package/src/core/collection/array/typed/float32_array_hash.js +38 -0
- package/src/core/graph/csr/CSRGraph.d.ts +8 -1
- package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
- package/src/core/graph/csr/CSRGraph.js +14 -6
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
- package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
- package/src/engine/animation/AnimationUtils.js +246 -246
- package/src/engine/animation/Animations.js +74 -74
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
- package/src/engine/ecs/EventType.d.ts +0 -1
- package/src/engine/ecs/EventType.js +1 -26
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
- package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
- package/src/engine/ecs/parent/EntityNode.js +4 -9
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
- package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
- package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
- package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
- package/src/engine/ecs/transform/t64_announce_change.js +12 -12
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
- package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
- package/src/engine/graphics3/LightSystem.js +4 -8
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +9 -19
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
- package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
- package/src/shade/playground/particle_editor/README.md +43 -2
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_prototype.js +4 -5
- package/src/shade/playground/particle_system/particle_scene.js +4 -4
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +13 -1
- package/src/shade/renderer/particles/DESIGN.md +104 -19
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
- package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
- package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
- package/src/shade/renderer/particles/ParticleConstants.js +66 -23
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
- package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
- package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
- package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
- package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
- package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
- package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
- package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
- package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
- package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
- package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
- package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
- package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +105 -262
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
- package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
- package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
- package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
- package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
- package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
- package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
- package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
- package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
- package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
- package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
- package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapCameraView.js +4 -9
- package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
- package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
- package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
- package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
- package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
- package/src/engine/ecs/transform/__probe.d.ts +0 -4
- package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
- package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
- package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
- package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
- package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
- package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
|
@@ -1,286 +1,438 @@
|
|
|
1
|
-
import { assert } from "../../../../core/assert.js";
|
|
2
|
-
import { GPUDatabase } from "../../buffer/table/GPUDatabase.js";
|
|
3
|
-
import {
|
|
4
|
-
PARTICLE_DATABASE_INITIAL_SIZE,
|
|
5
|
-
PARTICLE_DATABASE_SPEC,
|
|
6
|
-
PARTICLE_EMITTER_STATE_TABLE,
|
|
7
|
-
PARTICLE_EMITTER_TABLE
|
|
8
|
-
} from "../data/PARTICLE_DATABASE_SPEC.js";
|
|
9
|
-
import { PARTICLE_EMITTER_STATE_EMPTY } from "../data/PARTICLE_EMITTER_STATE.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* The
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*
|
|
68
|
-
* @type {ParticleEmitter[]}
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
* @
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
* @
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
*
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
*
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
*
|
|
141
|
-
* @
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
emitter
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { GPUDatabase } from "../../buffer/table/GPUDatabase.js";
|
|
3
|
+
import {
|
|
4
|
+
PARTICLE_DATABASE_INITIAL_SIZE,
|
|
5
|
+
PARTICLE_DATABASE_SPEC,
|
|
6
|
+
PARTICLE_EMITTER_STATE_TABLE,
|
|
7
|
+
PARTICLE_EMITTER_TABLE
|
|
8
|
+
} from "../data/PARTICLE_DATABASE_SPEC.js";
|
|
9
|
+
import { PARTICLE_EMITTER_STATE_EMPTY } from "../data/PARTICLE_EMITTER_STATE.js";
|
|
10
|
+
import { create_emitter_record, write_emitter_record } from "../data/particle_emitter_record.js";
|
|
11
|
+
import { PARTICLE_GENERATION_FIRST, particle_generation_next } from "../data/particle_header.js";
|
|
12
|
+
import { GPUParticleEmitterContext } from "./GPUParticleEmitterContext.js";
|
|
13
|
+
import { ParticleEmitter } from "./ParticleEmitter.js";
|
|
14
|
+
import { ProgramHeap } from "./ProgramHeap.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Staging for one emitter row. Reused across every write — the table serializes it into its page
|
|
18
|
+
* shadow synchronously, so nothing outlives the call. This is what keeps a frame's flush free of
|
|
19
|
+
* allocation whatever the number of rows it restages.
|
|
20
|
+
*/
|
|
21
|
+
const RECORD = create_emitter_record();
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The emitter set: {@link ParticleEmitter} instances on the CPU, one GPU table row each.
|
|
25
|
+
*
|
|
26
|
+
* Rows live in a {@link GPUDatabase} table ({@link ../data/PARTICLE_DATABASE_SPEC.js}), which is
|
|
27
|
+
* what makes the set editable at runtime. Adding an emitter stages one record; removing one frees
|
|
28
|
+
* its slot for the next add; changing one restages that record and nothing else. Rows are handed
|
|
29
|
+
* out by the table and are stable for an emitter's lifetime — they have to be, because every live
|
|
30
|
+
* particle's record header stores the row of the emitter that spawned it.
|
|
31
|
+
*
|
|
32
|
+
* Reuse of a freed row is made safe by the **generation**: every add takes the next value of one
|
|
33
|
+
* running counter, so no two emitters this registry has ever registered share one, and the
|
|
34
|
+
* particles of a removed emitter — which carry its generation — cannot be mistaken for the new
|
|
35
|
+
* tenant's. The simulate pass kills them on sight; see {@link ../data/particle_header.js}.
|
|
36
|
+
*
|
|
37
|
+
* **None of that bookkeeping is on the emitter.** An emitter is a scene node and a description of
|
|
38
|
+
* an effect, with nothing in it that depends on a device; the row, the generation, the program
|
|
39
|
+
* placement, the node's `transforms` row and the atlas patch are a
|
|
40
|
+
* {@link ./GPUParticleEmitterContext.js} this registry holds against the emitter and hands out
|
|
41
|
+
* through {@link EmitterRegistry#context}. Registering an emitter creates one, removing it destroys
|
|
42
|
+
* one, and an emitter with no context here is an emitter this registry does not have.
|
|
43
|
+
*
|
|
44
|
+
* The GPU-owned per-emitter state is the database's second table, claimed and released here at the
|
|
45
|
+
* emitter's row and never written by the CPU otherwise.
|
|
46
|
+
*
|
|
47
|
+
* Programs are the one thing NOT in the database: they are variable-length and shared, so they go
|
|
48
|
+
* into a packed {@link ProgramHeap} buffer and the emitter record carries offsets into it. The heap
|
|
49
|
+
* is content-deduplicated and reference-counted — two emitters compiled from the same graph land on
|
|
50
|
+
* one program id, which is what the simulation-order bucketing buckets on, and the last emitter of
|
|
51
|
+
* an effect is what releases it.
|
|
52
|
+
*/
|
|
53
|
+
export class EmitterRegistry {
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @type {GPUDatabase}
|
|
57
|
+
*/
|
|
58
|
+
database;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Packed instruction + constant buffers for every distinct program in the set.
|
|
62
|
+
* @type {ProgramHeap}
|
|
63
|
+
*/
|
|
64
|
+
programs = new ProgramHeap();
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The live emitters, in no particular order — the row in {@link context} is the identity.
|
|
68
|
+
* @type {ParticleEmitter[]}
|
|
69
|
+
*/
|
|
70
|
+
emitters = [];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The live emitters by table row. Sparse: a freed row reads `undefined` until it is reused.
|
|
74
|
+
* Rows are small dense integers handed out lowest-free-first, so an array is the right index.
|
|
75
|
+
*
|
|
76
|
+
* @type {ParticleEmitter[]}
|
|
77
|
+
*/
|
|
78
|
+
by_row = [];
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Whether {@link programs} has changed since {@link build_program} last packed it. The buffer is
|
|
82
|
+
* monolithic (a program is variable-length, so there is no table to page it into), so any change
|
|
83
|
+
* means re-uploading it whole — which is why the heap dedupes by content, and why this is
|
|
84
|
+
* separate from the per-row dirtiness the table tracks.
|
|
85
|
+
*
|
|
86
|
+
* Read off the heap's own version rather than kept as a flag: there is then no path that changes
|
|
87
|
+
* the programs and forgets to say so.
|
|
88
|
+
*
|
|
89
|
+
* @returns {boolean}
|
|
90
|
+
*/
|
|
91
|
+
get programs_dirty() {
|
|
92
|
+
return this.programs.version !== this.#built_programs_version;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* {@link ProgramHeap#version} the last {@link build_program} packed. `-1` for "nothing has been
|
|
97
|
+
* built yet", which no version reaches.
|
|
98
|
+
*
|
|
99
|
+
* @type {number}
|
|
100
|
+
*/
|
|
101
|
+
#built_programs_version = -1;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* {@link ProgramHeap#placement_version} the rows were last staged against. When the heap repacks,
|
|
105
|
+
* every program that was already placed moves, so every row built from the old offsets has to be
|
|
106
|
+
* written again — see {@link flush}.
|
|
107
|
+
*
|
|
108
|
+
* @type {number}
|
|
109
|
+
*/
|
|
110
|
+
#staged_placement_version = 0;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* What this registry knows about each emitter it holds, and the only place any of it exists.
|
|
114
|
+
*
|
|
115
|
+
* @type {Map<ParticleEmitter, GPUParticleEmitterContext>}
|
|
116
|
+
*/
|
|
117
|
+
#contexts = new Map();
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The generation the next add will take.
|
|
121
|
+
* @type {number}
|
|
122
|
+
*/
|
|
123
|
+
#generation = PARTICLE_GENERATION_FIRST;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param {GPUDevice} device
|
|
127
|
+
*/
|
|
128
|
+
constructor(device) {
|
|
129
|
+
assert.defined(device, 'device');
|
|
130
|
+
|
|
131
|
+
this.database = new GPUDatabase({
|
|
132
|
+
device,
|
|
133
|
+
definition: PARTICLE_DATABASE_SPEC,
|
|
134
|
+
label: 'Particles / Emitters',
|
|
135
|
+
initial_data_size_bytes: PARTICLE_DATABASE_INITIAL_SIZE,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The emitter table.
|
|
141
|
+
* @returns {GPUTypedTable}
|
|
142
|
+
*/
|
|
143
|
+
get table() {
|
|
144
|
+
return this.database.get(PARTICLE_EMITTER_TABLE);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The GPU-owned state table: one row per emitter, at the emitter's row, claimed and released
|
|
149
|
+
* here and otherwise the GPU's.
|
|
150
|
+
* @returns {GPUTypedTable}
|
|
151
|
+
*/
|
|
152
|
+
get state_table() {
|
|
153
|
+
return this.database.get(PARTICLE_EMITTER_STATE_TABLE);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @returns {number} number of live emitters
|
|
158
|
+
*/
|
|
159
|
+
get count() {
|
|
160
|
+
return this.emitters.length;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Number of distinct compiled programs registered.
|
|
165
|
+
* @returns {number}
|
|
166
|
+
*/
|
|
167
|
+
get program_count() {
|
|
168
|
+
return this.programs.program_count;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Number of buckets the simulation-order coherence pass histograms into: every live program id
|
|
173
|
+
* is below it. See {@link ProgramHeap#program_id_capacity}.
|
|
174
|
+
*
|
|
175
|
+
* @returns {number}
|
|
176
|
+
*/
|
|
177
|
+
get program_id_capacity() {
|
|
178
|
+
return this.programs.program_id_capacity;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Register slots the hungriest registered effect needs — a property of the whole set, since
|
|
183
|
+
* there is one simulate pipeline and it is chosen once. What a caller does with the number (pick
|
|
184
|
+
* a register backing, refuse the effect, warn an author) is the caller's; see
|
|
185
|
+
* {@link ProgramHeap#max_register_count}.
|
|
186
|
+
*
|
|
187
|
+
* @returns {number}
|
|
188
|
+
*/
|
|
189
|
+
get max_register_count() {
|
|
190
|
+
return this.programs.max_register_count;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* What this registry assigned an emitter: its table row, generation, program placement, the
|
|
195
|
+
* `transforms` row of its node and its atlas patch.
|
|
196
|
+
*
|
|
197
|
+
* `undefined` for an emitter this registry does not hold — which is the way to ask whether one
|
|
198
|
+
* is live, there being no `-1` on the emitter to read instead.
|
|
199
|
+
*
|
|
200
|
+
* @param {ParticleEmitter} emitter
|
|
201
|
+
* @returns {GPUParticleEmitterContext|undefined}
|
|
202
|
+
*/
|
|
203
|
+
context(emitter) {
|
|
204
|
+
return this.#contexts.get(emitter);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Register an emitter and give it a table row.
|
|
209
|
+
*
|
|
210
|
+
* @param {ParticleEmitter|object} config a {@link ParticleEmitter}, or a description
|
|
211
|
+
* {@link ParticleEmitter.from} accepts
|
|
212
|
+
* @param {number} [transform_row] the emitter node's row in the scene's `transforms` table, if
|
|
213
|
+
* already known; {@link set_transform_row} sets it later otherwise
|
|
214
|
+
* @returns {ParticleEmitter}
|
|
215
|
+
*/
|
|
216
|
+
add(config, transform_row = 0) {
|
|
217
|
+
const emitter = config.isParticleEmitter === true ? config : ParticleEmitter.from(config);
|
|
218
|
+
|
|
219
|
+
assert.equal(this.#contexts.has(emitter), false, 'this emitter is already registered');
|
|
220
|
+
|
|
221
|
+
const context = new GPUParticleEmitterContext();
|
|
222
|
+
|
|
223
|
+
context.placement = this.programs.acquire(emitter.program);
|
|
224
|
+
|
|
225
|
+
context.generation = this.#generation;
|
|
226
|
+
this.#generation = particle_generation_next(this.#generation);
|
|
227
|
+
|
|
228
|
+
context.transform_row = transform_row;
|
|
229
|
+
|
|
230
|
+
// The table picks the slot — the lowest free one, so a removed emitter's row is reused
|
|
231
|
+
// rather than the id space growing without bound.
|
|
232
|
+
context.row = this.table.add(write_emitter_record(RECORD, emitter, context));
|
|
233
|
+
context.staged(emitter);
|
|
234
|
+
|
|
235
|
+
// Claim the state row alongside: zeroed, so the first tick starts it over. The CPU never
|
|
236
|
+
// writes it again — see PARTICLE_EMITTER_STATE.
|
|
237
|
+
this.state_table.set(context.row, PARTICLE_EMITTER_STATE_EMPTY);
|
|
238
|
+
|
|
239
|
+
this.#contexts.set(emitter, context);
|
|
240
|
+
this.emitters.push(emitter);
|
|
241
|
+
this.by_row[context.row] = emitter;
|
|
242
|
+
|
|
243
|
+
return emitter;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Unregister an emitter and free its table row.
|
|
248
|
+
*
|
|
249
|
+
* Its particles are not touched here; they carry its generation, the row they will read is
|
|
250
|
+
* zero-filled (or a later tenant's, with a different generation), and the simulate pass frees
|
|
251
|
+
* them the next time it sees them. Retiring an emitter gently — spawn rate to zero, remove once
|
|
252
|
+
* its particles have died — remains available to an author who wants the tail to play out.
|
|
253
|
+
*
|
|
254
|
+
* The emitter itself comes out of this unchanged: what it loses is its context, which is
|
|
255
|
+
* everything being registered gave it. Its program goes with the context — the heap counts
|
|
256
|
+
* references, so an effect is only unpacked when its last emitter leaves.
|
|
257
|
+
*
|
|
258
|
+
* @param {ParticleEmitter} emitter
|
|
259
|
+
*/
|
|
260
|
+
remove(emitter) {
|
|
261
|
+
assert.defined(emitter, 'emitter');
|
|
262
|
+
assert.equal(emitter.isParticleEmitter, true, 'emitter.isParticleEmitter !== true');
|
|
263
|
+
|
|
264
|
+
const context = this.#contexts.get(emitter);
|
|
265
|
+
|
|
266
|
+
assert.defined(context, 'emitter is not registered here');
|
|
267
|
+
|
|
268
|
+
const position = this.emitters.indexOf(emitter);
|
|
269
|
+
|
|
270
|
+
// Swap-remove: order carries no meaning, and a splice would allocate.
|
|
271
|
+
const last = this.emitters.pop();
|
|
272
|
+
|
|
273
|
+
if (last !== emitter) {
|
|
274
|
+
this.emitters[position] = last;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
this.by_row[context.row] = undefined;
|
|
278
|
+
this.table.remove(context.row);
|
|
279
|
+
this.state_table.remove(context.row);
|
|
280
|
+
|
|
281
|
+
this.programs.release(context.placement);
|
|
282
|
+
|
|
283
|
+
context.placement = null;
|
|
284
|
+
|
|
285
|
+
this.#contexts.delete(emitter);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Give a registered emitter different bytecode to run: its old program loses a reference, the new
|
|
290
|
+
* one gains one, and its row is restaged with the new placement.
|
|
291
|
+
*
|
|
292
|
+
* This is the runtime edit the emitter table has always allowed and the program buffer used not
|
|
293
|
+
* to — an author reworking an effect in the editor changes the program of an emitter that is
|
|
294
|
+
* already live, and the effect it used to run goes away with the last emitter that ran it.
|
|
295
|
+
*
|
|
296
|
+
* The attribute {@link ../layout/ParticleLayout.js layout} is NOT part of this and must not
|
|
297
|
+
* change with it: particles already in flight are laid out the old way, and new bytecode reading
|
|
298
|
+
* them at new offsets would read somebody else's field. Re-laying-out an effect means new
|
|
299
|
+
* emitters.
|
|
300
|
+
*
|
|
301
|
+
* @param {ParticleEmitter} emitter
|
|
302
|
+
* @param {import("../isa/ParticleProgram.js").ParticleProgram} program
|
|
303
|
+
*/
|
|
304
|
+
set_program(emitter, program) {
|
|
305
|
+
assert.defined(program, 'program');
|
|
306
|
+
|
|
307
|
+
const context = this.#contexts.get(emitter);
|
|
308
|
+
|
|
309
|
+
assert.defined(context, 'emitter is not registered here');
|
|
310
|
+
|
|
311
|
+
const previous = context.placement;
|
|
312
|
+
|
|
313
|
+
// acquired before the old one is let go, so that re-setting the program an emitter already
|
|
314
|
+
// runs — which is what an editor does on every keystroke that changes nothing — neither
|
|
315
|
+
// unpacks it nor gives it a new id
|
|
316
|
+
context.placement = this.programs.acquire(program);
|
|
317
|
+
|
|
318
|
+
emitter.program = program;
|
|
319
|
+
|
|
320
|
+
this.programs.release(previous);
|
|
321
|
+
|
|
322
|
+
context.invalidate();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Look up a live emitter by its table row.
|
|
327
|
+
*
|
|
328
|
+
* @param {number} row
|
|
329
|
+
* @returns {ParticleEmitter|undefined}
|
|
330
|
+
*/
|
|
331
|
+
get(row) {
|
|
332
|
+
return this.by_row[row];
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Point an emitter's record at its node's row in the scene's `transforms` table. The row is
|
|
337
|
+
* restaged on the next flush.
|
|
338
|
+
*
|
|
339
|
+
* @param {ParticleEmitter} emitter
|
|
340
|
+
* @param {number} transform_row
|
|
341
|
+
*/
|
|
342
|
+
set_transform_row(emitter, transform_row) {
|
|
343
|
+
assert.isNonNegativeInteger(transform_row, 'transform_row');
|
|
344
|
+
|
|
345
|
+
const context = this.#contexts.get(emitter);
|
|
346
|
+
|
|
347
|
+
assert.defined(context, 'emitter is not registered here');
|
|
348
|
+
|
|
349
|
+
if (context.transform_row === transform_row) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
context.transform_row = transform_row;
|
|
354
|
+
context.invalidate();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Point an emitter's record at the patch its texture was packed into: uv offset `.xy`, uv scale
|
|
359
|
+
* `.zw`. The row is restaged on the next flush.
|
|
360
|
+
*
|
|
361
|
+
* For whoever owns the atlas to call, on registration and again after every repack — a repack
|
|
362
|
+
* moves every patch, and an emitter left holding the old one draws the wrong image.
|
|
363
|
+
*
|
|
364
|
+
* @param {ParticleEmitter} emitter
|
|
365
|
+
* @param {ArrayLike<number>} region [uvOffsetX, uvOffsetY, uvScaleX, uvScaleY]
|
|
366
|
+
*/
|
|
367
|
+
set_atlas_region(emitter, region) {
|
|
368
|
+
assert.equal(region.length, 4, 'region.length');
|
|
369
|
+
|
|
370
|
+
const context = this.#contexts.get(emitter);
|
|
371
|
+
|
|
372
|
+
assert.defined(context, 'emitter is not registered here');
|
|
373
|
+
|
|
374
|
+
const atlas_region = context.atlas_region;
|
|
375
|
+
|
|
376
|
+
if (
|
|
377
|
+
atlas_region[0] === region[0] && atlas_region[1] === region[1]
|
|
378
|
+
&& atlas_region[2] === region[2] && atlas_region[3] === region[3]
|
|
379
|
+
) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
atlas_region.set(region);
|
|
384
|
+
context.invalidate();
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Restage the table rows of every emitter whose fields have moved since the last flush.
|
|
389
|
+
*
|
|
390
|
+
* "Moved" is the node's own change counter: an emitter is restaged when its
|
|
391
|
+
* {@link ../../scene/Node3D.js Node3D#version} is not the one its row was staged from, or when
|
|
392
|
+
* something in its context changed. So an author marks an edited emitter the way they mark any
|
|
393
|
+
* edited node, with `needsUpdate = true`, and there is no second flag to forget.
|
|
394
|
+
*
|
|
395
|
+
* Cheap to call every frame: an emitter that has not changed costs one integer comparison, and
|
|
396
|
+
* the table coalesces repeated writes to one row within a frame anyway. Walks the context map
|
|
397
|
+
* rather than the emitter list so that a pass over the set is not also a lookup per emitter.
|
|
398
|
+
* Stages through the one module-static record, so a frame's restaging allocates nothing however
|
|
399
|
+
* many rows it touches.
|
|
400
|
+
*/
|
|
401
|
+
flush() {
|
|
402
|
+
const table = this.table;
|
|
403
|
+
|
|
404
|
+
const placement_version = this.programs.placement_version;
|
|
405
|
+
|
|
406
|
+
// A repack moved every program that was already placed, so every row holds offsets into
|
|
407
|
+
// where its code used to be. That is the one change no emitter announces — it is not an edit
|
|
408
|
+
// to any of them — so it is asked of the heap once here rather than pushed onto each context.
|
|
409
|
+
const relocated = placement_version !== this.#staged_placement_version;
|
|
410
|
+
|
|
411
|
+
this.#staged_placement_version = placement_version;
|
|
412
|
+
|
|
413
|
+
for (const [emitter, context] of this.#contexts) {
|
|
414
|
+
if (!relocated && !context.is_stale(emitter)) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
table.set(context.row, write_emitter_record(RECORD, emitter, context));
|
|
419
|
+
context.staged(emitter);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* The packed program buffer — header, constant pools, code — rebuilt whole.
|
|
425
|
+
*
|
|
426
|
+
* Call when {@link programs_dirty}; it answers the flag. The buffer is monolithic (a program is
|
|
427
|
+
* variable-length, so there is no table to page it into), so this is a full rebuild — the heap's
|
|
428
|
+
* content deduplication is what keeps it rare (it changes only when an effect the set has never
|
|
429
|
+
* seen is registered, or when the sections are repacked to make room for one).
|
|
430
|
+
*
|
|
431
|
+
* @returns {Uint32Array}
|
|
432
|
+
*/
|
|
433
|
+
build_program() {
|
|
434
|
+
this.#built_programs_version = this.programs.version;
|
|
435
|
+
|
|
436
|
+
return this.programs.build_buffer();
|
|
437
|
+
}
|
|
438
|
+
}
|