Tree Gen 1.29.0: LOD-Kette (Punkt 5) + Aufraeumen/Pruefen (Punkt 6)

Punkt 5 - LOD-Kette fuer den Stand-Baum
  Haken "LOD-Kette erzeugen" liefert <Name>_LODGroup.fbx mit _LOD0..3 unter
  einem fbx_type=LodGroup-Empty, wie die Fels-Pipeline. NUR der Stand-Baum -
  die Faell-Teile leben Sekunden als Physik-Actor, dort reicht LOD0.

  Blatt-Reduktion ueber die DICHTE, nicht ueber Decimate: eine Card besteht aus
  zwei Dreiecken und laesst sich nicht vereinfachen, man muss weniger davon
  setzen. Die verbleibenden werden groesser, damit die Krone nicht ausduennt.

    LOD0  578 Rinde / 170 Blatt / 1306 Tris
    LOD1  477 / 118 /  912
    LOD2  364 /  66 /  575
    LOD3  221 /  28 /  302   (16 % der Cards von LOD0)

  Kugel-Normalen auf JEDER Stufe gemessen, nicht nur LOD0 - LOD1-3 haben eine
  eigene Card-Verteilung. Am reimportierten FBX: 100 % radial auf allen vier.

  Zwei Reihenfolge-Sachen: das Rinden-Decimate laeuft VOR dem Verschmelzen,
  danach wuerde es die Blatt-Cards mit einschmelzen. Und der Ursprung kommt aus
  LOD0 (Unreal platziert danach); alle Stufen werden um denselben Betrag
  verschoben, sonst springt der Baum beim LOD-Wechsel.

Punkt 6 - Aufraeumen und Pruefen
  Blatt-Streuung ueber alle neun Presets nachgemessen. Der Max-Radius-Filter
  arbeitet richtig: 0-22 % der Cards landen am Stamm (meist unter 9 %), und
  alle Presets bleiben unter dem 2500-Tri-Budget (Maximum weide 2246).

  Messfalle, die ich dabei selbst produziert habe: zuerst hatte ich den Anteil
  der VERTICES unter der Radius-Schwelle gemessen - beim Busch 95 %, sah nach
  einem Problem aus. Das misst aber die Vertex-Verteilung, nicht wo Blaetter
  landen; ein Busch besteht fast nur aus duennen Zweigen. Die richtige Frage
  beantwortet erst ast_id.

  Der Kaktus erzeugt regulaer 0 Cards (kein Ast duenner als Max Radius, botanisch
  richtig). Das lief still durch und man stand vor einer leeren _Leaf-Ebene -
  jetzt sagt der Operator es und nennt den Regler beim Namen.

  Panels: das Export-Panel trug Stand-Baum, LODs und Faell-Teile in einem
  Kasten. Die Teile haben jetzt "5 - Faell-Teile" fuer sich.

