Weiter an den Baum Systemen gearbeitet
This commit is contained in:
@@ -16,7 +16,8 @@ out vec2 texCoord;
|
||||
out vec3 worldNormal;
|
||||
|
||||
void main() {
|
||||
float windW = inColor.r;
|
||||
float windW = inColor.r; // Ast-Wind (0=Wurzel, 1=Astspitze)
|
||||
float leafFlutter = inColor.g; // Blatt-Flattern (0=Ansatz, 1=Blattspitze)
|
||||
float t = g_Time * m_WindSpeed;
|
||||
|
||||
vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);
|
||||
@@ -30,16 +31,20 @@ void main() {
|
||||
vec2 hashPos = floor(vec2(g_WorldMatrix[3][0], g_WorldMatrix[3][2]));
|
||||
float randPhase = fract(sin(dot(hashPos, vec2(127.1, 311.7))) * 43758.5453) * 6.2832;
|
||||
|
||||
// Ast-Schwingen (niedrige Frequenz, große Amplitude)
|
||||
float mainSway = sin(t + wavePhase * 0.08 + randPhase) * windW * m_WindStrength;
|
||||
float crossSway = cos(t * 0.73 + wavePhase * 0.06 + randPhase) * windW * m_WindStrength * 0.25;
|
||||
|
||||
// Blatt-Flattern (hohe Frequenz, kleine Amplitude, unabhängig vom Ast-Wind)
|
||||
float flutter = sin(t * 2.9 + wavePhase * 0.22 + randPhase * 1.6) * leafFlutter * m_WindStrength * 0.5;
|
||||
|
||||
// Y-Kompression: Äste neigen sich statt zu strecken → verhindert Breiterwerden der Spitzen
|
||||
float sway2 = mainSway * mainSway + crossSway * crossSway;
|
||||
|
||||
vec3 animPos = inPosition + vec3(
|
||||
windN.x * mainSway + perpN.x * crossSway,
|
||||
windN.x * mainSway + perpN.x * crossSway + perpN.x * flutter,
|
||||
-sway2 * 0.5,
|
||||
windN.y * mainSway + perpN.y * crossSway
|
||||
windN.y * mainSway + perpN.y * crossSway + perpN.y * flutter
|
||||
);
|
||||
|
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(animPos, 1.0);
|
||||
|
||||
@@ -1939,9 +1939,9 @@ public class EditorApp extends Application {
|
||||
levelSpinner.valueProperty().addListener((o, a, b) -> treeParams.levels = b);
|
||||
inner.getChildren().add(levelSpinner);
|
||||
|
||||
// Gravitation
|
||||
inner.getChildren().add(paramSlider("Gravitation:", -0.15, 0.20, treeParams.gravityStrength,
|
||||
v -> treeParams.gravityStrength = v));
|
||||
// Stamm-Aufrichtung
|
||||
inner.getChildren().add(paramSlider("Stamm-Aufrichtung:", 0.0, 0.40, treeParams.trunkUprightness,
|
||||
v -> treeParams.trunkUprightness = v));
|
||||
|
||||
inner.getChildren().add(new Separator());
|
||||
|
||||
|
||||
@@ -39,12 +39,14 @@ public class TreeMeshBuilder {
|
||||
VertexCollector barkCol = new VertexCollector();
|
||||
VertexCollector leafCol = new VertexCollector();
|
||||
|
||||
record BranchTask(Vector3f origin, Vector3f dir, int level, float windBase) {}
|
||||
// parentDir: Wachstumsrichtung des Elternastes an der Abzweigstelle
|
||||
// (für L2+-Äste: 90° davon weg = natürliche Spreizung)
|
||||
record BranchTask(Vector3f origin, Vector3f dir, Vector3f parentDir, int level, float windBase) {}
|
||||
record SectionPt (Vector3f pos, Vector3f dir, float wind) {}
|
||||
|
||||
Deque<BranchTask> stack = new ArrayDeque<>();
|
||||
stack.push(new BranchTask(new Vector3f(0, 0, 0), new Vector3f(0, 1, 0),
|
||||
0, p.trunkFlexibility));
|
||||
new Vector3f(0, 1, 0), 0, p.trunkFlexibility));
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
BranchTask t = stack.pop();
|
||||
@@ -75,28 +77,78 @@ public class TreeMeshBuilder {
|
||||
Vector3f dir = t.dir().clone();
|
||||
List<SectionPt> sectionPts = new ArrayList<>(numSec);
|
||||
|
||||
for (int s = 0; s < numSec; s++) {
|
||||
float rBot = baseRad * lerp(1f, tapFactor, (float) s / numSec);
|
||||
float rTop = baseRad * lerp(1f, tapFactor, (float)(s + 1) / numSec);
|
||||
float wBot = lerp(t.windBase(), windEnd, (float) s / numSec);
|
||||
float wTop = lerp(t.windBase(), windEnd, (float)(s + 1) / numSec);
|
||||
// Alle Sektionspunkte sammeln, danach als nahtlose Röhre (Bisektor-Ringe,
|
||||
// kein Parallel-Transport-Twisting, keine Lücken an Richtungswechseln).
|
||||
Vector3f[] tubePts = new Vector3f[numSec + 1];
|
||||
float[] tubeRad = new float[numSec + 1];
|
||||
float[] tubeWind = new float[numSec + 1];
|
||||
tubePts[0] = pos.clone();
|
||||
tubeRad[0] = baseRad;
|
||||
tubeWind[0] = t.windBase();
|
||||
|
||||
// Gnarliness: dünne Äste stärker perturbieren (nur ab Level 1)
|
||||
if (lv > 0 && gnarl > 1e-4f) {
|
||||
float g = gnarl / (float) Math.sqrt(Math.max(0.01f, rBot));
|
||||
for (int s = 0; s < numSec; s++) {
|
||||
float t0 = (float) s / numSec;
|
||||
float t1 = (float)(s + 1) / numSec;
|
||||
float rBot = baseRad * lerp(1f, tapFactor, t0);
|
||||
|
||||
// Gnarliness auch für den Stamm (lv=0), dort aber gedämpft
|
||||
if (gnarl > 1e-4f) {
|
||||
float gScale = (lv == 0) ? 0.25f : 1.0f;
|
||||
float g = gnarl * gScale / (float) Math.sqrt(Math.max(0.01f, rBot));
|
||||
dir.x += rng.range(-g, g);
|
||||
dir.z += rng.range(-g, g);
|
||||
dir.normalizeLocal();
|
||||
}
|
||||
|
||||
// Gravitation: Richtung graduell zur Gravitations-Richtung drehen
|
||||
applyGravity(dir, rBot, p.gravityStrength);
|
||||
// Wachstumstendenz per Level
|
||||
if (lv == 0) {
|
||||
// Stamm: Drang nach oben (korrigiert Gnarliness-Knicke zurück)
|
||||
applyTendency(dir, Vector3f.UNIT_Y, p.trunkUprightness);
|
||||
} else {
|
||||
float outw = TreeParams.lv(p.outwardness, lv);
|
||||
if (outw > 1e-5f) {
|
||||
Vector3f ideal;
|
||||
if (lv == 1) {
|
||||
// L1: vom Stamm weg, je höher am Stamm desto mehr nach oben
|
||||
float hFrac = FastMath.clamp(t.origin().y / TreeParams.lv(p.length, 0), 0f, 1f);
|
||||
ideal = new Vector3f(t.origin().x, 0f, t.origin().z);
|
||||
if (ideal.lengthSquared() < 1e-6f) ideal = new Vector3f(1f, 0f, 0f);
|
||||
ideal.normalizeLocal();
|
||||
ideal.y = hFrac;
|
||||
ideal.normalizeLocal();
|
||||
} else {
|
||||
// L2+: 90° weg vom Elternast + weg vom Stamm
|
||||
Vector3f pDir = t.parentDir();
|
||||
// Horizontale Senkrechte zum Elternast
|
||||
Vector3f perpH = new Vector3f(pDir.z, 0f, -pDir.x);
|
||||
if (perpH.lengthSquared() < 1e-6f) perpH = new Vector3f(1f, 0f, 0f);
|
||||
perpH.normalizeLocal();
|
||||
// Outward-Vektor vom Stammzentrum
|
||||
Vector3f outXZ = new Vector3f(pos.x, 0f, pos.z);
|
||||
if (outXZ.lengthSquared() > 1e-6f) {
|
||||
outXZ.normalizeLocal();
|
||||
if (perpH.dot(outXZ) < 0f) perpH.negateLocal();
|
||||
}
|
||||
ideal = perpH.add(outXZ);
|
||||
if (ideal.lengthSquared() < 1e-6f) ideal = perpH.clone();
|
||||
ideal.normalizeLocal();
|
||||
}
|
||||
applyTendency(dir, ideal, outw);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3f end = pos.add(dir.mult(segLen));
|
||||
addCylinder(barkCol, pos, end, rBot, rTop, wBot, wTop, segs);
|
||||
sectionPts.add(new SectionPt(pos.clone(), dir.clone(), wTop));
|
||||
|
||||
// t^1.5-Kurve: Stamm/Ast bleibt länger dick, verjüngt sich am Ende schneller
|
||||
float tapT = FastMath.pow(t1, 1.5f);
|
||||
tubePts[s + 1] = end.clone();
|
||||
tubeRad[s + 1] = baseRad * lerp(1f, tapFactor, tapT);
|
||||
tubeWind[s + 1] = lerp(t.windBase(), windEnd, t1);
|
||||
|
||||
sectionPts.add(new SectionPt(pos.clone(), dir.clone(), tubeWind[s + 1]));
|
||||
pos = end;
|
||||
}
|
||||
buildTube(barkCol, tubePts, tubeRad, tubeWind, segs);
|
||||
|
||||
if (lv < maxLevel - 1) {
|
||||
// Kind-Äste stratifiziert entlang des Eltern-Astes verteilen
|
||||
@@ -114,7 +166,7 @@ public class TreeMeshBuilder {
|
||||
float nextAngle = TreeParams.lv(p.angle, lv + 1);
|
||||
stack.push(new BranchTask(
|
||||
sp.pos(), branchDir(sp.dir(), yRot, nextAngle),
|
||||
lv + 1, sp.wind()));
|
||||
sp.dir().clone(), lv + 1, sp.wind()));
|
||||
}
|
||||
} else if (p.generateLeaves) {
|
||||
// Blätter entlang des gesamten letzten Astes (jede Sektion)
|
||||
@@ -137,9 +189,11 @@ public class TreeMeshBuilder {
|
||||
+ rng.range(-0.5f, 0.5f);
|
||||
Vector3f twigDir = branchDir(sp.dir(), yRot, twigAngle);
|
||||
Vector3f twigEnd = sp.pos().add(twigDir.mult(twigLen));
|
||||
addCylinder(barkCol, sp.pos(), twigEnd,
|
||||
twigRad, twigRad * 0.35f,
|
||||
sp.wind(), windEnd, Math.max(3, segs - 1));
|
||||
buildTube(barkCol,
|
||||
new Vector3f[]{sp.pos(), twigEnd},
|
||||
new float[]{twigRad, twigRad * 0.35f},
|
||||
new float[]{sp.wind(), windEnd},
|
||||
Math.max(3, segs - 1));
|
||||
addLeafCluster(leafCol, twigEnd, windEnd,
|
||||
p.leafScale, p.leafCount, p.leafAngle, rng);
|
||||
}
|
||||
@@ -151,20 +205,18 @@ public class TreeMeshBuilder {
|
||||
return new MeshResult(barkCol.toMesh(), leafCol.toMesh(), computeBounds(barkCol));
|
||||
}
|
||||
|
||||
// ── Gravitations-Kraft ────────────────────────────────────────────────────
|
||||
// ── Wachstumstendenz ─────────────────────────────────────────────────────
|
||||
// Dreht dir pro Sektion um bis zu `strength` Radiant in Richtung ideal.
|
||||
|
||||
private static void applyGravity(Vector3f dir, float radius, float strength) {
|
||||
if (Math.abs(strength) < 1e-5f) return;
|
||||
// strength > 0 → nach unten ziehen; strength < 0 → nach oben ziehen
|
||||
Vector3f target = new Vector3f(0, strength > 0 ? -1f : 1f, 0);
|
||||
Vector3f axis = dir.cross(target);
|
||||
float sinFull = axis.length();
|
||||
if (sinFull < 1e-6f) return;
|
||||
axis.divideLocal(sinFull);
|
||||
float fullAngle = FastMath.atan2(sinFull, dir.dot(target));
|
||||
float step = Math.abs(strength) / Math.max(0.01f, radius);
|
||||
float clamped = FastMath.clamp(step, 0f, Math.abs(fullAngle));
|
||||
new Quaternion().fromAngleAxis(clamped, axis).multLocal(dir);
|
||||
private static void applyTendency(Vector3f dir, Vector3f ideal, float strength) {
|
||||
if (strength < 1e-5f) return;
|
||||
Vector3f axis = dir.cross(ideal);
|
||||
float sinA = axis.length();
|
||||
if (sinA < 1e-6f) return;
|
||||
axis.divideLocal(sinA);
|
||||
float angle = FastMath.atan2(sinA, dir.dot(ideal));
|
||||
float step = FastMath.clamp(strength, 0f, angle);
|
||||
new Quaternion().fromAngleAxis(step, axis).multLocal(dir);
|
||||
dir.normalizeLocal();
|
||||
}
|
||||
|
||||
@@ -172,48 +224,73 @@ public class TreeMeshBuilder {
|
||||
|
||||
private static float lerp(float a, float b, float t) { return a + (b - a) * t; }
|
||||
|
||||
// ── Zylinder-Segment ─────────────────────────────────────────────────────
|
||||
// ── Nahtlose Röhre entlang eines Pfades ──────────────────────────────────
|
||||
// Bisektor-Achsen an Gelenken → keine Lücken bei Richtungswechsel.
|
||||
// Parallel-Transport des Perp-Vektors → kein Twisting.
|
||||
|
||||
private static void addCylinder(VertexCollector col,
|
||||
Vector3f start, Vector3f end,
|
||||
float rBot, float rTop,
|
||||
float windBot, float windTop,
|
||||
int N) {
|
||||
Vector3f axis = end.subtract(start);
|
||||
if (axis.lengthSquared() < 1e-8f) return;
|
||||
axis.normalizeLocal();
|
||||
private static void buildTube(VertexCollector col,
|
||||
Vector3f[] pts, float[] radii, float[] winds, int N) {
|
||||
int nPts = pts.length;
|
||||
if (nPts < 2) return;
|
||||
|
||||
Vector3f perp1 = (Math.abs(axis.y) < 0.9f)
|
||||
? axis.cross(Vector3f.UNIT_Y).normalizeLocal()
|
||||
: axis.cross(Vector3f.UNIT_X).normalizeLocal();
|
||||
Vector3f perp2 = axis.cross(perp1).normalizeLocal();
|
||||
|
||||
int base = col.vertexCount;
|
||||
int N1 = N + 1;
|
||||
|
||||
for (int ring = 0; ring < 2; ring++) {
|
||||
Vector3f center = (ring == 0) ? start : end;
|
||||
float r = (ring == 0) ? rBot : rTop;
|
||||
float wind = (ring == 0) ? windBot : windTop;
|
||||
float vCoord = ring;
|
||||
for (int i = 0; i <= N; i++) {
|
||||
float theta = FastMath.TWO_PI * i / N;
|
||||
float cos = FastMath.cos(theta);
|
||||
float sin = FastMath.sin(theta);
|
||||
float nx = cos * perp1.x + sin * perp2.x;
|
||||
float ny = cos * perp1.y + sin * perp2.y;
|
||||
float nz = cos * perp1.z + sin * perp2.z;
|
||||
col.add(center.x + nx * r, center.y + ny * r, center.z + nz * r,
|
||||
nx, ny, nz,
|
||||
(float) i / N, vCoord, wind);
|
||||
}
|
||||
Vector3f[] segDir = new Vector3f[nPts - 1];
|
||||
for (int i = 0; i < nPts - 1; i++) {
|
||||
segDir[i] = pts[i + 1].subtract(pts[i]);
|
||||
float len = segDir[i].length();
|
||||
if (len > 1e-6f) segDir[i].divideLocal(len); else segDir[i].set(0, 1, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
int b0 = base + i, b1 = base + i + 1;
|
||||
int t0 = base + N1 + i, t1 = base + N1 + i + 1;
|
||||
col.tri(b0, b1, t1);
|
||||
col.tri(b0, t1, t0);
|
||||
Vector3f[] ringAxis = new Vector3f[nPts];
|
||||
ringAxis[0] = segDir[0].clone();
|
||||
ringAxis[nPts - 1] = segDir[nPts - 2].clone();
|
||||
for (int i = 1; i < nPts - 1; i++) {
|
||||
ringAxis[i] = segDir[i - 1].add(segDir[i]);
|
||||
float len = ringAxis[i].length();
|
||||
if (len > 1e-6f) ringAxis[i].divideLocal(len); else ringAxis[i] = segDir[i].clone();
|
||||
}
|
||||
|
||||
Vector3f axis0 = ringAxis[0];
|
||||
Vector3f perp = (Math.abs(axis0.y) < 0.9f)
|
||||
? axis0.cross(Vector3f.UNIT_Y).normalizeLocal()
|
||||
: axis0.cross(Vector3f.UNIT_X).normalizeLocal();
|
||||
|
||||
int N1 = N + 1;
|
||||
int base = col.vertexCount;
|
||||
|
||||
for (int i = 0; i < nPts; i++) {
|
||||
Vector3f axis = ringAxis[i];
|
||||
if (i > 0) {
|
||||
float dot = perp.dot(axis);
|
||||
perp = perp.subtract(axis.mult(dot));
|
||||
float len = perp.length();
|
||||
if (len > 1e-6f) perp.divideLocal(len);
|
||||
else perp = (Math.abs(axis.y) < 0.9f)
|
||||
? axis.cross(Vector3f.UNIT_Y).normalizeLocal()
|
||||
: axis.cross(Vector3f.UNIT_X).normalizeLocal();
|
||||
}
|
||||
Vector3f perp2 = axis.cross(perp).normalizeLocal();
|
||||
float r = radii[i];
|
||||
float w = winds[i];
|
||||
|
||||
for (int j = 0; j <= N; j++) {
|
||||
float theta = FastMath.TWO_PI * j / N;
|
||||
float cosT = FastMath.cos(theta);
|
||||
float sinT = FastMath.sin(theta);
|
||||
float nx = cosT * perp.x + sinT * perp2.x;
|
||||
float ny = cosT * perp.y + sinT * perp2.y;
|
||||
float nz = cosT * perp.z + sinT * perp2.z;
|
||||
col.add(pts[i].x + nx * r, pts[i].y + ny * r, pts[i].z + nz * r,
|
||||
nx, ny, nz, (float) j / N, (float) i / (nPts - 1), w);
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
int pb = base + (i - 1) * N1;
|
||||
int cb = base + i * N1;
|
||||
for (int j = 0; j < N; j++) {
|
||||
col.tri(pb + j, pb + j + 1, cb + j + 1);
|
||||
col.tri(pb + j, cb + j + 1, cb + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,18 +339,17 @@ public class TreeMeshBuilder {
|
||||
float ny = rz * gx - rx * gz;
|
||||
float nz = rx * gy - ry * gx;
|
||||
|
||||
float windTip = Math.min(1.0f, wind + 0.25f);
|
||||
int base = col.vertexCount;
|
||||
// Untere Kante am Ast (verankert)
|
||||
// Untere Kante: am Ast verankert – schwingt mit dem Ast (flutter=0)
|
||||
col.add(cx - rx * hw, cy - ry * hw, cz - rz * hw,
|
||||
nx, ny, nz, 0f, 0f, wind);
|
||||
nx, ny, nz, 0f, 0f, wind, 0f);
|
||||
col.add(cx + rx * hw, cy + ry * hw, cz + rz * hw,
|
||||
nx, ny, nz, 1f, 0f, wind);
|
||||
// Obere Kante frei (schwingt im Wind)
|
||||
nx, ny, nz, 1f, 0f, wind, 0f);
|
||||
// Obere Kante: flattert zusätzlich (flutter=1)
|
||||
col.add(cx + rx * hw + gx * hh, cy + ry * hw + gy * hh, cz + rz * hw + gz * hh,
|
||||
nx, ny, nz, 1f, 1f, windTip);
|
||||
nx, ny, nz, 1f, 1f, wind, 1f);
|
||||
col.add(cx - rx * hw + gx * hh, cy - ry * hw + gy * hh, cz - rz * hw + gz * hh,
|
||||
nx, ny, nz, 0f, 1f, windTip);
|
||||
nx, ny, nz, 0f, 1f, wind, 1f);
|
||||
|
||||
col.tri(base, base + 1, base + 2);
|
||||
col.tri(base, base + 2, base + 3);
|
||||
@@ -343,10 +419,16 @@ public class TreeMeshBuilder {
|
||||
void add(float x, float y, float z,
|
||||
float nx, float ny, float nz,
|
||||
float u, float v, float wind) {
|
||||
add(x, y, z, nx, ny, nz, u, v, wind, 0f);
|
||||
}
|
||||
|
||||
void add(float x, float y, float z,
|
||||
float nx, float ny, float nz,
|
||||
float u, float v, float wind, float flutter) {
|
||||
pos.add(x); pos.add(y); pos.add(z);
|
||||
norm.add(nx); norm.add(ny); norm.add(nz);
|
||||
uv.add(u); uv.add(v);
|
||||
col.add(wind); col.add(0f); col.add(0f); col.add(1f);
|
||||
col.add(wind); col.add(flutter); col.add(0f); col.add(1f);
|
||||
vertexCount++;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,12 @@ package de.blight.editor.tree;
|
||||
public class TreeParams {
|
||||
|
||||
// ── Global ────────────────────────────────────────────────────────────────
|
||||
public int seed = 42;
|
||||
public int levels = 3; // Rekursionstiefe (1–4)
|
||||
public float gravityStrength = 0.03f; // >0 = Äste hängen, <0 = aufwärts (Tanne)
|
||||
public int seed = 42;
|
||||
public int levels = 3; // Rekursionstiefe (1–4)
|
||||
/** Wie stark der Stamm pro Sektion zurück zur Senkrechten korrigiert (rad/Sektion). */
|
||||
public float trunkUprightness = 0.12f;
|
||||
/** Wie stark Äste pro Sektion vom Stamm / Elternast weg tendieren (rad/Sektion, per Level). */
|
||||
public float[] outwardness = { 0f, 0.08f, 0.07f, 0.05f };
|
||||
|
||||
// ── Per-Level-Arrays (Index = Level) ──────────────────────────────────────
|
||||
/** Astwinkel zur Eltern-Richtung in Grad (Level 0 = Stamm, ignoriert). */
|
||||
@@ -53,18 +56,19 @@ public class TreeParams {
|
||||
|
||||
public static TreeParams oak() {
|
||||
TreeParams p = new TreeParams();
|
||||
p.seed = 35729;
|
||||
p.levels = 3;
|
||||
p.gravityStrength = 0.04f;
|
||||
p.angle = new float[]{ 0f, 54f, 58f, 32f };
|
||||
p.children = new int[] { 6, 4, 3, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.35f, 0.20f, 0.10f };
|
||||
p.length = new float[]{ 14f, 11f, 8f, 1.5f};
|
||||
p.radius = new float[]{ 0.45f, 0.20f, 0.11f, 0.06f };
|
||||
p.sections = new int[] { 8, 6, 4, 2 };
|
||||
p.segments = new int[] { 8, 6, 4, 3 };
|
||||
p.taper = new float[]{ 0.73f, 0.65f, 0.69f, 0.75f };
|
||||
p.gnarliness= new float[]{ 0.00f, 0.10f, 0.15f, 0.09f };
|
||||
p.seed = 35729;
|
||||
p.levels = 3;
|
||||
p.trunkUprightness = 0.14f;
|
||||
p.outwardness = new float[]{ 0f, 0.09f, 0.07f, 0.05f };
|
||||
p.angle = new float[]{ 0f, 54f, 58f, 32f };
|
||||
p.children = new int[] { 6, 4, 3, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.35f, 0.20f, 0.10f };
|
||||
p.length = new float[]{ 14f, 11f, 8f, 1.5f};
|
||||
p.radius = new float[]{ 0.45f, 0.20f, 0.11f, 0.06f };
|
||||
p.sections = new int[] { 8, 6, 4, 2 };
|
||||
p.segments = new int[] { 8, 6, 4, 3 };
|
||||
p.taper = new float[]{ 0.22f, 0.30f, 0.42f, 0.58f };
|
||||
p.gnarliness = new float[]{ 0.40f, 0.10f, 0.15f, 0.09f };
|
||||
p.leafScale = 1.4f; p.leafCount = 6; p.leafAngle = 42f; p.leafBranchings = 2;
|
||||
p.trunkFlexibility = 0.04f; p.branchFlexibility = 0.85f;
|
||||
p.barkTexture = "Textures/internal/bark/Bark001_Color.jpg";
|
||||
@@ -74,18 +78,19 @@ public class TreeParams {
|
||||
|
||||
public static TreeParams birch() {
|
||||
TreeParams p = new TreeParams();
|
||||
p.seed = 11204;
|
||||
p.levels = 3;
|
||||
p.gravityStrength = 0.01f;
|
||||
p.angle = new float[]{ 0f, 45f, 40f, 25f };
|
||||
p.children = new int[] { 4, 3, 3, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.45f, 0.30f, 0.10f };
|
||||
p.length = new float[]{ 18f, 12f, 6f, 1.2f};
|
||||
p.radius = new float[]{ 0.30f, 0.12f, 0.07f, 0.04f };
|
||||
p.sections = new int[] { 10, 7, 4, 2 };
|
||||
p.segments = new int[] { 7, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.68f, 0.60f, 0.62f, 0.70f };
|
||||
p.gnarliness= new float[]{ 0.00f, 0.05f, 0.10f, 0.04f };
|
||||
p.seed = 11204;
|
||||
p.levels = 3;
|
||||
p.trunkUprightness = 0.18f; // Birke wächst besonders gerade
|
||||
p.outwardness = new float[]{ 0f, 0.07f, 0.06f, 0.04f };
|
||||
p.angle = new float[]{ 0f, 45f, 40f, 25f };
|
||||
p.children = new int[] { 4, 3, 3, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.45f, 0.30f, 0.10f };
|
||||
p.length = new float[]{ 18f, 12f, 6f, 1.2f};
|
||||
p.radius = new float[]{ 0.30f, 0.12f, 0.07f, 0.04f };
|
||||
p.sections = new int[] { 10, 7, 4, 2 };
|
||||
p.segments = new int[] { 7, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.16f, 0.25f, 0.38f, 0.55f };
|
||||
p.gnarliness = new float[]{ 0.25f, 0.05f, 0.10f, 0.04f };
|
||||
p.leafScale = 0.9f; p.leafCount = 4; p.leafAngle = 38f; p.leafBranchings = 1;
|
||||
p.trunkFlexibility = 0.03f; p.branchFlexibility = 0.95f;
|
||||
p.barkTexture = "Textures/internal/bark/Bark002_Color.jpg";
|
||||
@@ -95,18 +100,19 @@ public class TreeParams {
|
||||
|
||||
public static TreeParams pine() {
|
||||
TreeParams p = new TreeParams();
|
||||
p.seed = 72831;
|
||||
p.levels = 3;
|
||||
p.gravityStrength = -0.015f;
|
||||
p.angle = new float[]{ 0f, 75f, 60f, 40f };
|
||||
p.children = new int[] { 7, 5, 4, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.15f, 0.20f, 0.10f };
|
||||
p.length = new float[]{ 12f, 7f, 4f, 0.8f};
|
||||
p.radius = new float[]{ 0.35f, 0.12f, 0.07f, 0.04f };
|
||||
p.sections = new int[] { 8, 5, 3, 2 };
|
||||
p.segments = new int[] { 7, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.65f, 0.58f, 0.60f, 0.65f };
|
||||
p.gnarliness= new float[]{ 0.00f, 0.03f, 0.08f, 0.02f };
|
||||
p.seed = 72831;
|
||||
p.levels = 3;
|
||||
p.trunkUprightness = 0.20f; // Kiefer sehr aufrecht
|
||||
p.outwardness = new float[]{ 0f, 0.10f, 0.08f, 0.05f };
|
||||
p.angle = new float[]{ 0f, 75f, 60f, 40f };
|
||||
p.children = new int[] { 7, 5, 4, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.15f, 0.20f, 0.10f };
|
||||
p.length = new float[]{ 12f, 7f, 4f, 0.8f};
|
||||
p.radius = new float[]{ 0.35f, 0.12f, 0.07f, 0.04f };
|
||||
p.sections = new int[] { 8, 5, 3, 2 };
|
||||
p.segments = new int[] { 7, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.20f, 0.28f, 0.40f, 0.58f };
|
||||
p.gnarliness = new float[]{ 0.25f, 0.03f, 0.08f, 0.02f };
|
||||
p.leafScale = 0.7f; p.leafCount = 8; p.leafAngle = 70f; p.leafBranchings = 1;
|
||||
p.trunkFlexibility = 0.03f; p.branchFlexibility = 0.70f;
|
||||
p.barkTexture = "Textures/internal/bark/Bark003_Color.jpg";
|
||||
@@ -116,18 +122,19 @@ public class TreeParams {
|
||||
|
||||
public static TreeParams willow() {
|
||||
TreeParams p = new TreeParams();
|
||||
p.seed = 54321;
|
||||
p.levels = 3;
|
||||
p.gravityStrength = 0.12f;
|
||||
p.angle = new float[]{ 0f, 60f, 50f, 35f };
|
||||
p.children = new int[] { 5, 4, 3, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.30f, 0.20f, 0.10f };
|
||||
p.length = new float[]{ 10f, 12f, 8f, 2.0f};
|
||||
p.radius = new float[]{ 0.38f, 0.16f, 0.09f, 0.05f };
|
||||
p.sections = new int[] { 8, 8, 5, 3 };
|
||||
p.segments = new int[] { 7, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.72f, 0.68f, 0.65f, 0.72f };
|
||||
p.gnarliness= new float[]{ 0.00f, 0.25f, 0.35f, 0.15f };
|
||||
p.seed = 54321;
|
||||
p.levels = 3;
|
||||
p.trunkUprightness = 0.12f;
|
||||
p.outwardness = new float[]{ 0f, 0.08f, 0.07f, 0.05f };
|
||||
p.angle = new float[]{ 0f, 60f, 50f, 35f };
|
||||
p.children = new int[] { 5, 4, 3, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.30f, 0.20f, 0.10f };
|
||||
p.length = new float[]{ 10f, 12f, 8f, 2.0f};
|
||||
p.radius = new float[]{ 0.38f, 0.16f, 0.09f, 0.05f };
|
||||
p.sections = new int[] { 8, 8, 5, 3 };
|
||||
p.segments = new int[] { 7, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.26f, 0.32f, 0.44f, 0.58f };
|
||||
p.gnarliness = new float[]{ 0.30f, 0.25f, 0.35f, 0.15f };
|
||||
p.leafScale = 1.5f; p.leafCount = 7; p.leafAngle = 55f; p.leafBranchings = 2;
|
||||
p.trunkFlexibility = 0.06f; p.branchFlexibility = 0.98f;
|
||||
p.barkTexture = "Textures/internal/bark/Bark001_Color.jpg";
|
||||
@@ -137,18 +144,19 @@ public class TreeParams {
|
||||
|
||||
public static TreeParams bush() {
|
||||
TreeParams p = new TreeParams();
|
||||
p.seed = 9876;
|
||||
p.levels = 2;
|
||||
p.gravityStrength = 0.02f;
|
||||
p.angle = new float[]{ 0f, 65f, 55f, 40f };
|
||||
p.children = new int[] { 8, 5, 0, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.10f, 0.15f, 0.10f };
|
||||
p.length = new float[]{ 2f, 2f, 1.2f, 0.5f};
|
||||
p.radius = new float[]{ 0.18f, 0.08f, 0.05f, 0.03f };
|
||||
p.sections = new int[] { 4, 4, 3, 2 };
|
||||
p.segments = new int[] { 6, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.65f, 0.60f, 0.62f, 0.65f };
|
||||
p.gnarliness= new float[]{ 0.00f, 0.15f, 0.25f, 0.10f };
|
||||
p.seed = 9876;
|
||||
p.levels = 2;
|
||||
p.trunkUprightness = 0.08f;
|
||||
p.outwardness = new float[]{ 0f, 0.10f, 0.08f, 0.05f };
|
||||
p.angle = new float[]{ 0f, 65f, 55f, 40f };
|
||||
p.children = new int[] { 8, 5, 0, 0 };
|
||||
p.start = new float[]{ 0.0f, 0.10f, 0.15f, 0.10f };
|
||||
p.length = new float[]{ 2f, 2f, 1.2f, 0.5f};
|
||||
p.radius = new float[]{ 0.18f, 0.08f, 0.05f, 0.03f };
|
||||
p.sections = new int[] { 4, 4, 3, 2 };
|
||||
p.segments = new int[] { 6, 5, 4, 3 };
|
||||
p.taper = new float[]{ 0.65f, 0.60f, 0.62f, 0.65f };
|
||||
p.gnarliness = new float[]{ 0.00f, 0.15f, 0.25f, 0.10f };
|
||||
p.leafScale = 1.0f; p.leafCount = 5; p.leafAngle = 50f; p.leafBranchings = 2;
|
||||
p.trunkFlexibility = 0.05f; p.branchFlexibility = 0.90f;
|
||||
p.barkTexture = "Textures/internal/bark/Bark001_Color.jpg";
|
||||
@@ -160,10 +168,11 @@ public class TreeParams {
|
||||
|
||||
public TreeParams copy() {
|
||||
TreeParams c = new TreeParams();
|
||||
c.seed = seed;
|
||||
c.levels = levels;
|
||||
c.gravityStrength = gravityStrength;
|
||||
c.angle = angle.clone();
|
||||
c.seed = seed;
|
||||
c.levels = levels;
|
||||
c.trunkUprightness = trunkUprightness;
|
||||
c.outwardness = outwardness.clone();
|
||||
c.angle = angle.clone();
|
||||
c.children = children.clone();
|
||||
c.start = start.clone();
|
||||
c.length = length.clone();
|
||||
|
||||
Reference in New Issue
Block a user