orbit: turn about the surface under the pointer

With nothing selected, Shift+MMB orbit pivoted on the surface at the
view centre, so grabbing a small part off-centre flung the model away.
It now pivots on the solid or mesh surface under the pointer where the
drag began, falling back to the view centre and then the camera target
(#1389).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-15 05:06:07 +03:00
1 parent bfc9ead28d
commit 6996505d70
2 files changed
+14 -2

No files matched your search

+4
View File
@@ -1436,9 +1436,13 @@ impl OpenCADStudio {
if sel.orbit.pivot.is_none() {
let scene = &self.tabs[i].scene;
let bounds = scene.active_model_tile_bounds(vp_size.0, vp_size.1);
// The surface under the pointer where the drag
// began, so the model turns about what is grabbed.
let grabbed = iced::Point::new(last.x - bounds.x, last.y - bounds.y);
sel.orbit.pivot = Some(
scene
.orbit_pivot()
.or_else(|| scene.surface_pivot_at(bounds, grabbed))
.or_else(|| scene.view_center_surface_pivot(bounds))
.unwrap_or_else(|| scene.camera.borrow().target),
);
+10 -2
View File
@@ -11322,14 +11322,22 @@ impl Scene {
}
pub fn view_center_surface_pivot(&self, bounds: iced::Rectangle) -> Option<glam::DVec3> {
self.surface_pivot_at(bounds, iced::Point::new(bounds.width * 0.5, bounds.height * 0.5))
}
/// The nearest solid or mesh surface under `local` (relative to `bounds`).
pub fn surface_pivot_at(
&self,
bounds: iced::Rectangle,
local: iced::Point,
) -> Option<glam::DVec3> {
let camera = self.camera.borrow();
let view_rot = camera.view_proj_rte(bounds);
let eye = camera.eye();
drop(camera);
let meshes = self.interaction_meshes_arc();
let center = iced::Point::new(bounds.width * 0.5, bounds.height * 0.5);
pick::hit_test::mesh_click_point(
center,
local,
meshes.iter().filter_map(|set| {
let handle = set.entity_handle()?;
let mesh = set.geometry_lods().first()?;