Neu: tests/test_baum_lod.py. 22 Tests bestehen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 07:55:45 +02:00
co-authored by Claude Opus 4.8
parent 95ddcb40b3
commit 914a1af967
9 changed files with 391 additions and 39 deletions
+60 -1
View File
@@ -23,7 +23,7 @@ nummerierten, eingeklappten Unter-Panels in der Reihenfolge des Arbeitsablaufs:
| Addon | Unter-Panels |
|---|---|
| Rock Gen | 1 Benennung & Groesse · 2 Form · 3 Detail & Cleanup · 4 Shading · 5 Vertex-Farben · 6 UV/LOD/Material · 7 Batch & Transform · 8 FBX-Export · 9 Textur-Bake |
| Tree Gen | 1 Wachstum · 2 Blattwerk · 3 Zusatz-Ebenen · 4 Export |
| Tree Gen | 1 Wachstum · 2 Blattwerk · 3 Zusatz-Ebenen · 4 Export · 5 Faell-Teile |
| Grass Gen | 1 Form · 2 Haltung · 3 Batch & Budget · 4 Kanal-Belegung |
| Asset Utils | 1 Vorbereiten · 2 Vertex-Farben · 3 Benennung · 4 Pruefen · 5 Export |
@@ -385,6 +385,64 @@ Zwei Fallen beim Bauen:
- `join` loescht das zweite Objekt; jede gehaltene Referenz darauf ist danach
tot. Die Aufraeumliste fuehrt deshalb **Namen** statt Objekte.
### LOD-Kette (Stand-Baum)
Haken `LOD-Kette erzeugen`: exportiert `<Name>_LODGroup.fbx` mit `_LOD0..3` unter
einem `fbx_type=LodGroup`-Empty — dasselbe Schema wie die Fels-Pipeline. **Nur
der Stand-Baum**; die Faell-Teile leben Sekunden als Physik-Actor, dort reicht LOD0.
Die Blatt-Reduktion laeuft ueber die **Dichte**, nicht ueber Decimate: eine Card
besteht aus zwei Dreiecken und laesst sich nicht vereinfachen — man muss weniger
davon setzen. Damit die Krone dabei nicht ausduennt, werden die verbleibenden
Cards groesser. LOD3 ist der Impostor-Ersatz.
| Stufe | Dichte | Card-Groesse | Rinde | gemessen (Rinde/Blatt/Tris) |
|---|---|---|---|---|
| LOD0 | 100 % | 100 % | 100 % | 578 / 170 / 1306 |
| LOD1 | 60 % | 115 % | 70 % | 477 / 118 / 912 |
| LOD2 | 30 % | 145 % | 45 % | 364 / 66 / 575 |
| LOD3 | 12 % | 200 % | 25 % | 221 / 28 / 302 |
**Kugel-Normalen auf jeder Stufe** — LOD13 haben eine eigene Card-Verteilung,
die Normalen muessen dazu passen. Am reimportierten FBX gemessen: **100 %
radial auf allen vier Stufen**. LOD3 traegt 16 % der Cards von LOD0.
Der Ursprung kommt aus **LOD0** (Unreal platziert danach); alle Stufen werden um
denselben Betrag verschoben, damit der Baum beim LOD-Wechsel nicht springt.
Das Decimate der Rinde laeuft **vor** dem Verschmelzen — danach wuerde es die
Blatt-Cards mit einschmelzen, und eine halbe Card ist keine Card.
### Blatt-Streuung: nachgemessen (Punkt 6)
`Max Radius` filtert die dicken Aeste heraus, damit keine Blaetter am Stamm
kleben. Ueber alle Presets gemessen, wie viele Cards tatsaechlich am Stamm
landen (moeglich, weil `ast_id` mitlaeuft):
| Preset | Cards | am Stamm | Tris gesamt |
|---|---|---|---|
| baum | 85 | 19 % | 1306 |
| palme | 246 | 0 % | 1710 |
| busch | 118 | 2 % | 876 |
| tanne | 176 | 6 % | 2244 |
| eiche | 172 | 2 % | 1772 |
| birke | 133 | 9 % | 1918 |
| weide | 297 | 1 % | 2246 |
| toter_baum | 49 | 22 % | 838 |
| kaktus | **0** | | 740 |
Der Filter arbeitet also richtig, und **alle Presets bleiben unter dem
2500-Tri-Budget** (Maximum weide 2246).
> **Messfalle dabei:** Zuerst hatte ich den Anteil der Vertices unter der
> Radius-Schwelle gemessen — der lag beim Busch bei 95 % und sah nach einem
> Problem aus. Das misst aber die Vertex-Verteilung, nicht wo Blaetter landen:
> ein Busch besteht nun mal fast nur aus duennen Zweigen. Die richtige Frage
> beantwortet erst `ast_id`.
Der Kaktus erzeugt regulaer **0 Cards** — kein Ast ist duenner als `Max Radius`,
und das ist botanisch richtig. Vorher lief das still durch und man stand vor
einer leeren `_Leaf`-Ebene; jetzt sagt der Operator es und nennt den Regler.
### Faell-Teile (Punkt 4)
Kein Laufzeit-Zerlegen: beim Faellen tauscht das Spiel die ISM-Instanz gegen
@@ -641,6 +699,7 @@ gefiltert `.\run_tests.ps1 -Filter panels`.
| Datei | prueft |
|---|---|
| `tests/test_baum_export.py` | Stand-Baum: ein Mesh, zwei Slots, Ursprung, **Kugel-Normalen im exportierten FBX** |
| `tests/test_baum_lod.py` | LOD-Kette: 4 Stufen unter LodGroup, Cards werden nach oben duenner, **Kugel-Normalen auf jeder Stufe**, kein Hoehenversatz |
| `tests/test_faell_teile.py` | Faell-Teile: **Blatt-Bilanz 170=170**, Pivot am Massenmittelpunkt, UCX je Teil, Gesamtdatei mit gemeinsamem Ursprung |
| `tests/test_blatt_varianten.py` | Card-Sammlung: alle Varianten werden gezogen, seed-stabil, Einzelobjekt weiter moeglich |
| `tests/test_proportionen.py` | Baum-Proportionen: Palmenkrone, Strauch-Breite, Setzling-Schlankheit, Branch Count 0 |