forked from 1b-agent/opencadstudio-upstream
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:
1 parent
bfc9ead28d
commit
6996505d70
2 files changed
+14
-2
No files matched your search
@@ -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
@@ -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()?;
|
||||
|
||||
Reference in new issue
Block a user