feat(paper): render the sheet as a top-locked GPU viewport

Paper space now renders its sheet through the unified shader, the same
path as model space: a full-canvas "sheet" ViewportInstance draws the
layout's own entities + viewport borders + interim/preview wires, with a
camera locked to the top/plan orientation (paper is 2-D and never
orbits). Floating content viewports overlay it.

- PaperCanvas no longer draws entity wires (still paints the desk, sheet
  and hatch/wipeout/image fills; full removal is the next step).
- Right-drag on the paper sheet no longer orbits the camera (it would
  corrupt the frame and skew subsequent pans).
- Fix floating-viewport orbit oscillation: orbit_active_viewport wrote
  view_direction.y negated while camera_for_viewport reads it un-negated,
  so each drag step read back a Y-mirrored camera and flipped the model
  between a rotation and its opposite every frame. Store eye directly,
  matching snap_active_viewport_to_direction and the reader.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-02 20:05:51 +03:00
1 parent 568422679d
commit 0ef99ff2fc
4 files changed
+65 -64

No files matched your search

+17 -3
View File
@@ -597,6 +597,11 @@ impl Scene {
1.0
};
self.model_tile_wires_arc(tile_idx, &inst.camera, aspect, full.height)
} else if inst.paper_sheet {
// The sheet renders the paper block's own entities + viewport
// borders — NOT the projected viewport content (the GPU content
// viewports draw that themselves).
self.paper_sheet_wires_arc()
} else if inst.handle == acadrust::Handle::NULL {
self.entity_wires_arc()
} else {
@@ -648,13 +653,22 @@ impl Scene {
height: visible_h / canvas.1,
};
// Stage 1: the paper sheet instance contributes only entity wires; its
// hatch / wipeout / image fills are still drawn by PaperCanvas beneath
// the shader. (Stage 2 moves those into the shader and drops PaperCanvas.)
let (hatches, wipeout_hatches, images) = if inst.paper_sheet {
(Arc::new(Vec::new()), Arc::new(Vec::new()), Arc::new(Vec::new()))
} else {
(self.hatch_models_arc(), self.wipeout_models_arc(), self.images_arc())
};
Some(ViewportData {
wires: all_wires,
face3d_wires: Arc::new(face3d_wires),
draw_depths: self.draw_depth_map(),
hatches: self.hatch_models_arc(),
wipeout_hatches: self.wipeout_models_arc(),
images: self.images_arc(),
hatches,
wipeout_hatches,
images,
meshes: self.meshes_arc(),
uniforms,
cam_rotation: inst.camera.view_rotation_mat(),