Skip to content

Drag individual pieces out of the assembly, inspect them, and snap them back #3

Description

@PouyanJay

The separation slider moves every piece at once along a path we decide. Learners also want to grab one part, pull it out, turn it over, and put it back. Direct manipulation makes the parts feel like objects instead of a rendering.

What is needed

Drag any piece out of the assembly, inspect it, and snap it back to its home position. Users should be able to:

  • Click and drag a piece in Assembled or Cutaway mode. The piece follows the pointer on a plane facing the camera.
  • Release it to leave it where it is, with a faint ghost at its home position.
  • Double click it, or press a "Return" button on its detail card, to animate it back home.
  • Return everything at once from the "Show all components" control.
  • Drag on touch devices with a long press, so a normal touch still orbits.

Success criteria

  • Every independently selectable piece, including instanced blades and fasteners, can be dragged.
  • A dragged piece keeps its orientation unless the user rotates it with a modifier key or a second control.
  • Dragging never changes the captured home matrix. After returning, the piece's world matrix equals its home matrix to within 1e-6; this is asserted in the engine check.
  • The separation slider still works while pieces are displaced: moving it returns displaced pieces to the slider's pose, and moving it back to zero returns everything home.
  • Hidden or isolated pieces cannot be dragged, and a dragged piece stays visible when its group is later hidden until it is returned.
  • Labels and the component detail card follow a dragged piece.
  • No frame drops below the current baseline while dragging one piece on the turbofan.

Suggested approach

  • The ExplosionController already owns a current matrix per piece and writes it into the instanced batches every frame. Add an optional per-piece offset matrix that is composed on top of the derived separation pose. The slider path and the drag path then share one write routine and cannot fight each other.
  • Picking already maps a raycast hit to a piece id through the batch's pieceIds. Reuse it for pointer down. During drag, intersect the pointer ray with a plane through the piece's current position facing the camera and update the offset translation.
  • Disable orbit controls while a drag is active and re-enable them on pointer up. On touch, start a drag only after a 300 ms press with less than 8 px of movement.
  • Draw the home ghost by rendering the same geometry with a transparent, unlit material in an overlay group. Ghosts are excluded from picking and from the piece count.
  • Return animations can use the same easing helper as camera fits: interpolate the offset to identity over about 400 ms.
  • Keep hidden, isolated and the new displaced: string[] list in ViewerState so "Show all components" can clear all three.
  • Extend the engine check: pick a piece, apply an offset, call return, and assert the world matrix equals home.

Out of scope

Physics, collisions, and saving displaced layouts across reloads.

Touchpoints

lib/engine/explosion-controller.ts, components/engine/engine-scene.tsx, app/page.tsx, scripts/check-explosion.mjs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: sceneThree.js scene, geometry, cameras, renderingarea: uiControls, panels, layout, interactionenhancementNew feature or requestfeatureA new user-facing capabilitypriority: mediumImportant, after the high itemssize: LRoughly one to two weeks of focused workv0.2.0Planned for the v0.2.0 release

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions