import { e as PropSurface, c as Prop } from './types-C_yucwmh.cjs'; export { C as CarryStyle, a as Carryable, D as DEFAULT_PALETTE, G as Gathering, O as Obstacle, P as PALETTES, b as Palette, d as PropSlot, R as Rng, W as WaterBody, f as addApproach, g as collectObstacles, h as createPropSurface, i as createSlot, j as fractalNoise2, k as hash2, v as valueNoise2 } from './types-C_yucwmh.cjs'; import { Object3D } from 'three'; /** * Placement — putting things where a person would have put them. * * Prop generators say what a thing *is*. This says where it *goes*, and for * decoration that is the larger half of the problem: the difference between * a decorated room and an undecorated one is a few meshes, but the * difference between a decorated room and a showroom is entirely placement. * Three identical frames, centred, evenly spaced and perfectly level is * what every hand-placed wall ends up as, and it is instantly readable as * generated. * * ```ts * hangOn(room.walls[0], painting, { height: 1.55, seed: 3 }); * hangGallery(room.walls[1], [a, b, c, d, e], { seed: 7 }); * ``` */ /** * A surface you can hang things on. * * Structural, like everything else in this library: anything with an anchor * oriented **+z out of the wall, +x along the run, +y up from the floor** * works, whether it came from `createRoom`, from `createWallAnchor`, or from * a wall the caller built themselves. */ interface HangSurface { /** Anchor, already parented into whatever owns the wall. */ anchor: Object3D; /** Usable run along the anchor's local x, in metres. */ length: number; /** Wall height, in metres. */ height: number; } /** * Make a hangable surface out of a bare wall: an anchor at (x, y, z) in the * parent's space, turned by `rotY` so its +z faces into the room. */ declare function createWallAnchor(parent: Object3D, x: number, y: number, z: number, rotY: number, length: number, height: number): HangSurface; interface HangOptions { /** * Height of the item's centre above the floor. Default 1.55 — a shade * above eye level for the centre of the picture, which is where galleries * hang and where a room looks wrong without. */ height?: number; /** Offset along the wall from its centre, in metres. Default 0. */ along?: number; /** * Maximum tilt, in radians. Default 0.02 (about a degree). **Nothing hangs * level.** This single value is most of the difference between a prop on a * wall and a picture in a room; set 0 only for things actually screwed on, * like a clock or a fixture. */ tilt?: number; /** Gap between the wall face and the back of the item. Default 0.004. */ standoff?: number; seed?: number; } /** * Hang one thing on a wall. Returns the object placed, already parented. * * Placement assumes the art's origin is at its own centre with the picture * facing +z — the convention every piece in `wallArt` follows — so the only * decisions left are how high, how far along, and how crooked. */ declare function hangOn(wall: HangSurface, item: Prop | Object3D, options?: HangOptions): Object3D; interface GalleryOptions extends HangOptions { /** Mean gap between neighbours, in metres. Default 0.1. */ gap?: number; /** * How far items stray from the spine line, in metres. Default 0.09. Zero * gives a picture rail; a large value gives a salon hang. */ scatter?: number; } /** * Hang several things as an arrangement. * * A wall of pictures is not a row of pictures. What holds a real group * together is a **spine** — an invisible horizontal line that most of the * pieces touch with either their centre, their top or their bottom edge — * and what stops it looking mechanical is that they touch it in different * ways and the gaps are uneven. * * Returns the items it actually placed. If the wall is not long enough for * all of them the overflow is **left off and reported by the shorter * return**, rather than being crammed in or silently overlapped. */ declare function hangGallery(wall: HangSurface, items: Array, options?: GalleryOptions): Object3D[]; interface PlaceOptions { /** Position along the surface's local x, from its centre. Default 0. */ along?: number; /** Position along the surface's local z. Default 0. */ across?: number; /** Yaw, in radians. Default 0. */ turn?: number; } /** * Put one thing down on a surface, at a position you choose. * * The object is **seated on** the surface rather than centred on it: whatever * its own origin convention, its lowest point ends up at surface level. Props * in this kit mostly have their origin at their base, but not all of them do, * and a mug sunk half way into a tabletop is the same defect every time. */ declare function placeOn(surface: PropSurface, item: Prop | Object3D, options?: PlaceOptions): Object3D; interface DressOptions { /** * How full the surface gets, 0–1. Default 0.55. This is a target, not a * promise — items that will not fit are left off. */ density?: number; /** Clear border kept around the edge, in metres. Default 0.03. */ margin?: number; /** Minimum gap between neighbours, in metres. Default 0.02. */ gap?: number; /** * Maximum yaw off square, in radians. Default 0.4. Nobody sets a mug down * aligned to the table, and a surface of perfectly square objects is the * clearest possible tell. */ turn?: number; /** * How tightly things cluster, 0–1. Default 0.6. At 0 they spread evenly * across the surface; at 1 they pile into one region and leave the rest * clear — which is what real surfaces look like. */ cluster?: number; seed?: number; } /** * Dress a surface: put a set of things down on it the way a person would. * * The naive version — space them evenly, centred, square — is what every * hand-placed tabletop ends up as, and it reads as generated instantly. Four * things fix it, and they are the whole of this function: * * - **Tall things go behind.** Sorted by height, and the taller an item is * the further back it is aimed. Otherwise a candlestick lands in front of * a bowl and hides it. * - **Things cluster.** Positions are drawn around a seeded centre of * gravity rather than uniformly, so one part of the surface is busy and * another is clear. An even spread is a display of merchandise. * - **The middle stays emptier.** Items are biased toward the back and front * edges, because the middle of a table is where you put your plate. * - **Nothing is square, and nothing overlaps.** Small random yaw, and * placement is rejection-sampled against what is already down. * * ```ts * dress(table.surfaces[0], [mug, bowl, candle, book], { seed: 3 }); * ``` * * Returns what it actually placed. Items that could not be fitted are left * unparented and simply missing from the result, rather than crammed in or * silently overlapped — check `placed.length` if you care. */ declare function dress(surface: PropSurface, items: Array, options?: DressOptions): Object3D[]; export { type DressOptions, type GalleryOptions, type HangOptions, type HangSurface, type PlaceOptions, Prop, PropSurface, createWallAnchor, dress, hangGallery, hangOn, placeOn };