forked from 1b-agent/opencadstudio-upstream
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:
1 parent
4b00504453
commit
15c0da8b79
6 files changed
+87
-39
No files matched your search
+19
-8
@@ -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));
|
||||
|
||||
Reference in new issue
Block a user