Skip to content

Add scale block support and fix transform chain replay logic#331

Open
tracygardner wants to merge 2 commits intomainfrom
claude/fix-shape-transform-updates-kCE3j
Open

Add scale block support and fix transform chain replay logic#331
tracygardner wants to merge 2 commits intomainfrom
claude/fix-shape-transform-updates-kCE3j

Conversation

@tracygardner
Copy link
Contributor

Summary

This PR adds support for the scale block type and refactors transform block handling to properly replay the entire DO-chain when any transform block is modified. This ensures the live preview correctly matches runtime behavior, especially when multiple transforms are chained together (e.g., resize → rotate_to → resize).

Key Changes

  • Added scale block support: Extended getMeshFromBlock() and getMeshesFromBlock() to recognize and handle the scale block type alongside rotate_to and resize.

  • Introduced DO-chain replay logic: Created two new helper functions:

    • getContainerBlock(): Walks up the block hierarchy to find the containing create_/load_ block that owns the DO chain
    • applyTransformBlockToMeshes(): Applies a single transform block's effect to a list of meshes
    • applyDoChainToMeshes(): Resets meshes to their creation state, restores base position, then replays all enabled transform blocks in order
  • Fixed transform block updates: Modified updateMeshFromBlock() to replay the entire DO chain when transform blocks are moved or their fields change, rather than applying transforms in isolation. This ensures anchor compensation in resize() always operates on an unrotated mesh, matching runtime behavior.

  • Added BLOCK_MOVE event handling: Transform blocks now properly handle block reordering by replaying the full chain, ensuring the preview reflects the new block order.

  • Updated block change handlers: Modified blocks/transform.js to trigger DO-chain replay when a transform block itself is moved/connected, and added scale to the list of recognized transform block types.

Notable Implementation Details

  • The DO-chain replay resets each mesh to its creation-time state (identity rotation, unit scale) before replaying transforms, ensuring deterministic results regardless of previous transform history.
  • Mesh metadata (originalMin/originalMax) is cleared during reset to force resize() to re-capture geometry dimensions from the reset state.
  • The implementation maintains backward compatibility by falling back to applying just the changed block's transform if no DO container is found.

https://claude.ai/code/session_011dYQCXitV5ZhAgoT7537XF

The anchor compensation in resize() uses world-space AABB coordinates.
When a mesh is rotated, the world AABB is larger than the actual mesh
bounds, so applying a subsequent resize produced a different position
offset in the live preview than at runtime (where resize runs before
rotation in the sequential chain).

Fix: when any transform block (resize, rotate_to, scale) in a DO chain
has a value changed or is moved, reset the mesh to its initial creation
state (identity rotation, unit scaling, base position) and replay the
entire DO chain in order. This exactly replicates the runtime execution
sequence so the live preview always matches what "play" produces.

Also extends scale block support to getMeshFromBlock/getMeshesFromBlock
and the contextBlock detection in updateMeshFromBlock, and adds
BLOCK_MOVE replay so reordering DO-chain blocks updates the preview.

https://claude.ai/code/session_011dYQCXitV5ZhAgoT7537XF
…r walk

Two bugs in the rotation gizmo onDragEndObservable caused shapes to jump
vertically after being rotated with the gizmo:

1. Wrong while-loop condition: `!mesh.parent.physics` checked the PARENT's
   physics instead of the current node's, stopping one level too early for
   compound meshes. The subsequent `if (!mesh?.physics) return` then always
   fired early, skipping the entire block update.

2. Non-physics meshes were completely bypassed by `if (!mesh?.physics) return`,
   so the rotate_to block was never created/updated. The next time
   applyDoChainToMeshes ran (e.g. from another block change event), it would
   replay the DO chain without any rotate_to block, resetting the mesh rotation
   (and thus the Y position compensation) to zero — causing the visible jump.

Fix: separate physicsMesh walk (corrected condition checks current node),
remove the early-exit guard, use findParentWithBlockId for reliable
mesh→block lookup on both compound and simple meshes.

https://claude.ai/code/session_011dYQCXitV5ZhAgoT7537XF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants