Merge pull request #1299: Add Windows SpaceMouse navigation

This commit is contained in:
Hakan Seven committed 2026-09-16 09:41:25 +03:00
commit af847ad92e
32 files changed
+3508 -12

No files matched your search

+13 -3
View File
@@ -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
}
+39
View File
@@ -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) {
+1 -1
View File
@@ -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 {