Rock Gen 2.14.0: Export-Haertung (Wunschliste 1-3) + LOD/Vertex-Farben geklaert

Punkt 1 - Ursprung erzwingen (keine Option mehr)
  Der Export schrieb die Objekt-Transformation mit ins FBX. Dadurch trug das
  25er-Set seine Szenen-Rasterpositionen (bis 20 m) im Asset und die Steine
  schwebten im Spiel neben ihrem Platzierungspunkt. Jetzt wandert jedes Objekt
  an den Welt-Ursprung, Origin unten-mittig der Bbox. Am REIMPORTIERTEN FBX
  gemessen: Bbox-Mitte 0.000/0.000, min.Z 0.000.

Punkt 2 - flache Steine hinlegen
  Kuerzeste Bbox-Achse zeigt nach oben. Gedreht wird nur, wenn es etwas bringt:
  bei 2.53/1.40/1.54 wuerde Kippen die Form nur willkuerlich drehen.

Punkt 3 - UCX-Kollisionshuellen
  Konvexe Huelle als UCX_<Name> im selben FBX, Budget einstellbar (Default 32
  Verts). Gemessen 29-32 Verts, geschlossen, umschliesst den Stein.

Alles auf temporaeren KOPIEN - die Szene des Users bleibt unveraendert
(Test prueft Namen und Objektzahl vorher/nachher).

Offener Punkt der Spielseite beantwortet: LOD-Gruppen + Vertex-Farben gingen
NICHT. Der LOD-Zweig in make_one_rock sprang komplett am Cavity-Bake vorbei -
gemessen: kein Farbattribut auf einer der vier Stufen, dazu fehlten Origin und
Material. Jetzt wird auf LOD0 gebacken, BEVOR dupliziert wird; das Decimate
interpoliert mit, damit alle Stufen dieselbe Cavity zeigen und der LOD-Wechsel
nicht poppt. Nach Roundtrip: LOD0 40 V R 0.30..1.00, LOD1 21 V, LOD2 11 V,
LOD3 6 V - alle mit Farben.

Vier Fallen, die der Test aufgedeckt hat:
- Blender haengt an Kopien ".001" an; Unreal ordnet UCX ueber den EXAKTEN
  Mesh-Namen zu -> Original bekommt fuer die Exportdauer einen Hilfsnamen.
- bmesh.from_mesh bringt die Originalflaechen mit, convex_hull legt seine
  Huelle obendrauf -> 16-21 offene Kanten. Nur die PUNKTE einlesen.
- Jede Vereinfachung schneidet Ecken ab, die Huelle wird KLEINER als der Stein
  (der Spieler wuerde einsinken). Jetzt exakt so weit aufgeblasen, dass wieder
  alles hineinpasst - fuer Kollision ist minimal zu gross unkritisch.
- ob.matrix_world = Identity loescht die Transformation NICHT bei geparenteten
  Objekten; bei einer LOD-Gruppe auf (13/-7.5/2.2) landete das Mesh bei MINUS
  dieser Position. matrix_basis und matrix_parent_inverse direkt nullen.

