wgpu: overlay-line groups (stroke + dash, per-group dynamic uniform offset)

Ports GL OverlayRenderer's LineGroup API to WgpuOverlayRenderer. Each
group's segments are CPU-expanded into screen-space quads; the WGSL
fragment reproduces the GL pixel-distance stroke pick + arc-length
dash logic. One uniform slot per group, bound via dynamic offset so a
single bind-group services up to N groups.

No caller yet — sets up the API the wgpu measure tools (task #29) will
use. WgpuViewportWindow.setOverlayLines mirrors the GL viewport's
signature so the bonsai Measurement code can target either backend
through one interface.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-30 20:38:59 +10:00
parent 814ae8304f
commit 1d26e5fb92
4 changed files with 424 additions and 0 deletions
+12
View File
@@ -2831,6 +2831,12 @@ void WgpuViewportWindow::clearSectionPlanes() {
if (isExposed()) requestUpdate();
}
void WgpuViewportWindow::setOverlayLines(
const std::vector<WgpuOverlayRenderer::LineGroup>& groups) {
overlays_.setOverlayLines(groups);
if (isExposed()) requestUpdate();
}
// Project a world point to LOGICAL pixel coords (Qt's mouse-event units).
// Returns false if behind the camera.
static bool projectWorldToLogicalScreen(const QMatrix4x4& vp,
@@ -3942,6 +3948,12 @@ void WgpuViewportWindow::render() {
// surfaces. Visibility is driven by orbit/wheel UI handlers.
overlays_.encodePivot(pass, overlay_frame, pivot_indicator_visible_);
// Overlay line groups (measurement / dimension annotation lines).
// Depth-tested against geometry so they hide behind closer surfaces;
// depth-write off so the corner gizmo + marquee can still draw over
// them on the resolved surface afterwards.
overlays_.encodeOverlayLines(pass, overlay_frame);
wgpuRenderPassEncoderEnd(pass);
wgpuRenderPassEncoderRelease(pass);