Tap-to-measure (issue #68)
ViewportController.measurementMode (.distance / .angle / .radius) now actually drives interaction. While a mode is active, taps on geometry accumulate world-space surface points and commit a ViewportMeasurement (rendered by the existing MeasurementOverlay). Previously the property was published but consumed by nothing.
Added
- Point order per mode:
.distance→ start, end (2 taps);.angle→ armA, vertex, armB (3 taps);.radius→ center, edge (2 taps). ViewportBody.worldHitPoint(ray:triangleIndex:)— reconstructs the picked surface point in world space, respecting the body'stransform.- Controller:
pendingMeasurementPoints,addMeasurementPoint(_:),handleMeasurementPick(...),cancelPendingMeasurement(),clearMeasurements(),static pointCount(for:). Mode change clears pending; face picks only; selection stream untouched. MeasurementModeis nowEquatable.
Tests
- New
MeasurementModeTests(14). 160 tests total, all green.
Additive and source-compatible.
🤖 Generated with Claude Code