feat(ucs): orient the ViewCube to the active UCS
The ViewCube showed world Front/Top/Right. It now composes the camera rotation with the active UCS (scene.viewcube_ucs, synced from the tab's active_ucs), so its faces follow the user's coordinate system in model space. Render uniform, hover/click hit-test, and the click→snap direction all go through scene.viewcube_ucs_mat() so they stay in lock-step; identity outside model space leaves paper-viewport navigation unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
88bf2e57dc
commit
d78ed60582
5 changed files with 43 additions and 9 deletions
|
|
@ -803,6 +803,10 @@ pub struct Scene {
|
|||
paper_projected_cache: RefCell<HashMap<Handle, (u64, Vec<WireModel>)>>,
|
||||
/// Active layout name — "Model" or a paper space layout name.
|
||||
pub current_layout: String,
|
||||
/// UCS→world rotation for the ViewCube, kept in sync with the tab's active
|
||||
/// UCS by `DocumentTab::sync_ucs_to_scene`. Identity = WCS. Applied only in
|
||||
/// model space so the cube's faces follow the user's coordinate system.
|
||||
pub viewcube_ucs: glam::Mat4,
|
||||
/// GPU render data for hatch fills, keyed by the DXF entity Handle.
|
||||
pub hatches: HashMap<Handle, HatchModel>,
|
||||
/// GPU render data for solid meshes (truck Shell/Solid tessellation).
|
||||
|
|
@ -954,6 +958,7 @@ impl Scene {
|
|||
paper_sheet_cache: RefCell::new(None),
|
||||
paper_projected_cache: RefCell::new(HashMap::default()),
|
||||
current_layout: "Model".to_string(),
|
||||
viewcube_ucs: glam::Mat4::IDENTITY,
|
||||
hatches: HashMap::default(),
|
||||
meshes: HashMap::default(),
|
||||
block_meshes: HashMap::default(),
|
||||
|
|
@ -3794,7 +3799,18 @@ impl Scene {
|
|||
return cam.view_rotation_mat();
|
||||
}
|
||||
}
|
||||
self.camera.borrow().view_rotation_mat()
|
||||
self.camera.borrow().view_rotation_mat() * self.viewcube_ucs_mat()
|
||||
}
|
||||
|
||||
/// The UCS→world rotation the ViewCube should compose with the camera —
|
||||
/// the active UCS in model space, identity everywhere else. Render,
|
||||
/// hit-test, and click-snap all go through this so they stay in lock-step.
|
||||
pub fn viewcube_ucs_mat(&self) -> glam::Mat4 {
|
||||
if self.current_layout == "Model" {
|
||||
self.viewcube_ucs
|
||||
} else {
|
||||
glam::Mat4::IDENTITY
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the handle of the user viewport whose bounding rectangle contains
|
||||
|
|
|
|||
|
|
@ -794,7 +794,7 @@ impl Scene {
|
|||
images,
|
||||
meshes: self.meshes_arc(),
|
||||
uniforms,
|
||||
cam_rotation: inst.camera.view_rotation_mat(),
|
||||
cam_rotation: inst.camera.view_rotation_mat() * self.viewcube_ucs_mat(),
|
||||
// Only the active viewport gets the hovered-region highlight.
|
||||
hover_region: if inst.active { hover_region } else { None },
|
||||
show_viewcube: inst.active,
|
||||
|
|
@ -826,7 +826,7 @@ impl Scene {
|
|||
cursor: mouse::Cursor,
|
||||
) {
|
||||
let pos = cursor.position_in(bounds);
|
||||
let cam_rotation = self.camera.borrow().view_rotation_mat();
|
||||
let cam_rotation = self.camera.borrow().view_rotation_mat() * self.viewcube_ucs_mat();
|
||||
if let Some(p) = pos {
|
||||
let tile = self.active_model_tile_bounds(bounds.width, bounds.height);
|
||||
state.hover_region = hover_id(
|
||||
|
|
|
|||
Loading…
Reference in a new issue