# Foliage presets

Plant a scene's terrain with a named plant community in one call:

```
foliage.preset {scene, preset: "meadow", area: [-100, -100, 100, 100]}
```

The same from a shell: `argus-agent foliage-preset --scene scenes/main.scene.json --preset meadow --area -100,-100,100,100`
(`--dry-run` answers without writing; `--help` lists the presets).

## The presets

| Preset | What it plants | Ground cover it brings |
|---|---|---|
| `meadow` | open grassland, the odd lone oak or birch, clumps of shrubs | `meadow` |
| `roadside-verge` | shrubs from 2 m off the roads' edge, trees from 8 m, over meadow grass | `meadow` |
| `pine-forest` | mountain pine, fir and some spruce, snags, a low shrub layer | `forest-floor` |
| `broadleaf-wood` | oak and birch woodland, a shrub layer, ferns | `meadow-forest` |

Each preset is data, `crates/flora-scatter/presets/<name>.json`: terrain `scatter` ops using only the
op's existing fields, the ground-cover preset to pair them with, a variant cap per op and a budget.
Every preset keeps off the scene's roads (the edge ground cover leaves bare): the verge's shrubs 2 m
and trees 8 m, the others' trees 3 m and shrubs and ferns 1 m.

## Arguments

- `area`: `[minX, minZ, maxX, maxZ]` in scene metres; it should lie on the scene's terrain.
- `seed`: optional, default 1. The same scene, preset, area and seed give the same bytes.
- `scene`: optional; the open scene when absent. The scene needs a terrain entity (`terrain.create`).
- `dryRun`: cook and answer, write nothing.

## What it writes

- One `foliage` entity `fp-<preset>` at the terrain's origin (a layer lists at most 32 prototypes,
  so a preset with more adds `fp-<preset>-layer-2`, `-layer-3`, ...). Under it, one `instancedMesh` entity
  `fp-<preset>-<n>` per (op, model), with its `.instances` file beside the scene. All of them carry
  the tag `foliage-preset:<preset>`.
- One glb per model in the scene's `assets/foliage-preset/` (`<template>.v<variant>.a<age>.glb`),
  declared once as the asset `fp-<stem>`. The models are shared by every scene in that folder and
  rewritten only when their bytes change.
- The preset's `groundCover` on the terrain, only when it has none.
- Trees get colliders (a kart hits them); shrubs and ferns get none. Trees cull at 300 m. Shrubs cull
  at 150 m in `meadow` and `roadside-verge`, 80 m in `pine-forest`, and 70 m (ferns too) in
  `broadleaf-wood`: near the camera, the understory is most of a wood's drawn triangles.

## Re-running and undo

- A re-run REPLACES that preset's plants in that scene (it finds them by tag); it never plants
  twice. Other presets and every other entity stay. Two different presets over one area both plant.
- With no editor on the scene it is one change: `revert` with its `changeId` takes it back,
  including the models it created. With the scene open in the editor, the editor's undo takes the
  scene back.

## Budget

The answer gives `instances`, `models` (each one instanced draw) and `triangles` (full detail, over
every instance) against the preset's budget, scaled to the area. `overBudget` says what is over.
Each budget is 30% above the worst of four seeds over the documented 200 m square:

| Preset | Instances | Models | Triangles |
|---|---|---|---|
| `meadow` | 250 | 11 | 3.8M |
| `roadside-verge` | 267 | 13 | 4.0M |
| `pine-forest` | 332 | 19 | 5.0M |
| `broadleaf-wood` | 597 | 15 | 5.6M |

**Draws.** A model draws as about two draw groups (measured headless on a kart scene: 88 models
added 168 groups), so a preset costs about twice its models in draws. To keep that low, a preset caps the variants each op
draws (`variants` in its file, op id -> cap): trees use 2 of their template's 8 variants, shrubs and
ferns 1. The cap folds a placement's variant (`v % cap`) after the cook, so positions and spacing are
the cook's and only fewer models are cooked.

**Triangles.** GPU time follows the triangles drawn (about 0.4 ms per million on an RTX 3080 at
1080p), so the presets are tuned in their data to draw about 1.5M or fewer from a ground camera:
trees grow in the younger half of their template's ages (`ageRange` 0-0.49), the heaviest templates
are a small share of their op's mix, and density is set from the budget table above.

