{"version":3,"sources":["../src/core.ts","../src/core/random.ts","../src/core/palette.ts","../src/core/types.ts","../src/core/place.ts"],"sourcesContent":["// SCENA — core: randomness, palettes, structural types\n//\n// A sub-path entry point. `import from 'scena3d'` still gives you everything;\n// this exists so a bundler can see module boundaries, and so an import says\n// what part of the library it depends on.\n//\n// GENERATED from src/index.ts by scripts/entries.mjs — every statement below\n// is the root barrel's own, partitioned by source directory. `npm run\n// entries:check` fails if this file and the barrel disagree.\n\nexport { Rng, valueNoise2, fractalNoise2, hash2 } from './core/random';\nexport { PALETTES, DEFAULT_PALETTE, type Palette } from './core/palette';\nexport {\n  collectObstacles,\n  createSlot,\n  addApproach,\n  createPropSurface,\n  type Obstacle,\n  type Prop,\n  type PropSlot,\n  type PropSurface,\n  type Carryable,\n  type CarryStyle,\n  type Gathering,\n  type WaterBody,\n} from './core/types';\nexport {\n  hangOn,\n  hangGallery,\n  createWallAnchor,\n  placeOn,\n  dress,\n  type HangSurface,\n  type HangOptions,\n  type GalleryOptions,\n  type PlaceOptions,\n  type DressOptions,\n} from './core/place';\n","/**\n * Deterministic seeded randomness — the backbone of SCENA. Same seed,\n * same tree; forests are reproducible, diffable and network-syncable.\n */\nexport class Rng {\n  private state: number;\n\n  constructor(seed = 1) {\n    this.state = seed >>> 0 || 1;\n  }\n\n  /** Next float in [0, 1) (mulberry32). */\n  next(): number {\n    this.state = (this.state + 0x6d2b79f5) >>> 0;\n    let t = this.state;\n    t = Math.imul(t ^ (t >>> 15), t | 1);\n    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n  }\n\n  /** Float in [min, max). */\n  range(min: number, max: number): number {\n    return min + this.next() * (max - min);\n  }\n\n  /** Integer in [min, max] inclusive. */\n  int(min: number, max: number): number {\n    return min + Math.floor(this.next() * (max - min + 1));\n  }\n\n  /** Random element of a non-empty array. */\n  pick<T>(items: readonly T[]): T {\n    return items[Math.floor(this.next() * items.length)];\n  }\n\n  /** value ± spread (uniform). */\n  jitter(value: number, spread: number): number {\n    return value + (this.next() * 2 - 1) * spread;\n  }\n\n  /** A new independent Rng derived from this one. */\n  fork(): Rng {\n    return new Rng(Math.floor(this.next() * 0xffffffff) || 1);\n  }\n}\n\n/** Integer-lattice hash to [0, 1) — the base of the value noise. */\nexport function hash2(ix: number, iz: number, seed: number): number {\n  let h = (ix * 374761393 + iz * 668265263 + seed * 2246822519) >>> 0;\n  h = Math.imul(h ^ (h >>> 13), 1274126177) >>> 0;\n  return ((h ^ (h >>> 16)) >>> 0) / 4294967296;\n}\n\nconst smooth = (t: number): number => t * t * (3 - 2 * t);\n\n/** 2D value noise in [0, 1). Continuous; used by terrain and scatter density. */\nexport function valueNoise2(x: number, z: number, seed: number): number {\n  const ix = Math.floor(x);\n  const iz = Math.floor(z);\n  const fx = smooth(x - ix);\n  const fz = smooth(z - iz);\n  const a = hash2(ix, iz, seed);\n  const b = hash2(ix + 1, iz, seed);\n  const c = hash2(ix, iz + 1, seed);\n  const d = hash2(ix + 1, iz + 1, seed);\n  return a + (b - a) * fx + (c - a) * fz + (a - b - c + d) * fx * fz;\n}\n\n/** Fractal (octaved) value noise in [0, 1). */\nexport function fractalNoise2(\n  x: number,\n  z: number,\n  seed: number,\n  octaves = 4,\n  lacunarity = 2,\n  gain = 0.5\n): number {\n  let amplitude = 1;\n  let frequency = 1;\n  let sum = 0;\n  let total = 0;\n  for (let i = 0; i < octaves; i++) {\n    sum += valueNoise2(x * frequency, z * frequency, seed + i * 101) * amplitude;\n    total += amplitude;\n    amplitude *= gain;\n    frequency *= lacunarity;\n  }\n  return sum / total;\n}\n","/**\n * Theme palettes: one coherent set of colors shared by every generator,\n * so procedural props look like a matched set rather than a junk drawer.\n * Pass `palette` to any generator to restyle it; whole scenes retheme by\n * building with a different palette.\n */\nexport interface Palette {\n  foliage: number[];\n  trunk: number;\n  rock: number[];\n  wood: number;\n  woodDark: number;\n  metal: number;\n  lampGlow: number;\n  grassLow: number;\n  grassHigh: number;\n  cliff: number;\n  peak: number;\n  skyTop: number;\n  skyBottom: number;\n  fog: number;\n  water: number;\n  sand: number;\n  path: number;\n  /** Building plaster/wall color. */\n  wall: number;\n  /** Building roof color. */\n  roof: number;\n}\n\nexport const PALETTES: Record<'meadow' | 'autumn' | 'dusk' | 'winter' | 'urban', Palette> = {\n  meadow: {\n    foliage: [0x2f9e57, 0x37b26a, 0x2a8f4f, 0x45b878],\n    trunk: 0x6b4a33,\n    rock: [0x8a8f98, 0x767c86, 0x9aa0a8],\n    wood: 0x8a6642,\n    woodDark: 0x6b4a33,\n    metal: 0x3d4451,\n    lampGlow: 0xffd889,\n    grassLow: 0x3f9d5a,\n    grassHigh: 0x6fae66,\n    cliff: 0x7d7a72,\n    peak: 0xe8ecef,\n    skyTop: 0x3d70b8,\n    skyBottom: 0xbfd9e8,\n    fog: 0xb8cfdd,\n    water: 0x3f7fae,\n    sand: 0xc9b98a,\n    path: 0x9a815f,\n    wall: 0xd9ccb0,\n    roof: 0xa8563e,\n  },\n  autumn: {\n    foliage: [0xc9752f, 0xd98e3a, 0xb35c2a, 0xe0a545],\n    trunk: 0x5d4030,\n    rock: [0x8d8578, 0x776f63, 0x9c948a],\n    wood: 0x7d5a3a,\n    woodDark: 0x5d4030,\n    metal: 0x463f3a,\n    lampGlow: 0xffc571,\n    grassLow: 0x9d8a3f,\n    grassHigh: 0xb59b4a,\n    cliff: 0x82746a,\n    peak: 0xe3ded4,\n    skyTop: 0x8e6ca8,\n    skyBottom: 0xe8c9a8,\n    fog: 0xd9c1a8,\n    water: 0x4a7a92,\n    sand: 0xcbb083,\n    path: 0x8d7454,\n    wall: 0xccb894,\n    roof: 0x8a4a30,\n  },\n  dusk: {\n    foliage: [0x1f5e46, 0x24684f, 0x1a5240, 0x2d7458],\n    trunk: 0x413147,\n    rock: [0x565672, 0x484861, 0x646484],\n    wood: 0x5d4a63,\n    woodDark: 0x413147,\n    metal: 0x2b2b3d,\n    lampGlow: 0xffb35c,\n    grassLow: 0x2d6b52,\n    grassHigh: 0x3d7a5e,\n    cliff: 0x52516b,\n    peak: 0xb8b8d9,\n    skyTop: 0x1d2145,\n    skyBottom: 0xc96a4a,\n    fog: 0x6a5a7a,\n    water: 0x2d4a68,\n    sand: 0x8a7a6a,\n    path: 0x6a5a52,\n    wall: 0x8d8299,\n    roof: 0x453558,\n  },\n  winter: {\n    foliage: [0x2e5c48, 0x38695a, 0x527a68, 0x87a596],\n    trunk: 0x4a3a33,\n    rock: [0x9aa4ad, 0x848e98, 0xb0b8c0],\n    wood: 0x776049,\n    woodDark: 0x54453a,\n    metal: 0x39404d,\n    lampGlow: 0xffd889,\n    grassLow: 0xcfd9de,\n    grassHigh: 0xe4ebee,\n    cliff: 0x76797d,\n    peak: 0xf4f7fa,\n    skyTop: 0x5a7ba6,\n    skyBottom: 0xd8e4ec,\n    fog: 0xccd8e0,\n    water: 0x4a7086,\n    sand: 0xb8c2c6,\n    path: 0x8b8378,\n    wall: 0xd2c9bb,\n    roof: 0x6b4638,\n  },\n  // Modern district: warm-white render, charcoal trim, teak accents, clipped\n  // green — for bungalows, towers and the Tier-4 surfaces.\n  urban: {\n    foliage: [0x4a8f56, 0x5aa065, 0x3f7f4b, 0x6aae74],\n    trunk: 0x5d4a38,\n    rock: [0x9a9a96, 0x85857f, 0xaaaaa4],\n    wood: 0x8a5c36, // teak\n    woodDark: 0x54402c,\n    metal: 0x2f353c, // charcoal powder-coat\n    lampGlow: 0xffe0a8,\n    grassLow: 0x5a9a5e,\n    grassHigh: 0x7aae6e,\n    cliff: 0x8a8a84,\n    peak: 0xe8ecef,\n    skyTop: 0x4a7ec2,\n    skyBottom: 0xcfe0ec,\n    fog: 0xc8d4dd,\n    water: 0x3f7fae,\n    sand: 0xc9bfa8,\n    path: 0xb0aca2, // pale concrete\n    wall: 0xe8e2d6, // warm-white render\n    roof: 0x3a3d42, // charcoal fascia\n  },\n};\n\nexport const DEFAULT_PALETTE: Palette = PALETTES.meadow;\n","import { Object3D, Vector3, type Group } from 'three';\n\n/**\n * A steering obstacle in world space — structurally identical to GAMA's\n * `Obstacle`, so SCENA props plug straight into `ObstacleAvoidance`\n * without either library importing the other.\n */\nexport interface Obstacle {\n  center: Vector3;\n  radius: number;\n}\n\n/**\n * An interaction slot — where and how a character uses this prop.\n * Structurally identical to ANIMA's `InteractionSlot` (anchor at floor\n * level, +z the facing direction, pitched for lying poses), so a prop's\n * slot drops straight into `new Interaction(rig, loco).use(slot)` without\n * either library importing the other.\n */\nexport interface PropSlot {\n  /** Free label: 'sit', 'sleep', 'driver', 'run'… */\n  kind: string;\n  /** The transform target for the character's root (a child of the prop). */\n  anchor: Object3D;\n  /** ANIMA pose name ('sit', 'sleep', 'drive', 'cycle', …) or 'run'. */\n  pose: string;\n  /** Optional arms loop ('strum', 'hammer', 'knead'). */\n  loop?: string;\n  /**\n   * Where a character should *stand* before taking the slot — beside the\n   * chair, not on it. Nobody materialises into a seat: they walk here, turn,\n   * then lower. ANIMA's `Interaction.use(slot, { approach: true })` reads it\n   * to stage the sit; steering agents path to it rather than to the anchor.\n   */\n  approach?: Object3D;\n}\n\n/** How a character holds a carryable — structurally ANIMA's `CarryStyle`. */\nexport type CarryStyle = 'crate' | 'tray' | 'shoulder' | 'side';\n\n/**\n * A prop a character can pick up and carry. Structurally identical to ANIMA's\n * `Holdable`, so a SCENA crate drops into `new Carry(rig, loco).pickUp(crate)`\n * with no cross-imports. The object's origin stays at its base (natural for\n * ground placement); `grip` offsets the *hold point* — where it rides in the\n * hands — from that origin.\n */\nexport interface Carryable extends Prop {\n  /** The carry pose the holder adopts. */\n  carry: CarryStyle;\n  /** Hold-point offset from the object's origin (metres). */\n  grip?: { x?: number; y?: number; z?: number };\n}\n\n/**\n * A flat surface on a prop that things can be put down on: a tabletop, a\n * shelf board, the lid of a chest, a windowsill.\n *\n * The anchor sits **on** the surface with +y up, +x along its width and +z\n * along its depth, so `dress` only has to think in two dimensions and the\n * height of whatever it places.\n */\nexport interface PropSurface {\n  /** Free label: 'top', 'shelf', 'sill'. */\n  kind: string;\n  /** Anchor at surface level, a child of the prop. */\n  anchor: Object3D;\n  /** Usable extent along the anchor's local x and z, in metres. */\n  width: number;\n  depth: number;\n}\n\n/**\n * A body of water something can be in, in **world** coordinates.\n *\n * The swimming handshake, and it mirrors `terrain.heightAt` and\n * `ocean.heightAt`: the prop answers questions about the water and ANIMA\n * decides what a body does about it. `depthAt` returns 0 anywhere outside,\n * so \"am I in the water\" needs no separate `contains`.\n *\n * The interesting number is the **depth**, not the surface. Whether a\n * character wades or swims is a decision made against their own height, and\n * a pool with one depth everywhere cannot pose that question at all.\n */\nexport interface WaterBody {\n  /** World Y of the still surface. */\n  readonly surfaceY: number;\n  /** Water depth at a world point, in metres. 0 anywhere outside. */\n  depthAt(x: number, z: number): number;\n  /** Ripple it at a world point — a stroke, a dive, a hand going in. */\n  disturb(x: number, z: number, strength?: number): void;\n}\n\n/** What a prop generator returns: the visual plus gameplay metadata. */\nexport interface Prop {\n  object: Group;\n  /**\n   * Footprint radius for steering/placement, in the prop's local space\n   * (centered at its origin). 0 means walk-through (e.g. grass).\n   */\n  obstacleRadius: number;\n  /** Interaction slots, on props a character can use. */\n  slots?: PropSlot[];\n  /** Flat surfaces things can be set down on — feed these to `dress`. */\n  surfaces?: PropSurface[];\n  /**\n   * Which way up this comes to rest when it is set down on something.\n   *\n   * Props are authored in the orientation they are *used* in, which for a\n   * phone is upright in a hand — put one down as authored and it stands on\n   * its short edge like a domino. `dress` works this out for itself from the\n   * shape (a slab lies down, a candle does not); set this only to override.\n   */\n  rest?: 'upright' | 'flat';\n}\n\n/** Build a surface: an anchor parented into the prop at (x, y, z). */\nexport function createPropSurface(\n  kind: string,\n  parent: Group,\n  x: number,\n  y: number,\n  z: number,\n  width: number,\n  depth: number,\n  rotY = 0\n): PropSurface {\n  const anchor = new Object3D();\n  anchor.name = `surface:${kind}`;\n  anchor.position.set(x, y, z);\n  anchor.rotation.y = rotY;\n  parent.add(anchor);\n  return { kind, anchor, width, depth };\n}\n\n/**\n * A prop several characters use *together* — a dining table, a bench, a\n * game board. Beyond the seats it publishes a **focus**: the thing the\n * occupants attend to. Point every sitter's gaze at it and a row of bodies\n * becomes a group; without it they are strangers who happen to be adjacent.\n */\nexport interface Gathering extends Prop {\n  /** The places, in a stable order — index 0 is the head of the table. */\n  seats: PropSlot[];\n  /** What the occupants look at: table centre, game board, campfire. */\n  focus: Object3D;\n}\n\n/** Build a slot: an anchor Object3D parented into the prop at (x, y, z). */\nexport function createSlot(\n  kind: string,\n  pose: string,\n  parent: Group,\n  x: number,\n  y: number,\n  z: number,\n  rotY = 0,\n  rotX = 0\n): PropSlot {\n  const anchor = new Object3D();\n  anchor.name = `slot:${kind}`;\n  anchor.position.set(x, y, z);\n  anchor.rotation.set(rotX, rotY, 0);\n  parent.add(anchor);\n  return { kind, anchor, pose };\n}\n\n/**\n * Give a slot its standing-room-before: an approach anchor `distance` metres\n * from the seat, facing the same way. The character walks here, turns, and\n * lowers backwards into the slot — which is how sitting actually works.\n *\n * `from` picks the side the character comes at it from, and it must be the\n * side that is *open*. A dining chair is approached from behind (the table\n * is in front of it); a park bench is approached from the front (the\n * backrest is behind it). Get this backwards and characters walk through\n * the furniture to reach their seats.\n */\nexport function addApproach(\n  slot: PropSlot,\n  parent: Group,\n  distance = 0.7,\n  from: 'behind' | 'front' = 'behind'\n): PropSlot {\n  const anchor = new Object3D();\n  anchor.name = `approach:${slot.kind}`;\n  const rotY = slot.anchor.rotation.y;\n  const sign = from === 'front' ? 1 : -1;\n  anchor.position.set(\n    slot.anchor.position.x + Math.sin(rotY) * distance * sign,\n    slot.anchor.position.y,\n    slot.anchor.position.z + Math.cos(rotY) * distance * sign\n  );\n  anchor.rotation.y = rotY;\n  parent.add(anchor);\n  slot.approach = anchor;\n  return slot;\n}\n\n/** Collect world-space obstacles from placed props (call after positioning). */\nexport function collectObstacles(props: Iterable<Prop>): Obstacle[] {\n  const obstacles: Obstacle[] = [];\n  for (const prop of props) {\n    if (prop.obstacleRadius <= 0) continue;\n    prop.object.updateWorldMatrix(true, false);\n    obstacles.push({\n      center: prop.object.getWorldPosition(new Vector3()),\n      radius: prop.obstacleRadius * maxScale(prop.object),\n    });\n  }\n  return obstacles;\n}\n\nfunction maxScale(object: Object3D): number {\n  return Math.max(object.scale.x, object.scale.z);\n}\n","import { Box3, Object3D, Vector3 } from 'three';\nimport { Rng } from './random';\nimport type { Prop, PropSurface } from './types';\n\n/**\n * Placement — putting things where a person would have put them.\n *\n * Prop generators say what a thing *is*. This says where it *goes*, and for\n * decoration that is the larger half of the problem: the difference between\n * a decorated room and an undecorated one is a few meshes, but the\n * difference between a decorated room and a showroom is entirely placement.\n * Three identical frames, centred, evenly spaced and perfectly level is\n * what every hand-placed wall ends up as, and it is instantly readable as\n * generated.\n *\n * ```ts\n * hangOn(room.walls[0], painting, { height: 1.55, seed: 3 });\n * hangGallery(room.walls[1], [a, b, c, d, e], { seed: 7 });\n * ```\n */\n\n/**\n * A surface you can hang things on.\n *\n * Structural, like everything else in this library: anything with an anchor\n * oriented **+z out of the wall, +x along the run, +y up from the floor**\n * works, whether it came from `createRoom`, from `createWallAnchor`, or from\n * a wall the caller built themselves.\n */\nexport interface HangSurface {\n  /** Anchor, already parented into whatever owns the wall. */\n  anchor: Object3D;\n  /** Usable run along the anchor's local x, in metres. */\n  length: number;\n  /** Wall height, in metres. */\n  height: number;\n}\n\n/**\n * Make a hangable surface out of a bare wall: an anchor at (x, y, z) in the\n * parent's space, turned by `rotY` so its +z faces into the room.\n */\nexport function createWallAnchor(\n  parent: Object3D,\n  x: number,\n  y: number,\n  z: number,\n  rotY: number,\n  length: number,\n  height: number\n): HangSurface {\n  const anchor = new Object3D();\n  anchor.name = 'wall';\n  anchor.position.set(x, y, z);\n  anchor.rotation.y = rotY;\n  parent.add(anchor);\n  return { anchor, length, height };\n}\n\nexport interface HangOptions {\n  /**\n   * Height of the item's centre above the floor. Default 1.55 — a shade\n   * above eye level for the centre of the picture, which is where galleries\n   * hang and where a room looks wrong without.\n   */\n  height?: number;\n  /** Offset along the wall from its centre, in metres. Default 0. */\n  along?: number;\n  /**\n   * Maximum tilt, in radians. Default 0.02 (about a degree). **Nothing hangs\n   * level.** This single value is most of the difference between a prop on a\n   * wall and a picture in a room; set 0 only for things actually screwed on,\n   * like a clock or a fixture.\n   */\n  tilt?: number;\n  /** Gap between the wall face and the back of the item. Default 0.004. */\n  standoff?: number;\n  seed?: number;\n}\n\nfunction objectOf(item: Prop | Object3D): Object3D {\n  return item instanceof Object3D ? item : item.object;\n}\n\n/**\n * Hang one thing on a wall. Returns the object placed, already parented.\n *\n * Placement assumes the art's origin is at its own centre with the picture\n * facing +z — the convention every piece in `wallArt` follows — so the only\n * decisions left are how high, how far along, and how crooked.\n */\nexport function hangOn(\n  wall: HangSurface,\n  item: Prop | Object3D,\n  options: HangOptions = {}\n): Object3D {\n  const object = objectOf(item);\n  const rng = new Rng(options.seed ?? 1);\n  const tilt = options.tilt ?? 0.02;\n  object.position.set(\n    options.along ?? 0,\n    options.height ?? 1.55,\n    options.standoff ?? 0.004\n  );\n  // Roll about the view axis: a picture hangs from one point and swings, so\n  // the error is roll, not yaw or pitch. Tilting in the wrong axis pushes a\n  // corner into the plaster and reads as broken rather than as crooked.\n  object.rotation.z = tilt === 0 ? 0 : rng.range(-tilt, tilt);\n  wall.anchor.add(object);\n  return object;\n}\n\nexport interface GalleryOptions extends HangOptions {\n  /** Mean gap between neighbours, in metres. Default 0.1. */\n  gap?: number;\n  /**\n   * How far items stray from the spine line, in metres. Default 0.09. Zero\n   * gives a picture rail; a large value gives a salon hang.\n   */\n  scatter?: number;\n}\n\n/**\n * Hang several things as an arrangement.\n *\n * A wall of pictures is not a row of pictures. What holds a real group\n * together is a **spine** — an invisible horizontal line that most of the\n * pieces touch with either their centre, their top or their bottom edge —\n * and what stops it looking mechanical is that they touch it in different\n * ways and the gaps are uneven.\n *\n * Returns the items it actually placed. If the wall is not long enough for\n * all of them the overflow is **left off and reported by the shorter\n * return**, rather than being crammed in or silently overlapped.\n */\nexport function hangGallery(\n  wall: HangSurface,\n  items: Array<Prop | Object3D>,\n  options: GalleryOptions = {}\n): Object3D[] {\n  const rng = new Rng(options.seed ?? 1);\n  const gap = options.gap ?? 0.1;\n  const scatter = options.scatter ?? 0.09;\n  const spine = options.height ?? 1.55;\n  const tilt = options.tilt ?? 0.02;\n\n  // Measure each item. Props from `wallArt` publish width/height; anything\n  // else gets measured from its bounding box, so a caller's own mesh works.\n  const sized = items.map((item) => {\n    const object = objectOf(item);\n    const w = (item as { width?: number }).width;\n    const h = (item as { height?: number }).height;\n    if (typeof w === 'number' && typeof h === 'number') return { object, w, h };\n    const box = new Vector3();\n    object.updateMatrixWorld(true);\n    new Box3().setFromObject(object).getSize(box);\n    return { object, w: box.x || 0.3, h: box.y || 0.3 };\n  });\n\n  // Uneven gaps, and lay the run out before committing to it so it can be\n  // centred on the wall rather than starting at one end.\n  const gaps = sized.map(() => gap * rng.range(0.6, 1.5));\n  const placed: Object3D[] = [];\n  let total = 0;\n  let fits = 0;\n  for (let i = 0; i < sized.length; i++) {\n    const next = total + sized[i].w + (i > 0 ? gaps[i] : 0);\n    if (next > wall.length) break;\n    total = next;\n    fits = i + 1;\n  }\n\n  let x = -total / 2;\n  for (let i = 0; i < fits; i++) {\n    const { object, w, h } = sized[i];\n    if (i > 0) x += gaps[i];\n    // Three ways to relate to the spine — centred on it, hung from it, or\n    // standing on it. Mixing them is what makes a group look composed\n    // instead of aligned.\n    const relation = rng.next();\n    let y = spine;\n    if (relation > 0.72) y = spine + h / 2 - rng.range(0.0, 0.04);\n    else if (relation > 0.44) y = spine - h / 2 + rng.range(0.0, 0.04);\n    else y = spine + rng.range(-scatter, scatter);\n\n    object.position.set(x + w / 2, y, options.standoff ?? 0.004);\n    object.rotation.z = tilt === 0 ? 0 : rng.range(-tilt, tilt);\n    wall.anchor.add(object);\n    placed.push(object);\n    x += w;\n  }\n  return placed;\n}\n\n// --- putting things down -------------------------------------------------\n\nexport interface PlaceOptions {\n  /** Position along the surface's local x, from its centre. Default 0. */\n  along?: number;\n  /** Position along the surface's local z. Default 0. */\n  across?: number;\n  /** Yaw, in radians. Default 0. */\n  turn?: number;\n}\n\n/** The measured footprint of an object, and where its origin sits in it. */\ninterface Footprint {\n  object: Object3D;\n  /** Extent on each axis. */\n  w: number;\n  d: number;\n  h: number;\n  /** Offset from the object's origin to the centre of its footprint. */\n  cx: number;\n  cz: number;\n  /** How far below the origin the object reaches — what it must be lifted by. */\n  drop: number;\n  /** Tilt that lays the thing down, if it is not something that stands. */\n  tiltX: number;\n  tiltZ: number;\n}\n\n/**\n * Which way up does this thing come to rest?\n *\n * Props are authored in the orientation they are *used* in, and for a phone\n * or a tablet that is upright, in a hand. Set one down without thinking and\n * it stands on its short edge like a domino, which is what the first version\n * of this did to a whole tabletop.\n *\n * A **slab** — one dimension far smaller than the other two, and that thin\n * dimension currently horizontal — is a thing that lies down. A candle is\n * tall and thin too but it is not a slab, so it stays standing; a framed\n * photo has a strut, which thickens it past the threshold, so it stays\n * standing as well. Props can override with `rest`.\n */\nfunction restOf(size: Vector3, rest: string | undefined): { x: number; z: number } {\n  if (rest === 'upright') return { x: 0, z: 0 };\n  const dims = [size.x, size.y, size.z].sort((a, b) => a - b);\n  const [min, mid] = dims;\n  if (rest !== 'flat' && min > mid * 0.3) return { x: 0, z: 0 };\n  // Turn whichever axis is thinnest to point up.\n  if (size.y === min) return { x: 0, z: 0 }; // already lying down\n  if (size.z === min) return { x: -Math.PI / 2, z: 0 };\n  return { x: 0, z: Math.PI / 2 };\n}\n\nfunction measure(item: Prop | Object3D): Footprint {\n  const object = objectOf(item);\n  // Measure in the object's own space, with any previous placement undone —\n  // otherwise dressing the same surface twice measures the first placement's\n  // rotation into the second's footprint.\n  object.position.set(0, 0, 0);\n  object.rotation.set(0, 0, 0);\n  object.updateMatrixWorld(true);\n  const upright = new Box3().setFromObject(object).getSize(new Vector3());\n  const tilt = restOf(upright, (item as { rest?: string }).rest);\n\n  // Re-measure once it is the way up it will actually sit, or the footprint\n  // describes an object nobody will ever see.\n  object.rotation.order = 'YXZ';\n  object.rotation.set(tilt.x, 0, tilt.z);\n  object.updateMatrixWorld(true);\n  const box = new Box3().setFromObject(object);\n  const size = box.getSize(new Vector3());\n  const centre = box.getCenter(new Vector3());\n  return {\n    object,\n    w: size.x,\n    d: size.z,\n    h: size.y,\n    cx: centre.x,\n    cz: centre.z,\n    drop: box.min.y,\n    tiltX: tilt.x,\n    tiltZ: tilt.z,\n  };\n}\n\n/**\n * Put one thing down on a surface, at a position you choose.\n *\n * The object is **seated on** the surface rather than centred on it: whatever\n * its own origin convention, its lowest point ends up at surface level. Props\n * in this kit mostly have their origin at their base, but not all of them do,\n * and a mug sunk half way into a tabletop is the same defect every time.\n */\nexport function placeOn(\n  surface: PropSurface,\n  item: Prop | Object3D,\n  options: PlaceOptions = {}\n): Object3D {\n  const fp = measure(item);\n  const turn = options.turn ?? 0;\n  seat(surface, fp, options.along ?? 0, options.across ?? 0, turn);\n  return fp.object;\n}\n\n/** Place a measured item, correcting for its origin and its yaw. */\nfunction seat(\n  surface: PropSurface,\n  fp: Footprint,\n  along: number,\n  across: number,\n  turn: number\n): void {\n  const cos = Math.cos(turn);\n  const sin = Math.sin(turn);\n  // The footprint centre moves when the object turns about its own origin,\n  // so the correction has to be rotated too. YXZ order so the yaw is applied\n  // last, about world up, whatever tilt lays the object down.\n  fp.object.rotation.order = 'YXZ';\n  fp.object.rotation.set(fp.tiltX, turn, fp.tiltZ);\n  fp.object.position.set(\n    along - (fp.cx * cos + fp.cz * sin),\n    -fp.drop,\n    across - (-fp.cx * sin + fp.cz * cos)\n  );\n  surface.anchor.add(fp.object);\n}\n\n/** Axis-aligned extent of a w×d footprint turned by `turn`. */\nfunction turnedExtent(w: number, d: number, turn: number): { w: number; d: number } {\n  const c = Math.abs(Math.cos(turn));\n  const s = Math.abs(Math.sin(turn));\n  return { w: w * c + d * s, d: w * s + d * c };\n}\n\nexport interface DressOptions {\n  /**\n   * How full the surface gets, 0–1. Default 0.55. This is a target, not a\n   * promise — items that will not fit are left off.\n   */\n  density?: number;\n  /** Clear border kept around the edge, in metres. Default 0.03. */\n  margin?: number;\n  /** Minimum gap between neighbours, in metres. Default 0.02. */\n  gap?: number;\n  /**\n   * Maximum yaw off square, in radians. Default 0.4. Nobody sets a mug down\n   * aligned to the table, and a surface of perfectly square objects is the\n   * clearest possible tell.\n   */\n  turn?: number;\n  /**\n   * How tightly things cluster, 0–1. Default 0.6. At 0 they spread evenly\n   * across the surface; at 1 they pile into one region and leave the rest\n   * clear — which is what real surfaces look like.\n   */\n  cluster?: number;\n  seed?: number;\n}\n\n/**\n * Dress a surface: put a set of things down on it the way a person would.\n *\n * The naive version — space them evenly, centred, square — is what every\n * hand-placed tabletop ends up as, and it reads as generated instantly. Four\n * things fix it, and they are the whole of this function:\n *\n * - **Tall things go behind.** Sorted by height, and the taller an item is\n *   the further back it is aimed. Otherwise a candlestick lands in front of\n *   a bowl and hides it.\n * - **Things cluster.** Positions are drawn around a seeded centre of\n *   gravity rather than uniformly, so one part of the surface is busy and\n *   another is clear. An even spread is a display of merchandise.\n * - **The middle stays emptier.** Items are biased toward the back and front\n *   edges, because the middle of a table is where you put your plate.\n * - **Nothing is square, and nothing overlaps.** Small random yaw, and\n *   placement is rejection-sampled against what is already down.\n *\n * ```ts\n * dress(table.surfaces[0], [mug, bowl, candle, book], { seed: 3 });\n * ```\n *\n * Returns what it actually placed. Items that could not be fitted are left\n * unparented and simply missing from the result, rather than crammed in or\n * silently overlapped — check `placed.length` if you care.\n */\nexport function dress(\n  surface: PropSurface,\n  items: Array<Prop | Object3D>,\n  options: DressOptions = {}\n): Object3D[] {\n  const rng = new Rng(options.seed ?? 1);\n  const margin = options.margin ?? 0.03;\n  const gap = options.gap ?? 0.02;\n  const maxTurn = options.turn ?? 0.4;\n  const cluster = Math.min(1, Math.max(0, options.cluster ?? 0.6));\n  const density = Math.min(1, Math.max(0, options.density ?? 0.55));\n\n  const halfW = surface.width / 2 - margin;\n  const halfD = surface.depth / 2 - margin;\n  if (halfW <= 0 || halfD <= 0) return [];\n\n  // Tallest first: they claim the back, and everything shorter arranges\n  // itself around what is already there.\n  const measured = items.map(measure);\n  const order = measured.slice().sort((a, b) => b.h - a.h);\n  const tallest = Math.max(...measured.map((m) => m.h), 1e-4);\n\n  // The busy end. Off-centre on purpose — a cluster centred on the middle of\n  // the surface is just a symmetrical arrangement with extra steps.\n  const focus = rng.range(-0.55, 0.55) * halfW;\n  const spread = halfW * (0.9 - cluster * 0.62);\n\n  const taken: Array<{ x: number; z: number; w: number; d: number }> = [];\n  const placed: Object3D[] = [];\n  // Area budget: stop once the surface is as full as asked for.\n  const budget = surface.width * surface.depth * density;\n  let used = 0;\n\n  for (const fp of order) {\n    if (used + fp.w * fp.d > budget) continue;\n    const backness = Math.min(1, fp.h / tallest);\n    let seated = false;\n\n    for (let attempt = 0; attempt < 24 && !seated; attempt++) {\n      const turn = rng.range(-maxTurn, maxTurn);\n      const ext = turnedExtent(fp.w, fp.d, turn);\n      if (ext.w > halfW * 2 || ext.d > halfD * 2) break; // never going to fit\n\n      // Along: clustered around the focus. Three uniforms summed is close\n      // enough to a bell, and unlike a uniform draw it actually clumps.\n      const bell = rng.next() + rng.next() + rng.next() - 1.5;\n      // Widen GRADUALLY around the focus as attempts fail, so a crowded\n      // surface still fills. Falling back to a uniform draw instead — the\n      // first version — makes a tight cluster spread out MORE than a loose\n      // one, because a tight cluster is what fails often enough to trigger\n      // the fallback.\n      let x = focus + bell * spread * (1 + attempt * 0.22);\n      const limitX = halfW - ext.w / 2;\n      if (limitX < 0) break;\n      x = Math.max(-limitX, Math.min(limitX, x));\n\n      // Across: a BIAS toward the back for tall things, not a target.\n      //\n      // Aiming each item at a depth computed from its height puts everything\n      // of similar height at the same z, and a set of tabletop props are all\n      // of similar height — so the whole arrangement came out as a straight\n      // line across the middle of the table, which is the exact showroom\n      // failure this function exists to avoid. Sample the full depth and\n      // bend the sample, so the bias shows up across a group without any\n      // single item being pinned.\n      const limitZ = halfD - ext.d / 2;\n      if (limitZ < 0) break;\n      const aim = (0.25 + backness * 0.6) * 2 - 1; // -1 front .. +1 back\n      const z = (rng.range(-1, 1) * 0.62 + aim * 0.38) * limitZ;\n\n      const clash = taken.some(\n        (t) =>\n          Math.abs(t.x - x) < (t.w + ext.w) / 2 + gap &&\n          Math.abs(t.z - z) < (t.d + ext.d) / 2 + gap\n      );\n      if (clash) continue;\n\n      seat(surface, fp, x, z, turn);\n      taken.push({ x, z, w: ext.w, d: ext.d });\n      placed.push(fp.object);\n      used += fp.w * fp.d;\n      seated = true;\n    }\n\n    if (seated) continue;\n\n    // Random sampling cannot find a narrow gap, and once a couple of big\n    // things are down a shallow surface is effectively one-dimensional:\n    // nothing can pass a 48 cm basket within the depth of a 90 cm table. A\n    // phone with plenty of room in the corner was missing it 24 times out of\n    // 24. Sweep a coarse grid in a shuffled order and take the first opening,\n    // so small things reliably find the space that is genuinely there.\n    const turn = rng.range(-maxTurn, maxTurn);\n    const ext = turnedExtent(fp.w, fp.d, turn);\n    const limitX = halfW - ext.w / 2;\n    const limitZ = halfD - ext.d / 2;\n    if (limitX < 0 || limitZ < 0) continue;\n\n    const cells: Array<[number, number]> = [];\n    const nx = 11;\n    const nz = 7;\n    for (let i = 0; i < nx; i++) {\n      for (let j = 0; j < nz; j++) {\n        cells.push([((i / (nx - 1)) * 2 - 1) * limitX, ((j / (nz - 1)) * 2 - 1) * limitZ]);\n      }\n    }\n    // Shuffled, and jittered on use, so a fallback placement does not read as\n    // a grid.\n    for (let i = cells.length - 1; i > 0; i--) {\n      const j = Math.floor(rng.next() * (i + 1));\n      const swap = cells[i];\n      cells[i] = cells[j];\n      cells[j] = swap;\n    }\n    for (const [gx, gz] of cells) {\n      const x = Math.max(-limitX, Math.min(limitX, gx + rng.range(-0.02, 0.02)));\n      const z = Math.max(-limitZ, Math.min(limitZ, gz + rng.range(-0.02, 0.02)));\n      const clash = taken.some(\n        (t) =>\n          Math.abs(t.x - x) < (t.w + ext.w) / 2 + gap &&\n          Math.abs(t.z - z) < (t.d + ext.d) / 2 + gap\n      );\n      if (clash) continue;\n      seat(surface, fp, x, z, turn);\n      taken.push({ x, z, w: ext.w, d: ext.d });\n      placed.push(fp.object);\n      used += fp.w * fp.d;\n      break;\n    }\n  }\n  return placed;\n}\n"],"mappings":"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","names":["import_three","turn","ext","limitX","limitZ"]}