From 2507a8fe5592ed37b3dbea87564ab7b45b0b6e2e Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Wed, 24 Jun 2026 21:38:51 +0300 Subject: [PATCH] refactor: unify eye() to a single f64 accessor (drop eye_f64) The whole pipeline is relative-to-eye now, so the f32/f64 split is vestigial. Merge eye_f64 into eye() returning DVec3; direction-only callers take .as_vec3(). Co-Authored-By: Claude Opus 4.8 --- src/app/view.rs | 6 +++--- src/scene/view/camera.rs | 25 +++++++++---------------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/app/view.rs b/src/app/view.rs index f08fb7d78..1d7c57d5b 100644 --- a/src/app/view.rs +++ b/src/app/view.rs @@ -102,7 +102,7 @@ impl OpenCADStudio { grips_to_screen_rte( &tab.selected_grips, cam.view_proj_rte(bounds), - cam.eye_f64(), + cam.eye(), bounds, ) } else if is_paper { @@ -185,7 +185,7 @@ impl OpenCADStudio { let plane = grid_plane_from_camera(cam.pitch, cam.yaw); overlay::GridParams { view_rot: cam.view_proj_rte(bounds), - eye: cam.eye_f64(), + eye: cam.eye(), bounds, plane, origin, @@ -227,7 +227,7 @@ impl OpenCADStudio { let ost_points: Vec = if self.snapper.otrack_enabled { let (view_rot, eye) = { let cam = tab.scene.camera.borrow(); - (cam.view_proj_rte(vp_bounds), cam.eye_f64()) + (cam.view_proj_rte(vp_bounds), cam.eye()) }; self.snapper .tracking_points diff --git a/src/scene/view/camera.rs b/src/scene/view/camera.rs index 1a79c1f45..bd1065d02 100644 --- a/src/scene/view/camera.rs +++ b/src/scene/view/camera.rs @@ -69,17 +69,10 @@ pub const OPENGL_TO_WGPU: Mat4 = glam::mat4( impl Camera { // ── Eye position ─────────────────────────────────────────────────────── - pub fn eye(&self) -> Vec3 { - // The canonical eye direction is +Z (looking at origin from above). - // The rotation maps that canonical pose to the current orientation. - let eye_dir = self.rotation * Vec3::Z; - self.target.as_vec3() + eye_dir * self.distance - } - - /// Eye position in full f64 precision (offset-relative world space). Used - /// by the relative-to-eye render path; the f32 [`eye`] stays for ray/pick - /// math that operates at human scale. - pub fn eye_f64(&self) -> DVec3 { + /// Eye position in full f64 precision (world space). The whole pipeline is + /// relative-to-eye, so this is the canonical eye; direction-only callers + /// (view-matrix basis, ray casts) take `.as_vec3()`. + pub fn eye(&self) -> DVec3 { let eye_dir = (self.rotation * Vec3::Z).as_dvec3(); self.target + eye_dir * self.distance as f64 } @@ -114,7 +107,7 @@ impl Camera { let aspect = bounds.width / bounds.height; let up_dir = self.rotation * Vec3::Y; - let mut view = Mat4::look_at_rh(self.eye(), self.target.as_vec3(), up_dir); + let mut view = Mat4::look_at_rh(self.eye().as_vec3(), self.target.as_vec3(), up_dir); // Zero the translation column → pure rotation (world→view basis). view.w_axis = glam::vec4(0.0, 0.0, 0.0, 1.0); @@ -138,7 +131,7 @@ impl Camera { /// coordinates — the CPU equivalent of the GPU's relative-to-eye path. /// Returns `None` for points at/behind the eye plane (w ≈ 0). pub fn project(&self, p: glam::DVec3, bounds: Rectangle) -> Option { - let rel = (p - self.eye_f64()).as_vec3(); + let rel = (p - self.eye()).as_vec3(); let clip = self.view_proj_rte(bounds) * rel.extend(1.0); if clip.w.abs() < 1e-9 { return None; @@ -161,7 +154,7 @@ impl Camera { plane_normal: Vec3, plane_point: glam::DVec3, ) -> glam::DVec3 { - let eye = self.eye_f64(); + let eye = self.eye(); let ndc_x = (screen.x / bounds.width) * 2.0 - 1.0; let ndc_y = 1.0 - (screen.y / bounds.height) * 2.0; let inv = self.view_proj_rte(bounds).inverse(); @@ -194,7 +187,7 @@ impl Camera { /// double-single relative-to-eye shaders. `high + low ≈ eye` to ~f64 /// precision; the shader subtracts these from each vertex's own high/low. pub fn eye_high_low(&self) -> ([f32; 3], [f32; 3]) { - let e = self.eye_f64(); + let e = self.eye(); let high = [e.x as f32, e.y as f32, e.z as f32]; let low = [ (e.x - high[0] as f64) as f32, @@ -222,7 +215,7 @@ impl Camera { /// Project a screen point onto the plane through the orbit target. pub fn pick_on_target_plane(&self, screen: Point, bounds: Rectangle) -> glam::DVec3 { - let forward = (self.target.as_vec3() - self.eye()).normalize_or(Vec3::NEG_Z); + let forward = (self.target.as_vec3() - self.eye().as_vec3()).normalize_or(Vec3::NEG_Z); self.unproject_on_plane(screen, bounds, forward, self.target) }