glPlan: bildschirm-adaptive Bogen-Tessellierung (LOD)

Boegen (Tuer-Schwenkbogen) wurden mit fester Segmentzahl (16/90 Grad) beim
Kompilieren tesselliert und beim Zoom nur per Matrix neu gezeichnet - beim
Reinzoomen daher sichtbare Facetten. Jetzt skaliert die Segmentzahl mit der
Bildschirmgroesse des Bogens: Sagitta < 0.5 px (segs = clamp(ceil(|dPhi|/theta),
8, 2048)), theta = 2*acos(1 - 0.5/rPx). Weit weg wenige Segmente (Perf),
nah rund.

Anti-Thrash per LOD-Bucket round(log2(pxPerMeter)): Neu-Tessellierung nur
bei Bucket-Wechsel, sonst bleibt Zoom/Pan reiner Matrix-Update. Bogen laeuft
weiter durch strokePolyline - runde Caps/Joins bleiben erhalten.
This commit is contained in:
2026-07-03 20:29:12 +02:00
parent f9a5e763fd
commit 1fd688896c
3 changed files with 71 additions and 11 deletions
+9 -3
View File
@@ -85,12 +85,18 @@ export function useGlPlanRenderer(
};
}, [enabled, canvasRef]);
/** Geometrie beim Plan-Wechsel neu tessellieren (einmalig, gecacht). */
const updateGeometry = useCallback((plan: Plan) => {
/**
* Geometrie (neu) tessellieren und cachen. Läuft beim Plan-Wechsel UND bei
* jedem LOD-Bucket-Wechsel des Zooms (PlanView triggert beides). `pxPerMeter`
* = aktueller Bildschirm-Massstab (Geräte-px je Modell-Meter); steuert die
* adaptive Bogen-Tessellierung (mehr Segmente beim Hineinzoomen). 0 → fixer
* zoom-unabhängiger Rückfall.
*/
const updateGeometry = useCallback((plan: Plan, pxPerMeter = 0) => {
const gl = glRef.current;
if (!gl || !plan) return;
try {
geomRef.current = compilePrimitivesToGpu(gl, plan.primitives);
geomRef.current = compilePrimitivesToGpu(gl, plan.primitives, pxPerMeter);
} catch (e) {
console.warn('Tessellierung fehlgeschlagen:', e);
geomRef.current = null;