fix: ViewCube hover, glow, centroids, corner geometry and snap angles
- Hide OS crosshair and drawn crosshair when cursor is over ViewCube area - Enhanced hover glow in WGSL shader (blue tint + brightness boost) - Fixed region_centroids() Y-axis sign for all FRONT/BACK-related regions - Swapped corner geometry assignments (TPF↔TBK, BTF↔BBK) to match intended FRONT/BACK semantics (sy=-1 = FRONT, sy=+1 = BACK) - Corrected all snap_angles: yaw_pitch_to_quat(0,0) places eye at -Y (FRONT view), so FRONT=0 and BACK=PI — cascaded through edges/corners Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
578dd51af4
commit
a6592cc9bc
4 changed files with 87 additions and 59 deletions
|
|
@ -189,7 +189,7 @@ impl H7CAD {
|
|||
vec![]
|
||||
};
|
||||
|
||||
overlay::selection_overlay(sel, snap_info, grips, grid, ucs_icon, ost_points, tab.last_cursor_screen)
|
||||
overlay::selection_overlay(sel, snap_info, grips, grid, ucs_icon, ost_points, tab.last_cursor_screen, !is_paper)
|
||||
};
|
||||
|
||||
let nav = container(overlay::nav_toolbar())
|
||||
|
|
|
|||
|
|
@ -78,30 +78,30 @@ impl CubeRegion {
|
|||
match self.id() {
|
||||
0 => (0.0, FRAC_PI_2),
|
||||
1 => (0.0, -FRAC_PI_2),
|
||||
2 => (PI, 0.0),
|
||||
3 => (0.0, 0.0),
|
||||
4 => (FRAC_PI_2, 0.0),
|
||||
5 => (-FRAC_PI_2, 0.0),
|
||||
6 => (PI, FRAC_PI_4),
|
||||
7 => (0.0, FRAC_PI_4),
|
||||
8 => (FRAC_PI_2, FRAC_PI_4),
|
||||
9 => (-FRAC_PI_2, FRAC_PI_4),
|
||||
10 => (PI, -FRAC_PI_4),
|
||||
11 => (0.0, -FRAC_PI_4),
|
||||
2 => (0.0, 0.0), // FRONT: yaw=0 (eye at -Y)
|
||||
3 => (PI, 0.0), // BACK: yaw=PI (eye at +Y)
|
||||
4 => (FRAC_PI_2, 0.0), // RIGHT
|
||||
5 => (-FRAC_PI_2, 0.0), // LEFT
|
||||
6 => (0.0, FRAC_PI_4), // EDGE_TOP_FRONT
|
||||
7 => (PI, FRAC_PI_4), // EDGE_TOP_BACK
|
||||
8 => (FRAC_PI_2, FRAC_PI_4), // EDGE_TOP_RIGHT
|
||||
9 => (-FRAC_PI_2, FRAC_PI_4), // EDGE_TOP_LEFT
|
||||
10 => (0.0, -FRAC_PI_4), // EDGE_BOT_FRONT
|
||||
11 => (PI, -FRAC_PI_4), // EDGE_BOT_BACK
|
||||
12 => (FRAC_PI_2, -FRAC_PI_4),
|
||||
13 => (-FRAC_PI_2, -FRAC_PI_4),
|
||||
14 => (FRAC_PI_4, 0.0),
|
||||
15 => (-FRAC_PI_4, 0.0),
|
||||
16 => (PI * 0.75, 0.0),
|
||||
17 => (-PI * 0.75, 0.0),
|
||||
18 => (PI * 0.75, iso),
|
||||
19 => (-PI * 0.75, iso),
|
||||
20 => (FRAC_PI_4, iso),
|
||||
21 => (-FRAC_PI_4, iso),
|
||||
22 => (PI * 0.75, -iso),
|
||||
23 => (-PI * 0.75, -iso),
|
||||
24 => (FRAC_PI_4, -iso),
|
||||
25 => (-FRAC_PI_4, -iso),
|
||||
14 => (FRAC_PI_4, 0.0), // EDGE_FRONT_RIGHT (between 0 and PI/2)
|
||||
15 => (-FRAC_PI_4, 0.0), // EDGE_FRONT_LEFT
|
||||
16 => (PI * 0.75, 0.0), // EDGE_BACK_RIGHT (between PI and PI/2)
|
||||
17 => (-PI * 0.75, 0.0), // EDGE_BACK_LEFT
|
||||
18 => (FRAC_PI_4, iso), // CORNER_TPF_R (FRONT+RIGHT)
|
||||
19 => (-FRAC_PI_4, iso), // CORNER_TPF_L (FRONT+LEFT)
|
||||
20 => (PI * 0.75, iso), // CORNER_TBK_R (BACK+RIGHT)
|
||||
21 => (-PI * 0.75, iso), // CORNER_TBK_L (BACK+LEFT)
|
||||
22 => (FRAC_PI_4, -iso), // CORNER_BTF_R
|
||||
23 => (-FRAC_PI_4, -iso), // CORNER_BTF_L
|
||||
24 => (PI * 0.75, -iso), // CORNER_BBK_R
|
||||
25 => (-PI * 0.75, -iso), // CORNER_BBK_L
|
||||
_ => (0.0, 0.0),
|
||||
}
|
||||
}
|
||||
|
|
@ -909,14 +909,14 @@ pub fn build_geometry() -> (Vec<CubeVertex>, Vec<u32>) {
|
|||
&mut is,
|
||||
);
|
||||
for &([sx, sy, sz], region) in &[
|
||||
([1.0f32, 1.0, 1.0], CORNER_TPF_R),
|
||||
([-1.0, 1.0, 1.0], CORNER_TPF_L),
|
||||
([1.0, 1.0, -1.0], CORNER_BTF_R),
|
||||
([-1.0, 1.0, -1.0], CORNER_BTF_L),
|
||||
([1.0, -1.0, 1.0], CORNER_TBK_R),
|
||||
([-1.0, -1.0, 1.0], CORNER_TBK_L),
|
||||
([1.0, -1.0, -1.0], CORNER_BBK_R),
|
||||
([-1.0, -1.0, -1.0], CORNER_BBK_L),
|
||||
([1.0f32, 1.0, 1.0], CORNER_TBK_R), // sy=+1 = BACK yönü
|
||||
([-1.0, 1.0, 1.0], CORNER_TBK_L),
|
||||
([1.0, 1.0, -1.0], CORNER_BBK_R),
|
||||
([-1.0, 1.0, -1.0], CORNER_BBK_L),
|
||||
([1.0, -1.0, 1.0], CORNER_TPF_R), // sy=-1 = FRONT yönü
|
||||
([-1.0, -1.0, 1.0], CORNER_TPF_L),
|
||||
([1.0, -1.0, -1.0], CORNER_BTF_R),
|
||||
([-1.0, -1.0, -1.0], CORNER_BTF_L),
|
||||
] {
|
||||
push_tri(
|
||||
[sx * F, sy * F, sz * E],
|
||||
|
|
@ -934,32 +934,32 @@ pub fn build_geometry() -> (Vec<CubeVertex>, Vec<u32>) {
|
|||
pub fn region_centroids() -> [[f32; 3]; NUM_REGIONS] {
|
||||
let m = (F + E) * 0.5;
|
||||
[
|
||||
[0.0, 0.0, E],
|
||||
[0.0, 0.0, -E],
|
||||
[0.0, E, 0.0],
|
||||
[0.0, -E, 0.0],
|
||||
[E, 0.0, 0.0],
|
||||
[-E, 0.0, 0.0],
|
||||
[0.0, m, m],
|
||||
[0.0, -m, m],
|
||||
[m, 0.0, m],
|
||||
[-m, 0.0, m],
|
||||
[0.0, m, -m],
|
||||
[0.0, -m, -m],
|
||||
[m, 0.0, -m],
|
||||
[-m, 0.0, -m],
|
||||
[m, m, 0.0],
|
||||
[-m, m, 0.0],
|
||||
[m, -m, 0.0],
|
||||
[-m, -m, 0.0],
|
||||
[m, m, m],
|
||||
[-m, m, m],
|
||||
[m, -m, m],
|
||||
[-m, -m, m],
|
||||
[m, m, -m],
|
||||
[-m, m, -m],
|
||||
[m, -m, -m],
|
||||
[-m, -m, -m],
|
||||
[0.0, 0.0, E], // FACE_TOP
|
||||
[0.0, 0.0, -E], // FACE_BOTTOM
|
||||
[0.0, -E, 0.0], // FACE_FRONT (geometry Y=-E)
|
||||
[0.0, E, 0.0], // FACE_BACK (geometry Y=+E)
|
||||
[E, 0.0, 0.0], // FACE_RIGHT
|
||||
[-E, 0.0, 0.0], // FACE_LEFT
|
||||
[0.0, -m, m], // EDGE_TOP_FRONT
|
||||
[0.0, m, m], // EDGE_TOP_BACK
|
||||
[m, 0.0, m], // EDGE_TOP_RIGHT
|
||||
[-m, 0.0, m], // EDGE_TOP_LEFT
|
||||
[0.0, -m, -m], // EDGE_BOT_FRONT
|
||||
[0.0, m, -m], // EDGE_BOT_BACK
|
||||
[m, 0.0, -m], // EDGE_BOT_RIGHT
|
||||
[-m, 0.0, -m], // EDGE_BOT_LEFT
|
||||
[m, -m, 0.0], // EDGE_FRONT_RIGHT
|
||||
[-m, -m, 0.0], // EDGE_FRONT_LEFT
|
||||
[m, m, 0.0], // EDGE_BACK_RIGHT
|
||||
[-m, m, 0.0], // EDGE_BACK_LEFT
|
||||
[m, -m, m], // CORNER_TPF_R (geometry sy=-1 = FRONT)
|
||||
[-m, -m, m], // CORNER_TPF_L
|
||||
[m, m, m], // CORNER_TBK_R (geometry sy=+1 = BACK)
|
||||
[-m, m, m], // CORNER_TBK_L
|
||||
[m, -m, -m], // CORNER_BTF_R (geometry sy=-1 = FRONT)
|
||||
[-m, -m, -m], // CORNER_BTF_L
|
||||
[m, m, -m], // CORNER_BBK_R (geometry sy=+1 = BACK)
|
||||
[-m, m, -m], // CORNER_BBK_L
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ fn fs_main(in: VOut) -> @location(0) vec4<f32> {
|
|||
let is_hovered = abs(in.region_f - u.hover_region.x) < 0.001 && u.hover_region.x >= 0.0;
|
||||
var final_rgb = in.color;
|
||||
if is_hovered {
|
||||
final_rgb = mix(final_rgb, vec3<f32>(0.55, 0.78, 1.0), 0.45);
|
||||
let glow = vec3<f32>(0.68, 0.88, 1.0);
|
||||
final_rgb = mix(final_rgb, glow, 0.60);
|
||||
final_rgb = clamp(final_rgb * 1.30, vec3<f32>(0.0), vec3<f32>(1.0));
|
||||
}
|
||||
return vec4<f32>(final_rgb, 1.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ pub fn selection_overlay<'a>(
|
|||
ucs_icon: Option<UcsIconParams>,
|
||||
ost_points: Vec<OstTrackPoint>,
|
||||
cursor_screen: Point,
|
||||
show_viewcube: bool,
|
||||
) -> Element<'a, Message> {
|
||||
canvas(SelectionCanvas {
|
||||
selection,
|
||||
|
|
@ -213,6 +214,7 @@ pub fn selection_overlay<'a>(
|
|||
ucs_icon,
|
||||
ost_points,
|
||||
cursor_screen,
|
||||
show_viewcube,
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
|
|
@ -227,6 +229,7 @@ struct SelectionCanvas {
|
|||
ucs_icon: Option<UcsIconParams>,
|
||||
ost_points: Vec<OstTrackPoint>,
|
||||
cursor_screen: Point,
|
||||
show_viewcube: bool,
|
||||
}
|
||||
|
||||
impl canvas::Program<Message> for SelectionCanvas {
|
||||
|
|
@ -238,6 +241,18 @@ impl canvas::Program<Message> for SelectionCanvas {
|
|||
bounds: iced::Rectangle,
|
||||
cursor: mouse::Cursor,
|
||||
) -> mouse::Interaction {
|
||||
if self.show_viewcube {
|
||||
if let Some(pos) = cursor.position_in(bounds) {
|
||||
use crate::scene::{VIEWCUBE_DRAW_PX, VIEWCUBE_PAD};
|
||||
let vc_x = bounds.width - VIEWCUBE_DRAW_PX - VIEWCUBE_PAD;
|
||||
let vc_y = VIEWCUBE_PAD;
|
||||
if pos.x >= vc_x && pos.x <= vc_x + VIEWCUBE_DRAW_PX
|
||||
&& pos.y >= vc_y && pos.y <= vc_y + VIEWCUBE_DRAW_PX
|
||||
{
|
||||
return mouse::Interaction::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor.is_over(bounds) {
|
||||
mouse::Interaction::Crosshair
|
||||
} else {
|
||||
|
|
@ -251,7 +266,7 @@ impl canvas::Program<Message> for SelectionCanvas {
|
|||
renderer: &iced::Renderer,
|
||||
_theme: &Theme,
|
||||
bounds: iced::Rectangle,
|
||||
_cursor: mouse::Cursor,
|
||||
cursor: mouse::Cursor,
|
||||
) -> Vec<canvas::Geometry> {
|
||||
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||
|
||||
|
|
@ -506,6 +521,16 @@ impl canvas::Program<Message> for SelectionCanvas {
|
|||
}
|
||||
|
||||
// ── CAD crosshair cursor ──────────────────────────────────────────────
|
||||
let over_viewcube = self.show_viewcube && {
|
||||
use crate::scene::{VIEWCUBE_DRAW_PX, VIEWCUBE_PAD};
|
||||
cursor.position_in(bounds).map_or(false, |pos| {
|
||||
let vc_x = bounds.width - VIEWCUBE_DRAW_PX - VIEWCUBE_PAD;
|
||||
let vc_y = VIEWCUBE_PAD;
|
||||
pos.x >= vc_x && pos.x <= vc_x + VIEWCUBE_DRAW_PX
|
||||
&& pos.y >= vc_y && pos.y <= vc_y + VIEWCUBE_DRAW_PX
|
||||
})
|
||||
};
|
||||
if !over_viewcube {
|
||||
if let Some(cp) = self.selection.last_move_pos {
|
||||
let color = Color {
|
||||
r: 0.85,
|
||||
|
|
@ -551,6 +576,7 @@ impl canvas::Program<Message> for SelectionCanvas {
|
|||
frame.stroke(&v_bot, stroke.clone());
|
||||
frame.stroke(&square, stroke);
|
||||
}
|
||||
} // end !over_viewcube
|
||||
|
||||
// ── UCS icon ──────────────────────────────────────────────────────
|
||||
if let Some(ref ucs) = self.ucs_icon {
|
||||
|
|
|
|||
Loading…
Reference in a new issue