Paste mixed two frames. The pointer comes from the Scene View, which
draws every object moved by the editor offsets of it and its parents.
Paste turned that point into a local position through the parents'
plain world transform, so the copy landed beside the pointer by the
offset of the parent it went into. Without a pointer, an original with
an offset of its own had its copy placed beside its game position,
which the view does not show.
- A copied root now remembers where the view showed it
(`ClipRoot.shown`, from `editorTransform`) instead of its world
position.
- New `editorLocalPositionFor` in `properties/transform.ts` turns a
shown point into a local position through the parent chain with the
editor offsets, as the view draws it. Paste uses it.
- The copy itself still gets no editor offset of its own, as since
#240. In the game it stands where it was drawn, minus the offsets of
its parents.
- Re-parenting under a parent with an offset still keeps the game
position, so the object jumps in the view by that offset. That is a
different rule from paste and is left as it is.
Tests:
- Unit (clipboard, groups, references, transform): 50 passed, 2 new.
- e2e 51 on melektaus-atx: ALL PASSED, 12 checks, 1 new (51f).
- Gate on melektaus-atx: 195 files, 2829 tests, CHECK EXIT 0.
- Counter-checks: without the paste fix both new unit tests fail
(copy at 540/470 instead of 500/500) and 51f fails by exactly the
60/-40 offset. With the root remembering its world position again,
the own-offset unit test fails.
- No full run. The e2e total of 1591 is 1590 plus 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>