Mossgrim's heart: a gnarled moss-grown tree rising from the throne, the heart glowing in its hollow

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-07 23:49:00 +01:00
1 parent 45060e85b7
commit 16e299d1f1
1 file changed
+49 -19
+49 -19
View File
@@ -2811,34 +2811,64 @@ fn draw_rival_heart(base: Vec3, hc: Vec3, hp: f32, t: f32, ph: f32, beat: f32, r
let col = |v: Vec3, a: f32| Color::new(v.x.min(1.0), v.y.min(1.0), v.z.min(1.0), a); let col = |v: Vec3, a: f32| Color::new(v.x.min(1.0), v.y.min(1.0), v.z.min(1.0), a);
let life = 0.45 + 0.55 * hp; // a hurt heart fades let life = 0.45 + 0.55 * hp; // a hurt heart fades
match side { match side {
// Mossgrim: a gnarled knot of branches grown into a heart, moss cushions on it that swell // Mossgrim: a gnarled, moss-grown tree without leaves growing out of the throne, roots
// with every beat, green spores drifting up // clawing over its steps, bare twisted branches; in a hollow of the trunk his heart glows
// green, the moss cushions swell with every beat, green spores drift up
2 => { 2 => {
let bark = Color::new(0.32, 0.22, 0.14, 1.0); let wood = crate::props::material(crate::props::Mat::Wood);
let bark = Color::new(0.36, 0.25, 0.16, 1.0);
let y0 = base.y + 0.5;
let y1 = hc.y + 0.35;
let segs = 7;
// the trunk's middle at height f (0..1): it winds a little
let mid = |f: f32| base + vec3((f * 5.0).sin() * 0.07, y0 - base.y + f * (y1 - y0), (f * 4.0 + 1.0).cos() * 0.06);
for q in 0..segs {
let (f0, f1) = (q as f32 / segs as f32, (q + 1) as f32 / segs as f32);
let (r0, r1) = (0.24 - f0 * 0.15, 0.24 - f1 * 0.15);
let p = mid(f0);
draw_cylinder(p, r1, r0, mid(f1).y - p.y + 0.02, wood.as_ref(), bark);
}
// roots over the steps
for k in 0..6 { for k in 0..6 {
let a0 = k as f32 * 1.05; let a = k as f32 * 1.05 + 0.3;
let mut prev = hc + up * -0.5 + right * (a0.cos() * 0.08); let d = vec3(a.cos(), 0.0, a.sin());
for q in 1..=7 { let mut prev = mid(0.0) + d * 0.15 + up * 0.05;
let f = q as f32 / 7.0; for q in 1..=4 {
// two lobes: the branches part above and meet below let f = q as f32 / 4.0;
let side_ = if k % 2 == 0 { 1.0 } else { -1.0 }; let next = mid(0.0) + d * (0.15 + f * 0.75) + up * (0.05 - f * 0.12) + vec3(0.0, 0.0, (a * 3.0 + f * 4.0).sin() * 0.05);
let x = side_ * (f * std::f32::consts::PI).sin() * 0.32 + (a0 + f * 4.0).sin() * 0.04; line3(prev, next, 0.09 - f * 0.06, bark);
let next = hc + up * (-0.5 + f * 0.85) + right * x + front * ((a0 + f * 3.0).cos() * 0.12);
line3(prev, next, 0.07 - f * 0.03, bark);
prev = next; prev = next;
} }
} }
for k in 0..9 { // bare branches from the upper trunk, curling up and out
let a = k as f32 * 2.1; for k in 0..4 {
let p = hc + right * (a.cos() * 0.26) + up * (a.sin() * 0.22 - 0.05) + front * 0.12; let a = k as f32 * 1.57 + 0.4;
let r = (0.07 + (k % 3) as f32 * 0.025) * (1.0 + beat * 0.35); let d = vec3(a.cos(), 0.0, a.sin());
draw_sphere(p, r, None, col(vec3(0.16, 0.42, 0.14) * (life + beat * 0.5), 1.0)); let mut prev = mid(0.7 + k as f32 * 0.07);
for q in 1..=5 {
let f = q as f32 / 5.0;
let next = prev + d * (0.11 - f * 0.03) + up * (0.05 + f * 0.06) + vec3((f * 6.0 + a).sin() * 0.03, 0.0, 0.0);
line3(prev, next, 0.06 - f * 0.045, bark);
prev = next;
} }
draw_sphere(hc, 0.7 * (1.0 + beat * 0.08), None, col(mc * 0.6, 0.1 + 0.1 * beat)); }
// the glowing heart in a hollow of the trunk, facing the viewer
let hollow = mid(0.62) + front * 0.13;
draw_sphere(hollow, 0.13, None, Color::new(0.05, 0.08, 0.04, 1.0));
draw_sphere(hollow + front * 0.03, 0.08 * (1.0 + beat * 0.4), None, col(vec3(0.4, 1.0, 0.35) * (0.6 + 0.4 * life + beat * 0.4), 1.0));
// moss cushions on the trunk, the roots and the branch forks
for k in 0..11 {
let f = 0.08 + (k as f32 * 0.37).fract() * 0.8;
let a = k as f32 * 2.3;
let p = mid(f) + vec3(a.cos(), 0.0, a.sin()) * (0.22 - f * 0.13);
let r = (0.05 + (k % 3) as f32 * 0.02) * (1.0 + beat * 0.35);
draw_sphere(p, r, None, col(vec3(0.18, 0.45, 0.14) * (life + beat * 0.4), 1.0));
}
draw_sphere(hollow, 0.55 * (1.0 + beat * 0.08), None, col(mc * 0.6, 0.08 + 0.1 * beat));
for k in 0..12 { for k in 0..12 {
let e = (t * 0.22 + k as f32 * 0.083).fract(); let e = (t * 0.22 + k as f32 * 0.083).fract();
let a = k as f32 * 2.4 + t * 0.4; let a = k as f32 * 2.4 + t * 0.4;
let p = hc + vec3(a.cos() * (0.3 + e * 0.6), -0.3 + e * 1.8, a.sin() * (0.3 + e * 0.6)); let p = hollow + vec3(a.cos() * (0.3 + e * 0.6), -0.3 + e * 1.8, a.sin() * (0.3 + e * 0.6));
draw_cube(p, Vec3::splat(0.035 * (1.0 - e) + 0.012), None, col(vec3(0.5, 1.0, 0.45), (1.0 - e) * 0.9)); draw_cube(p, Vec3::splat(0.035 * (1.0 - e) + 0.012), None, col(vec3(0.5, 1.0, 0.45), (1.0 - e) * 0.9));
} }
} }