forked from 1b-agent/opencadstudio-upstream
Feat: Phase 3 — perspective projection and per-viewport UCS properties
- viewport_content_wires(): conditional perspective divide using camera_dist = view_height * lens_length / 24.0 (35mm-film equiv.); points behind the camera are mapped to NaN for safe clipping - viewport.rs: expose lens_length, ucs_per_viewport, ucs_origin, ucs_x_axis, ucs_y_axis as editable properties; handle all new fields in apply_geom_prop() Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
1aa44ac987
commit
5ad2f4a8cb
2 files changed
+57
-1
No files matched your search
+26
-1
@@ -661,6 +661,17 @@ impl Scene {
|
||||
let vp_y0 = pcy - hh;
|
||||
let vp_y1 = pcy + hh;
|
||||
|
||||
// ── Perspective setup ─────────────────────────────────────────
|
||||
// camera_dist: how far the camera is from the target plane.
|
||||
// Derived from lens_length (mm, 35mm-film equiv.) and view_height:
|
||||
// tan(fov_v/2) = 12 / lens_length → camera_dist = view_height * lens_length / 24
|
||||
let use_perspective = vp.status.perspective && vp.lens_length > 1.0;
|
||||
let camera_dist = if use_perspective {
|
||||
(vp.view_height as f32 * vp.lens_length as f32 / 24.0).max(0.001)
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
for wire in &model_wires {
|
||||
// Project 3-D model points onto view plane → paper space.
|
||||
let projected_pts: Vec<[f32; 3]> = wire.points.iter().map(|&[mx, my, mz]| {
|
||||
@@ -670,7 +681,21 @@ impl Scene {
|
||||
let mp = glam::Vec3::new(mx, my, mz) - target;
|
||||
let u = mp.dot(view_right);
|
||||
let v = mp.dot(view_up);
|
||||
[pcx + u * scale, pcy + v * scale, pcz]
|
||||
if use_perspective {
|
||||
// vd points from target toward camera, so depth along vd is the
|
||||
// distance from the target plane toward the camera.
|
||||
let d_vd = mp.dot(vd);
|
||||
// Forward distance from camera (positive = in front of camera).
|
||||
let fwd = camera_dist - d_vd;
|
||||
if fwd <= 0.001 {
|
||||
// Point is behind or at the camera — discard.
|
||||
return [f32::NAN; 3];
|
||||
}
|
||||
let factor = camera_dist / fwd;
|
||||
[pcx + u * factor * scale, pcy + v * factor * scale, pcz]
|
||||
} else {
|
||||
[pcx + u * scale, pcy + v * scale, pcz]
|
||||
}
|
||||
}).collect();
|
||||
|
||||
// Fast AABB pre-reject: skip entirely if no finite point is
|
||||
|
||||
Reference in new issue
Block a user