forked from 1b-agent/opencadstudio-upstream
fix(view): unify model VPORT / paper VIEWPORT view handling
Model-space tiled VPORTs and paper-space floating VIEWPORTs each carried their own copy of the saved-view→camera math, so a fix to one drifted from the other (the recurring grid/twist regressions). Route both, plus the View-table and sheet-viewport paths, through one decoder and fix the bugs that the duplication hid. Decoder unification: - New camera_from_view(direction, target, center, height, twist, world_offset): the single saved-view→Camera decoder. camera_from_vport (tiled), camera_for_viewport (floating, + auto-fit), and the View-entry / sheet-viewport apply paths all delegate to it. Tiled vs floating now differ only in field source and the floating auto-fit fallback. Twist round-trips on layout switch and file save: - camera_from_view applies roll = -twist; the write path was dropping it, so model→paper→model (and reload) reset the view to raw orientation. - New Camera::roll() recovers the camera roll; sync_camera_to_document, write_camera_view_entry, and vport_from_camera now store -roll as the view twist on the *Active VPort, the OpenCADStudio_Camera_Model View entry, the per-tile VPorts, and the paper sheet viewport. Rotation-aware frustum cull: - New view_cull_aabb(): the entity-cull rectangle is built from the camera's right/up basis (so a twisted/rotated view's rotated rectangle is enclosed) instead of world X/Y axes; returns None for tilted views to disable the flat-XY cull rather than wrongly hide geometry. Applied to the model-tile and paper-viewport cull sites. Paper viewport scale: - The floating-viewport auto-fit overlap test summed view_target + view_center raw; under a twist view_center is a DCS offset, so the sum landed far from the real WCS centre and wrongly tripped the auto-fit, rendering content at the wrong zoom. It now tests the decoded (twist-folded, wire-space) target. The CPU projection path derives its scale from that same camera, locking hit-test/snap to the GPU render. Grid enumeration: - ViewportInstance gains grid_on; the two grid-view collectors collapse into one grid_views() derived from the same active_viewports() list the renderer uses, so the grid overlay can no longer drift from the views on screen. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
7a1988e851
commit
44d2df9361
3 files changed
+256
-319
No files matched your search
@@ -187,6 +187,18 @@ impl Camera {
|
||||
Mat4::from_quat(self.rotation.conjugate())
|
||||
}
|
||||
|
||||
/// The camera's roll — rotation about the view axis, in radians — the
|
||||
/// inverse of the `roll` argument to [`yaw_pitch_to_quat`]. Recovered by
|
||||
/// removing the yaw/pitch frame from the live rotation, so a saved view can
|
||||
/// store its twist and round-trip it. Exact for a plan view (the twisted-
|
||||
/// UCS case); approximate after a free 3D orbit.
|
||||
pub fn roll(&self) -> f32 {
|
||||
let q_yp = yaw_pitch_to_quat(self.yaw, self.pitch, 0.0);
|
||||
let q_roll = q_yp.conjugate() * self.rotation;
|
||||
// q_roll is (nominally) a rotation about Z; extract its angle.
|
||||
2.0 * q_roll.z.atan2(q_roll.w)
|
||||
}
|
||||
|
||||
// ── Navigation ────────────────────────────────────────────────────────
|
||||
|
||||
/// Arcball orbit: drag delta (dx, dy) in screen pixels.
|
||||
|
||||
Reference in new issue
Block a user