feat(viewcube): add compass ring, cardinals, and nav controls

Build the ViewCube out into a full navigation widget:

- Compass ring painted in the cube's ground plane (z = base) so it
  reads as a ground compass and foreshortens with the view.
- N/E/S/W cardinals painted flat onto the ring band; clicking one snaps
  to that side elevation. Added S/W glyphs to the bitmap atlas.
- Home button (top-down view), roll arrows (90° roll about the view
  axis), and four nudge triangles (90° tip/spin) as SVG iced controls
  laid out around the cube. New home.svg.
- WCS / named-UCS selector under the cube, switching the active UCS.

The cube hit area now shares one stack with the control buttons, so a
click on a button is caught by the button while a click on the cube
falls through. Face clicks snap to the highlighted region rather than a
cursor position the viewport's move handler can overwrite.

Camera gains home_view / roll_by / nudge_90; floating viewports drive
the same ops through mutate_active_viewport_camera, which re-encodes the
result to the stored view direction + twist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-25 23:46:43 +03:00
commit f00c48bebb
9 changed files with 633 additions and 40 deletions

View file

@ -1114,6 +1114,14 @@ pub enum Message {
ViewportScroll(mouse::ScrollDelta),
ViewportExit,
ViewCubeSnap(CubeRegion),
/// ViewCube home button → jump to the default isometric view.
ViewCubeHome,
/// ViewCube roll arrow → roll the view 90° (true = clockwise).
ViewCubeRoll(bool),
/// ViewCube nudge triangle → tip / spin the view 90°.
ViewCubeNudge(crate::scene::NudgeDir),
/// WCS/UCS selector under the cube — empty string = World.
SetViewcubeUcs(String),
/// User picked an item in the multi-functional grip popup menu —
/// the index is into `grip_popup.items`.
GripMenuPick(usize),