creature Ribbons
// A spinning donut trailing colourful ribbons that ripple as time goes by,
// with a tower on top swaying in the wind.

gene body    = hsv(45, 0.8, 1) in hsv(0, 0.3, 0.5)..hsv(360, 1, 1)
gene hue     = 0    in 0..360        // colour of the first ribbon; the rest go round the wheel
gene ribbons = 4    in 1..8 step 1   // how many ribbons
gene pieces  = 10   in 4..16 step 1  // pieces in each ribbon
gene curl    = 0    in -20..20       // a lean to one side, added to every piece
gene ripple  = 15   in 0..40         // how far the ribbons ripple
gene speed   = 0.6  in 0.1..3 log    // ripples per second
gene spin    = 10   in -60..60       // how fast the donut turns, in degrees per second
gene stone   = hsv(30, 0.15, 0.85) in hsv(0, 0, 0.4)..hsv(360, 0.6, 1)
gene roof    = hsv(350, 0.75, 0.8) in hsv(0, 0.3, 0.4)..hsv(360, 1, 1)
gene floors  = 4    in 2..8 step 1   // how tall the tower is
gene sway    = 3    in 0..10         // how far each floor leans in the wind
gene gusts   = 0.25 in 0.05..1 log   // how often the wind comes and goes, per second

pitch -35  // lean back, so the tower shows from the front

// The tower stands on the donut's top, the face towards the viewer. It's
// outside the spin, so the wind keeps blowing the same way as the donut turns
branch {
  forward 0.3
  // A round plate across the hole for the tower to stand on
  colour stone
  shape tube
  lay { grow (2, 2, 0.12) }
  forward 0.06
  tower
}

roll spin * time

branch {
  colour body
  shine 0.6
  shape donut
  lay { grow (3, 3, 2) }
}

repeat ribbons as i {
  branch {
    roll 360 * i / ribbons + 45
    pitch -90  // point outwards in the donut's plane, flat towards the viewer
    forward 1.4
    ribbon(hue + 360 * i / ribbons)
  }
}

part ribbon(h) {
  let skin = gradient(hsv(h, 0.9, 1), hsv(h + 40, 0.5, 1, 0.8))
  shape cube
  repeat pieces as j {
    let t = j / (pieces - 1)
    // The ripple swings each piece both ways in turn; the delay along the
    // ribbon makes it travel to the tip like a wave
    yaw curl + ripple * wave(time * speed - j * 0.06)
    pitch 0.5 * ripple * wave(time * speed * 0.7 - j * 0.15)
    forward 0.25
    colour skin(t)
    lay { grow (0.6 - 0.3 * t, 0.05, 0.55) }
    forward 0.25
  }
}

part tower {
  repeat floors as k {
    // Each floor leans a little more than the one below, so the tower bends;
    // the noise keeps the wind from being too regular
    yaw sway * (wave(time * gusts) + 0.4 * noise(time * 0.8))
    pitch 0.5 * sway * noise(time * 0.6 + 10)
    let w = 0.75 - 0.3 * k / floors
    colour stone
    shape tube
    forward 0.3
    lay { grow (w, w, 0.6) }
    forward 0.3
    colour roof
    shape ring
    lay { grow (w + 0.08, w + 0.08, 0.5) }
  }
  colour roof
  shape cone
  forward 0.35
  lay { grow (0.75, 0.75, 0.7) }
  forward 0.4
  colour body
  shine 0.6
  shape ball
  lay { grow 0.18 }
}

background {
  fill gradient(hsv(260, 0.5, 0.12), hsv(300, 0.4, 0.35))
}
