forked from 1b-agent/opencadstudio-upstream
Merge pull request #1299: Add Windows SpaceMouse navigation
This commit is contained in:
commit
af847ad92e
32 files changed
+3508
-12
No files matched your search
+13
-3
@@ -10921,11 +10921,21 @@ vis_index={:.1} visible_probe={:.1}",
|
||||
/// when something is selected. `None` keeps the current camera target as
|
||||
/// the orbit centre. (#229)
|
||||
pub fn orbit_pivot(&self) -> Option<glam::DVec3> {
|
||||
self.navigation_selection_bounds()
|
||||
.map(|(min, max)| (min + max) * 0.5)
|
||||
}
|
||||
|
||||
pub(crate) fn navigation_selection_bounds(&self) -> Option<(glam::DVec3, glam::DVec3)> {
|
||||
if self.selected.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let block = self.current_layout_block_handle();
|
||||
let scale = if self.current_layout == "Model" {
|
||||
let model_view = self.current_layout == "Model" || self.active_viewport.is_some();
|
||||
let block = if self.active_viewport.is_some() {
|
||||
self.model_space_block_handle()
|
||||
} else {
|
||||
self.current_layout_block_handle()
|
||||
};
|
||||
let scale = if model_view {
|
||||
crate::scene::annotative::scale_handle_by_name(
|
||||
&self.document,
|
||||
&self.document.header.current_annotation_scale,
|
||||
@@ -10982,7 +10992,7 @@ vis_index={:.1} visible_probe={:.1}",
|
||||
}
|
||||
}
|
||||
if any {
|
||||
Some((min + max) * 0.5)
|
||||
Some((min, max))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -446,6 +446,45 @@ impl Scene {
|
||||
self.camera.borrow().rotation
|
||||
}
|
||||
|
||||
/// Camera owning navigation, including an entered paper-space viewport.
|
||||
pub(crate) fn navigation_camera(&self) -> view::camera::Camera {
|
||||
self.active_viewport
|
||||
.and_then(|h| self.camera_for_viewport(h))
|
||||
.unwrap_or_else(|| self.camera.borrow().clone())
|
||||
}
|
||||
|
||||
pub(crate) fn navigation_locked(&self) -> bool {
|
||||
self.active_viewport.is_some_and(|h| {
|
||||
!matches!(self.document.get_entity(h), Some(acadrust::EntityType::Viewport(v)) if !v.status.locked)
|
||||
})
|
||||
}
|
||||
|
||||
/// Commit an externally navigated camera through the same floating-view
|
||||
/// encoding as the ViewCube. Camera coordinates already include view_center.
|
||||
pub(crate) fn apply_navigation_camera(&mut self, camera: view::camera::Camera) -> bool {
|
||||
if self.navigation_locked() {
|
||||
return false;
|
||||
}
|
||||
if let Some(handle) = self.active_viewport {
|
||||
if !self.mutate_active_viewport_camera(|c| *c = camera.clone()) {
|
||||
return false;
|
||||
}
|
||||
if let Some(acadrust::EntityType::Viewport(vp)) = self.document.get_entity_mut(handle) {
|
||||
vp.view_target.x = camera.target.x;
|
||||
vp.view_target.y = camera.target.y;
|
||||
vp.view_target.z = camera.target.z;
|
||||
vp.view_center.x = 0.;
|
||||
vp.view_center.y = 0.;
|
||||
vp.view_height = camera.ortho_size() as f64 * 2.;
|
||||
vp.custom_scale = vp.height / vp.view_height;
|
||||
}
|
||||
} else {
|
||||
*self.camera.borrow_mut() = camera;
|
||||
}
|
||||
self.camera_generation += 1;
|
||||
true
|
||||
}
|
||||
|
||||
pub fn active_camera_projection(&self) -> view::camera::Projection {
|
||||
if let Some(handle) = self.active_viewport {
|
||||
if let Some(camera) = self.camera_for_viewport(handle) {
|
||||
|
||||
@@ -752,7 +752,7 @@ impl Camera {
|
||||
// ── Internal helpers ───────────────────────────────────────────────────
|
||||
|
||||
/// Derive yaw and pitch from the current quaternion.
|
||||
fn sync_yaw_pitch(&mut self) {
|
||||
pub(crate) fn sync_yaw_pitch(&mut self) {
|
||||
let eye_dir = self.rotation * Vec3::Z;
|
||||
self.pitch = eye_dir.z.clamp(-1.0, 1.0).asin();
|
||||
self.yaw = if eye_dir.x.abs() < 1e-6 && eye_dir.y.abs() < 1e-6 {
|
||||
|
||||
Reference in new issue
Block a user