8fd8987b70
Neuer GPU-Renderer fuer den Grundriss (src/plan/glPlan/): Earcut-Tessellierung (konkav-faehig), gehrte Linienzuege (Miter), echte Papier-mm-Strichbreiten im Massstab (repliziert den SVG-printStrokeVb-Pfad), Hybrid mit scharfem SVG-Text- Overlay. GPU ist der Standardpfad; der SVG-Renderer bleibt automatischer Fallback, falls WebGL2/Shader nicht verfuegbar sind. Imperativer Pan (rAF + CSS-transform) fuer fluessige Interaktion ohne React-Re-Render je Frame. Enthaelt zudem den bisher nicht committeten Arbeitsstand des Browser-BIM (Oeffnungen, Treppen, Raeume, Decken, DXF-Export, Materialbibliothek, Kontext- Import, Tauri-Compute-Boundary-PoC).
82 lines
4.9 KiB
Markdown
82 lines
4.9 KiB
Markdown
# Briefing — Nativer wgpu-2D-Renderer (parallele Instanz)
|
||
|
||
> Für die Instanz/den Agenten, der den nativen GPU-Renderer baut. Isoliert vom
|
||
> Web-Renderer; koordiniert über dieses Dokument.
|
||
|
||
## COMMIT-REGEL (verbindlich)
|
||
Dieses Repo darf **keinerlei Hinweise auf KI-Werkzeuge** enthalten — nicht im Code,
|
||
in Kommentaren oder in der Git-Historie. Keine `Co-Authored-By`-Trailer, keine
|
||
„Generated with"-Zeilen, keine Modell-/Agenten-Namen. Kommentare deutsch,
|
||
Identifier englisch. **Kein Commit ohne Ansage der Hauptinstanz.**
|
||
|
||
## Warum
|
||
Der 2D-Plan wird aktuell in einem WebGL-Canvas gerendert (Web-Stack). In Chromium
|
||
ist das 144-Hz-flüssig, aber **Tauris Linux-Webview = WebKitGTK bremst** (langsamer
|
||
Compositor, vermutlich 60-Hz-rAF-Cap). Bewiesen: dieselbe App im `chromium --app`-
|
||
Fenster = butterweich, im Tauri-Fenster = zäh — trotz imperativem Pan, CSS-transform-
|
||
Overlay, DMABUF-Tweaks. Siehe Memo `webkitgtk-bottleneck`.
|
||
|
||
**Lösung:** die schwere Grafik **nativ mit wgpu** rendern (Rust), die Webview macht
|
||
nur noch UI-Chrome (Panels/Buttons). So bleibt Tauri (natives Rust-Backend, winziges
|
||
Bundle) UND wir umgehen den Webview-Compositor komplett.
|
||
|
||
## Referenz-Implementierung (NICHT wegwerfen — 1:1 portierbar)
|
||
Der WebGL-Renderer unter `src/plan/glPlan/` ist die **arbeitende Referenz**. Die
|
||
harte Arbeit ist dort schon gelöst und portiert konzeptuell direkt nach wgpu:
|
||
- `glPlanCompile.ts` — **Earcut-Triangulierung** (konkav-fähig), Linien→Quads mit
|
||
Normale+Seiten-Flag, Batch-Merging, Farb-Parsing. Unit-Tests: `glPlanCompile.test.ts`.
|
||
- `glPlanShaders.ts` — Vertex/Fragment (GLSL 300 es). **WGSL ≈ GLSL** — direkt übersetzbar.
|
||
- Füll-VS: Bildschirm-Position → Clip via `viewProj`-Matrix.
|
||
- Linien-VS: bildschirmkonstante bzw. papier-mm-Breite via Normalen-Offset im Clip
|
||
(siehe `strokeScale`/`strokePx`-Logik — Papier-mm × Massstab N × meet-Skala).
|
||
- `glPlanRender.ts` — Ortho-Matrix (aspekt-korrekt = SVG `xMidYMid meet`), Fill-/Line-
|
||
Pass, `computeOrthoMatrix`.
|
||
- Koordinaten-Konvention: BILDSCHIRM-Raum `sx = mx·PX_PER_M, sy = -my·PX_PER_M`
|
||
(`PX_PER_M=90`), Modell-Y hoch → Bildschirm-Y runter.
|
||
- Strichbreite = **echte Papier-mm im Massstab**: `Breite_px = mm · N/1000 · PX_PER_M ·
|
||
meetSkala` (repliziert SVG `printStrokeVb`). Am Beispiel 0.35 mm @ 1:100 = 0.35 mm.
|
||
|
||
Die **Daten** kommen aus `src/plan/generatePlan.ts` → `Plan.primitives` (Union-Typ
|
||
`Primitive`: polygon/line/arc/text). Text bleibt Overlay (nicht wgpu).
|
||
|
||
## Die EINE harte Frage (zuerst spiken/recherchieren)
|
||
**Wie rendert wgpu in das Tauri-Fenster neben der Webview?** Optionen recherchieren:
|
||
1. Natives Child-Surface unter der Webview (raw-window-handle), Webview transparent
|
||
drüber für UI-Chrome. Vermutlich der Zielweg.
|
||
2. Eigenes wgpu-Fenster (entkoppelt) — nur für den Spike, um Rendering von der
|
||
Fenster-Integration zu trennen.
|
||
3. wgpu→Textur→Webview — verwirft den Zweck (Copy-Overhead), nur Notnagel.
|
||
|
||
**Empfehlung:** Rendering-Spike ZUERST entkoppelt (Option 2, standalone `winit`+wgpu-
|
||
Fenster), das die `Primitive` als gefüllte Polygone + Striche zeichnet und Pan/Zoom
|
||
per Matrix-Uniform macht. Fenster-Integration in Tauri ist der zweite, separate Schritt.
|
||
|
||
## Meilensteine
|
||
- **M0 (Research):** kurzer Bericht `docs/design/wgpu-integration-findings.md` — wie
|
||
wgpu-Surface + Tauri/webview koexistieren (raw-window-handle, Transparenz, Z-Order,
|
||
Input-Routing). Quellen verlinken.
|
||
- **M1 (Rendering-Spike, standalone):** neue Crate `src-tauri/render2d/` (serde-Input
|
||
= geflachte Primitive), wgpu + WGSL:
|
||
- Earcut-Port (oder `lyon`/`earcutr` Crate evaluieren) → Dreiecke.
|
||
- Füll-Pipeline (gefüllte Polygone, Ortho-Matrix-Uniform).
|
||
- Linien-Pipeline (Quad-Expansion, echte Papier-mm-Breite).
|
||
- `cargo test` für die Tessellierung (Muster: `src-tauri/geometry` hat 4/4 Tests —
|
||
z. B. konkaves L flächentreu, wie `glPlanCompile.test.ts`).
|
||
- `cargo build` grün. (Visuelle Fenster-Verifikation braucht Display → an Mensch/
|
||
Display-Session übergeben; im Bericht vermerken.)
|
||
- **M2 (Tauri-Integration):** Surface unter die Webview, Pan/Zoom-Input aus der
|
||
Webview an den Renderer, Parität mit dem WebGL-Pfad messen (144 Hz).
|
||
- **M3:** Schraffur, Bögen, Auswahl-Highlight; danach 3D (three.js→wgpu).
|
||
|
||
## Koordination (WICHTIG)
|
||
- **Eigener Branch** (z. B. `feature/wgpu-renderer`), NICHT auf `master`/
|
||
`feature/parametric-walls` committen. Isolierter Worktree.
|
||
- **Nur** `src-tauri/` + neue Rust-Module + `docs/`. **NICHT** `src/App.tsx`,
|
||
`src/plan/*`, `types.ts` anfassen (die Hauptinstanz arbeitet dort an Features).
|
||
- Der Web-WebGL-Renderer bleibt bestehen (Browser-Lauffähigkeit + Referenz).
|
||
- Ergebnisse/Diffs zurückliefern; die Hauptinstanz committet und pflegt das Memory.
|
||
|
||
## Gates
|
||
`cargo check`/`cargo test`/`cargo build` grün. Trace-Scan sauber (COMMIT-REGEL).
|
||
`npx tsc -b` + `npm run build` müssen unberührt grün bleiben (keine Web-Änderungen).
|