Nordstern-3D: Auswahl-Highlight (orange Outline, immer sichtbar)

Ein selektiertes Bauteil wird jetzt im 3D-Viewport mit einer orangen
Umrisslinie markiert, die dank No-Depth-Pipeline auch hinter Wänden
durchscheint (klare Selektions-Rückmeldung). Zusammen mit Objekt-Info
(numerisch) und Attribute-Panel ist die 3D-Auswahl damit vollständig.

- Engine: set_highlight_lines(vertices) + highlight_pipeline
  (LineList, depth_compare Always, kein Depth-Write), als letzter
  Draw-Call obenauf. Reuse der Grid-Linien-Infrastruktur.
- TS: selectionHighlightLines() baut die Quader-/Prisma-Kanten der
  Auswahl in Akzentfarbe; App berechnet sie per useMemo aus der
  Store-Auswahl und reicht sie durch.
This commit is contained in:
2026-07-04 06:26:29 +02:00
parent ca60b5a9a4
commit aabfa3db53
8 changed files with 358 additions and 35 deletions
+20
View File
@@ -176,6 +176,7 @@ export function Wasm3DViewport({
groundElevation = 0,
onToggleGrid,
onPick3d,
highlightLines = null,
}: {
project: Project;
/** Kanonischer Blickwinkel (Oberleiste) — s. Datei-Kommentar. */
@@ -199,6 +200,13 @@ export function Wasm3DViewport({
* Aufrufer (App) setzt daraus die Store-Selektion; ohne Angabe passiert nichts.
*/
onPick3d?: (hit: Pick3dHit, additive: boolean) => void;
/**
* Umriss-Linien der aktuellen Auswahl (LineList-Vertex-Array, s.
* `selectionHighlightLines` in plan/toWalls3d.ts) — werden ohne Tiefentest
* immer sichtbar obenauf gezeichnet (Akzentfarbe kommt vom Aufrufer/App).
* `null`/leeres Array = kein Highlight (leere Auswahl).
*/
highlightLines?: Float32Array | null;
}) {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
// Pick-Callback in einem Ref spiegeln, damit der (einmal registrierte)
@@ -212,6 +220,7 @@ export function Wasm3DViewport({
setRenderStyle,
applyViewPreset,
setGroundGrid,
setHighlightLines,
ready,
failed,
} = useWasm3dRenderer(canvasRef, true);
@@ -268,6 +277,17 @@ export function Wasm3DViewport({
redrawRef.current();
}, [ready, gridVisible, groundElevation, setGroundGrid]);
// Auswahl-Hervorhebung: bei Bereitschaft oder Änderung der Highlight-Linien
// (Auswahl gewechselt/aufgehoben) neu setzen + zeichnen. Die Engine hält das
// Highlight, bis es erneut gesetzt wird — Kamerabewegungen (Orbit/Pan/Zoom)
// lösen hier KEINEN neuen `setHighlightLines`-Aufruf aus, das Highlight
// bleibt einfach über den nächsten `render()`-Aufruf hinweg sichtbar.
useEffect(() => {
if (!ready) return;
setHighlightLines(highlightLines ?? new Float32Array(0));
redrawRef.current();
}, [ready, highlightLines, setHighlightLines]);
// Canvas-Größe beobachten: bei Layout-Änderung mit aktueller Kamera neu
// zeichnen (die Surface-Anpassung übernimmt der Hook im render()).
useEffect(() => {