@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
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bound on one lane of an operation's result, from the bounds on that lane of its sources.
|
|
3
|
+
*
|
|
4
|
+
* The rules are magnitudes and nothing else — `|a * b| <= |a| * |b|` — so they say the same thing
|
|
5
|
+
* about a lane of an instruction and about a node of a value graph, and both callers read them from
|
|
6
|
+
* here rather than each keeping a copy of the table.
|
|
7
|
+
*
|
|
8
|
+
* @param {number} op
|
|
9
|
+
* @param {number} a bound on source 0, `Infinity` when it is unknown or absent
|
|
10
|
+
* @param {number} b bound on source 1
|
|
11
|
+
* @param {number} c bound on source 2
|
|
12
|
+
* @param {number} [width] lanes the operation spans — read only by the reductions
|
|
13
|
+
* @param {function(): number[]} [whole_operands] bounds over EVERY lane of sources 0 and 1, which is
|
|
14
|
+
* what a reduction sums over; never called for a lanewise operation
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
export function particle_integer_bound_of_operation(op: number, a: number, b: number, c: number, width?: number, whole_operands?: () => number[]): number;
|
|
18
|
+
/**
|
|
19
|
+
* @param {number} value
|
|
20
|
+
* @returns {number} the value's magnitude when it is an integer, `Infinity` otherwise
|
|
21
|
+
*/
|
|
22
|
+
export function particle_integer_bound_of_value(value: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* Which register slots hold an integer, and how big it can be — the one fact that makes a float
|
|
25
|
+
* rewrite exact.
|
|
26
|
+
*
|
|
27
|
+
* `a * b + c` as `MAD` is a different number from `MUL` then `ADD` because the pair rounds the
|
|
28
|
+
* product before adding it and the fused form does not. When the product is an integer below 2^24
|
|
29
|
+
* it needs no rounding, and the two forms are then the same number on every executor — whether the
|
|
30
|
+
* hardware contracts the `MAD` into an FMA or not. So the peephole can fuse those pairs without
|
|
31
|
+
* giving anything up, provided it can PROVE the product is that small, and this is the analysis
|
|
32
|
+
* that proves it.
|
|
33
|
+
*
|
|
34
|
+
* The facts come from the shapes effects are actually made of. A comparison or a `step` is 0 or 1;
|
|
35
|
+
* a mask built from one, `cmp * 2 - 1`, is -1 or 1; a literal is whatever it is. Those flow through
|
|
36
|
+
* copies, negation, `abs`, `floor`, `min`, `max`, `clamp` and `select` unchanged in kind, and
|
|
37
|
+
* through the arithmetic with their bounds combined. Everything else — a draw, an attribute, a
|
|
38
|
+
* builtin, `fract`, a division, a transcendental — is unknown. So is any value whose bound would
|
|
39
|
+
* pass 2^24: above it an integer may no longer be representable, and once a rounding could have
|
|
40
|
+
* happened nothing downstream is exact any more.
|
|
41
|
+
*
|
|
42
|
+
* ## Why the bound is a magnitude and not an interval
|
|
43
|
+
*
|
|
44
|
+
* Exactness of a product is a question about magnitudes, and `|a * b| <= |a| * |b|` is all it
|
|
45
|
+
* needs. An interval would prove more — that `x - floor(x / 289) * 289` is small, say, which is
|
|
46
|
+
* the other shape the noise library is made of — but only from a bound on `x`, which is a
|
|
47
|
+
* position, and there is none. That rewrite stays behind the `fuse_multiply_add` switch.
|
|
48
|
+
*
|
|
49
|
+
* The file starts zeroed on both executors, so every slot begins as the integer 0.
|
|
50
|
+
*/
|
|
51
|
+
export class ParticleIntegerBounds {
|
|
52
|
+
/**
|
|
53
|
+
* @param {ArrayLike<number>} constants the shared constant pool, which `LOAD_CONST` reads
|
|
54
|
+
* @param {number} [slots]
|
|
55
|
+
*/
|
|
56
|
+
constructor(constants: ArrayLike<number>, slots?: number);
|
|
57
|
+
/** @type {ArrayLike<number>} */
|
|
58
|
+
constants: ArrayLike<number>;
|
|
59
|
+
/** @type {Float64Array} per slot, the largest magnitude the integer it holds can have; `Infinity` when it is not known to hold one */
|
|
60
|
+
bound: Float64Array;
|
|
61
|
+
/**
|
|
62
|
+
* @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
|
|
63
|
+
* @param {number} [lanes] how many lanes are read; the operand's own count when left out
|
|
64
|
+
* @returns {number} the largest bound among the lanes read, or `Infinity`
|
|
65
|
+
*/
|
|
66
|
+
bound_of_read(read: import("./particle_program_analysis.js").ParticleOperandRun, lanes?: number): number;
|
|
67
|
+
/**
|
|
68
|
+
* @param {import("./particle_program_analysis.js").ParticleOperandRun} source any operand
|
|
69
|
+
* @param {number} [lanes] how many lanes are read; the operand's own count when left out
|
|
70
|
+
* @returns {number} the bound on what it reads: a literal's own magnitude, or a run's
|
|
71
|
+
*/
|
|
72
|
+
bound_of_source(source: import("./particle_program_analysis.js").ParticleOperandRun, lanes?: number): number;
|
|
73
|
+
/**
|
|
74
|
+
* Record what an instruction leaves in its destination.
|
|
75
|
+
*
|
|
76
|
+
* @param {ArrayLike<number>} words the four words of a single instruction, as they will run
|
|
77
|
+
*/
|
|
78
|
+
publish(words: ArrayLike<number>): void;
|
|
79
|
+
/**
|
|
80
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction} instruction
|
|
81
|
+
* @param {number} span lanes the instruction writes
|
|
82
|
+
* @returns {number[]} the bound each written lane will hold — gathered before anything is
|
|
83
|
+
* written, since a source may alias the destination
|
|
84
|
+
*/
|
|
85
|
+
lanes_written(instruction: import("./particle_program_analysis.js").ParticleDecodedInstruction, span: number): number[];
|
|
86
|
+
/**
|
|
87
|
+
* @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
|
|
88
|
+
* @param {number} lane
|
|
89
|
+
* @returns {number} the bound of the slot that lane reads
|
|
90
|
+
*/
|
|
91
|
+
bound_of_slot(read: import("./particle_program_analysis.js").ParticleOperandRun, lane: number): number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Integers up to here are exactly representable as `f32`, and so are all their sums and products
|
|
95
|
+
* that stay under it. Above it, integers thin out and a rounding could have happened.
|
|
96
|
+
*
|
|
97
|
+
* @type {number}
|
|
98
|
+
*/
|
|
99
|
+
export const PARTICLE_EXACT_INTEGER_LIMIT: number;
|
|
100
|
+
//# sourceMappingURL=particle_integer_bounds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particle_integer_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_integer_bounds.js"],"names":[],"mappings":"AAmJA;;;;;;;;;;;;;;;GAeG;AACH,wDATW,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,UACN,MAAM,yBACM,MAAM,EAAE,GAElB,MAAM,CAkDlB;AAUD;;;GAGG;AACH,uDAHW,MAAM,GACJ,MAAM,CAIlB;AA/ND;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH;IACI;;;OAGG;IACH,uBAHW,UAAU,MAAM,CAAC,UACjB,MAAM,EAOhB;IAJG,gCAAgC;IAChC,WADW,UAAU,MAAM,CAAC,CACF;IAC1B,sIAAsI;IACtI,OADW,YAAY,CACa;IAGxC;;;;OAIG;IACH,oBAJW,OAAO,gCAAgC,EAAE,kBAAkB,UAC3D,MAAM,GACJ,MAAM,CAclB;IAED;;;;OAIG;IACH,wBAJW,OAAO,gCAAgC,EAAE,kBAAkB,UAC3D,MAAM,GACJ,MAAM,CAMlB;IAED;;;;OAIG;IACH,eAFW,UAAU,MAAM,CAAC,QAiB3B;IAED;;;;;OAKG;IACH,2BALW,OAAO,gCAAgC,EAAE,0BAA0B,QACnE,MAAM,GACJ,MAAM,EAAE,CAkCpB;IAED;;;;OAIG;IACH,oBAJW,OAAO,gCAAgC,EAAE,kBAAkB,QAC3D,MAAM,GACJ,MAAM,CAMlB;CACJ;AAoED;;;;;GAKG;AACH,2CAFU,MAAM,CAEoC"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { PARTICLE_VM_REGISTER_SLOTS } from "../ParticleConstants.js";
|
|
2
|
+
import { VM_KIND, VM_OP, vm_f32_value } from "../isa/ParticleVMISA.js";
|
|
3
|
+
import { decode_particle_instruction, particle_read_slots } from "./particle_program_analysis.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Which register slots hold an integer, and how big it can be — the one fact that makes a float
|
|
7
|
+
* rewrite exact.
|
|
8
|
+
*
|
|
9
|
+
* `a * b + c` as `MAD` is a different number from `MUL` then `ADD` because the pair rounds the
|
|
10
|
+
* product before adding it and the fused form does not. When the product is an integer below 2^24
|
|
11
|
+
* it needs no rounding, and the two forms are then the same number on every executor — whether the
|
|
12
|
+
* hardware contracts the `MAD` into an FMA or not. So the peephole can fuse those pairs without
|
|
13
|
+
* giving anything up, provided it can PROVE the product is that small, and this is the analysis
|
|
14
|
+
* that proves it.
|
|
15
|
+
*
|
|
16
|
+
* The facts come from the shapes effects are actually made of. A comparison or a `step` is 0 or 1;
|
|
17
|
+
* a mask built from one, `cmp * 2 - 1`, is -1 or 1; a literal is whatever it is. Those flow through
|
|
18
|
+
* copies, negation, `abs`, `floor`, `min`, `max`, `clamp` and `select` unchanged in kind, and
|
|
19
|
+
* through the arithmetic with their bounds combined. Everything else — a draw, an attribute, a
|
|
20
|
+
* builtin, `fract`, a division, a transcendental — is unknown. So is any value whose bound would
|
|
21
|
+
* pass 2^24: above it an integer may no longer be representable, and once a rounding could have
|
|
22
|
+
* happened nothing downstream is exact any more.
|
|
23
|
+
*
|
|
24
|
+
* ## Why the bound is a magnitude and not an interval
|
|
25
|
+
*
|
|
26
|
+
* Exactness of a product is a question about magnitudes, and `|a * b| <= |a| * |b|` is all it
|
|
27
|
+
* needs. An interval would prove more — that `x - floor(x / 289) * 289` is small, say, which is
|
|
28
|
+
* the other shape the noise library is made of — but only from a bound on `x`, which is a
|
|
29
|
+
* position, and there is none. That rewrite stays behind the `fuse_multiply_add` switch.
|
|
30
|
+
*
|
|
31
|
+
* The file starts zeroed on both executors, so every slot begins as the integer 0.
|
|
32
|
+
*/
|
|
33
|
+
export class ParticleIntegerBounds {
|
|
34
|
+
/**
|
|
35
|
+
* @param {ArrayLike<number>} constants the shared constant pool, which `LOAD_CONST` reads
|
|
36
|
+
* @param {number} [slots]
|
|
37
|
+
*/
|
|
38
|
+
constructor(constants, slots = PARTICLE_VM_REGISTER_SLOTS) {
|
|
39
|
+
/** @type {ArrayLike<number>} */
|
|
40
|
+
this.constants = constants;
|
|
41
|
+
/** @type {Float64Array} per slot, the largest magnitude the integer it holds can have; `Infinity` when it is not known to hold one */
|
|
42
|
+
this.bound = new Float64Array(slots);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
|
|
47
|
+
* @param {number} [lanes] how many lanes are read; the operand's own count when left out
|
|
48
|
+
* @returns {number} the largest bound among the lanes read, or `Infinity`
|
|
49
|
+
*/
|
|
50
|
+
bound_of_read(read, lanes = read.lanes) {
|
|
51
|
+
let bound = 0;
|
|
52
|
+
|
|
53
|
+
for (const slot of particle_read_slots(read, lanes)) {
|
|
54
|
+
if (slot < 0 || slot >= this.bound.length) {
|
|
55
|
+
return Infinity;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
bound = Math.max(bound, this.bound[slot]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return bound;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {import("./particle_program_analysis.js").ParticleOperandRun} source any operand
|
|
66
|
+
* @param {number} [lanes] how many lanes are read; the operand's own count when left out
|
|
67
|
+
* @returns {number} the bound on what it reads: a literal's own magnitude, or a run's
|
|
68
|
+
*/
|
|
69
|
+
bound_of_source(source, lanes = source.lanes) {
|
|
70
|
+
return source.kind === VM_KIND.IMM
|
|
71
|
+
? particle_integer_bound_of_value(vm_f32_value(source.word))
|
|
72
|
+
: this.bound_of_read(source, lanes);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Record what an instruction leaves in its destination.
|
|
77
|
+
*
|
|
78
|
+
* @param {ArrayLike<number>} words the four words of a single instruction, as they will run
|
|
79
|
+
*/
|
|
80
|
+
publish(words) {
|
|
81
|
+
const instruction = decode_particle_instruction(words);
|
|
82
|
+
|
|
83
|
+
if (instruction.write === null) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const { base, span } = instruction.write;
|
|
88
|
+
const lanes = this.lanes_written(instruction, span);
|
|
89
|
+
|
|
90
|
+
for (let lane = 0; lane < span; lane++) {
|
|
91
|
+
if (base + lane < this.bound.length) {
|
|
92
|
+
this.bound[base + lane] = lanes[lane];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {import("./particle_program_analysis.js").ParticleDecodedInstruction} instruction
|
|
99
|
+
* @param {number} span lanes the instruction writes
|
|
100
|
+
* @returns {number[]} the bound each written lane will hold — gathered before anything is
|
|
101
|
+
* written, since a source may alias the destination
|
|
102
|
+
*/
|
|
103
|
+
lanes_written(instruction, span) {
|
|
104
|
+
const [a, b, c] = instruction.sources;
|
|
105
|
+
const per_lane = (combine) => {
|
|
106
|
+
const out = new Array(span);
|
|
107
|
+
|
|
108
|
+
for (let lane = 0; lane < span; lane++) {
|
|
109
|
+
out[lane] = capped(combine(lane));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return out;
|
|
113
|
+
};
|
|
114
|
+
const lane_of = (source, lane) => (source.kind === VM_KIND.IMM
|
|
115
|
+
? particle_integer_bound_of_value(vm_f32_value(source.word))
|
|
116
|
+
: this.bound_of_slot(source, lane));
|
|
117
|
+
|
|
118
|
+
// `LOAD_CONST` is the one operation whose lanes come from somewhere other than its
|
|
119
|
+
// operands, so it is answered here; every other one is the scalar rule below.
|
|
120
|
+
if (instruction.op === VM_OP.LOAD_CONST) {
|
|
121
|
+
return per_lane(lane => particle_integer_bound_of_value(this.constants[instruction.words[1] + lane]));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return per_lane(lane => particle_integer_bound_of_operation(
|
|
125
|
+
instruction.op,
|
|
126
|
+
a === undefined ? Infinity : lane_of(a, lane),
|
|
127
|
+
b === undefined ? Infinity : lane_of(b, lane),
|
|
128
|
+
c === undefined ? Infinity : lane_of(c, lane),
|
|
129
|
+
instruction.operation_width,
|
|
130
|
+
// The reductions read every lane, so their bound is over the whole operand rather than
|
|
131
|
+
// over one lane of it.
|
|
132
|
+
() => [this.bound_of_source(a, instruction.operation_width), this.bound_of_source(b, instruction.operation_width)]
|
|
133
|
+
));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @param {import("./particle_program_analysis.js").ParticleOperandRun} read a `REG` run
|
|
138
|
+
* @param {number} lane
|
|
139
|
+
* @returns {number} the bound of the slot that lane reads
|
|
140
|
+
*/
|
|
141
|
+
bound_of_slot(read, lane) {
|
|
142
|
+
const slot = particle_read_slots(read, lane + 1)[lane];
|
|
143
|
+
|
|
144
|
+
return slot >= 0 && slot < this.bound.length ? this.bound[slot] : Infinity;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The bound on one lane of an operation's result, from the bounds on that lane of its sources.
|
|
150
|
+
*
|
|
151
|
+
* The rules are magnitudes and nothing else — `|a * b| <= |a| * |b|` — so they say the same thing
|
|
152
|
+
* about a lane of an instruction and about a node of a value graph, and both callers read them from
|
|
153
|
+
* here rather than each keeping a copy of the table.
|
|
154
|
+
*
|
|
155
|
+
* @param {number} op
|
|
156
|
+
* @param {number} a bound on source 0, `Infinity` when it is unknown or absent
|
|
157
|
+
* @param {number} b bound on source 1
|
|
158
|
+
* @param {number} c bound on source 2
|
|
159
|
+
* @param {number} [width] lanes the operation spans — read only by the reductions
|
|
160
|
+
* @param {function(): number[]} [whole_operands] bounds over EVERY lane of sources 0 and 1, which is
|
|
161
|
+
* what a reduction sums over; never called for a lanewise operation
|
|
162
|
+
* @returns {number}
|
|
163
|
+
*/
|
|
164
|
+
export function particle_integer_bound_of_operation(op, a, b, c, width = 1, whole_operands = () => [a, b]) {
|
|
165
|
+
switch (op) {
|
|
166
|
+
case VM_OP.CMP_LT:
|
|
167
|
+
case VM_OP.CMP_LE:
|
|
168
|
+
case VM_OP.CMP_GT:
|
|
169
|
+
case VM_OP.CMP_GE:
|
|
170
|
+
case VM_OP.CMP_EQ:
|
|
171
|
+
case VM_OP.STEP:
|
|
172
|
+
return 1;
|
|
173
|
+
|
|
174
|
+
case VM_OP.MOV:
|
|
175
|
+
case VM_OP.NEG:
|
|
176
|
+
case VM_OP.ABS:
|
|
177
|
+
case VM_OP.FLOOR:
|
|
178
|
+
return capped(a);
|
|
179
|
+
|
|
180
|
+
case VM_OP.MIN:
|
|
181
|
+
case VM_OP.MAX:
|
|
182
|
+
return capped(Math.max(a, b));
|
|
183
|
+
|
|
184
|
+
case VM_OP.CLAMP:
|
|
185
|
+
return capped(Math.max(a, b, c));
|
|
186
|
+
|
|
187
|
+
// Whichever of the two the condition picks, and the condition itself is not a value.
|
|
188
|
+
case VM_OP.SELECT:
|
|
189
|
+
return capped(Math.max(a, b));
|
|
190
|
+
|
|
191
|
+
case VM_OP.ADD:
|
|
192
|
+
case VM_OP.SUB:
|
|
193
|
+
return capped(a + b);
|
|
194
|
+
|
|
195
|
+
case VM_OP.MUL:
|
|
196
|
+
return capped(a * b);
|
|
197
|
+
|
|
198
|
+
case VM_OP.MAD:
|
|
199
|
+
return capped(a * b + c);
|
|
200
|
+
|
|
201
|
+
// Every product exact and every partial sum within the cap is what makes the sum an
|
|
202
|
+
// integer whatever order the hardware adds it in.
|
|
203
|
+
case VM_OP.DOT: {
|
|
204
|
+
const [whole_a, whole_b] = whole_operands();
|
|
205
|
+
|
|
206
|
+
return capped(width * whole_a * whole_b);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
default:
|
|
210
|
+
return Infinity;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Integers up to here are exactly representable as `f32`, and so are all their sums and products
|
|
216
|
+
* that stay under it. Above it, integers thin out and a rounding could have happened.
|
|
217
|
+
*
|
|
218
|
+
* @type {number}
|
|
219
|
+
*/
|
|
220
|
+
export const PARTICLE_EXACT_INTEGER_LIMIT = 2 ** 24;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @param {number} value
|
|
224
|
+
* @returns {number} the value's magnitude when it is an integer, `Infinity` otherwise
|
|
225
|
+
*/
|
|
226
|
+
export function particle_integer_bound_of_value(value) {
|
|
227
|
+
return Number.isInteger(value) ? capped(Math.abs(value)) : Infinity;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @param {number} bound
|
|
232
|
+
* @returns {number} the bound, or `Infinity` once it is past what is exact
|
|
233
|
+
*/
|
|
234
|
+
function capped(bound) {
|
|
235
|
+
return bound <= PARTICLE_EXACT_INTEGER_LIMIT ? bound : Infinity;
|
|
236
|
+
}
|