Tree Gen 1.32.0: Deckung pro Stufe, mitwachsender Radius-Filter, LOD als Teilset
Drei Befunde aus der Turnhalle abgearbeitet. 1) Deckung PRO STUFE statt globaler Formel Die alte Rechnung (Dichte durch faktor^2) hielt den Setzling vor der Kahlheit, gab ihm aber die Deckung eines Altbaums. Jetzt Tabelle LEAF_STUFEN. S4 traegt die volle Dichte 170, S2 liegt 15 % darunter, S1 deutlich. Der Dichte-Anteil bei S1/S2 sieht hoch aus - "Dichte" ist Punkte pro m2 ZWEIGFLAECHE, und die waechst ueber die Stufen dramatisch. Was zaehlt ist die Anzahl: 17 / 43 / 67 / 130 Cards, Kante 0.19 / 0.29 / 0.37 / 0.45. Budget S3/S4 auf 4300 (die Spielseite hebt ASSETS.md nach dem 170er-Export entsprechend an). 2) Radius-Filter skaliert mit dem Wachstum (der S3-Befund) Der Filter trennt duenne Zweige von dickem Geaest - aber mit starren 0.04 m greift er bei jungen Baeumen nicht: gemessen sassen bei S2 81 % der Cards am Stamm, bei S3 58 %. Jetzt 48 bzw. 52 %. Dabei eine eigene Fehldeutung korrigiert: bei S1 bleiben ~88 % am Stamm, und das ist KEIN Defekt. Nachgemessen ist die zulaessige Flaeche dort fuer jeden Schwellwert identisch (0.013 m2) - der Saemling hat kein dickes Geaest, an dem sich etwas trennen liesse. Blaetter am Stiel sind bei einem Saemling der Normalfall. Ein erster Sweep hatte mich in die Irre gefuehrt, weil ich growth_t=0 auf einen AUSGEWACHSENEN Baum gesetzt hatte - der hat die volle Zweigflaeche und verhaelt sich voellig anders als ein echter Setzling. 3) LOD-Reduktion als TEILSET der LOD0-Cards Bisher wurde je Stufe neu gestreut - die Cards sassen an anderen Stellen und die Silhouette sprang beim LOD-Wechsel um. Jetzt wird ausgeduennt: jede verbleibende Card liegt genau dort, wo sie in LOD0 schon war, die Ueberlebenden werden groesser. Gearbeitet wird auf zusammenhaengenden INSELN, nicht auf Faces - eine Card muss ganz bleiben oder ganz verschwinden. Auswahl ist seed-stabil. Gemessen am reimportierten FBX: 260 / 156 / 78 / 32 Blatt-Faces, und 100 % der Cards auf LOD1-3 sitzen auf einer LOD0-Position. Der Versatz zu LOD0 ist dabei kleiner geworden als beim Neustreuen. 23 Tests bestehen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -186,6 +186,68 @@ if blatt_zahlen and blatt_zahlen[0] > 0:
|
||||
fails.append("LOD3 hat noch %.0f%% der Cards - als Impostor-Ersatz zu "
|
||||
"teuer" % anteil)
|
||||
|
||||
# --- Die Cards muessen ein TEILSET von LOD0 sein -------------------------
|
||||
# Das ist der Test gegen den Silhouetten-Sprung: wuerde je Stufe neu gestreut,
|
||||
# saessen die Cards an anderen Stellen und die Krone spraenge beim LOD-Wechsel
|
||||
# sichtbar um. Als Teilset liegt jede verbleibende Card dort, wo sie in LOD0
|
||||
# schon war.
|
||||
def card_mitten(ob):
|
||||
"""Mittelpunkte der Blatt-Inseln (eine Insel = eine Card)."""
|
||||
m = ob.data
|
||||
faces = [p for p in m.polygons if p.material_index == 1]
|
||||
if not faces:
|
||||
return []
|
||||
# Inseln ueber gemeinsame Vertices finden
|
||||
von_vert = {}
|
||||
for p in faces:
|
||||
for vi in p.vertices:
|
||||
von_vert.setdefault(vi, []).append(p.index)
|
||||
gesehen = set()
|
||||
mitten = []
|
||||
for p in faces:
|
||||
if p.index in gesehen:
|
||||
continue
|
||||
stapel = [p.index]
|
||||
gesehen.add(p.index)
|
||||
insel = []
|
||||
while stapel:
|
||||
fi = stapel.pop()
|
||||
f = m.polygons[fi]
|
||||
insel.append(f)
|
||||
for vi in f.vertices:
|
||||
for nb in von_vert.get(vi, ()):
|
||||
if nb not in gesehen:
|
||||
gesehen.add(nb)
|
||||
stapel.append(nb)
|
||||
mitte = Vector((0.0, 0.0, 0.0))
|
||||
for f in insel:
|
||||
mitte += f.center
|
||||
mitten.append(mitte / len(insel))
|
||||
return mitten
|
||||
|
||||
|
||||
mitten0 = card_mitten(stufen[0])
|
||||
print("")
|
||||
print("LOD0 hat %d Cards" % len(mitten0))
|
||||
for ob in stufen[1:]:
|
||||
mitten = card_mitten(ob)
|
||||
if not mitten0 or not mitten:
|
||||
continue
|
||||
treffer = 0
|
||||
for m1 in mitten:
|
||||
nah = min((m1 - m0).length for m0 in mitten0)
|
||||
# Die Card wurde vergroessert, ihre Mitte bleibt aber - ein paar
|
||||
# Zentimeter Toleranz reichen.
|
||||
if nah < 0.15:
|
||||
treffer += 1
|
||||
quote = 100.0 * treffer / len(mitten)
|
||||
print("%-24s %3d Cards, %.0f%% davon sitzen auf einer LOD0-Card"
|
||||
% (ob.name, len(mitten), quote))
|
||||
if quote < 90.0:
|
||||
fails.append("%s: nur %.0f%% der Cards sitzen auf LOD0-Positionen - "
|
||||
"die Stufe wurde neu gestreut statt ausgeduennt, die "
|
||||
"Silhouette springt beim LOD-Wechsel" % (ob.name, quote))
|
||||
|
||||
# --- Alle Stufen deckungsgleich am Ursprung ------------------------------
|
||||
# Das ist der Test fuer den aus UE gemeldeten Fehler: LOD1-3 sassen bei MINUS
|
||||
# der Standposition, weil ihre Weltmatrix nie ins Mesh gebacken wurde.
|
||||
|
||||
Reference in New Issue
Block a user