Expand description
L-system scene: expensive to build, cheap to animate (ADR-0007 generator
build model). At preset load (configure, off the hot path) the grammar is
expanded and turtle-walked into one cached segment buffer per depth
1..=max_depth. Per frame the scene only picks the visible depth and applies
a rotation / scale / colour / draw-on transform into the draw buffer — no
expansion, no allocation.
That is growth = "fixed". Under growth = "endless" nothing is cached:
the derivation is streamed through Endless (a lazy depth-first walk of the
grammar, see grammar::Stream) and turtle-walked a few draw steps every frame
into a fixed ring of trail segments. Every buffer it touches is reserved at
configure, so the per-frame walk still allocates nothing.
Beat accents advance visible_depth (grow one iteration); continuous motion
drives rotation, hue, draw_progress, etc.
§The colour axis: generation depth (ADR-0059)
This scene honours [palette] / [palette_b] / palette_mix / hue_spread
/ saturation, sampled on the CPU exactly as spectrum
does. Each line scene walks hue_spread along the axis its own generator
makes meaningful, and for an L-system that axis is generation depth: the
branch-nesting level the turtle drew a segment at, 0 on the trunk and one
more for every open [. Colouring by it makes an older branch read as older,
which is what the whole subject of a rewriting system is.
The ramp is normalized over the figure’s own deepest generation, not over
visible_depth. ADR-0059 wrote the latter; it is wrong in both directions
and the code follows the measurement instead. A grammar can open more than one
branch per rewrite — lsystem_fern’s X -> F+[[X]-X]-F[-FX]+X opens two, so
its deepest generation runs 1, 3, 5, 7, 9, 11 over visible_depth
1 to 6, and dividing by 6 would leave five sixths of the figure clamped at the
palette’s far end — while a grammar with no brackets at all
(lsystem_arrowhead, deepest generation 0 at every one of its seven
depths) has no range for the divisor to describe. Normalizing over the built
figure’s own maximum makes hue_spread = 1 span the palette exactly once on
any grammar, and it is a load-time quantity, so an eased visible_depth
cannot sweep the divisor through fractional values mid-fall.
A bracket-free grammar therefore has exactly one generation and colours flat — that is a property of such a figure (every segment of a Sierpinski arrowhead genuinely sits at the same recursion level), not a gap. Such a preset still reaches the palette; what it cannot reach is a ramp across a figure that has no depth to ramp along.
hue_spread = 0 collapses the ramp to the single hue the scene has always
drawn, so the surface is a strict superset.
Structs§
- LSystem
Scene - A generator scene driven by an L-system grammar.
Enums§
- Growth
- How the figure is grown:
[generator] growth.
Constants§
- DEFAULT_
FOLLOW_ WINDOW [generator] follow_window’s default: how many of the newest segments the follow point is the centroid of.- DEFAULT_
TRAIL [generator] trail’s default: how many segments an endless figure keeps.- FAMILY_
PARAMS - Every parameter whose reading depends on the turtle or the growth (ADR-0258, ADR-0180 rule 4). The generated reference prints each as inert on the modes that ignore it.
- MODES
- The modes
FAMILY_PARAMSis written against: each turtle, fixed and endless, in that order. - PARAMS
- Parameter vocabulary — see
fragment_field::PARAMS. Keep in sync withset_parambelow.