Fahrzeug-3D — Modell-Quellen, Rendering & Markierungen am Modell (OP-R6-2)
Status: V-2 gebaut 2026-08-08 (
0.161.0), Binding aktiv · Recherche-Provenienz 2026-07-04 · V-1 gebaut 2026-08-02 (0.160.0) — das renderer-neutrale Datenmodell (karosserieTyp+markierungen[]am Auftrag, §5), Karosserietyp-Auswahl bei der Annahme
markierung.setzen/entfernen-Handler stehen; V-2 gebaut 2026-08-08 (0.161.0) — sichtbarer Lazy-<model-viewer>(drehbar/zoombar) im Auftrag-Detail, Binding aktiv; V-3 (Markieren-per-Klick) offen; ehemals blockiert durch CC0-GLB-Assets + R2-Buckettaktano-models/Binding (PO-Deploy). (Ursprung: Nutzer-Frage „Gibt es eine Quelle für 3D-Modelle, die wir easy einbetten/drehen können — mit nummerierten Markierungen + Kommentaren/Fotos?") · Bezug: OP-R6-2 (Owning; fachlicher Rahmen Lastenheft §11.1, Aspekt 1 Fahrzeug-Visualisierung) · OP-R7-16 · OP-QS-3 · OP-R7-12 · OP-FEEDBACK-1 · Zielgruppe: IT-Dev/Architektur (primär) · Business/Management (§1–§3 reichen) · True North: Frage 2 (Fahrzeug-Standort) genauer — Markierungen am 3D-Modell zeigen, wo am Fahrzeug etwas ist/passiert (Vorschaden · Zone · Mangel) und machen die Bearbeitungs-Doku räumlich statt nur textuell
Kernaussage. Ja — und günstiger als gedacht. Fahrzeug-Besonderheiten und Schäden werden an einem drehbaren 3D-Modell mit nummerierten Hotspots (Kommentar/Foto) markiert: ein kleines Set generischer Karosserietyp-Modelle (CC0-lizenziert, GLB-Format, z. B. Quaternius/Poly Pizza/Kenney) plus Googles
<model-viewer>-Web-Component liefert Drehen/Zoomen und nummerierte Markierungen (Hotspots) out of the box — im Web sofort, auf iOS später über dieselben Assets (GLB → USDZ, RealityKit/Quick Look). Das Markierungs-Datenmodell ist renderer-neutral (§5).
1. Einordnung — das ⚠-Aufwand-Flag relativiert sich
Das ⚠-Aufwand-Flag aus OP-R6-2 („3D-Asset-Pipeline je Fahrzeugmodell = erheblich") relativiert sich: es galt für fahrzeuggenaue Modelle je Kunden-Pkw. Für den Markierungszweck (Vorschäden, Folierungs-Zonen, Arbeitsbereiche) genügt der Karosserietyp — und fahrzeuggenaue Marken-Modelle wären ohnehin lizenz-/markenrechtlich heikel (§3).
2. Modell-Quelle: generisches Karosserietyp-Set (CC0)
Empfehlung: ein kuratiertes Set von ca. 7 Karosserietypen — Limousine · Kombi · SUV · Van/ Transporter · Coupé/Sportwagen · Kleinwagen · Pickup (erweiterbar, G-1-analog als Katalog). Bei der Annahme wird der Typ gewählt (später aus FIN/Beschreibung vorgeschlagen, OP-R7-16/OP-R6-2 Aspekt 2).
| Quelle | Lizenz | Format | Eignung |
|---|---|---|---|
| Quaternius (u. a. Cars Bundle, 8 Modelle) | CC0 (auch kommerziell frei) | GLB/glTF, FBX | ✅ Erststufe: konsistenter Low-Poly-Stil, klein (< 1 MB/Modell) |
| Poly Pizza (Aggregator, CC0-Filter) | je Asset (CC0 filterbar) | glTF-Download | ✅ Ergänzung fehlender Typen |
| Kenney (Car Kit) | CC0 | GLB u. a. | ✅ Alternative, gleicher Stil-Anspruch |
| TurboSquid / CGTrader / Fab (Sketchfab) — „generic car" ohne Branding | Standard-Lizenz (Kauf) | div. | 🟡 nur falls später höherwertige neutrale Modelle gewünscht; Redistributions-Klausel beachten (§3) |
| Marken-genaue Modelle (z. B. „Porsche 911") | Editorial/Brand-Restriktionen | div. | ⛔ nicht verwenden (§3) |
Ablage: Assets im R2-Bucket taktano-models (Binding MODELLE_BUCKET in server/wrangler.toml
aktiv seit V-2/2026-08-08 — Bucket + karosserie/*-GLBs bereitgestellt; jurisdiction = "eu", Muster OP-QS-2) — hinter Cloudflare
Access, mit LICENSE.md je Asset (Quelle · Lizenz · Abrufdatum) als Compliance-Nachweis
(OP-COMPLIANCE-1). Keine PII in den Assets → DSGVO-unkritisch; personenbezogen bleiben nur
Markierungen/Fotos, die wie bisher als Auftragsdaten behandelt werden (Löschkonzept OP-CRUD-1).
3. Warum nicht fahrzeuggenaue Marken-Modelle?
- Markenrecht: Design/Marke realer Fahrzeuge ist geschützt; Sketchfab führt solche Assets unter Editorial-Lizenz (kommerzielle Nutzung ausgeschlossen), TurboSquid verlangt je Marke Einzelfreigabe des Herstellers.
- Redistribution: Kauf-Lizenzen verbieten die Weitergabe in offenen Formaten — ein GLB, das der Browser lädt, ist technisch herunterladbar. CC0 hat dieses Problem nicht.
- Kein fachlicher Mehrwert: die Markierung „Kratzer hinten links über dem Radlauf" braucht die Karosserie-Form, nicht das exakte Modell. Modell-Besonderheiten sind Text-Wissen (OP-R6-2 Aspekt 2), keine Geometrie.
4. Rendering Web: <model-viewer> (einfachste tragfähige Lösung)
@google/model-viewer (v4.3.1, aktiv gepflegt, Apache-2.0; nutzt three.js
intern) statt eigenem three.js-/Babylon-Aufbau — Leitprinzip Einfachheit:
- Drehen/Zoomen/Auto-Rotate: Attribute
camera-controls,auto-rotate— null eigener Code. - Nummerierte Markierungen = Hotspots: Kind-Elemente
mit
slot="hotspot-<n>"+data-position/data-normal(Modellkoordinaten) — unsere runden Nummern-Badges (Musterfeedback-marker-overlay.component.ts, OP-FEEDBACK-1) als Slot-Inhalt, Styling frei über--tk-*-Tokens. - Markierung setzen per Klick/Tap:
positionAndNormalFromPoint(x, y)liefert 3D-Position + Normale unter dem Zeiger → direkt das Markierungs-Objekt (§5). - Angular 22: Web Component →
CUSTOM_ELEMENTS_SCHEMAin der Standalone-Komponente; die Komponentefahrzeug-viewerist statisch ins Auftrag-Detail importiert, aber die Renderer-Lib@google/model-viewerlädt lazy per dynamicimport()beim Öffnen (eigener Chunk, nicht im Initial-Bundle) — keinloadComponent-Boundary nötig; die ~Hunderte-KB-3D-Runtime belastet so die Kern-Workspaces nicht. - Abgrenzung: three.js direkt nur, falls später Zonen-Flächen (Mesh-Painting statt Punkt-Marker) nötig werden — dann ist model-viewer durch die Datenmodell-Neutralität (§5) ersetzbar.
5. Markierungs-Datenmodell (renderer-neutral)
Markierungen sind Daten am Auftrag, kein Renderer-Zustand — Position + Normale in Modellkoordinaten funktionieren identisch in model-viewer (Web), RealityKit (iOS) oder einem späteren Renderer:
// am Auftrag (operativ), analog maengel/protokoll — §4.9-konform (kein eigenes Fahrzeug-Objekt)
interface FahrzeugMarkierung {
id: string;
nummer: number; // stabil vergeben (1, 2, 3 …), springt bei Löschung nicht um
karosserieTyp: string; // Katalog-Key des angezeigten Modells
position: { x: number; y: number; z: number }; // Modellkoordinaten
normal: { x: number; y: number; z: number };
art: "vorschaden" | "mangel"; // Vorschaden (Annahme/Haftung) oder Mangel (Quality-Check, via mangelId)
kommentar?: string; // Freitext (Diktat/Voice später via OP-R7-12)
mangelId?: string; // Verknüpfung Mangel (OP-QS-1/OP-QS-3)
fotoIds?: string[]; // FotoAttachment-IDs (§4.10) — Foto „hängt am Ort"
erstelltUm?: number; // Aktor-Identität NICHT hier — nur im Access-geschützten D1-Audit (keine PII-at-rest)
}
Anschluss an Bestehendes: FotoAttachment (bewusst generisch gebaut), Mangel (bekommt damit
den bisher fehlenden Ortsbezug), Offline-Foto-Queue + Upload-Pfad POST /api/foto/upload
unverändert. nummer wird gespeichert (Referenz in Kommentaren/Gesprächen muss stabil bleiben —
bewusste Ausnahme von „derived nie speichern", da nicht ableitbar nach Löschungen).
6. iOS-nativ später: gleiche Assets, gleiche Daten
- GLB bleibt Master. Je Karosserietyp einmalig nach USDZ konvertieren (Apple
Reality Converter oder CLI
usd_from_gltf) → beide Varianten im selben R2-Bucket. - Nativ: RealityKit/SceneKit rendern USDZ; Markierungen (Position/Normale) werden als Entities an denselben Koordinaten gesetzt — das Datenmodell (§5) ist die gemeinsame Sprache.
- Zwischenschritt ohne App: model-viewer bringt einen AR-Modus mit (iOS Quick Look via USDZ, Android Scene Viewer/WebXR) — „AR vorbereiten" aus OP-R6-2 ist damit strukturell miterledigt.
7. Stufenplan (revidiert) & Aufwand
OP-R6-2 sah „2D-Silhouette → generisches 3D → modellgenaues 3D → AR" vor. Da die generische 3D-Stufe mit CC0-GLB + model-viewer kaum teurer ist als eine 2D-Silhouette mit Zonen (die als eigenes SVG-Asset-Set auch erst entstehen müsste), kann Stufe 1 direkt generisches 3D sein; „modellgenaues 3D" entfällt bewusst (§3). Vorgeschlagene Slices:
Umsetzungshinweis (2026-08-02): Das Datenmodell (
karosserieTyp+markierungen[]am Auftrag, §5) + Karosserietyp-Auswahl bei der Annahme wurden vorgezogen (V-1 unten,0.160.0) — es trägt Vorschaden- und QS-Use-Case gemeinsam und ist ohne die Asset-/Bucket-Abhängigkeit lauffähig. Die Slice-Nummern unten sind entsprechend re-geschnitten: die reine Datenschicht ist raus aus V-2/V-3 und als V-1 erledigt.
| Slice | Inhalt | Status / Abhängigkeit |
|---|---|---|
| V-1 ✅ | Datenmodell karosserieTyp (Katalog) + markierungen[] am Auftrag (§5), Schema-Migration v23, markierung.setzen/entfernen-Handler (Chronik+Audit), Karosserietyp-Auswahl bei der Annahme + Anzeige am Auftrag-Detail | gebaut 0.160.0 (Server+Client, ohne Assets/Bucket) |
| V-1b ✅ | CC0-Karosserietyp-GLBs kuratieren (+ LICENSE.md) → R2 taktano-models (karosserie/<key>.glb), Binding aktivieren; GET /models/* bedient nur die Allowlist karosserie/·mediapipe/·nsfwjs/ (serveModellAsset), alle anderen Keys → 404 | erledigt (PO-Deploy 2026-08-08) — Aufbereitung via scripts/build-fahrzeug-modelle.mjs, Runbook Fahrzeug-Modelle-V1b.md (Bucket/Binding = Bildbewertung §7b) |
| V-2 ✅ | 3D-Viewer-Komponente fahrzeug-viewer (statisch ins Auftrag-Detail importiert; nur die Renderer-Lib @google/model-viewer lädt lazy per dynamic import() beim Öffnen — kein loadComponent-Boundary), Drehen/Zoomen, lädt GLB je karosserieTyp aus /models/karosserie/<typ>.glb; per Toggle; Fallback + strukturierter Log (ClientObs/OTLP) bei fehlendem Typ/404. Binding MODELLE_BUCKET aktiviert. | gebaut 0.161.0 (nach V-1b-Deploy) |
| V-3 | Markierungen: setzen per Klick (positionAndNormalFromPoint → markierung.setzen), Nummern-Badges, Kommentar + Foto-Verknüpfung; Sicht in Annahme + Auftrag-Detail | V-2; Datenmodell + setzeMarkierung stehen (V-1) |
| V-4 | Mangel-Verknüpfung (mangelId bereits im Modell), Quality-Check-Sicht; später AR/USDZ + iOS | V-3 |
Risiken/Kosten: model-viewer-Runtime nur im Lazy-Chunk (Bundle-Disziplin) · Low-Poly-Stil ist eine bewusste Ästhetik-Entscheidung (mit Design-Tokens einfärbbar, kein Fotorealismus — zum Markieren ein Vorteil) · Lizenz-Nachweis je Asset mitführen (§2).
8. Quellen (Recherche 07-04)
modelviewer.dev · Annotations-Beispiele ·
web.dev zu model-viewer · Quaternius ·
Poly Pizza · Kenney ·
Sketchfab-Lizenzen ·
TurboSquid-Lizenz ·
usd_from_gltf · npm @google/model-viewer 4.3.1 (Stand 06/2026).
↩ Zurück zur Doku-Landkarte · Lesepfade · Register (alle OPs)