Neu: tests/test_export_robust.py misst am reimportierten FBX statt an der
Szene - nur so faellt eine mitgeschriebene Transformation ueberhaupt auf.
15 Tests bestehen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-03 08:02:14 +02:00
co-authored by Claude Opus 4.8
parent 26131f9346
commit 20a751edca
8 changed files with 619 additions and 13 deletions
+61
View File
@@ -118,6 +118,66 @@ Abgestimmt auf `A:\eco\EcoGame` (UE 5.8). Kurzfassung:
---
## Export-Haertung (Rock Gen)
Drei Dinge passieren beim FBX-Export jetzt automatisch. Alles laeuft auf
**temporaeren Kopien** - die Szene bleibt unveraendert.
**1. Ursprung wird erzwungen** (keine Option). Jedes Objekt wandert an den
Welt-Ursprung, der Ursprung sitzt unten-mittig der Bounding-Box. Anlass: das
25er-Set trug seine Szenen-Rasterpositionen (bis 20 m) im Mesh, die Steine
schwebten im Spiel neben ihrem Platzierungspunkt. Nachgemessen am
**reimportierten** FBX: Bbox-Mitte 0.000/0.000, `min.Z` 0.000.
**2. Flache Steine werden hingelegt** (`Flache Steine hinlegen`, Default an).
Die kuerzeste Bbox-Achse wird nach oben gedreht. Gedreht wird nur, wenn es etwas
bringt - bei einem 2.53/1.40/1.54-Stein wuerde Kippen die Form nur willkuerlich
drehen. Im Spiel gibt es nur zufaelligen Yaw, die gebackene Ausrichtung ist also
endgueltig.
**3. UCX-Kollision** (`UCX-Kollision mitexportieren`, Default an). Konvexe Huelle
als `UCX_<Name>` im selben FBX, Unreal nimmt sie als Simple Collision. Budget
ueber `UCX max. Verts` (Default 32).
Drei Fallen, die dabei aufgefallen sind:
- Blender haengt an Kopien `.001` an. Unreal ordnet die Kollision aber ueber den
**exakten** Mesh-Namen zu - das Original bekommt fuer die Dauer des Exports
einen Hilfsnamen, die Kopie den echten.
- `bmesh.from_mesh` bringt die **Originalflaechen** mit, `convex_hull` legt seine
Huelle dann obendrauf: gemessen 16-21 offene Kanten. Es duerfen nur die
**Punkte** eingelesen werden.
- Jede Vereinfachung der Huelle schneidet Ecken ab, sie wird dadurch **kleiner**
als der Stein - eine Kollision kleiner als das Mesh laesst den Spieler
einsinken. Deshalb wird sie danach exakt so weit aufgeblasen, dass wieder alles
hineinpasst.
### LOD-Gruppen + Vertex-Farben (war offen, jetzt geklaert)
Ging **nicht**: der LOD-Zweig sprang komplett am Cavity-Bake vorbei, LOD-Gruppen
kamen ohne Farbattribut aus dem Export - auf keiner der vier Stufen. Jetzt wird
auf LOD0 gebacken, **bevor** dupliziert wird; das Decimate interpoliert die
Farben mit. Wuerde je Stufe neu gebacken, haette jede Stufe ihre eigene Cavity
und der LOD-Wechsel wuerde poppen. Nach dem FBX-Roundtrip gemessen:
| Stufe | Verts | R-Bereich |
|---|---|---|
| LOD0 | 40 | 0.30..1.00 |
| LOD1 | 21 | 0.41..0.92 |
| LOD2 | 11 | 0.45..0.92 |
| LOD3 | 6 | 0.49..0.88 |
Dazu die zweite Falle: `ob.matrix_world = Identity` loescht die Transformation
**nicht**, wenn das Objekt ein Eltern-Objekt hat - Blender rechnet eine lokale
Gegen-Matrix aus. Bei einer LOD-Gruppe auf (13/-7.5/2.2) landete das Mesh dadurch
bei genau MINUS dieser Position. `matrix_basis` und `matrix_parent_inverse`
muessen direkt genullt werden.
Die UCX-Huelle haengt bewusst **neben** dem LodGroup-Empty, nicht darunter -
Unreal wuerde jedes Kind der Gruppe als weitere LOD-Stufe lesen.
---
## Stylized Asset Utils
Fuer alles, was **von Hand** gebaut wird (Pilze, Baumstumpf, Erzfels, Props) und
@@ -391,6 +451,7 @@ gefiltert `.\run_tests.ps1 -Filter panels`.
| Datei | prueft |
|---|---|
| `tests/test_proportionen.py` | Baum-Proportionen: Palmenkrone, Strauch-Breite, Setzling-Schlankheit, Branch Count 0 |
| `tests/test_export_robust.py` | Export am **reimportierten** FBX: Ursprung erzwungen, flach = liegend, UCX geschlossen/umschliessend/im Budget, LOD+Vertex-Farben |
| `tests/test_panels.py` | Alle vier Addons: registrieren, jedes Panel zeichnet, Unter-Panels im richtigen Tab, **jede Property irgendwo erreichbar** |
| `tests/test_tree_addon.py` | Tree-Addon: Presets, Wachstums-Stufen, UVs, Modifier-Apply |
| `tests/test_ecogame_rock.py` | Fels-Benennung, Bake liefert nur `_albedo`/`_normal`, AO im Albedo |