fix(ucs): object snap tracking rays follow the active UCS

OTRACK alignment rays (0°/90° and polar steps, plus the polar pencil from
the last point) were built along world X/Y. They now rotate with the
active UCS via a Mat4 passed into otrack_snap (scene.viewcube_ucs_mat() —
the UCS in model space, identity in paper), so tracking lines and the
intersection lock align to the user's coordinate system like ortho,
polar, and the grid. sync_ucs_to_scene now reuses UcsXform::rotation_mat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-22 11:17:55 +03:00
commit 2509396ba0
4 changed files with 21 additions and 10 deletions

View file

@ -263,6 +263,9 @@ impl Snapper {
bounds: iced::Rectangle,
polar_step_deg: Option<f32>,
last_point: Option<Vec3>,
// UCS→world rotation: tracking rays run along the UCS axes, matching
// ortho/polar. Identity = world-aligned rays.
ucs: glam::Mat4,
) -> Option<OtrackHit> {
if !self.otrack_enabled || self.tracking_points.is_empty() {
return None;
@ -307,7 +310,7 @@ impl Snapper {
let ar = adeg.to_radians();
rays.push(Ray {
origin: tp,
dir: Vec3::new(ar.cos(), ar.sin(), 0.0),
dir: ucs.transform_vector3(Vec3::new(ar.cos(), ar.sin(), 0.0)),
group: gi,
});
}
@ -322,7 +325,7 @@ impl Snapper {
let ar = a.to_radians();
rays.push(Ray {
origin: lp,
dir: Vec3::new(ar.cos(), ar.sin(), 0.0),
dir: ucs.transform_vector3(Vec3::new(ar.cos(), ar.sin(), 0.0)),
group: POLAR_GROUP,
});
a += step;