@woosh/meep-engine 3.16.0 → 3.17.1
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/README.md +8 -72
- 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/t64_set_rotation_axis_angle.d.ts +25 -0
- package/src/engine/ecs/transform/t64_set_rotation_axis_angle.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_set_rotation_axis_angle.js +45 -0
- 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/AcousticSimulator.d.ts +11 -8
- package/src/engine/sound/simulation/AcousticSimulator.d.ts.map +1 -1
- package/src/engine/sound/simulation/AcousticSimulator.js +45 -36
- package/src/engine/sound/simulation/README.md +2 -2
- package/src/engine/sound/simulation/core/OcclusionSolver.d.ts.map +1 -1
- package/src/engine/sound/simulation/core/VolumeField.d.ts +9 -9
- package/src/engine/sound/simulation/core/VolumeField.d.ts.map +1 -1
- package/src/engine/sound/simulation/core/VolumeField.js +29 -13
- package/src/engine/sound/simulation/core/acoustic_occlusion_solve.d.ts +31 -0
- package/src/engine/sound/simulation/core/acoustic_occlusion_solve.d.ts.map +1 -0
- package/src/engine/sound/simulation/core/acoustic_occlusion_solve.js +134 -0
- 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/playground/volumetrics_froxel/main.d.ts.map +1 -1
- package/src/shade/playground/volumetrics_froxel/main.js +6 -1
- 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/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/renderer/volumetrics/ParticipatingMediaVolume.d.ts +7 -0
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +7 -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/engine/sound/simulation/core/OcclusionSolver.js +0 -112
- 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.d.ts +0 -89
- package/src/shade/renderer/particles/runtime/ProgramArena.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,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nodes lifted out of a graph, waiting to be put back into one.
|
|
3
|
+
*
|
|
4
|
+
* ## Why a fragment rather than a graph
|
|
5
|
+
*
|
|
6
|
+
* What is copied cannot be node ids: ids are pooled, so the ones a fragment was cut from are handed
|
|
7
|
+
* to unrelated nodes the moment the originals are deleted, and a paste that named them would wire
|
|
8
|
+
* itself to whatever happened to be holding them. A fragment therefore refers to its own nodes by
|
|
9
|
+
* **index**, and is a thing in its own right rather than a view onto the graph it came from.
|
|
10
|
+
*
|
|
11
|
+
* Nor can it be a live {@link NodeInstance}: the instance would keep pointing at the graph it is in,
|
|
12
|
+
* and its parameters would be shared with it — an author editing the original after copying it would
|
|
13
|
+
* be editing what they had copied. Parameters are cloned on the way in for the same reason a group
|
|
14
|
+
* clones its body on the way out.
|
|
15
|
+
*
|
|
16
|
+
* A {@link NodeDescription}, on the other hand, *is* carried by reference. A description is a type,
|
|
17
|
+
* shared by every instance of it, and there is nothing to copy; it is also the one part of a node
|
|
18
|
+
* that cannot be written down — a particle node's description carries the closure that is the whole
|
|
19
|
+
* of what the node does. Which is why this clipboard is an object in the page rather than text on
|
|
20
|
+
* the system one: what it holds is only meaningful to a canvas that shares its node library.
|
|
21
|
+
*
|
|
22
|
+
* ## Who holds one
|
|
23
|
+
*
|
|
24
|
+
* A host with several canvases over one document — the particle editor's two phases, and the body of
|
|
25
|
+
* every group opened inside them — builds one of these and gives it to all of them, so a copy in one
|
|
26
|
+
* pastes in the next. A canvas built without one gets its own, and copies to itself.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* One node in a fragment.
|
|
31
|
+
*
|
|
32
|
+
* @typedef {object} NodeGraphFragmentNode
|
|
33
|
+
* @property {NodeDescription} description the type, by reference
|
|
34
|
+
* @property {object} parameters a deep copy, shared with nothing
|
|
35
|
+
* @property {number} x graph-space position it was copied from
|
|
36
|
+
* @property {number} y graph-space position it was copied from
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* One wire in a fragment, between two of its own nodes.
|
|
41
|
+
*
|
|
42
|
+
* @typedef {object} NodeGraphFragmentConnection
|
|
43
|
+
* @property {number} from index into the fragment's nodes
|
|
44
|
+
* @property {number} fromPort port id on that node's description
|
|
45
|
+
* @property {number} to index into the fragment's nodes
|
|
46
|
+
* @property {number} toPort port id on that node's description
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {object} NodeGraphFragment
|
|
51
|
+
* @property {NodeGraphFragmentNode[]} nodes never empty — a fragment with no nodes is `null`
|
|
52
|
+
* @property {NodeGraphFragmentConnection[]} connections
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* How far each repeat paste of the same content steps, in graph-space units.
|
|
57
|
+
*
|
|
58
|
+
* Enough to see the copy is a second thing rather than a redraw of the first, and small enough that
|
|
59
|
+
* it lands next to what it came from rather than somewhere else entirely.
|
|
60
|
+
*
|
|
61
|
+
* @type {number}
|
|
62
|
+
*/
|
|
63
|
+
export const NODE_GRAPH_PASTE_STEP = 32;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* What was copied, and how many times it has been put down since.
|
|
67
|
+
*/
|
|
68
|
+
export class NodeGraphClipboard {
|
|
69
|
+
/**
|
|
70
|
+
* @type {NodeGraphFragment|null}
|
|
71
|
+
*/
|
|
72
|
+
#fragment = null;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @type {number}
|
|
76
|
+
*/
|
|
77
|
+
#pastes = 0;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* How many times what is held has been pasted already.
|
|
81
|
+
*
|
|
82
|
+
* A paste lands in the middle of what the author is looking at, so a second one would land
|
|
83
|
+
* exactly on top of the first and read as nothing having happened. The count is what steps it
|
|
84
|
+
* aside; see {@link NODE_GRAPH_PASTE_STEP}.
|
|
85
|
+
*
|
|
86
|
+
* @returns {number}
|
|
87
|
+
*/
|
|
88
|
+
get pastes() {
|
|
89
|
+
return this.#pastes;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @returns {boolean}
|
|
94
|
+
*/
|
|
95
|
+
isEmpty() {
|
|
96
|
+
return this.#fragment === null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @returns {NodeGraphFragment|null}
|
|
101
|
+
*/
|
|
102
|
+
read() {
|
|
103
|
+
return this.#fragment;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Replace what is held. New content starts its paste count over, because the first paste of
|
|
108
|
+
* something new belongs where the author is looking rather than however far the last thing had
|
|
109
|
+
* walked.
|
|
110
|
+
*
|
|
111
|
+
* @param {NodeGraphFragment} fragment
|
|
112
|
+
*/
|
|
113
|
+
write(fragment) {
|
|
114
|
+
this.#fragment = fragment;
|
|
115
|
+
this.#pastes = 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Record that what is held has been put down. Called by whoever is pasting it, once the paste is
|
|
120
|
+
* going ahead — a paste a canvas refused must not move the next one aside.
|
|
121
|
+
*/
|
|
122
|
+
notePaste() {
|
|
123
|
+
this.#pastes++;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
clear() {
|
|
127
|
+
this.#fragment = null;
|
|
128
|
+
this.#pastes = 0;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Take a copy of some of a graph.
|
|
134
|
+
*
|
|
135
|
+
* The wires that come along are the ones the fragment holds whole — both ends among the copied
|
|
136
|
+
* nodes. A wire with one end outside cannot be brought back: the node it reached is not part of
|
|
137
|
+
* what was copied, and a paste elsewhere in the graph, or in another graph entirely, has nothing to
|
|
138
|
+
* attach it to.
|
|
139
|
+
*
|
|
140
|
+
* @param {object} params
|
|
141
|
+
* @param {NodeGraph} params.graph
|
|
142
|
+
* @param {NodeGraphVisualData} [params.visual] where the nodes are; without it, everything is at the
|
|
143
|
+
* origin and a paste arranges nothing
|
|
144
|
+
* @param {Iterable<number>} params.nodes ids to copy; ones that are not in the graph are skipped
|
|
145
|
+
* @param {function(NodeInstance):boolean} [params.copyable] whether a node may be had a second of.
|
|
146
|
+
* Everything, by default. A host with node types that exist once per graph — a group body's
|
|
147
|
+
* two boundary blocks — says so here, and they are left out rather than the whole copy being
|
|
148
|
+
* refused.
|
|
149
|
+
* @returns {NodeGraphFragment|null} `null` when nothing was copied, so that a copy of nothing can be
|
|
150
|
+
* told from a copy of something and left to leave the clipboard alone
|
|
151
|
+
*/
|
|
152
|
+
export function node_graph_fragment_from_nodes({ graph, visual, nodes, copyable = () => true }) {
|
|
153
|
+
/** @type {Map<number, number>} node id -> its index in the fragment */
|
|
154
|
+
const index = new Map();
|
|
155
|
+
|
|
156
|
+
/** @type {NodeGraphFragmentNode[]} */
|
|
157
|
+
const records = [];
|
|
158
|
+
|
|
159
|
+
for (const id of nodes) {
|
|
160
|
+
if (index.has(id)) {
|
|
161
|
+
// a selection should not hold one node twice, and a fragment must not whatever it does
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const node = graph.getNode(id);
|
|
166
|
+
|
|
167
|
+
if (node === undefined || !copyable(node)) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const placed = visual === undefined ? undefined : visual.getNode(id);
|
|
172
|
+
|
|
173
|
+
index.set(id, records.length);
|
|
174
|
+
|
|
175
|
+
records.push({
|
|
176
|
+
description: node.description,
|
|
177
|
+
// deeply: a copy must not share so much as a gradient stop with what it was copied from
|
|
178
|
+
parameters: structuredClone(node.parameters),
|
|
179
|
+
x: placed?.dimensions.position.x ?? 0,
|
|
180
|
+
y: placed?.dimensions.position.y ?? 0,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (records.length === 0) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** @type {NodeGraphFragmentConnection[]} */
|
|
189
|
+
const connections = [];
|
|
190
|
+
|
|
191
|
+
graph.traverseConnections(connection => {
|
|
192
|
+
const from = index.get(connection.source.instance.id);
|
|
193
|
+
const to = index.get(connection.target.instance.id);
|
|
194
|
+
|
|
195
|
+
if (from === undefined || to === undefined) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
connections.push({
|
|
200
|
+
from,
|
|
201
|
+
fromPort: connection.source.port.id,
|
|
202
|
+
to,
|
|
203
|
+
toPort: connection.target.port.id,
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return { nodes: records, connections };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* The middle of a fragment, in the graph space it was copied from.
|
|
212
|
+
*
|
|
213
|
+
* What a paste puts where the author is looking, so that what lands is centred on the view rather
|
|
214
|
+
* than hanging off one corner of it.
|
|
215
|
+
*
|
|
216
|
+
* @param {NodeGraphFragment} fragment
|
|
217
|
+
* @returns {{x: number, y: number}}
|
|
218
|
+
*/
|
|
219
|
+
export function node_graph_fragment_centre(fragment) {
|
|
220
|
+
let x = 0;
|
|
221
|
+
let y = 0;
|
|
222
|
+
|
|
223
|
+
for (const node of fragment.nodes) {
|
|
224
|
+
x += node.x;
|
|
225
|
+
y += node.y;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const count = fragment.nodes.length;
|
|
229
|
+
|
|
230
|
+
return count === 0 ? { x: 0, y: 0 } : { x: x / count, y: y / count };
|
|
231
|
+
}
|
|
@@ -28,8 +28,14 @@ export class NodeGraphEditorView extends View {
|
|
|
28
28
|
* type the menu places, so a node arrives ready to compile rather than to repair
|
|
29
29
|
* @param {boolean} [readOnly] show the graph without offering to change it; see
|
|
30
30
|
* {@link NodeGraphView}. Turns off the add-node menu and the editing shortcuts too.
|
|
31
|
+
* @param {NodeGraphClipboard} [clipboard] what `Ctrl+C` writes and `Ctrl+V` reads. A host with
|
|
32
|
+
* several canvases over one document passes one to all of them, so a copy taken in one
|
|
33
|
+
* pastes in the next; on its own, a canvas gets one of its own and copies to itself.
|
|
34
|
+
* @param {function(NodeInstance):boolean} [copyable] whether a node may be had a second of, for
|
|
35
|
+
* a host with types that exist once per graph. See
|
|
36
|
+
* {@link node_graph_fragment_from_nodes}.
|
|
31
37
|
*/
|
|
32
|
-
constructor({ graph, nodeRegistry, visual, camera, actions, actionProcessor, parameterViewFactory, portDataType, minimap, library, readOnly }: NodeGraph);
|
|
38
|
+
constructor({ graph, nodeRegistry, visual, camera, actions, actionProcessor, parameterViewFactory, portDataType, minimap, library, readOnly, clipboard, copyable }: NodeGraph);
|
|
33
39
|
/**
|
|
34
40
|
* @readonly
|
|
35
41
|
*/
|
|
@@ -43,6 +49,17 @@ export class NodeGraphEditorView extends View {
|
|
|
43
49
|
* @type {ActionProcessor}
|
|
44
50
|
*/
|
|
45
51
|
actionProcessor: ActionProcessor<any, any>;
|
|
52
|
+
/**
|
|
53
|
+
* What a copy is written to and a paste read from. Shared with the host's other canvases
|
|
54
|
+
* when it supplied one.
|
|
55
|
+
*
|
|
56
|
+
* @type {NodeGraphClipboard}
|
|
57
|
+
*/
|
|
58
|
+
clipboard: NodeGraphClipboard;
|
|
59
|
+
/**
|
|
60
|
+
* @type {function(NodeInstance):boolean}
|
|
61
|
+
*/
|
|
62
|
+
copyable: (arg0: NodeInstance) => boolean;
|
|
46
63
|
/**
|
|
47
64
|
*
|
|
48
65
|
* @type {NodeGraphSelection}
|
|
@@ -181,11 +198,52 @@ export class NodeGraphEditorView extends View {
|
|
|
181
198
|
* queues, so nothing has been removed on return
|
|
182
199
|
*/
|
|
183
200
|
deleteSelection(): Promise<any>;
|
|
201
|
+
/**
|
|
202
|
+
* Take a copy of the selected nodes, and of every wire they hold whole.
|
|
203
|
+
*
|
|
204
|
+
* Reading, not editing, so a read-only canvas offers it: opening one of a library's own groups
|
|
205
|
+
* to take a copy of what is inside it is the point of being able to open them.
|
|
206
|
+
*
|
|
207
|
+
* @returns {boolean} whether anything was copied. A selection with nothing copyable in it leaves
|
|
208
|
+
* the clipboard alone rather than emptying it, which is the one outcome an author
|
|
209
|
+
* asking for a copy certainly did not want.
|
|
210
|
+
*/
|
|
211
|
+
copySelection(): boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Put what was copied into this graph, in the middle of what the author is looking at.
|
|
214
|
+
*
|
|
215
|
+
* Where a paste lands is the one decision here. It goes to the middle of the view rather than
|
|
216
|
+
* back where it was copied from, for the same reason a node added from the menu with no position
|
|
217
|
+
* does: what arrives has to be somewhere the author can see it, and the place it was copied from
|
|
218
|
+
* may be a long way off screen — a copy taken in one phase and pasted in the other has no
|
|
219
|
+
* meaningful "back where it was" at all. The arrangement inside the fragment is kept exactly; it
|
|
220
|
+
* is the whole of it that moves. A repeat paste of the same content steps aside by
|
|
221
|
+
* {@link NODE_GRAPH_PASTE_STEP} so that copies do not hide each other.
|
|
222
|
+
*
|
|
223
|
+
* @returns {Promise<NodeInstance[]>} the nodes that landed, once the timeline has applied them;
|
|
224
|
+
* empty when there was nothing on the clipboard
|
|
225
|
+
* @throws if this canvas is read-only
|
|
226
|
+
*/
|
|
227
|
+
paste(): Promise<NodeInstance[]>;
|
|
228
|
+
/**
|
|
229
|
+
* A second of everything selected, beside the originals.
|
|
230
|
+
*
|
|
231
|
+
* Beside rather than in the middle of the view, which is where {@link #paste} puts things: a
|
|
232
|
+
* duplicate is a second of something the author is already looking at, and centring it would
|
|
233
|
+
* take it away from the thing it is a second of. The clipboard is not touched — `Ctrl+D` is not
|
|
234
|
+
* a copy, and it must not cost the author whatever they had copied earlier.
|
|
235
|
+
*
|
|
236
|
+
* @returns {Promise<NodeInstance[]>} the new nodes; empty when nothing selected could be had a
|
|
237
|
+
* second of
|
|
238
|
+
* @throws if this canvas is read-only
|
|
239
|
+
*/
|
|
240
|
+
duplicateSelection(): Promise<NodeInstance[]>;
|
|
184
241
|
cameraContainAll(): void;
|
|
185
242
|
#private;
|
|
186
243
|
}
|
|
187
244
|
import View from "../../../src/view/View.js";
|
|
188
245
|
import { ActionProcessor } from "../../../src/core/process/undo/ActionProcessor.js";
|
|
246
|
+
import { NodeGraphClipboard } from "./NodeGraphClipboard.js";
|
|
189
247
|
import { NodeGraphSelection } from "./NodeGraphSelection.js";
|
|
190
248
|
import { NodeGraphCamera } from "./NodeGraphView.js";
|
|
191
249
|
import { NodeDescriptionVisualRegistry } from "../../../src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeGraphEditorView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphEditorView.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NodeGraphEditorView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphEditorView.js"],"names":[],"mappings":"AAmDA;IAyBI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,+KAiSC;IA7VD;;OAEG;IACH,iBAWE;IA+DE;;OAEG;IACH,UAFU,OAAO,CAEO;IAExB;;;OAGG;IACH,2CAAsC;IAEtC;;;;;OAKG;IACH,WAFU,kBAAkB,CAEF;IAE1B;;OAEG;IACH,kCAFiC,OAAO,CAEA;IAExC;;;OAGG;IACH,WAFU,kBAAkB,CAEa;IAEzC;;;OAGG;IACH,QAFU,eAAe,CAEL;IACpB;;;OAGG;IACH,4BAAoB;IAEpB;;;OAGG;IACH,iBAAkB;IAElB,mBAAuC;IAYvC;;;OAGG;IACH,gBAFU,6BAA6B,CAEH;IAepC;;OAEG;IACH,WAFU,aAAa,CAEG;IA4H1B;;;;;;;;OAQG;IACH,SAFU,oBAAoB,GAAC,IAAI,CAEhB;IA4BnB;;;;;OAKG;IACH,YAFU,uBAAuB,GAAC,IAAI,CAEhB;IAEtB;;;;;;;;;;OAUG;IACH,aAFU,qBAAqB,GAAC,IAAI,CAEb;IAgF3B;;;;;;;;;;;;;;;OAeG;IACH;QAP4B,CAAC,GAAlB,MAAM;QACW,CAAC,GAAlB,MAAM;QACW,UAAU,GAA3B,MAAM;QAC6B,QAAQ;QAC7B,IAAI;QAChB,qBAAqB,CAwBjC;IAED;;;;;;;;;;;;OAYG;IACH,eAWC;IAED;;;;;;;;;OASG;IACH,4BAFa,OAAO,CAInB;IAED;;;;;;;;;;;;;OAaG;IACH;QAN4B,CAAC,GAAlB,MAAM;QACW,CAAC,GAAlB,MAAM;QACW,UAAU,GAA3B,MAAM;QACJ,qBAAqB,CA6BjC;IAED;;;OAGG;IACH,0BAFa,OAAO,CAQnB;IAED;;;;;OAKG;IACH,gCA8BC;IAED;;;;;;;;;OASG;IACH,iBAJa,OAAO,CAmBnB;IAED;;;;;;;;;;;;;;OAcG;IACH,SAJa,QAAQ,cAAc,CAAC,CAiCnC;IAED;;;;;;;;;;;OAWG;IACH,sBAJa,QAAQ,cAAc,CAAC,CAqBnC;IA+DD,yBAuDC;;CACJ;iBAz1BgB,2BAA2B;gCAHZ,mDAAmD;mCA4B5E,yBAAyB;mCArBG,yBAAyB;gCAFb,oBAAoB;8CAS5D,4EAA4E;8BATpC,oBAAoB;qCAC9B,2BAA2B;wCAexB,8BAA8B;oBALlD,mCAAmC"}
|
|
@@ -21,8 +21,15 @@ import Vector2 from "../../../src/core/geom/Vector2.js";
|
|
|
21
21
|
import ButtonView from "../../../src/view/elements/button/ButtonView.js";
|
|
22
22
|
import EmptyView from "../../../src/view/elements/EmptyView.js";
|
|
23
23
|
import { PortDirection } from "../../../src/core/model/node-graph/node/PortDirection.js";
|
|
24
|
-
import {
|
|
24
|
+
import { connection_bind_actions } from "./actions/connection_bind_actions.js";
|
|
25
25
|
import { NodeGraphSearchMenuView } from "./NodeGraphSearchMenuView.js";
|
|
26
|
+
import { ConnectionCreateAction } from "./actions/ConnectionCreateAction.js";
|
|
27
|
+
import {
|
|
28
|
+
NODE_GRAPH_PASTE_STEP,
|
|
29
|
+
NodeGraphClipboard,
|
|
30
|
+
node_graph_fragment_centre,
|
|
31
|
+
node_graph_fragment_from_nodes,
|
|
32
|
+
} from "./NodeGraphClipboard.js";
|
|
26
33
|
|
|
27
34
|
/**
|
|
28
35
|
* Whether a port could take a value of this type, knowing nothing about the graph's domain: the same
|
|
@@ -96,6 +103,12 @@ export class NodeGraphEditorView extends View {
|
|
|
96
103
|
* type the menu places, so a node arrives ready to compile rather than to repair
|
|
97
104
|
* @param {boolean} [readOnly] show the graph without offering to change it; see
|
|
98
105
|
* {@link NodeGraphView}. Turns off the add-node menu and the editing shortcuts too.
|
|
106
|
+
* @param {NodeGraphClipboard} [clipboard] what `Ctrl+C` writes and `Ctrl+V` reads. A host with
|
|
107
|
+
* several canvases over one document passes one to all of them, so a copy taken in one
|
|
108
|
+
* pastes in the next; on its own, a canvas gets one of its own and copies to itself.
|
|
109
|
+
* @param {function(NodeInstance):boolean} [copyable] whether a node may be had a second of, for
|
|
110
|
+
* a host with types that exist once per graph. See
|
|
111
|
+
* {@link node_graph_fragment_from_nodes}.
|
|
99
112
|
*/
|
|
100
113
|
constructor({
|
|
101
114
|
graph,
|
|
@@ -108,7 +121,9 @@ export class NodeGraphEditorView extends View {
|
|
|
108
121
|
portDataType = undefined,
|
|
109
122
|
minimap = true,
|
|
110
123
|
library = undefined,
|
|
111
|
-
readOnly = false
|
|
124
|
+
readOnly = false,
|
|
125
|
+
clipboard = new NodeGraphClipboard(),
|
|
126
|
+
copyable = undefined
|
|
112
127
|
}) {
|
|
113
128
|
super();
|
|
114
129
|
|
|
@@ -123,6 +138,19 @@ export class NodeGraphEditorView extends View {
|
|
|
123
138
|
*/
|
|
124
139
|
this.actionProcessor = actionProcessor;
|
|
125
140
|
|
|
141
|
+
/**
|
|
142
|
+
* What a copy is written to and a paste read from. Shared with the host's other canvases
|
|
143
|
+
* when it supplied one.
|
|
144
|
+
*
|
|
145
|
+
* @type {NodeGraphClipboard}
|
|
146
|
+
*/
|
|
147
|
+
this.clipboard = clipboard;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @type {function(NodeInstance):boolean}
|
|
151
|
+
*/
|
|
152
|
+
this.copyable = copyable ?? (() => true);
|
|
153
|
+
|
|
126
154
|
/**
|
|
127
155
|
*
|
|
128
156
|
* @type {NodeGraphSelection}
|
|
@@ -230,11 +258,60 @@ export class NodeGraphEditorView extends View {
|
|
|
230
258
|
event.stopPropagation();
|
|
231
259
|
|
|
232
260
|
actionProcessor.undo();
|
|
233
|
-
|
|
261
|
+
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (event.keyCode === KeyCodes.y) {
|
|
234
266
|
event.preventDefault();
|
|
235
267
|
event.stopPropagation();
|
|
236
268
|
|
|
237
269
|
actionProcessor.redo();
|
|
270
|
+
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// The clipboard's three want Ctrl and nothing else. `AltGr` is `Ctrl+Alt` on a European
|
|
275
|
+
// keyboard, so a canvas that answered that combination would copy every time an author
|
|
276
|
+
// typed one of the characters behind it; and `Ctrl+Shift+C` belongs to the browser.
|
|
277
|
+
if (event.shiftKey || event.altKey) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Copying reads the graph, so a locked group body offers it: taking a copy of something
|
|
282
|
+
// out of one of the library's own groups and putting it in a graph of your own is the
|
|
283
|
+
// point of being able to open them. Putting something *into* one is not.
|
|
284
|
+
if (event.keyCode === KeyCodes.c) {
|
|
285
|
+
event.preventDefault();
|
|
286
|
+
event.stopPropagation();
|
|
287
|
+
|
|
288
|
+
this.copySelection();
|
|
289
|
+
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (readOnly) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// `Ctrl+D` is the browser's bookmark shortcut, so it is swallowed whether or not there
|
|
298
|
+
// is anything selected to duplicate — leaving it through on an empty selection would
|
|
299
|
+
// mean the canvas sometimes bookmarked the page instead.
|
|
300
|
+
if (event.keyCode === KeyCodes.d) {
|
|
301
|
+
event.preventDefault();
|
|
302
|
+
event.stopPropagation();
|
|
303
|
+
|
|
304
|
+
this.duplicateSelection()
|
|
305
|
+
.catch(e => console.error("could not duplicate the selection", e));
|
|
306
|
+
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (event.keyCode === KeyCodes.v) {
|
|
311
|
+
event.preventDefault();
|
|
312
|
+
event.stopPropagation();
|
|
313
|
+
|
|
314
|
+
this.paste().catch(e => console.error("could not paste", e));
|
|
238
315
|
}
|
|
239
316
|
});
|
|
240
317
|
|
|
@@ -419,12 +496,13 @@ export class NodeGraphEditorView extends View {
|
|
|
419
496
|
const outgoing = endpoint.port.direction === PortDirection.Out;
|
|
420
497
|
|
|
421
498
|
// `addNode` marked the timeline and has not marked it again, so this joins the same step
|
|
422
|
-
await this.actionProcessor.
|
|
499
|
+
await this.actionProcessor.doMany(connection_bind_actions(
|
|
423
500
|
this.graph,
|
|
424
501
|
outgoing ? endpoint.instance.id : node.id,
|
|
425
502
|
outgoing ? endpoint.port.id : port.id,
|
|
426
503
|
outgoing ? node.id : endpoint.instance.id,
|
|
427
|
-
outgoing ? port.id : endpoint.port.id
|
|
504
|
+
outgoing ? port.id : endpoint.port.id,
|
|
505
|
+
this.visual
|
|
428
506
|
));
|
|
429
507
|
|
|
430
508
|
return node;
|
|
@@ -562,6 +640,171 @@ export class NodeGraphEditorView extends View {
|
|
|
562
640
|
await this.actionProcessor.doMany(actions);
|
|
563
641
|
}
|
|
564
642
|
|
|
643
|
+
/**
|
|
644
|
+
* Take a copy of the selected nodes, and of every wire they hold whole.
|
|
645
|
+
*
|
|
646
|
+
* Reading, not editing, so a read-only canvas offers it: opening one of a library's own groups
|
|
647
|
+
* to take a copy of what is inside it is the point of being able to open them.
|
|
648
|
+
*
|
|
649
|
+
* @returns {boolean} whether anything was copied. A selection with nothing copyable in it leaves
|
|
650
|
+
* the clipboard alone rather than emptying it, which is the one outcome an author
|
|
651
|
+
* asking for a copy certainly did not want.
|
|
652
|
+
*/
|
|
653
|
+
copySelection() {
|
|
654
|
+
const fragment = node_graph_fragment_from_nodes({
|
|
655
|
+
graph: this.graph,
|
|
656
|
+
visual: this.visual,
|
|
657
|
+
nodes: this.selection.nodes.asArray(),
|
|
658
|
+
copyable: this.copyable,
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
if (fragment === null) {
|
|
662
|
+
return false;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
this.clipboard.write(fragment);
|
|
666
|
+
|
|
667
|
+
return true;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Put what was copied into this graph, in the middle of what the author is looking at.
|
|
672
|
+
*
|
|
673
|
+
* Where a paste lands is the one decision here. It goes to the middle of the view rather than
|
|
674
|
+
* back where it was copied from, for the same reason a node added from the menu with no position
|
|
675
|
+
* does: what arrives has to be somewhere the author can see it, and the place it was copied from
|
|
676
|
+
* may be a long way off screen — a copy taken in one phase and pasted in the other has no
|
|
677
|
+
* meaningful "back where it was" at all. The arrangement inside the fragment is kept exactly; it
|
|
678
|
+
* is the whole of it that moves. A repeat paste of the same content steps aside by
|
|
679
|
+
* {@link NODE_GRAPH_PASTE_STEP} so that copies do not hide each other.
|
|
680
|
+
*
|
|
681
|
+
* @returns {Promise<NodeInstance[]>} the nodes that landed, once the timeline has applied them;
|
|
682
|
+
* empty when there was nothing on the clipboard
|
|
683
|
+
* @throws if this canvas is read-only
|
|
684
|
+
*/
|
|
685
|
+
async paste() {
|
|
686
|
+
if (this.readOnly) {
|
|
687
|
+
throw new Error("This graph is read-only, so nothing can be pasted into it.");
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
const clipboard = this.clipboard;
|
|
691
|
+
|
|
692
|
+
const fragment = clipboard.read();
|
|
693
|
+
|
|
694
|
+
if (fragment === null) {
|
|
695
|
+
return [];
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
const centre = node_graph_fragment_centre(fragment);
|
|
699
|
+
const target = this.viewCentreInGraphSpace();
|
|
700
|
+
|
|
701
|
+
const step = clipboard.pastes * NODE_GRAPH_PASTE_STEP;
|
|
702
|
+
|
|
703
|
+
// before the placing rather than after it: the timeline queues, so two pastes issued in one
|
|
704
|
+
// tick — which is what holding Ctrl+V down is — would otherwise both read the same count and
|
|
705
|
+
// land on top of each other
|
|
706
|
+
clipboard.notePaste();
|
|
707
|
+
|
|
708
|
+
return this.#placeFragment(
|
|
709
|
+
fragment,
|
|
710
|
+
target.x - centre.x + step,
|
|
711
|
+
target.y - centre.y + step,
|
|
712
|
+
'paste'
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* A second of everything selected, beside the originals.
|
|
718
|
+
*
|
|
719
|
+
* Beside rather than in the middle of the view, which is where {@link #paste} puts things: a
|
|
720
|
+
* duplicate is a second of something the author is already looking at, and centring it would
|
|
721
|
+
* take it away from the thing it is a second of. The clipboard is not touched — `Ctrl+D` is not
|
|
722
|
+
* a copy, and it must not cost the author whatever they had copied earlier.
|
|
723
|
+
*
|
|
724
|
+
* @returns {Promise<NodeInstance[]>} the new nodes; empty when nothing selected could be had a
|
|
725
|
+
* second of
|
|
726
|
+
* @throws if this canvas is read-only
|
|
727
|
+
*/
|
|
728
|
+
async duplicateSelection() {
|
|
729
|
+
if (this.readOnly) {
|
|
730
|
+
throw new Error("This graph is read-only, so nothing in it can be duplicated.");
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
const fragment = node_graph_fragment_from_nodes({
|
|
734
|
+
graph: this.graph,
|
|
735
|
+
visual: this.visual,
|
|
736
|
+
nodes: this.selection.nodes.asArray(),
|
|
737
|
+
copyable: this.copyable,
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
if (fragment === null) {
|
|
741
|
+
return [];
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
return this.#placeFragment(fragment, NODE_GRAPH_PASTE_STEP, NODE_GRAPH_PASTE_STEP, 'duplicate');
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Build a fragment into this graph, offset, as one undoable step, and leave it selected.
|
|
749
|
+
*
|
|
750
|
+
* Two batches under one mark, because the wires need ids the creates have not handed out yet —
|
|
751
|
+
* the same shape an ungrouping has, and for the same reason. What is selected afterwards is what
|
|
752
|
+
* just arrived, so it can be dragged into place without being hunted for first.
|
|
753
|
+
*
|
|
754
|
+
* @param {import("./NodeGraphClipboard.js").NodeGraphFragment} fragment
|
|
755
|
+
* @param {number} offset_x graph-space
|
|
756
|
+
* @param {number} offset_y graph-space
|
|
757
|
+
* @param {string} label what the step is called on the timeline
|
|
758
|
+
* @returns {Promise<NodeInstance[]>}
|
|
759
|
+
*/
|
|
760
|
+
async #placeFragment(fragment, offset_x, offset_y, label) {
|
|
761
|
+
const graph = this.graph;
|
|
762
|
+
const visual = this.visual;
|
|
763
|
+
|
|
764
|
+
// A canvas draws a node in a box generated from its type, and throws when it has none — so a
|
|
765
|
+
// fragment carrying a type this canvas has never drawn would fail from inside the timeline,
|
|
766
|
+
// half-way through a step. Which is reachable: the clipboard is shared between canvases, and
|
|
767
|
+
// a host's canvases need not have been built from the same set of types. Generating a box is
|
|
768
|
+
// arithmetic over port and parameter counts, keyed by the description, so telling a registry
|
|
769
|
+
// about a type it already knows costs nothing.
|
|
770
|
+
for (const record of fragment.nodes) {
|
|
771
|
+
this.visualRegistry.generate(record.description);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
const creates = fragment.nodes.map(record => new NodeCreateAction(
|
|
775
|
+
graph,
|
|
776
|
+
visual,
|
|
777
|
+
this.visualRegistry,
|
|
778
|
+
record.description,
|
|
779
|
+
record.x + offset_x,
|
|
780
|
+
record.y + offset_y,
|
|
781
|
+
// cloned again on the way out: one fragment pasted twice must not hand both copies the
|
|
782
|
+
// same parameter objects, nor either of them the clipboard's
|
|
783
|
+
structuredClone(record.parameters)
|
|
784
|
+
));
|
|
785
|
+
|
|
786
|
+
this.actionProcessor.mark(label);
|
|
787
|
+
|
|
788
|
+
await this.actionProcessor.doMany(creates);
|
|
789
|
+
|
|
790
|
+
const nodes = creates.map(create => create.node);
|
|
791
|
+
|
|
792
|
+
const wires = fragment.connections.map(wire => new ConnectionCreateAction(
|
|
793
|
+
graph,
|
|
794
|
+
nodes[wire.from].id,
|
|
795
|
+
wire.fromPort,
|
|
796
|
+
nodes[wire.to].id,
|
|
797
|
+
wire.toPort
|
|
798
|
+
));
|
|
799
|
+
|
|
800
|
+
// `mark` has not been called again, so this joins the same step
|
|
801
|
+
wires.push(new SelectionSetAction(this.selection, nodes.map(node => node.id), []));
|
|
802
|
+
|
|
803
|
+
await this.actionProcessor.doMany(wires);
|
|
804
|
+
|
|
805
|
+
return nodes;
|
|
806
|
+
}
|
|
807
|
+
|
|
565
808
|
cameraContainAll() {
|
|
566
809
|
/**
|
|
567
810
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeGraphView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphView.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"NodeGraphView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphView.js"],"names":[],"mappings":";AA0GA;IA4GI;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gJAyhBC;IAxpBD,mBAAmC;IAEnC;;;;;;;;;OASG;IACH,oBAFU,IAAI,MAAM,EAAE,QAAQ,CAAC,CAET;IAmBtB;;;OAGG;IACH,qBAFmB,yBAAyB,cAE/B;IAEb;;OAEG;IACH,iBA0DE;IAEF;;;;OAIG;IACH,mBAFU,OAAO,CAEA;IAmCb;;;OAGG;IACH,2CAAsC;IAMtC;;;OAGG;IACH,QAFU,eAAe,CAEL;IAEpB;;;OAGG;IACH,iBAAkB;IAElB;;;OAGG;IACH,4BAAoB;IAEpB;;;OAGG;IACH,WAFU,kBAAkB,CAEF;IA8e9B;;;;;;;;;OASG;IACH,oBAFa,IAAI,CAgBhB;IAED;;;;;;;;OAQG;IACH,gBAFa,IAAI,CAMhB;IAED;;;;;;;;OAQG;IACH,cAFa,OAAO,CAInB;IAgBD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gCAFa,IAAI,CA+NhB;IAED;;;;;;;;OAQG;IACH,0BAHW,KAAK,GACH,MAAM,EAAE,CAwBpB;IAED;;;;;;;;;;;OAWG;IACH,gCAHW,KAAK,GACH,MAAM,EAAE,CAsBpB;IAED;;;;;;;;;;OAUG;IACH,6BAJW,KAAK,SACL,UAAU,GAAC,YAAY,GACrB,IAAI,CAgDhB;IAED;;;;OAIG;IACH,wBAHW,OAAO,GACL,aAAW,IAAI,CAiC3B;IAED;;;;;;;OAOG;IACH,4BAJW,MAAM,GAAC,IAAI,gBACX,MAAM,GAAC,IAAI,SACX,UAAU,GAAC,YAAY,QA8CjC;IAGD;;;;;;;OAOG;IACH,wDAFa,OAAO,CAcnB;IAED;;;;;;;;;OASG;IACH,+CAFa,oBAAoB,CAYhC;IAED;;;;;;OAMG;IACH,oBALW,wBAAwB,QACxB,oBAAoB,iCAEpB,OAAO,QA+DjB;IAED;;;;OAIG;IACH,mCAHW,yBAAyB,UACzB,OAAO,QAiBjB;IAeD;;;;OAIG;IACH,kCAHW,OAAO,UACP,OAAO,QAIjB;IAED;;;;OAIG;IACH,kCAHW,OAAO,UACP,OAAO,QAIjB;;CACJ;iBA/7CgB,2BAA2B;yBAInB,eAAe;0CAIE,sEAAsE;gCAChF,mDAAmD;gCACnD,sBAAsB;mCACnB,yBAAyB;kBAS1C,yCAAyC;oBAlBvC,mCAAmC;qCAiBlB,mEAAmE"}
|