You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When you drag a layer in a stack up or down, and it runs into the layers above/below it, we want the behavior to work based on this physical analogy:
Wooden blocks are strewn across the floor in a line. Any block can be pushed, which will accumulate blocks in the "wave of blocks" with one block at the front of the push, which continues to meet additional blocks in front of it as collisions occur, growing the wave and transferring the front further along to new blocks. Blocks fit together like puzzle pieces, so collision detection along the entire top/bottom surface is necessary. If the push is retracted, all the blocks get elastically pulled back towards their starting places by rubber bands that pinned them to their starting positions, but they will travel no further than being restored back to where they began.
Algorithm:
When dragging begins, the vertical positions of all the layers (and their upstream nodes that feed in through primary or secondary flow) have their positions stored, like they are "held in place by rubber bands".
The selected layer (or if multiple, this occurs for all of them) starts as the "front" (like a "wave front" or "storm font").
The front detects collision in the direction of travel between the selected nodes and the with the next nodes in the direction of travel. When shifting up this is any nodes downstream of the moved nodes. When shifting down this is any nodes upstream of the shifted nodes. This means when shifting down, dangling nodes of the selected layer are treated the same as the upstream sibling layer. These upstream absolute nodes are treated as "loose" meaning they will get pushed together if there is space (possibly recreating a chain), and if they are touching then force would be transferred through them.
If a collision occurs, the role of being the front is switched to that layer and it (plus its upstream nodes that were part of the collision area) get pushed along with the wave of blocks.
If the user reverses direction and backs off, the "rubber bands" attempt to push all layers (and associated nodes that also got shifted) back to their starting positions, but no further.
When the user releases the pointer click, the drag is over and the "rubber bands" are erased.
Implementation:
Get an ordered list of layer and nodes to be shifted based on the current selection, and the vertical direction of the shift. A shift down sorts the nodes with the greatest y position first. Collision detection should only be performed for layers and nodes that are upstream from a layer being moved.
Get a list of all nodes to check collision with. For a shifted node, it gets the downstream layer it is connected to (with the tuple), all upstream nodes of the layer which are not selected (since selected nodes would never get intersected due to the ordering), the upstream/downstream layer based on the direction, and all nodes upstream of that layer. For a shifted layer, it checks all upstream nodes, the layer above/below based on direction, and all nodes upstream of that layer.
Get a list of colliding nodes if there is a collision or negative y offset after the shift with the selected node. Run the entire function for this group of colliding nodes (as if they were selected and shifted), then run the entire function again for the node/layer. A recursion limit can be applied to prevent extreme shifting, and allow overlap instead.
For an upward shift, the selected nodes are shifted top to bottom, and each shift sends a wave from bottom to top in order to make space for that node. This means there can be multiple "wave fronts" if multiple nodes are selected in a stack, but not those in between.
Collapsing space due to rubber banding will be handled by the node graph message handler, since this requires saving state and should not happen during programmatic shifts.
The text was updated successfully, but these errors were encountered:
When you drag a layer in a stack up or down, and it runs into the layers above/below it, we want the behavior to work based on this physical analogy:
Wooden blocks are strewn across the floor in a line. Any block can be pushed, which will accumulate blocks in the "wave of blocks" with one block at the front of the push, which continues to meet additional blocks in front of it as collisions occur, growing the wave and transferring the front further along to new blocks. Blocks fit together like puzzle pieces, so collision detection along the entire top/bottom surface is necessary. If the push is retracted, all the blocks get elastically pulled back towards their starting places by rubber bands that pinned them to their starting positions, but they will travel no further than being restored back to where they began.
Algorithm:
Implementation:
The text was updated successfully, but these errors were encountered: