fix(viewcube): snap to direction with nearest-canonical up axis
ViewCube tıklaması artık sabit (yaw, pitch) tablosu yerine bir yön
vektörüne (eye direction) snap ediyor. Up vektörü şöyle seçiliyor:
1. Mevcut up alın.
2. ±X / ±Y / ±Z arasından (yeni gaze ile (anti-)paralel olmayanlar)
mevcut up'a en yüksek dot-product veren cardinal axis'i seç.
3. Bu axis'i yeni gaze yönüne dik plane'e projekte et ve up olarak
kullan.
Sonuç:
- Küçük tilt'ler ilgili canonical axis'e snap olarak temizleniyor.
- TOP yukarıda iken TOP-LEFT edge tıklayınca TOP yukarıda kalıyor;
cube edge'e dönüyor ama kullanıcının "yukarı" hissi korunuyor.
- Upside-down orbit edilmişse -Z up olarak seçilir, snap baş aşağı
yapılandırmayı bozmuyor.
CubeRegion::snap_angles ve Camera::snap_to_angles yerini
snap_direction / snap_to_direction aldı.
snap_active_viewport_to_direction viewport'un view_direction'ını
günceller, twist_angle'a dokunmaz.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
26bcd89358
commit
451239c4f9
4 changed files with 135 additions and 68 deletions
|
|
@ -2179,15 +2179,16 @@ impl Scene {
|
|||
}
|
||||
}
|
||||
|
||||
/// Snap the active viewport's view direction to a canonical yaw/pitch.
|
||||
/// No-op when there is no active viewport or it is locked.
|
||||
pub fn snap_active_viewport_to_angles(&mut self, yaw: f32, pitch: f32) {
|
||||
/// Snap the active viewport's view direction to `eye_dir` (unit
|
||||
/// vector from target toward camera). Twist angle is left at its
|
||||
/// current value so the up-sense is preserved across successive
|
||||
/// snaps. No-op when there is no active viewport or it is locked.
|
||||
pub fn snap_active_viewport_to_direction(&mut self, eye_dir: glam::Vec3) {
|
||||
let vp_handle = match self.active_viewport {
|
||||
Some(h) => h,
|
||||
None => return,
|
||||
};
|
||||
let cos_p = pitch.cos();
|
||||
let eye = glam::Vec3::new(cos_p * yaw.sin(), cos_p * yaw.cos(), pitch.sin());
|
||||
let eye = eye_dir.normalize_or(glam::Vec3::Z);
|
||||
if let Some(acadrust::EntityType::Viewport(vp)) = self.document.get_entity_mut(vp_handle) {
|
||||
if vp.status.locked {
|
||||
return;
|
||||
|
|
@ -3807,7 +3808,7 @@ impl Scene {
|
|||
} else {
|
||||
vd.x.atan2(-vd.y)
|
||||
};
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch);
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0);
|
||||
let view_right = rotation * glam::Vec3::X;
|
||||
let view_up = rotation * glam::Vec3::Y;
|
||||
let base = if model_space {
|
||||
|
|
@ -3877,7 +3878,7 @@ impl Scene {
|
|||
} else {
|
||||
vd.x.atan2(-vd.y)
|
||||
};
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch);
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0);
|
||||
let view_right = rotation * glam::Vec3::X;
|
||||
let view_up = rotation * glam::Vec3::Y;
|
||||
|
||||
|
|
@ -3964,7 +3965,7 @@ impl Scene {
|
|||
} else {
|
||||
vd.x.atan2(-vd.y)
|
||||
};
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch);
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0);
|
||||
let view_right = rotation * glam::Vec3::X;
|
||||
let view_up = rotation * glam::Vec3::Y;
|
||||
|
||||
|
|
@ -4337,7 +4338,7 @@ impl Scene {
|
|||
vd.x.atan2(-vd.y)
|
||||
};
|
||||
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch);
|
||||
let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0);
|
||||
let view_right = rotation * glam::Vec3::X;
|
||||
let view_up = rotation * glam::Vec3::Y;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue