Point clouds: measured lighting, highlighted extents box, gizmo shaft grab

- Lighting follows the view: the default source is a key light from the
  upper left and a fill light from the lower right over an ambient term,
  the other source one light from above; POINTCLOUDLIGHTING 1 lights the
  front faces, 2 both.
- A selected or hovered point cloud shows its extents box.
- A move-gizmo arrow can be grabbed along its shaft; the grab offset is
  taken on the press, so click-and-place and typed distances start from
  the insertion point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-09-30 17:21:33 +03:00
1 parent 4b00504453
commit 15c0da8b79
6 files changed
+87 -39

No files matched your search

+19 -8
View File
@@ -79,6 +79,21 @@ fn placed_marker(
}
}
/// Pixel distance from `cursor` to a marker; a gizmo arrow counts along its
/// whole shaft, not only at its tip.
fn marker_distance(shape: GripShape, screen: Vec2, dir: Option<[f32; 2]>, cursor: Point) -> f32 {
let cursor = Vec2::new(cursor.x, cursor.y);
match (shape, dir) {
(GripShape::GizmoAxis(_), Some([dx, dy])) => {
let d = Vec2::new(dx, -dy);
let start = screen - d * (GIZMO_AXIS_PX - 14.0);
let t = (cursor - start).dot(d).clamp(0.0, GIZMO_AXIS_PX - 14.0);
cursor.distance(start + d * t)
}
_ => cursor.distance(screen),
}
}
// ── Active drag state ─────────────────────────────────────────────────────
/// Stored on `OpenCADStudio` while a grip is being dragged.
@@ -327,12 +342,10 @@ pub fn find_hit_grip(
for (index, g) in grips.iter().enumerate() {
let project = |world: DVec3| camera.project(world, bounds);
let Some((screen, _)) = placed_marker(g, project(g.world), project) else {
let Some((screen, dir)) = placed_marker(g, project(g.world), project) else {
continue;
};
let dx = screen.x - cursor.x;
let dy = screen.y - cursor.y;
let d = (dx * dx + dy * dy).sqrt();
let d = marker_distance(g.shape, screen, dir, cursor);
if d < best_dist {
best_dist = d;
best = Some((index, g.id, g.is_midpoint, g.world));
@@ -396,12 +409,10 @@ pub fn find_hit_grip_rte(
for (index, g) in grips.iter().enumerate() {
let project = |world: DVec3| project_rte(world, view_rot, eye, bounds);
let Some((screen, _)) = placed_marker(g, project(g.world), project) else {
let Some((screen, dir)) = placed_marker(g, project(g.world), project) else {
continue;
};
let dx = screen.x - cursor.x;
let dy = screen.y - cursor.y;
let d = (dx * dx + dy * dy).sqrt();
let d = marker_distance(g.shape, screen, dir, cursor);
if d < best_dist {
best_dist = d;
best = Some((index, g.id, g.is_midpoint, g.world));