Thanks @DuBearte.
This commit is contained in:
1 parent
39850fb6ab
commit
cd9db57366
4 files changed
+47
-7
No files matched your search
@@ -3505,19 +3505,36 @@ fn plane_by_name(app: &SolveApp, name: &str) -> Option<solidcraft_engine::geom::
|
||||
|
||||
/// Animate the camera to look straight at the active sketch plane.
|
||||
pub fn look_at_sketch(app: &mut SolveApp) {
|
||||
look_at_sketch_from(app, false);
|
||||
}
|
||||
|
||||
/// Look At asked for by the user (Ctrl+8, the Look At buttons): like [`look_at_sketch`], and
|
||||
/// from the sketch's other side when the view already faces it (#1886).
|
||||
pub fn look_at_sketch_again(app: &mut SolveApp) {
|
||||
look_at_sketch_from(app, true);
|
||||
}
|
||||
|
||||
fn look_at_sketch_from(app: &mut SolveApp, again: bool) {
|
||||
let st = app.session.world_state();
|
||||
if let Some(ss) = app.session.active_sketch.and_then(|id| st.sketch(id)) {
|
||||
let mut to = app.cam.looking_from(ss.plane.normal());
|
||||
let n = facing(app, ss.plane.normal(), again);
|
||||
let mut to = app.cam.looking_from(n);
|
||||
// Keep the sketch's own x axis to the right when looking straight down or up.
|
||||
if ss.plane.normal().z.abs() > 0.999 {
|
||||
if n.z.abs() > 0.999 {
|
||||
let x = ss.plane.x;
|
||||
to.yaw = if ss.plane.normal().z > 0.0 { (-x.y).atan2(x.x) } else { x.y.atan2(x.x) };
|
||||
to.yaw = if n.z > 0.0 { (-x.y).atan2(x.x) } else { x.y.atan2(x.x) };
|
||||
}
|
||||
to.target = ss.plane.origin;
|
||||
app.animate_to(to);
|
||||
}
|
||||
}
|
||||
|
||||
/// The side to look from at a plane with normal `n`: its own side, or with `again` the other
|
||||
/// side when the view already looks from `n`, so a second Look At turns the view round (#1886).
|
||||
pub(crate) fn facing(app: &SolveApp, n: Vec3, again: bool) -> Vec3 {
|
||||
if again && app.cam.back().dot(n) > 0.999 { -n } else { n }
|
||||
}
|
||||
|
||||
fn sels(d: &Dialog, i: usize) -> &[Sel] {
|
||||
d.inputs.get(i).map(|x| x.items.as_slice()).unwrap_or(&[])
|
||||
}
|
||||
|
||||
@@ -915,4 +915,26 @@ mod view_key_tests {
|
||||
}
|
||||
assert!(crate::keymap::RESERVED.contains(&crate::keymap::key_name(egui::Key::Num8, egui::Modifiers::COMMAND).as_str()));
|
||||
}
|
||||
|
||||
/// #1886: Ctrl+8 looks straight at the sketch; pressed again while the view faces it, it
|
||||
/// looks from the other side, and a third press turns it back. Opening a sketch never flips.
|
||||
#[test]
|
||||
fn ctrl_8_again_looks_from_the_other_side() {
|
||||
let mut h = Harness::new();
|
||||
h.app.preferences.look_at_anim = false;
|
||||
h.app.run("sketch.create", json!({"plane": "XY"})).unwrap();
|
||||
h.frames(2);
|
||||
let back_z = |h: &Harness| h.app.cam.back().z;
|
||||
for want in [1.0, -1.0, 1.0] {
|
||||
h.step(&json!({"key": "8", "cmd": true})).unwrap();
|
||||
h.frames(2);
|
||||
assert!((back_z(&h) - want).abs() < 1e-3, "looking from z {want}: back {:?}", h.app.cam.back());
|
||||
}
|
||||
// Programmatic look-at (as on opening a sketch) keeps the sketch's own side.
|
||||
crate::dialogs::look_at_sketch(&mut h.app);
|
||||
h.frames(2);
|
||||
crate::dialogs::look_at_sketch(&mut h.app);
|
||||
h.frames(2);
|
||||
assert!((back_z(&h) - 1.0).abs() < 1e-3, "{:?}", h.app.cam.back());
|
||||
}
|
||||
}
|
||||
@@ -575,7 +575,7 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
|
||||
app.start(id);
|
||||
}
|
||||
if look {
|
||||
crate::dialogs::look_at_sketch(app);
|
||||
crate::dialogs::look_at_sketch_again(app);
|
||||
}
|
||||
if finish {
|
||||
app.finish_sketch();
|
||||
|
||||
@@ -3348,7 +3348,8 @@ pub(crate) fn nearest_quarter_turn(yaw: f64) -> f64 {
|
||||
}
|
||||
|
||||
/// Navigation bar (bottom centre).
|
||||
/// Turn the view to face the selected planar face or plane, else the active sketch.
|
||||
/// Turn the view to face the selected planar face or plane, else the active sketch; asked again
|
||||
/// while it already faces it, from the other side (#1886).
|
||||
pub fn look_at_selection(app: &mut SolveApp) {
|
||||
let target = app.session.selection.iter().find_map(|s| match s {
|
||||
Sel::Face { body, index, point } => crate::dialogs::planar_face(&app.session, body, *index).map(|(_, n)| (*point, n)),
|
||||
@@ -3357,11 +3358,11 @@ pub fn look_at_selection(app: &mut SolveApp) {
|
||||
});
|
||||
match target {
|
||||
Some((p, n)) => {
|
||||
let mut to = app.cam.looking_from(n);
|
||||
let mut to = app.cam.looking_from(crate::dialogs::facing(app, n, true));
|
||||
to.target = p;
|
||||
app.animate_to(to);
|
||||
}
|
||||
None => crate::dialogs::look_at_sketch(app),
|
||||
None => crate::dialogs::look_at_sketch_again(app),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user