Tree Gen 1.28.0: Faell-Teile mit exakter Ast-Zuordnung (Punkt 4)
Knopf "Faell-Teile exportieren": Stamm in 2-3 Segmente, jeder Ast als eigenes Teil SAMT seinen Sub-Aesten und Blatt-Cards, dazu <Name>_Pieces_All.fbx mit gemeinsamem Ursprung. Je Teil zwei Material-Slots, Pivot am Massenmittelpunkt, eigene UCX-Huelle. Die Ast-Zugehoerigkeit ist ein ATTRIBUT, keine Schaetzung - wie von der UE-Seite vorgeschlagen. Der Generator legt "ast_id" an den Astpunkten ab (0 = Stamm, 1..N = Aeste). Sub-Aeste erben die ID ihres Astes automatisch, weil sie aus Punkten auf dessen Kurve entstehen; nachgemessen: bei Sub Count 0 hat jeder Ast 28 Verts, bei 3 dann 64, der Stamm bleibt konstant bei 156. Beim Blatt-Streuen wird ast_id am Punkt abgegriffen und auf die Card gespeichert. Damit ist die Zuordnung exakt nachzaehlbar, und genau das prueft der Test: Summe der Cards ueber alle Teile == Cards des Stand-Baums. 170 = 170. Die Falle, die diese Bilanz aufgedeckt hat: die Z-Schnitte am Stamm zerschnitten anfangs auch Blatt-Cards. Aus einer wurden zwei, die Bilanz stand auf 178 gegen 170 - und die Atlas-UVs der Haelften waeren kaputt gewesen. Eine Card ist ein unteilbares Billboard; sie wandert jetzt als GANZES in das Segment, in dem ihre Inselmitte liegt. Nur die Rinde wird geschnitten, ihre Schlagflaechen werden gedeckelt. Massenmittelpunkt flaechengewichtet statt Vertex-Mittelwert: wo das Mesh dicht tesselliert ist (Astansatz), wuerde der Mittelwert den Pivot dorthin ziehen und das Teil torkelte beim Fallen. Alles am REIMPORTIERTEN FBX gemessen: 12 Teile (3 Stamm, 9 Ast), UCX 18-32 Verts im Budget, Pivot maximal 16 mm vom Schwerpunkt, 0 non-manifold Kanten, Gesamtdatei 5.41 m hoch - also volle Baumhoehe und deckungsgleich rekonstruierbar. Nebenbei: _deselect fiel ueber None-Eintraege in der Objektliste, die beim Entfernen von Objekten zwischen den Teilen staendig auftreten. Neu: tests/test_faell_teile.py. 21 Tests bestehen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -385,6 +385,41 @@ Zwei Fallen beim Bauen:
|
||||
- `join` loescht das zweite Objekt; jede gehaltene Referenz darauf ist danach
|
||||
tot. Die Aufraeumliste fuehrt deshalb **Namen** statt Objekte.
|
||||
|
||||
### Faell-Teile (Punkt 4)
|
||||
|
||||
Kein Laufzeit-Zerlegen: beim Faellen tauscht das Spiel die ISM-Instanz gegen
|
||||
einen Actor aus vordefinierten Teilen. Knopf **Faell-Teile exportieren**:
|
||||
|
||||
| Teil | Inhalt |
|
||||
|---|---|
|
||||
| `<Name>_Piece_Stamm01..03` | Stammsegmente, Schnittflaechen mit Deckel |
|
||||
| `<Name>_Piece_Ast01..N` | je ein Ast **samt seinen Sub-Aesten und Blatt-Cards** |
|
||||
| `<Name>_Pieces_All.fbx` | alle Teile an ihrer Originalposition, gemeinsamer Ursprung |
|
||||
|
||||
Je Teil: zwei Material-Slots, Pivot = **Massenmittelpunkt**, eigene `UCX_`-Huelle.
|
||||
|
||||
**Die Ast-Zugehoerigkeit ist ein Attribut, keine Schaetzung.** Der Generator legt
|
||||
`ast_id` an den Astpunkten ab (0 = Stamm, 1..N = Aeste); Sub-Aeste erben die ID
|
||||
ihres Astes automatisch, weil sie aus Punkten auf dessen Kurve entstehen —
|
||||
gemessen: bei `Sub Count` 0 hat jeder Ast 28 Verts, bei 3 dann 64, der Stamm
|
||||
bleibt bei 156. Beim Blatt-Streuen wird `ast_id` am Punkt abgegriffen und auf
|
||||
die Card gespeichert. „Welche Card gehoert zu welchem Ast" ist damit eine
|
||||
Nachschlage-Frage statt einer Nearest-Neighbor-Heuristik — und **exakt
|
||||
nachzaehlbar**:
|
||||
|
||||
> `tests/test_faell_teile.py` prueft die **Blatt-Bilanz**: Summe der Cards ueber
|
||||
> alle Teile == Cards des Stand-Baums. Gemessen **170 = 170**.
|
||||
|
||||
**Falle dabei:** Die Z-Schnitte am Stamm zerschnitten anfangs auch Blatt-Cards —
|
||||
aus einer wurden zwei, die Bilanz stand auf 178 gegen 170, und die Atlas-UVs der
|
||||
Haelften waeren kaputt gewesen. Eine Card ist ein **unteilbares** Billboard:
|
||||
sie wandert jetzt als Ganzes in das Segment, in dem ihre Inselmitte liegt.
|
||||
Nur die Rinde wird geschnitten.
|
||||
|
||||
Alles am **reimportierten** FBX gemessen: 12 Teile, UCX 18–32 Verts im Budget,
|
||||
Pivot maximal 16 mm vom Schwerpunkt, 0 non-manifold Kanten, Gesamtdatei 5.41 m
|
||||
hoch (= volle Baumhoehe, die Teile sind also deckungsgleich rekonstruierbar).
|
||||
|
||||
### Proportionen: gemessen, nicht geschaetzt
|
||||
|
||||
Drei Presets sahen falsch aus. Die Ursachen wurden gemessen bzw. belegt, nicht
|
||||
@@ -606,6 +641,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_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 |
|
||||
| `tests/test_bruchstuecke.py` | Bruchstuecke: Volumen 100 % des Muttersteins, dichte Topologie, genau ein Erz-Stueck, Material-Slots, Ursprung, UCX je Teil |
|
||||
|
||||
Reference in New Issue
Block a user