From 62680883cd8424d65ec4168f73a53261010d4021 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Sat, 4 Jul 2026 22:13:37 +0300 Subject: [PATCH] fix(pick): don't XY-cull the pick wire set in tilted 3D views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit view_world_aabb built a world-XY cull rectangle from the camera target and ortho size without checking the view angle, so in a tilted / 3D view it produced a top-down box that does not bound the on-screen footprint. That box culls the pick wire set (while the render holds the full set via the static hold), so a mesh running partially off-screen fell outside the box and became unselectable — by edge or by face — even though it still rendered. Top views were unaffected (the box is correct there), and 3D solids pick through their mesh AABBs (not this wire set) so they never showed it. Return None for tilted views (fwd.z.abs() < 0.999), matching view_cull_aabb, so no world-XY cull is applied and the pick reaches every on-screen wire. Co-Authored-By: Claude Opus 4.8 --- src/scene/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/scene/mod.rs b/src/scene/mod.rs index d89bfbecd..212cbdc3d 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -1028,6 +1028,17 @@ impl Scene { return None; } let cam = self.camera.borrow(); + // A world-XY rectangle only bounds the on-screen footprint in a plan + // (top-down) view. In a tilted / 3D view the visible area maps to a + // skewed world region, so an axis-aligned XY box would wrongly cull + // entities that are actually on screen — and because this box culls the + // pick wire set (while the render holds the full set), those entities + // render but become unselectable. Skip culling there, matching + // `view_cull_aabb`. + let fwd = cam.rotation * glam::Vec3::Z; + if fwd.z.abs() < 0.999 { + return None; + } let aspect = self.last_render_aspect.get().max(0.01); let h = cam.ortho_size(); let w = h * aspect;