@adatechnology/game-urban-three 0.2.9 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-XUITKOBO.js +998 -0
- package/dist/chunk-XUITKOBO.js.map +1 -0
- package/dist/index.d.ts +34 -138
- package/dist/index.global.js +2550 -179
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +15 -940
- package/dist/index.js.map +1 -1
- package/dist/testing-ZS5dhCJM.d.ts +145 -0
- package/dist/testing.d.ts +6 -0
- package/dist/testing.js +19 -0
- package/dist/testing.js.map +1 -0
- package/package.json +13 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/test-area/module.ts","../src/draw.ts","../src/rounded-box.ts","../src/text.ts","../src/resolvers.ts","../src/test-area/scenarios.ts","../src/test-area/text.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport { isLightBudget } from '@adatechnology/game-render-three'\nimport type { LightBudget } from '@adatechnology/game-render-three'\nimport { discardObject3D } from '@adatechnology/game-shapes-three'\nimport type { BenchChange, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ModuleScenario, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { createPlantProvider, createUrban, createVehicleProvider, SAMPLE_CELLS } from '@adatechnology/game-urban'\nimport type { Locale, Providers, TerrainOptions, UrbanBuilder, UrbanKit, UrbanOptions } from '@adatechnology/game-urban'\nimport { shapeGeometries } from '@adatechnology/game-shapes-three'\n\nimport { createUrbanThree } from '../draw'\nimport type { DrawnUrban } from '../draw'\nimport { createPlantResolver, createVehicleResolver } from '../resolvers'\nimport type { PlacementResolver } from '../resolvers'\nimport { createScenarios } from './scenarios'\nimport { fill, TEXT } from './text'\nimport type { UrbanContext, UrbanTestOptions } from './types'\nimport type { CanvasFactory } from '../text'\n\nexport const URBAN_AREA_ID = 'urban'\n\n/** The default terrain patch of the area: a rolling plain 96 m wide with a river across it and a round lake. A game passes its own through `terrain`. */\nexport const DEFAULT_TEST_TERRAIN: TerrainOptions = {\n world: { size: 96, scale: 1, origin: -48, segments: 48 },\n base: {\n level: 1.2,\n waves: [\n { kind: 'product', x: ['sin', 0.09], y: ['cos', 0.07], amplitude: 1.1 },\n { kind: 'diagonal', kx: 0.05, ky: 0.04, amplitude: 0.5 },\n ],\n },\n layers: [],\n flatten: [],\n rivers: [{ id: 'river', points: [[-48, -30], [-20, -24], [10, -30], [48, -22]], width: [3, 9], bed: { fixed: -1.2 } }],\n lakes: [{ id: 'lake', center: [24, 24], radius: [12, 12], level: -0.9, edge: [0.55, 1], reach: 1.4 }],\n forest: { zones: [{ mask: [{ axis: 'x', from: -48, to: -20, fullUntil: -40 }] }] },\n colors: [\n { kind: 'below', height: 0.1, color: 0x6b7a5a },\n { kind: 'forest', above: 0.5, color: 0x3e5a35 },\n ],\n fields: { colors: [0x7a8c55, 0x8a9a5e, 0x6f8450], cell: [8, 8] },\n water: { level: -0.35, color: 0x2b4452, roughness: 0.3, metalness: 0.25 },\n}\n\nconst FLOOR_Y = 0\nconst POLE_ROW_Z = -26\nconst POLE_GAP = 6\nconst SHEET_SHIFT_Z = -200\nconst VIEW_FAR = 600\nconst GRID = { block: 36, count: 2, width: 10 }\nconst LAMP_SHARES: Record<string, number | undefined> = { pattern: undefined, all: 1, half: 0.5, none: 0 }\n\ntype Three = typeof THREE_NS\ntype Placed = { root: THREE_NS.Object3D; drawn: DrawnUrban }\n/** A mesh, as three marks one (`isMesh`). */\nconst isMesh = (o: THREE_NS.Object3D): o is THREE_NS.Mesh => (o as THREE_NS.Mesh).isMesh === true\n\n/**\n * The urban test area as a `TestableModule`: the five poles of the Galeria in a row, a street grid with a filled block, a patch of terrain and the ten neighbourhoods of the\n * sample sheet in its cells, each drawn by the kit and `game-urban-three` (so a game that patches the catalogues sees its own). The bench draws any neighbourhood in front of the player with\n * a seed, a share of lamps on, a light budget and, when asked, the vehicles of the fleet and the species of the region; its layers show the reach of the real lights and the box of each sample.\n */\nexport function createUrbanTestModule(options: UrbanTestOptions = {}): TestableModule<UrbanContext> & { readonly placed: ReadonlyMap<string, unknown>; tick(t: number): void; readonly itemIds: readonly string[] } {\n const locale: Locale = (options.locale ?? 'pt-BR').toLowerCase().startsWith('en') ? 'en' : 'pt-BR'\n const text = TEXT[locale] as (typeof TEXT)[string]\n const terrain = options.terrain ?? DEFAULT_TEST_TERRAIN\n const seed = options.seed ?? 7\n const benchOrigin = options.benchOrigin ?? [0, -60]\n const settings = { pattern: 'downtown', seed, lamps: 'pattern', budget: 16, providers: 'none' }\n let host: ModuleHost | null = null\n let three: Three | null = null\n let clock = 0\n let helpersShown = ''\n let bench: (Placed & { plan: ReturnType<ReturnType<UrbanKit['neighbourhoods']['get']>['compose']> }) | null = null\n const placed = new Map<string, Placed>()\n let helpers: THREE_NS.Object3D[] = []\n const resolvers: { plant?: PlacementResolver; vehicle?: PlacementResolver } = {}\n\n const baseKit = createUrban(options.urban)\n const poleIds = baseKit.poles.ids()\n const patternIds = baseKit.neighbourhoods.ids()\n const itemIds = [...poleIds.map((id) => `pole_${id}`), 'street_grid', 'terrain_patch', ...patternIds]\n\n const kitWith = (overrides: { lamps?: string; budget?: number } = {}): UrbanKit => {\n const share = LAMP_SHARES[overrides.lamps ?? 'pattern']\n const urban: UrbanOptions = options.urban ?? {}\n const patch = share === undefined ? urban.patch : { ...urban.patch, neighbourhoods: { ...urban.patch?.neighbourhoods, ...Object.fromEntries(patternIds.map((id) => [id, { ...(urban.patch?.neighbourhoods?.[id] ?? {}), lit: share }])) } }\n return createUrban({ ...urban, ...(patch ? { patch } : {}), lights: { budget: overrides.budget ?? urban.lights?.budget } })\n }\n\n const resolversFor = (THREE: Three): { plant?: PlacementResolver; vehicle?: PlacementResolver } => {\n if (!resolvers.plant) resolvers.plant = createPlantResolver(THREE, { lod: 1, ...(options.plantSpec ? { toSpec: options.plantSpec } : {}) })\n if (!resolvers.vehicle && options.vehicles) resolvers.vehicle = createVehicleResolver(options.vehicles(THREE), { quality: 'lite' })\n return resolvers\n }\n const providersOf = (choice: string): Providers => {\n const providers: Providers = {}\n if (choice === 'plants' || choice === 'both') providers.plant = options.providers?.plant ?? createPlantProvider()\n if ((choice === 'vehicles' || choice === 'both') && options.vehicles) providers.vehicle = options.providers?.vehicle ?? createVehicleProvider()\n return providers\n }\n\n /** The room's light budget, when it lends one: the lights of what is drawn become its sources. */\n const lightsOption = (): { lights?: LightBudget } => (isLightBudget(host?.lights) ? { lights: host.lights } : {})\n\n const draw = (THREE: Three, build: (b: UrbanBuilder, kit: UrbanKit) => void, kit: UrbanKit, buildSeed: number): Placed => {\n const b = kit.builder({ seed: buildSeed })\n build(b, kit)\n const document = options.document ?? (globalThis as unknown as { document?: CanvasFactory }).document\n const drawn = createUrbanThree(THREE, { ...(document ? { document } : {}), resolvers: resolversFor(THREE), ...lightsOption() }).draw(b.scene())\n return { root: drawn.root, drawn }\n }\n\n const sample = (THREE: Three, key: string): Placed => {\n const kit = kitWith()\n if (key.startsWith('pole_')) return draw(THREE, (b, k) => k.poles.get(key.slice(5)).build(b, { x: 0, z: 0 }), kit, seed)\n if (key === 'street_grid') {\n return draw(THREE, (b, k) => {\n k.streets.grid(b, GRID)\n const inner = GRID.block - GRID.width\n k.block.fill(b, { cx: GRID.block / 2, cz: GRID.block / 2, size: inner - 4, minHeight: 10, maxHeight: 40, k: 3 })\n }, kit, seed)\n }\n if (key === 'terrain_patch') return draw(THREE, (b, k) => k.drawTerrain(b, k.terrain(terrain)), kit, seed)\n return draw(THREE, (b, k) => { k.neighbourhoods.get(key).compose(b, { x: 0, z: 0 }, { locale }) }, kit, seed)\n }\n\n const item = (id: string): TestableItem => ({\n id,\n name: text.items[id] ?? id,\n movable: false,\n build: (THREE: unknown) => {\n three = THREE as Three // the room hands its three.js namespace\n const made = sample(three, id)\n made.root.userData.urbanItem = id\n placed.set(made.root.uuid, made)\n return made.root\n },\n spec: (root: unknown) => {\n // an urban sample is scenery: one anchored slab of concrete as large as the sample, so the room has a body to put it on and a box to aim at\n const THREE_ = three as Three // build() ran before spec()\n const box = new THREE_.Box3().setFromObject(root as never)\n const size = box.getSize(new THREE_.Vector3())\n const centre = box.getCenter(new THREE_.Vector3())\n return { name: id, tags: ['structure'], parts: [{ id: 'ground', material: 'concrete', shape: { kind: 'box', size: [Math.max(size.x, 0.1), Math.max(size.y, 0.1), Math.max(size.z, 0.1)] }, position: [centre.x, centre.y, centre.z], anchored: true }] }\n },\n })\n\n // ---- the bench ----------------------------------------------------------------------------------------------------------------------------\n const clearBench = (): void => {\n if (!bench) return\n bench.drawn.dispose()\n bench = null\n }\n const countObjects = (root: THREE_NS.Object3D): number => {\n let n = 0\n root.traverse(() => n++)\n return n\n }\n const composeBench = (): void => {\n if (!host || !three) return\n clearBench()\n const kit = kitWith({ lamps: settings.lamps, budget: settings.budget })\n if ((settings.providers === 'vehicles' || settings.providers === 'both') && !options.vehicles) host.log(text.log.no_vehicles)\n const b = kit.builder({ seed: settings.seed })\n const made = kit.neighbourhoods.get(settings.pattern).compose(b, { x: 0, z: 0 }, { locale, providers: providersOf(settings.providers) })\n const document = options.document ?? (globalThis as unknown as { document?: CanvasFactory }).document\n const drawn = createUrbanThree(three, { ...(document ? { document } : {}), resolvers: resolversFor(three), ...lightsOption() }).draw(b.scene())\n drawn.root.position.set(benchOrigin[0], FLOOR_Y, benchOrigin[1])\n ;(host.scene as THREE_NS.Object3D).add(drawn.root) // the host's three.js scene\n bench = { root: drawn.root, drawn, plan: made }\n lightsLeft = b.lights.left\n host.log(fill(text.log.composed, settings.pattern, settings.seed, countObjects(drawn.root), drawn.lights.length), { pattern: settings.pattern, seed: settings.seed })\n helpersShown = ''\n }\n let lightsLeft = settings.budget\n const onChange = (change: BenchChange): void => {\n if (change.kind === 'layer') return refreshLayers()\n if (change.kind === 'action') {\n if (change.id === 'compose') composeBench()\n else if (change.id === 'clear') {\n clearBench()\n host?.log(text.log.cleared)\n }\n return\n }\n switch (change.id) {\n case 'pattern': settings.pattern = String(change.value); if (bench) composeBench(); break\n case 'seed': settings.seed = Number(change.value); if (bench) composeBench(); break\n case 'lamps': settings.lamps = String(change.value); if (bench) composeBench(); break\n case 'budget': settings.budget = Number(change.value); if (bench) composeBench(); break\n case 'providers': settings.providers = String(change.value); if (bench) composeBench(); break\n default: break\n }\n }\n\n // ---- the layers -----------------------------------------------------------------------------------------------------------------------------\n // the throwaway builds of the host's contract checks are never added to a scene and do not count\n const roots = (): Placed[] => [...[...placed.values()].filter((entry) => entry.root.parent), ...(bench ? [bench] : [])]\n const clearHelpers = (): void => {\n discardObject3D(helpers)\n helpers = []\n helpersShown = ''\n }\n const boxKey = (): string => `${host?.bench?.layer('light_radius')}|${host?.bench?.layer('bounds')}|${roots().length}|${bench ? bench.root.uuid : ''}`\n const refreshLayers = (): void => {\n if (!host?.bench || !three) return\n clearHelpers()\n const mark = (parent: THREE_NS.Object3D, helper: THREE_NS.Object3D): void => {\n helper.userData.helper = true\n parent.add(helper)\n helpers.push(helper)\n }\n for (const entry of roots()) {\n if (!entry.root.parent) continue\n entry.root.updateMatrixWorld(true)\n if (host.bench.layer('bounds')) {\n const box = new three.Box3().setFromObject(entry.root)\n const inverse = new three.Matrix4().copy(entry.root.matrixWorld).invert()\n box.applyMatrix4(inverse)\n mark(entry.root, new three.Box3Helper(box, 0x66ccff))\n }\n if (host.bench.layer('light_radius')) {\n for (const lamp of entry.drawn.lights) {\n // a lamp drawn through the budget is its bulb; one drawn as a real light is the light\n const light = 'bulb' in lamp ? { node: lamp.bulb, distance: lamp.part.distance, color: lamp.part.color } : lamp.isLight ? { node: lamp, distance: lamp.distance, color: lamp.color } : null\n if (!light) continue\n const reach = new three.Mesh(new (shapeGeometries(three)).SphereGeometry(Math.min(light.distance || 10, 60), 14, 8), new three.MeshBasicMaterial({ color: light.color ?? 0xffcc66, wireframe: true, transparent: true, opacity: 0.25 }))\n reach.position.copy(light.node.position)\n mark(light.node.parent ?? entry.root, reach)\n }\n }\n }\n helpersShown = boxKey()\n }\n\n const frame = (dt: number): void => {\n clock += dt\n for (const entry of roots()) entry.drawn.animate(clock)\n for (const [id, entry] of placed) {\n if (entry.root.parent) continue\n // the budget follows each lamp's bulb: a source left behind keeps the whole scene (signs, canvases) alive\n for (const lamp of entry.drawn.lights) if ('source' in lamp) lamp.source.remove()\n placed.delete(id)\n }\n if (host?.bench && boxKey() !== helpersShown && (host.bench.layer('light_radius') || host.bench.layer('bounds') || helpersShown !== '')) refreshLayers()\n }\n\n const count = (): { drawCalls: number; triangles: number; lights: number; instances: number } => {\n let drawCalls = 0\n let triangles = 0\n let lights = 0\n let instances = 0\n for (const entry of roots()) {\n entry.root.traverse((o) => {\n if ((o as THREE_NS.Light).isLight) lights += 1\n if (!isMesh(o) || o.userData.helper) return\n for (let p: THREE_NS.Object3D | null = o; p; p = p.parent) if (p.visible === false) return\n drawCalls += 1\n const instanced = (o as THREE_NS.InstancedMesh).isInstancedMesh === true\n if (instanced) instances += (o as THREE_NS.InstancedMesh).count\n const g = o.geometry\n const perInstance = (g.index ? g.index.count : g.attributes.position.count) / 3\n triangles += perInstance * (instanced ? (o as THREE_NS.InstancedMesh).count : 1)\n })\n // lamps drawn through the budget are no lights of the scene: they count as the lights they stand for\n lights += entry.drawn.lights.filter((lamp) => 'source' in lamp).length\n }\n return { drawCalls, triangles: Math.round(triangles), lights, instances }\n }\n\n // ---- the area ------------------------------------------------------------------------------------------------------------------------------\n const area = (): ModuleArea => {\n const placements: ModuleArea['placements'] = []\n poleIds.forEach((id, index) => placements.push({ item: `pole_${id}`, position: [(index - (poleIds.length - 1) / 2) * POLE_GAP, 0, POLE_ROW_Z] as Vec3, rotationY: 0 }))\n placements.push({ item: 'street_grid', position: [-230, 0, -200], rotationY: 0 })\n placements.push({ item: 'terrain_patch', position: [270, 0, -150], rotationY: 0 })\n for (const id of patternIds) {\n const cell = SAMPLE_CELLS[id]\n if (cell) placements.push({ item: id, position: [cell.x, 0, cell.z + SHEET_SHIFT_Z] as Vec3, rotationY: 0 })\n }\n const extra = patternIds.filter((id) => !SAMPLE_CELLS[id])\n extra.forEach((id, index) => placements.push({ item: id, position: [-80 + index * 80, 0, SHEET_SHIFT_Z - 112] as Vec3, rotationY: 0 }))\n return { placements, view: { eye: [20, 190, -20] as Vec3, target: [20, 0, -190] as Vec3 } }\n }\n\n return {\n id: URBAN_AREA_ID,\n name: text.name,\n ground: { surface: 'road' },\n group: text.group,\n get placed() {\n return placed\n },\n itemIds,\n tick: (t: number) => {\n for (const entry of roots()) entry.drawn.animate(t)\n },\n items: () => itemIds.map(item),\n scenarios: (): ModuleScenario<UrbanContext>[] => createScenarios({ text: TEXT[locale] as typeof text, urban: options.urban, terrain }),\n area,\n controls: (): ModuleControl[] => [\n { kind: 'choice', id: 'pattern', name: text.controls.pattern, hint: text.hints.pattern, options: patternIds.map((id) => ({ id, name: text.items[id] ?? id })), default: patternIds.includes('downtown') ? 'downtown' : (patternIds[0] as string) },\n { kind: 'number', id: 'seed', name: text.controls.seed, hint: text.hints.seed, min: 0, max: 99999, step: 1, default: seed },\n { kind: 'choice', id: 'lamps', name: text.controls.lamps, hint: text.hints.lamps, options: Object.keys(LAMP_SHARES).map((id) => ({ id, name: text.options.lamps[id] as string })), default: 'pattern' },\n { kind: 'number', id: 'budget', name: text.controls.budget, hint: text.hints.budget, min: 0, max: 64, step: 1, default: 16 },\n { kind: 'choice', id: 'providers', name: text.controls.providers, hint: text.hints.providers, options: (['none', 'plants', 'vehicles', 'both'] as const).map((id) => ({ id, name: text.options.providers[id] as string })), default: 'none' },\n { kind: 'action', id: 'compose', name: text.actions.compose },\n { kind: 'action', id: 'clear', name: text.actions.clear },\n ],\n layers: (): ModuleLayer[] => (['light_radius', 'bounds'] as const).map((id) => ({ id, name: text.layers[id], default: false })),\n metrics: (): ModuleMetric[] => [\n { id: 'samples', name: text.metrics.samples, read: () => [...placed.values()].filter((entry) => entry.root.parent).length },\n { id: 'draw_calls', name: text.metrics.draw_calls, read: () => count().drawCalls },\n { id: 'triangles', name: text.metrics.triangles, read: () => count().triangles },\n { id: 'real_lights', name: text.metrics.real_lights, read: () => count().lights },\n { id: 'instances', name: text.metrics.instances, read: () => count().instances },\n { id: 'bench_objects', name: text.metrics.bench_objects, read: () => (bench ? countObjects(bench.root) : 0) },\n { id: 'light_budget_left', name: text.metrics.light_budget_left, read: () => (bench ? lightsLeft : settings.budget) },\n ],\n attach(lent) {\n host = lent\n three = lent.THREE as Three\n // the sample sheet is 240 m wide: the room's camera sees 140 m, so the module lends it a longer view while it is loaded\n const camera = lent.camera as { far: number; updateProjectionMatrix(): void } | undefined\n const farBefore = camera?.far\n if (camera && camera.far < VIEW_FAR) {\n camera.far = VIEW_FAR\n camera.updateProjectionMatrix()\n }\n const stopChange = lent.bench?.onChange(onChange)\n const stopFrame = lent.onFrame(frame)\n return () => {\n stopChange?.()\n stopFrame()\n clearHelpers()\n clearBench()\n if (camera && farBefore !== undefined) {\n camera.far = farBefore\n camera.updateProjectionMatrix()\n }\n resolvers.plant?.dispose?.()\n resolvers.vehicle?.dispose?.()\n for (const entry of placed.values()) for (const lamp of entry.drawn.lights) if ('source' in lamp) lamp.source.remove()\n placed.clear()\n host = null\n }\n },\n }\n}\n\n/** What `loadUrbanTestModule` needs of a room: `TestRoom.loadModule` has it. */\nexport type ModuleRoomLike = { loadModule(module: never): unknown }\n\n/** Loads the urban module into a room. */\nexport function loadUrbanTestModule<Room extends ModuleRoomLike>(room: Room, options: UrbanTestOptions = {}): ReturnType<Room['loadModule']> {\n return room.loadModule(createUrbanTestModule(options) as never) as ReturnType<Room['loadModule']>\n}\n","import { markKitOrigin } from '@adatechnology/game-contracts'\nimport { LIGHT_PRIORITY } from '@adatechnology/game-render-three'\nimport type { LightBudget, SourceHandle } from '@adatechnology/game-render-three'\nimport type { ItemBox, LightPart, PartStyle, SilhouetteWindow, UrbanPart, UrbanScene } from '@adatechnology/game-urban'\nimport { shapeGeometries } from '@adatechnology/game-shapes-three'\nimport type * as THREE_NS from 'three'\n\nimport { createPrism, createRoundedBox } from './rounded-box'\nimport { createTextTexture } from './text'\nimport type { CanvasFactory } from './text'\nimport type { PlacementResolver } from './resolvers'\n\ntype Three = typeof THREE_NS\ntype Obj = THREE_NS.Object3D\n/** The lights a scene draws: street lamps and searchlights. */\nexport type UrbanLight = THREE_NS.PointLight | THREE_NS.SpotLight\n\nconst DEFAULT_ROUGHNESS = 0.9\nconst DEFAULT_METALNESS = 0\nconst ITEM_ROUNDNESS = 0.12\nconst LIT_WINDOW = 0xffb45e\nconst DARK_WINDOW = { color: 0x0d1217, roughness: 0.3, metalness: 0.5 }\nconst SIGN_FONT = '700 56px \"Arial Narrow\", Arial, sans-serif'\nconst SIGN_CANVAS = { width: 512, height: 128 }\n\nexport type UrbanThreeOptions = {\n /** Where canvases come from (the page's `document`). Needed only for signs and labels. */\n document?: CanvasFactory\n /** Who makes the objects of the vehicles and plants a scene places. A kind without a resolver is left empty. */\n resolvers?: { vehicle?: PlacementResolver; plant?: PlacementResolver }\n /**\n * The host's light budget: each `light` part becomes a source of it (it competes for a slot by distance; a flickering lamp and a sweeping searchlight update their source) instead of a real\n * light of the scene. `DrawnUrban.lights` then lists the sources. Without it the lights are created here (deprecated, removed in the next major).\n */\n lights?: LightBudget\n}\n\n/** What a drawn scene gives back: the group to add to a scene, the per-frame animation and the cleanup. */\nexport type DrawnUrban = {\n root: Obj\n /** Moves the animated parts to time `t` (seconds): flickering lamps and sweeping searchlights. */\n animate(t: number): void\n /** Lights drawn, for a budget meter: the lights of the scene, or (with `UrbanThreeOptions.lights`) a `BudgetedLamp` for each: its bulb in the scene and its source of the budget. */\n readonly lights: DrawnLight[]\n dispose(): void\n}\n\n/** A light part drawn through the budget: the node it hangs from, the part that describes it (distance, colour...) and the source that competes for a slot. */\nexport type BudgetedLamp = { readonly bulb: Obj; readonly part: LightPart; readonly source: SourceHandle }\n\n/** A light of `DrawnUrban.lights`: a light of the scene, or a lamp drawn through the budget. */\nexport type DrawnLight = UrbanLight | BudgetedLamp\n\nexport type DrawOptions = {\n /** Group the parts go into. Default a new `THREE.Group`. */\n root?: Obj\n}\n\n/**\n * Draws urban scenes with three.js the way the team's page does: a mesh per part in the order they were added (boxes with the\n * rounded edge, cylinders, flat-shaded cones and prisms, planes that only receive shadows, canvas signs), then one instanced mesh for\n * the small boxes and one for each kind of window. Materials are shared by colour. The instance matrices are the page's.\n */\nexport function createUrbanThree(THREE: Three, options: UrbanThreeOptions = {}) {\n // three with its primitive geometries made by game-shapes (bit-identical on r128 and r160, cached by parameters)\n const T = shapeGeometries(THREE)\n const geometries = new Map<string, THREE_NS.BufferGeometry>()\n const materials = new Map<string, THREE_NS.Material>()\n const disposables: Array<{ dispose(): void }> = []\n\n const standard = (color: number, style?: PartStyle, flat = false): THREE_NS.Material => {\n const roughness = style?.roughness ?? DEFAULT_ROUGHNESS\n const metalness = style?.metalness ?? DEFAULT_METALNESS\n const key = `s|${color}|${roughness}|${metalness}|${flat ? 1 : 0}`\n let material = materials.get(key)\n if (!material) {\n material = new THREE.MeshStandardMaterial({ color, roughness, metalness, flatShading: flat })\n materials.set(key, material)\n }\n return material\n }\n const glowing = (color: number): THREE_NS.Material => {\n const key = `b|${color}`\n let material = materials.get(key)\n if (!material) {\n material = new THREE.MeshBasicMaterial({ color })\n materials.set(key, material)\n }\n return material\n }\n const roundedBox = (width: number, height: number, depth: number, radius: number): THREE_NS.BufferGeometry => {\n const key = [width, height, depth, radius].map((value) => value.toFixed(3)).join('|')\n let geometry = geometries.get(key)\n if (!geometry) {\n geometry = createRoundedBox(THREE, width, height, depth, radius)\n geometries.set(key, geometry)\n }\n return geometry\n }\n const shadows = (mesh: Obj, style: PartStyle | undefined, cast: boolean, receive: boolean): void => {\n mesh.castShadow = style?.castShadow ?? cast\n mesh.receiveShadow = style?.receiveShadow ?? receive\n }\n const texture = (lines: readonly string[], width: number, height: number, background: string, foreground: string, font: string): THREE_NS.Texture => {\n if (!options.document) throw new Error('createUrbanThree needs a document (option) to draw signs and labels')\n const map = createTextTexture(THREE, options.document, lines, { width, height, background, foreground, font })\n disposables.push(map)\n return map\n }\n const textPlane = (part: { x: number; y: number; z: number; width: number; height: number; ry: number }, map: THREE_NS.Texture): THREE_NS.Mesh => {\n const mesh = new THREE.Mesh(new T.PlaneGeometry(part.width, part.height), new THREE.MeshBasicMaterial({ map, transparent: true }))\n mesh.userData.own = true\n mesh.position.set(part.x, part.y, part.z)\n if (part.ry) mesh.rotation.y = part.ry\n disposables.push(mesh.geometry, mesh.material)\n return mesh\n }\n\n const forward = new THREE.Vector3(0, 0, -1)\n const aimAt = (node: Obj, from: { x: number; y: number; z: number }, to: { x: number; y: number; z: number }): void => {\n node.quaternion.setFromUnitVectors(forward, new THREE.Vector3(to.x - from.x, to.y - from.y, to.z - from.z).normalize())\n }\n\n /** The bulb of a light part as a node of the scene, and its source of the budget. */\n const sourceOf = (part: LightPart, bulb: Obj, extra: Record<string, unknown>): SourceHandle =>\n options.lights!.addSource({ owner: 'urban.light', priority: LIGHT_PRIORITY.street, color: part.color, intensity: part.intensity, distance: part.distance, decay: part.decay, position: [0, 0, 0], follow: bulb, ...extra })\n\n const drawBudgetedLight = (part: LightPart, animators: ((t: number) => void)[], lights: DrawnLight[]): Obj[] => {\n const bulb = new THREE.Object3D()\n bulb.position.set(part.x, part.y, part.z)\n if (part.kind === 'point') {\n const source = sourceOf(part, bulb, {})\n lights.push({ bulb, part, source } satisfies BudgetedLamp)\n if (part.flicker) animators.push((t) => source.update({ intensity: part.intensity * (Math.sin(t * 23 + part.x) > 0.3 || Math.sin(t * 3.1) > 0.85 ? 0.15 : 1) }))\n return [bulb]\n }\n aimAt(bulb, part, part.target)\n const source = sourceOf(part, bulb, { kind: 'spot', angle: part.angle, penumbra: part.penumbra })\n lights.push({ bulb, part, source } satisfies BudgetedLamp)\n const { sweep } = part\n if (sweep) animators.push((t) => aimAt(bulb, part, { x: part.x + Math.sin(t * sweep.speed + part.x) * sweep.radius, y: 0, z: part.z + Math.cos(t * sweep.speed + part.x) * sweep.radius }))\n return [bulb]\n }\n\n const drawPart = (part: UrbanPart, animators: ((t: number) => void)[], lights: DrawnLight[]): Obj[] => {\n switch (part.shape) {\n case 'group': {\n const group = new THREE.Group()\n group.position.set(part.x, part.y, part.z)\n if (part.ry) group.rotation.y = part.ry\n return [group]\n }\n case 'box': {\n const mesh = new THREE.Mesh(roundedBox(part.width, part.height, part.depth, part.radius), part.emissive ? glowing(part.color) : standard(part.color, part.style))\n mesh.position.set(part.x, part.y, part.z)\n if (part.ry) mesh.rotation.y = part.ry\n if (part.rz) mesh.rotation.z = part.rz\n shadows(mesh, part.style, true, true)\n return [mesh]\n }\n case 'prism': {\n const geometry = createPrism(THREE, part.width, part.height, part.depth)\n disposables.push(geometry)\n const mesh = new THREE.Mesh(geometry, standard(part.color, part.style, true))\n mesh.position.set(part.x, part.y, part.z)\n if (part.ry) mesh.rotation.y = part.ry\n shadows(mesh, part.style, true, true)\n return [mesh]\n }\n case 'cylinder': {\n const geometry = new T.CylinderGeometry(part.radiusTop, part.radiusBottom, part.height, part.segments)\n disposables.push(geometry)\n const mesh = new THREE.Mesh(geometry, standard(part.color, part.style))\n mesh.position.set(part.x, part.y, part.z)\n shadows(mesh, part.style, true, true)\n return [mesh]\n }\n case 'cone': {\n const geometry = new T.ConeGeometry(part.radius, part.height, part.segments)\n disposables.push(geometry)\n const mesh = new THREE.Mesh(geometry, standard(part.color, part.style, true))\n mesh.position.set(part.x, part.y, part.z)\n shadows(mesh, part.style, true, true)\n return [mesh]\n }\n case 'crown': {\n const geometry = new THREE.DodecahedronGeometry(part.radius, 0)\n disposables.push(geometry)\n const mesh = new THREE.Mesh(geometry, standard(part.color, part.style))\n mesh.position.set(part.x, part.y, part.z)\n shadows(mesh, part.style, true, false)\n return [mesh]\n }\n case 'terrain': {\n const { grid } = part\n const geometry = new T.PlaneGeometry(grid.size, grid.size, grid.segments, grid.segments)\n geometry.rotateX(-Math.PI / 2)\n const position = geometry.attributes.position\n const colors = new Float32Array(position.count * 3)\n const color = new THREE.Color()\n for (let index = 0; index < position.count; index++) {\n position.setXYZ(index, grid.x[index], grid.heights[index], grid.z[index])\n color.setHex(grid.colors[index] as number)\n colors[index * 3] = color.r\n colors[index * 3 + 1] = color.g\n colors[index * 3 + 2] = color.b\n }\n geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))\n geometry.computeVertexNormals()\n disposables.push(geometry)\n const material = new THREE.MeshStandardMaterial({ vertexColors: true, flatShading: true, roughness: 1 })\n disposables.push(material)\n const mesh = new THREE.Mesh(geometry, material)\n mesh.userData.own = true\n shadows(mesh, part.style, true, true)\n return [mesh]\n }\n case 'vault': {\n const geometry = new T.CylinderGeometry(part.radius, part.radius, part.length, part.segments, 1, false, 0, part.arc)\n disposables.push(geometry)\n const mesh = new THREE.Mesh(geometry, standard(part.color, part.style))\n mesh.rotation.set(part.rotation.x, part.rotation.y, part.rotation.z)\n mesh.position.set(part.x, part.y, part.z)\n mesh.scale.set(part.scale.x, part.scale.y, part.scale.z)\n shadows(mesh, part.style, true, false)\n return [mesh]\n }\n case 'plane': {\n const geometry = new T.PlaneGeometry(part.width, part.depth).rotateX(-Math.PI / 2)\n disposables.push(geometry)\n const mesh = new THREE.Mesh(geometry, standard(part.color, part.style))\n mesh.position.set(part.x, part.y, part.z)\n shadows(mesh, part.style, false, true)\n return [mesh]\n }\n case 'line': {\n const geometry = new THREE.BufferGeometry().setFromPoints(part.points.map(([x, y, z]) => new THREE.Vector3(x, y, z)))\n const mesh = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: part.color }))\n mesh.userData.own = true\n disposables.push(geometry, mesh.material)\n return [mesh]\n }\n case 'sign':\n return [textPlane(part, texture([part.text], SIGN_CANVAS.width, SIGN_CANVAS.height, part.background, part.foreground, SIGN_FONT))]\n case 'label':\n return [textPlane(part, texture(part.lines, part.canvas.width, part.canvas.height, part.background, part.foreground, part.font))]\n case 'placement': {\n const holder = new THREE.Group()\n holder.position.set(part.x, part.y, part.z)\n if (part.ry) holder.rotation.y = part.ry\n if (part.scale !== 1) holder.scale.setScalar(part.scale)\n const object = options.resolvers?.[part.kind]?.(part)\n if (object) holder.add(object)\n holder.userData.placement = { kind: part.kind, id: part.id }\n return [holder]\n }\n case 'light': {\n if (options.lights) return drawBudgetedLight(part, animators, lights)\n if (part.kind === 'point') {\n // eslint-disable-next-line no-restricted-syntax -- D2: legacy path without LightBudget, removed in the next major\n const light = new THREE.PointLight(part.color, part.intensity, part.distance, part.decay)\n light.position.set(part.x, part.y, part.z)\n lights.push(light)\n if (part.flicker) {\n animators.push((t) => {\n light.intensity = part.intensity * (Math.sin(t * 23 + part.x) > 0.3 || Math.sin(t * 3.1) > 0.85 ? 0.15 : 1)\n })\n }\n return [light]\n }\n // eslint-disable-next-line no-restricted-syntax -- D2: legacy path without LightBudget, removed in the next major\n const light = new THREE.SpotLight(part.color, part.intensity, part.distance, part.angle, part.penumbra, part.decay)\n light.position.set(part.x, part.y, part.z)\n const target = new THREE.Object3D()\n target.position.set(part.target.x, part.target.y, part.target.z)\n light.target = target\n lights.push(light)\n const { sweep } = part\n if (sweep) {\n animators.push((t) => {\n target.position.set(part.x + Math.sin(t * sweep.speed + part.x) * sweep.radius, 0, part.z + Math.cos(t * sweep.speed + part.x) * sweep.radius)\n })\n }\n return [light, target]\n }\n }\n }\n\n const instancedItems = (list: readonly ItemBox[]): THREE_NS.InstancedMesh => {\n const mesh = new THREE.InstancedMesh(roundedBox(1, 1, 1, ITEM_ROUNDNESS), standard(0xffffff), list.length)\n const matrix = new THREE.Matrix4()\n const quaternion = new THREE.Quaternion()\n const euler = new THREE.Euler()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const color = new THREE.Color()\n list.forEach((entry, index) => {\n euler.set(entry.rx, entry.ry, entry.rz)\n quaternion.setFromEuler(euler)\n matrix.compose(position.set(entry.x, entry.y + entry.height / 2, entry.z), quaternion, scale.set(entry.width, entry.height, entry.depth))\n mesh.setMatrixAt(index, matrix)\n mesh.setColorAt(index, color.set(entry.color))\n })\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n }\n\n const instancedWindows = (list: readonly SilhouetteWindow[], material: THREE_NS.Material): THREE_NS.InstancedMesh => {\n const geometry = new T.PlaneGeometry(1, 1)\n disposables.push(geometry)\n const mesh = new THREE.InstancedMesh(geometry, material, list.length)\n const matrix = new THREE.Matrix4()\n const quaternion = new THREE.Quaternion()\n const axis = new THREE.Vector3(0, 1, 0)\n const scale = new THREE.Vector3()\n list.forEach((entry, index) => {\n quaternion.setFromAxisAngle(axis, entry.ry)\n matrix.compose(new THREE.Vector3(entry.x, entry.y, entry.z), quaternion, scale.set(entry.width, entry.height, 1))\n mesh.setMatrixAt(index, matrix)\n })\n return mesh\n }\n\n /** Draws a scene: its parts in order, then the instanced boxes, the lit windows and the dark windows. */\n function draw(scene: UrbanScene, drawOptions: DrawOptions = {}): DrawnUrban {\n const root = markKitOrigin(drawOptions.root ?? new THREE.Group(), { owner: 'game-urban-three', kind: 'urban' })\n const animators: ((t: number) => void)[] = []\n const lights: DrawnLight[] = []\n const objects: Obj[][] = []\n for (const part of scene.parts) {\n const made = drawPart(part, animators, lights)\n objects.push(made)\n const parent = part.parent < 0 ? root : (objects[part.parent] as Obj[])[0]\n parent.add(...made)\n }\n if (scene.items.length) root.add(instancedItems(scene.items))\n if (scene.windows.lit.length) root.add(instancedWindows(scene.windows.lit, glowing(LIT_WINDOW)))\n if (scene.windows.dark.length) root.add(instancedWindows(scene.windows.dark, standard(DARK_WINDOW.color, DARK_WINDOW)))\n return {\n root,\n lights,\n animate: (t) => animators.forEach((step) => step(t)),\n dispose: () => {\n if (options.lights) for (const lamp of lights) if ('source' in lamp) lamp.source.remove()\n root.parent?.remove(root)\n for (const item of disposables.splice(0)) item.dispose?.()\n for (const geometry of geometries.values()) geometry.dispose()\n for (const material of materials.values()) material.dispose()\n geometries.clear()\n materials.clear()\n },\n }\n }\n\n return { THREE, draw }\n}\n\nexport type UrbanThree = ReturnType<typeof createUrbanThree>\n","import { shapeGeometries } from '@adatechnology/game-shapes-three'\n\nimport type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\n\n/** The team's rounded box: a 4x4x4 grid per face with the edge vertices pushed onto an arc of the given radius (smooth normals). A radius of 0 is a plain box. */\nexport function createRoundedBox(THREE: Three, width: number, height: number, depth: number, radius: number): THREE_NS.BufferGeometry {\n const T = shapeGeometries(THREE) as Three\n if (radius === 0) return new T.BoxGeometry(width, height, depth)\n const geometry = new T.BoxGeometry(2, 2, 2, 4, 4, 4)\n const position = geometry.attributes.position\n const normal = geometry.attributes.normal\n const half = [width / 2, height / 2, depth / 2]\n const p = [0, 0, 0]\n const q = [0, 0, 0]\n const map = (value: number, halfSize: number): number => {\n const a = Math.abs(value)\n return Math.sign(value) * (a <= 0.5 ? a * 2 * (halfSize - radius) : halfSize - radius + (a - 0.5) * 2 * radius)\n }\n for (let index = 0; index < position.count; index++) {\n const source = [position.getX(index), position.getY(index), position.getZ(index)]\n let length = 0\n for (let axis = 0; axis < 3; axis++) {\n p[axis] = map(source[axis] as number, half[axis] as number)\n const clamped = Math.max(-((half[axis] as number) - radius), Math.min((half[axis] as number) - radius, p[axis] as number))\n q[axis] = (p[axis] as number) - clamped\n p[axis] = clamped\n length += (q[axis] as number) ** 2\n }\n length = Math.sqrt(length)\n if (length < 1e-6) {\n q[0] = normal.getX(index)\n q[1] = normal.getY(index)\n q[2] = normal.getZ(index)\n } else for (let axis = 0; axis < 3; axis++) q[axis] = (q[axis] as number) / length\n position.setXYZ(index, (p[0] as number) + (q[0] as number) * radius, (p[1] as number) + (q[1] as number) * radius, (p[2] as number) + (q[2] as number) * radius)\n normal.setXYZ(index, q[0] as number, q[1] as number, q[2] as number)\n }\n return geometry\n}\n\n/** Triangle prism: the triangle `width` wide and `height` high, extruded `depth` long and centred on z. Base at y = 0. */\nexport function createPrism(THREE: Three, width: number, height: number, depth: number): THREE_NS.BufferGeometry {\n const shape = new THREE.Shape()\n shape.moveTo(-width / 2, 0)\n shape.lineTo(width / 2, 0)\n shape.lineTo(0, height)\n shape.lineTo(-width / 2, 0)\n const geometry = new (shapeGeometries(THREE) as Three).ExtrudeGeometry(shape, { depth, bevelEnabled: false })\n geometry.translate(0, 0, -depth / 2)\n return geometry\n}\n","import type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\n\n/** What `document.createElement('canvas')` needs; a fake works in Node. */\nexport type CanvasFactory = { createElement(tag: 'canvas'): HTMLCanvasElement }\n\nexport type TextTextureOptions = { width: number; height: number; background: string; foreground: string; font: string }\n\nconst FIT = 0.92\n\n/** Canvas texture with centred lines of text, shrunk to fit 92 % of the width, on a filled background. */\nexport function createTextTexture(THREE: Three, document: CanvasFactory, lines: readonly string[], o: TextTextureOptions): THREE_NS.CanvasTexture {\n const canvas = document.createElement('canvas')\n canvas.width = o.width\n canvas.height = o.height\n const g = canvas.getContext('2d')\n if (!g) throw new Error('game-urban-three: the canvas has no 2D context')\n g.fillStyle = o.background\n g.fillRect(0, 0, o.width, o.height)\n g.fillStyle = o.foreground\n g.font = o.font\n g.textAlign = 'center'\n g.textBaseline = 'middle'\n const base = g.font\n lines.forEach((text, index) => {\n g.font = base\n const measured = g.measureText(text).width\n if (measured > o.width * FIT) g.font = base.replace(/(\\d+(?:\\.\\d+)?)px/, (_match: string, size: string) => ((Number(size) * o.width * FIT) / measured).toFixed(1) + 'px')\n g.fillText(text, o.width / 2, o.height / 2 + (index - (lines.length - 1) / 2) * (o.height / lines.length))\n })\n const texture = new THREE.CanvasTexture(canvas)\n texture.anisotropy = 4\n return texture\n}\n","import { generate } from '@adatechnology/game-vegetation'\nimport type { Condition, Lod, Season } from '@adatechnology/game-vegetation'\nimport { createPlantObject, createVegetationMaterials } from '@adatechnology/game-vegetation/three'\nimport { toSpec as defaultToSpec } from '@adatechnology/game-vegetation-species'\nimport type { PlacementPart } from '@adatechnology/game-urban'\n\nimport type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\n\n/** Makes the object of a placement; null when it cannot (an unknown id). The drawer clones it for each spot. */\nexport type PlacementResolver = ((part: PlacementPart) => THREE_NS.Object3D | null) & { dispose?: () => void }\n\nconst cssColor = (value: number): string => `#${value.toString(16).padStart(6, '0')}`\n\n/** The options of `createVehiclesThree().build` that the resolver passes (structural, so this package does not import game-vehicles-three). */\nexport type VehicleBuildOptions = { quality?: 'high' | 'lite'; color?: string; seed?: number | string }\n\nexport type VehicleResolverOptions = {\n /** `lite` fuses a vehicle into six meshes, the right cost for a street of parked cars. Default `lite`. */\n quality?: VehicleBuildOptions['quality']\n}\n\n/** What the vehicle resolver needs of `createVehiclesThree`. */\nexport type VehicleBuilder = { build(key: string, options?: VehicleBuildOptions): { group: THREE_NS.Object3D; dispose(): void } }\n\n/**\n * Resolves vehicle placements with the vehicles of `game-vehicles-three`. A vehicle is built once for each id and paint and cloned\n * (clones share geometry and materials) for each spot.\n */\nexport function createVehicleResolver(vehicles: VehicleBuilder, options: VehicleResolverOptions = {}): PlacementResolver {\n const quality = options.quality ?? 'lite'\n const built = new Map<string, { group: THREE_NS.Object3D; dispose(): void } | null>()\n const resolve: PlacementResolver = (part) => {\n const key = `${part.id}|${part.color ?? ''}|${part.seed}`\n if (!built.has(key)) {\n try {\n built.set(key, vehicles.build(part.id, { quality, ...(part.color === undefined ? { seed: part.seed } : { color: cssColor(part.color) }) }))\n } catch {\n built.set(key, null)\n }\n }\n return built.get(key)?.group.clone() ?? null\n }\n resolve.dispose = () => {\n for (const entry of built.values()) entry?.dispose()\n built.clear()\n }\n return resolve\n}\n\nexport type PlantResolverOptions = {\n /**\n * The generator spec of a species id (`defaultPlantSpec` of `game-kit-defaults`, or the game's own). Default `toSpec` of `game-vegetation-species`.\n * @deprecated pass `toSpec`; the default is removed in the next major.\n */\n toSpec?: (id: string) => Parameters<typeof generate>[0]\n /** Level of detail of the plants of a street. Default 1. */\n lod?: Lod\n condition?: Condition\n season?: Season\n /** Materials of the plants (wind included); default new ones. */\n materials?: ReturnType<typeof createVegetationMaterials>\n}\n\n/** Resolves plant placements with the species `toSpec` knows, built with `game-vegetation`. One plant for each species and seed, cloned for each spot. */\nexport function createPlantResolver(THREE: Three, options: PlantResolverOptions = {}): PlacementResolver {\n const materials = options.materials ?? createVegetationMaterials(THREE)\n const made = new Map<string, THREE_NS.Object3D | null>()\n const resolve: PlacementResolver = (part) => {\n const key = `${part.id}|${part.seed}`\n if (!made.has(key)) {\n try {\n const mesh = generate((options.toSpec ?? defaultToSpec)(part.id), { seed: part.seed, lod: options.lod ?? 1, condition: options.condition ?? 'healthy', season: options.season ?? 'spring', species: part.id })\n made.set(key, createPlantObject(THREE, mesh, materials))\n } catch {\n made.set(key, null)\n }\n }\n return made.get(key)?.clone() ?? null\n }\n resolve.dispose = () => {\n for (const object of made.values()) {\n object?.traverse((o) => (o as THREE_NS.Mesh).geometry?.dispose?.())\n }\n made.clear()\n }\n return resolve\n}\n","import { createPlantProvider, createUrban, createVehicleProvider } from '@adatechnology/game-urban'\nimport type { PlacementPart, TerrainOptions, UrbanOptions, UrbanPart } from '@adatechnology/game-urban'\nimport type { ModuleScenario } from '@adatechnology/game-contracts'\n\nimport { fill } from './text'\nimport type { UrbanText } from './text'\nimport type { UrbanContext } from './types'\n\n/** The heights of the five poles of the Galeria (m), the tops measured on the page's scenes. A game's own poles are not checked. */\nexport const POLE_TOPS: Readonly<Record<string, number>> = { led_double: 9, concrete_arm: 8, cast_iron: 4.8, wood_crossarm: 7, flood_tower: 12.55 }\n\n// the scenario checks the mechanics of the providers, so it hands them its own small fleet and species instead of a content pack\nconst STAND_IN_VEHICLE_IDS: readonly string[] = ['stand_in_car_a', 'stand_in_car_b', 'stand_in_van']\nconst standInSpecies = (context: string, key: string): string => `stand_in_${context}_${key.length % 3}`\n\nexport type ScenarioDeps = {\n readonly text: UrbanText\n readonly urban: UrbanOptions | undefined\n readonly terrain: TerrainOptions\n}\n\nconst topOf = (parts: readonly UrbanPart[]): number => Math.max(...parts.map((part) => ('height' in part && 'y' in part ? part.y + part.height / 2 : 0)))\nconst placements = (parts: readonly UrbanPart[], kind: PlacementPart['kind']): PlacementPart[] => parts.filter((part): part is PlacementPart => part.shape === 'placement' && part.kind === kind)\nconst round = (value: number, digits = 3): number => Math.round(value * 10 ** digits) / 10 ** digits\n\n/**\n * The scenarios of the urban area: checks on the numbers the kit promises (the poles' heights, the light budget, the dashes of a road,\n * the heights of a block, the determinism of a neighbourhood, burnt-out lamps, the terrain, the providers). They need no object of the\n * room, so a game that patches the catalogues sees at once what it changed.\n */\nexport const createScenarios = (deps: ScenarioDeps): ModuleScenario<UrbanContext>[] => {\n const { text } = deps\n const say = (id: string, ...values: unknown[]): string => fill(text.checks[id] as string, ...values)\n const scenario = (id: string, run: ModuleScenario<UrbanContext>['run']): ModuleScenario<UrbanContext> => ({ id, name: text.scenarios[id] ?? id, run })\n const kit = () => createUrban(deps.urban)\n\n return [\n scenario('urban_pole_heights', ({ expect }) => {\n const urban = kit()\n for (const id of urban.poles.ids()) {\n const expected = POLE_TOPS[id]\n if (expected === undefined) continue\n const b = urban.builder()\n urban.poles.get(id).build(b, { x: 0, z: 0 })\n const top = topOf(b.parts)\n expect(Math.abs(top - expected) < 1e-6, say('pole_top', id, round(top)), { pole: id, top })\n }\n }),\n scenario('urban_light_budget', ({ expect }) => {\n const urban = kit()\n const budget = 4\n const b = urban.builder({ budget })\n for (let index = 0; index < 8; index++) urban.poles.get('led_double').build(b, { x: index * 8, z: 0 })\n const real = b.parts.filter((part) => part.shape === 'light').length\n expect(real === budget, say('budget_real', 8, real, budget), { real, budget })\n expect(b.lights.left < 0, say('budget_left', b.lights.left), { left: b.lights.left })\n }),\n scenario('urban_road_dashes', ({ expect }) => {\n const urban = kit()\n const b = urban.builder()\n urban.streets.road(b, 0, 0, 7, 60, 'x')\n expect(b.items.length === 12 && b.items[0]?.x === -28 && b.items[1]?.x === -23, say('dashes', b.items.length, b.items[0]?.x), { dashes: b.items.length })\n }),\n scenario('urban_block_heights', ({ expect }) => {\n const urban = kit()\n const b = urban.builder({ seed: 3 })\n const placed = urban.block.fill(b, { cx: 0, cz: 0, size: 200, minHeight: 10, maxHeight: 50, k: 20, gap: 0.01 })\n const heights = placed.map((building) => building.height).sort((a, c) => a - c)\n const median = heights[Math.floor(heights.length / 2)] as number\n expect(heights.length > 0 && (heights[0] as number) >= 10 && (heights[heights.length - 1] as number) <= 50, say('heights_in_range', 10, 50), { count: heights.length })\n expect(median < 30, say('heights_median', round(median, 1), 30), { median })\n }),\n scenario('urban_neighbourhood_seed', ({ expect }) => {\n const urban = kit()\n const draw = (seed: number): string => {\n const b = urban.builder({ seed })\n urban.neighbourhoods.get(urban.neighbourhoods.ids()[1] as string).compose(b, { x: 0, z: 0 })\n return JSON.stringify(b.scene())\n }\n expect(draw(7) === draw(7), say('same_seed', 7))\n expect(draw(7) !== draw(8), say('other_seed', 8))\n }),\n scenario('urban_lamps_burnt', ({ expect }) => {\n const dark = createUrban({ ...deps.urban, patch: { ...deps.urban?.patch, neighbourhoods: { ...deps.urban?.patch?.neighbourhoods, suburb: { lit: 0 } } } })\n const suburb = dark.neighbourhoods.get('suburb').compose(dark.builder(), { x: 0, z: 0 })\n expect(suburb.poles.length > 0 && !suburb.poles.some((pole) => pole.on), say('lamps_none', suburb.poles.length), { poles: suburb.poles.length })\n const lit = kit()\n const downtown = lit.neighbourhoods.get('downtown').compose(lit.builder(), { x: 0, z: 0 })\n expect(downtown.poles.length > 0 && downtown.poles.every((pole) => pole.on), say('lamps_all', downtown.poles.length), { poles: downtown.poles.length })\n }),\n scenario('urban_terrain', ({ expect }) => {\n const urban = kit()\n const terrain = urban.terrain(deps.terrain)\n const grid = terrain.grid()\n const mid = (grid.segments / 2) * (grid.segments + 1) + grid.segments / 2\n const world = terrain.fromWorld(grid.x[mid] as number, grid.z[mid] as number)\n const height = terrain.heightAt(world[0], world[1])\n expect(Math.abs(height - (grid.heights[mid] as number)) < 1e-3, say('vertex_height', round(height), round(grid.heights[mid] as number)), { height })\n for (const river of deps.terrain.rivers) {\n if (!('fixed' in river.bed)) continue\n const point = river.points[Math.floor(river.points.length / 2)] as readonly [number, number]\n const bed = terrain.heightAt(point[0], point[1])\n expect(Math.abs(bed - river.bed.fixed) < 1e-6, say('river_bed', round(river.bed.fixed < 0 ? -river.bed.fixed : river.bed.fixed)), { river: river.id, bed })\n }\n for (const lake of deps.terrain.lakes) {\n const level = terrain.heightAt(lake.center[0], lake.center[1])\n expect(Math.abs(level - lake.level) < 1e-6, say('lake_level', round(level)), { lake: lake.id, level })\n }\n }),\n scenario('urban_providers', ({ expect }) => {\n const urban = kit()\n const cars = urban.builder()\n const downtown = urban.neighbourhoods.get('downtown').compose(cars, { x: 0, z: 0 }, { providers: { vehicle: createVehicleProvider({ ids: STAND_IN_VEHICLE_IDS }) } })\n const spots = placements(cars.parts, 'vehicle')\n expect(spots.length === downtown.vehicles.length && spots.length > 0, say('vehicles_placed', downtown.vehicles.length, spots.length))\n expect(spots.every((spot) => STAND_IN_VEHICLE_IDS.includes(spot.id)), say('vehicle_ids', [...new Set(spots.map((spot) => spot.id))].join(', ')))\n const trees = urban.builder()\n const mountain = urban.neighbourhoods.get('mountain_resort').compose(trees, { x: 0, z: 0 }, { providers: { plant: createPlantProvider({ pickSpecies: standInSpecies }) } })\n const planted = placements(trees.parts, 'plant')\n expect(planted.length === mountain.plants.length && planted.length > 0, say('plants_placed', mountain.plants.length, planted.length))\n }),\n ]\n}\n","/** Words and sentences of the urban area, by locale. `{0}`, `{1}`... are filled in order. */\nexport type UrbanText = {\n group: string\n name: string\n items: Record<string, string>\n controls: Record<'pattern' | 'seed' | 'lamps' | 'budget' | 'providers', string>\n hints: Record<'pattern' | 'seed' | 'lamps' | 'budget' | 'providers', string>\n options: { lamps: Record<string, string>; providers: Record<string, string> }\n actions: Record<'compose' | 'clear', string>\n layers: Record<'light_radius' | 'bounds', string>\n metrics: Record<'samples' | 'draw_calls' | 'triangles' | 'real_lights' | 'instances' | 'bench_objects' | 'light_budget_left', string>\n log: Record<'composed' | 'cleared' | 'no_vehicles', string>\n scenarios: Record<string, string>\n checks: Record<string, string>\n}\n\nconst ptBR: UrbanText = {\n group: 'Cidade',\n name: 'Área urbana',\n items: {\n pole_led_double: 'Poste LED de braço duplo',\n pole_concrete_arm: 'Poste de concreto com braço',\n pole_cast_iron: 'Lampião de ferro fundido',\n pole_wood_crossarm: 'Poste de madeira com cruzeta',\n pole_flood_tower: 'Torre de refletores',\n street_grid: 'Grade de ruas com quarteirão',\n terrain_patch: 'Trecho de terreno',\n downtown: 'Bairro: centro',\n suburb: 'Bairro: subúrbio',\n working_class: 'Bairro: popular',\n historic_street: 'Bairro: rua histórica',\n industrial_port: 'Bairro: industrial e porto',\n railway_village: 'Bairro: vila ferroviária',\n mountain_resort: 'Bairro: serra',\n stilt_village: 'Bairro: palafitas',\n military: 'Bairro: militar',\n rural: 'Bairro: rural',\n },\n controls: { pattern: 'Bairro da bancada', seed: 'Semente', lamps: 'Lampiões', budget: 'Luzes reais da cena', providers: 'Veículos e plantas' },\n hints: {\n pattern: 'Padrão que as ações desenham na frente do jogador',\n seed: 'A mesma semente desenha a mesma rua',\n lamps: 'Quantos lampiões ficam acesos; o resto queima',\n budget: 'Cada lampião aceso gasta uma; passando disso fica só a lente brilhando',\n providers: 'Pede ao game-vehicles-fleet e ao game-vegetation-species os carros e as árvores',\n },\n options: {\n lamps: { pattern: 'Os do padrão', all: 'Todos acesos', half: 'Metade', none: 'Nenhum' },\n providers: { none: 'Nenhum (padrão)', plants: 'Plantas das espécies', vehicles: 'Veículos da frota', both: 'Os dois' },\n },\n actions: { compose: 'Desenhar o bairro', clear: 'Tirar o bairro' },\n layers: { light_radius: 'Alcance das luzes', bounds: 'Caixas das amostras' },\n metrics: { samples: 'Amostras na sala', draw_calls: 'Chamadas de desenho', triangles: 'Triângulos', real_lights: 'Luzes reais', instances: 'Instâncias', bench_objects: 'Objetos da bancada', light_budget_left: 'Orçamento de luzes que sobra' },\n log: { composed: 'Bairro {0} desenhado com a semente {1}: {2} objetos, {3} luzes reais', cleared: 'Bairro tirado', no_vehicles: 'A sala não recebeu um construtor de veículos: os carros ficam de fora' },\n scenarios: {\n urban_pole_heights: 'Os cinco postes têm a altura da tabela',\n urban_light_budget: 'O orçamento de luzes: as primeiras acesas ganham luz real e o contador passa de zero',\n urban_road_dashes: 'A rua tem uma faixa a cada 5 m',\n urban_block_heights: 'Os prédios altos são mais raros',\n urban_neighbourhood_seed: 'A mesma semente desenha o mesmo bairro',\n urban_lamps_burnt: 'Um bairro com a fração zero de lampiões acesos não tem nenhum aceso',\n urban_terrain: 'O terreno tem a altura do vértice, o leito do rio e o nível do lago',\n urban_providers: 'Os provedores pedem veículos da frota e espécies da região onde o bairro estaciona e planta',\n },\n checks: {\n pole_top: 'o poste {0} chega a {1} m',\n budget_real: '{0} lâmpadas acesas, {1} luzes reais (o orçamento é {2})',\n budget_left: 'o contador chegou a {0}',\n dashes: 'uma rua de 60 m tem {0} faixas, a primeira em x = {1}',\n heights_in_range: 'os prédios ficam entre {0} e {1} m',\n heights_median: 'a mediana dos prédios é {0} m, abaixo do meio {1} m',\n same_seed: 'a mesma semente repete as partes: {0}',\n other_seed: 'outra semente muda o bairro: {0}',\n lamps_none: 'com a fração 0 nenhum dos {0} postes está aceso',\n lamps_all: 'o centro mantém os {0} postes acesos',\n vertex_height: 'a altura do vértice central é {0} m e a da malha {1} m',\n river_bed: 'o leito do rio está {0} m abaixo do chão ao lado',\n lake_level: 'o centro do lago está a {0} m',\n vehicles_placed: '{0} veículos pedidos, {1} vagas de veículo na cena',\n vehicle_ids: 'os veículos são da frota: {0}',\n plants_placed: '{0} plantas pedidas, {1} vagas de planta na cena',\n },\n}\n\nconst en: UrbanText = {\n group: 'City',\n name: 'Urban area',\n items: {\n pole_led_double: 'Double-arm LED pole',\n pole_concrete_arm: 'Concrete pole with an arm',\n pole_cast_iron: 'Cast-iron lantern',\n pole_wood_crossarm: 'Wooden pole with a crossarm',\n pole_flood_tower: 'Floodlight tower',\n street_grid: 'Street grid with a block',\n terrain_patch: 'Terrain patch',\n downtown: 'Neighbourhood: downtown',\n suburb: 'Neighbourhood: suburb',\n working_class: 'Neighbourhood: working class',\n historic_street: 'Neighbourhood: historic street',\n industrial_port: 'Neighbourhood: industrial and port',\n railway_village: 'Neighbourhood: railway village',\n mountain_resort: 'Neighbourhood: mountain resort',\n stilt_village: 'Neighbourhood: stilt village',\n military: 'Neighbourhood: military',\n rural: 'Neighbourhood: rural',\n },\n controls: { pattern: 'Bench neighbourhood', seed: 'Seed', lamps: 'Street lamps', budget: 'Real lights of the scene', providers: 'Vehicles and plants' },\n hints: {\n pattern: 'The pattern the actions draw in front of the player',\n seed: 'The same seed draws the same street',\n lamps: 'How many lamps are on; the rest are burnt out',\n budget: 'Every lamp that is on spends one; past that it keeps only its glowing lens',\n providers: 'Asks game-vehicles-fleet and game-vegetation-species for the cars and trees',\n },\n options: {\n lamps: { pattern: \"The pattern's own\", all: 'All on', half: 'Half', none: 'None' },\n providers: { none: 'None (default)', plants: 'Plants of the species pack', vehicles: 'Vehicles of the fleet', both: 'Both' },\n },\n actions: { compose: 'Draw the neighbourhood', clear: 'Take the neighbourhood away' },\n layers: { light_radius: 'Light reach', bounds: 'Sample boxes' },\n metrics: { samples: 'Samples in the room', draw_calls: 'Draw calls', triangles: 'Triangles', real_lights: 'Real lights', instances: 'Instances', bench_objects: 'Bench objects', light_budget_left: 'Light budget left' },\n log: { composed: 'Neighbourhood {0} drawn with seed {1}: {2} objects, {3} real lights', cleared: 'Neighbourhood taken away', no_vehicles: 'The room got no vehicle builder: the cars are left out' },\n scenarios: {\n urban_pole_heights: 'The five poles stand at the height of the table',\n urban_light_budget: 'The light budget: the first lamps get real lights and the counter goes below zero',\n urban_road_dashes: 'A road has a dash every 5 m',\n urban_block_heights: 'Tall buildings are rarer',\n urban_neighbourhood_seed: 'The same seed draws the same neighbourhood',\n urban_lamps_burnt: 'A neighbourhood with no lamps lit has none on',\n urban_terrain: 'The terrain has the vertex height, the river bed and the lake level',\n urban_providers: 'The providers ask for fleet vehicles and species of the region where the neighbourhood parks and plants',\n },\n checks: {\n pole_top: 'pole {0} reaches {1} m',\n budget_real: '{0} lamps on, {1} real lights (the budget is {2})',\n budget_left: 'the counter reached {0}',\n dashes: 'a 60 m road has {0} dashes, the first at x = {1}',\n heights_in_range: 'the buildings stand between {0} and {1} m',\n heights_median: 'the median building is {0} m, under the middle {1} m',\n same_seed: 'the same seed repeats the parts: {0}',\n other_seed: 'another seed changes the neighbourhood: {0}',\n lamps_none: 'with the share 0 none of the {0} poles is on',\n lamps_all: 'downtown keeps its {0} poles on',\n vertex_height: 'the height of the central vertex is {0} m and the mesh has {1} m',\n river_bed: 'the river bed is {0} m below the land beside it',\n lake_level: 'the centre of the lake is at {0} m',\n vehicles_placed: '{0} vehicles asked, {1} vehicle spots in the scene',\n vehicle_ids: 'the vehicles are of the fleet: {0}',\n plants_placed: '{0} plants asked, {1} plant spots in the scene',\n },\n}\n\nexport const TEXT: Record<string, UrbanText> = { 'pt-BR': ptBR, en }\n\n/** Fills `{0}`, `{1}`... in order. */\nexport const fill = (template: string, ...values: unknown[]): string => template.replace(/\\{(\\d+)\\}/g, (_match, index: string) => String(values[Number(index)] ?? ''))\n"],"mappings":"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","names":["createPlantProvider","createUrban","createVehicleProvider","shapeGeometries","shapeGeometries","shapeGeometries","source","light","createUrban","createPlantProvider","createVehicleProvider","shapeGeometries","placements"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,57 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { SourceHandle, LightBudget } from '@adatechnology/game-render-three';
|
|
2
|
+
import { LightPart, UrbanScene } from '@adatechnology/game-urban';
|
|
3
|
+
import * as THREE_NS from 'three';
|
|
4
|
+
import { C as CanvasFactory, P as PlacementResolver } from './testing-ZS5dhCJM.js';
|
|
5
|
+
export { D as DEFAULT_TEST_TERRAIN, M as ModuleRoomLike, a as POLE_TOPS, b as PlantResolverOptions, T as TEXT, c as TextTextureOptions, U as URBAN_AREA_ID, d as UrbanContext, e as UrbanTestOptions, f as UrbanText, V as VehicleBuildOptions, g as VehicleBuilder, h as VehicleResolverOptions, i as createPlantResolver, j as createScenarios, k as createTextTexture, l as createUrbanTestModule, m as createVehicleResolver, n as loadUrbanTestModule } from './testing-ZS5dhCJM.js';
|
|
6
|
+
import '@adatechnology/game-contracts';
|
|
7
|
+
import '@adatechnology/game-vegetation';
|
|
8
|
+
import '@adatechnology/game-vegetation/three';
|
|
6
9
|
|
|
7
|
-
type Three$
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
type TextTextureOptions = {
|
|
13
|
-
width: number;
|
|
14
|
-
height: number;
|
|
15
|
-
background: string;
|
|
16
|
-
foreground: string;
|
|
17
|
-
font: string;
|
|
18
|
-
};
|
|
19
|
-
/** Canvas texture with centred lines of text, shrunk to fit 92 % of the width, on a filled background. */
|
|
20
|
-
declare function createTextTexture(THREE: Three$3, document: CanvasFactory, lines: readonly string[], o: TextTextureOptions): any;
|
|
21
|
-
|
|
22
|
-
type Three$2 = any;
|
|
23
|
-
/** Makes the object of a placement; null when it cannot (an unknown id). The drawer clones it for each spot. */
|
|
24
|
-
type PlacementResolver = ((part: PlacementPart) => any | null) & {
|
|
25
|
-
dispose?: () => void;
|
|
26
|
-
};
|
|
27
|
-
type VehicleResolverOptions = {
|
|
28
|
-
/** `lite` fuses a vehicle into six meshes, the right cost for a street of parked cars. Default `lite`. */
|
|
29
|
-
quality?: BuildVehicleOptions['quality'];
|
|
30
|
-
};
|
|
31
|
-
/** What the vehicle resolver needs of `createVehiclesThree`. */
|
|
32
|
-
type VehicleBuilder = {
|
|
33
|
-
build(key: string, options?: BuildVehicleOptions): {
|
|
34
|
-
group: any;
|
|
35
|
-
dispose(): void;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Resolves vehicle placements with the vehicles of `game-vehicles-three`. A vehicle is built once for each id and paint and cloned
|
|
40
|
-
* (clones share geometry and materials) for each spot.
|
|
41
|
-
*/
|
|
42
|
-
declare function createVehicleResolver(vehicles: VehicleBuilder, options?: VehicleResolverOptions): PlacementResolver;
|
|
43
|
-
type PlantResolverOptions = {
|
|
44
|
-
/** Level of detail of the plants of a street. Default 1. */
|
|
45
|
-
lod?: Lod;
|
|
46
|
-
condition?: Condition;
|
|
47
|
-
season?: Season;
|
|
48
|
-
/** Materials of the plants (wind included); default new ones. */
|
|
49
|
-
materials?: ReturnType<typeof createVegetationMaterials>;
|
|
50
|
-
};
|
|
51
|
-
/** Resolves plant placements with the species of `game-vegetation-species`, built with `game-vegetation`. One plant for each species and seed, cloned for each spot. */
|
|
52
|
-
declare function createPlantResolver(THREE: Three$2, options?: PlantResolverOptions): PlacementResolver;
|
|
53
|
-
|
|
54
|
-
type Three$1 = any;
|
|
10
|
+
type Three$1 = typeof THREE_NS;
|
|
11
|
+
type Obj = THREE_NS.Object3D;
|
|
12
|
+
/** The lights a scene draws: street lamps and searchlights. */
|
|
13
|
+
type UrbanLight = THREE_NS.PointLight | THREE_NS.SpotLight;
|
|
55
14
|
type UrbanThreeOptions = {
|
|
56
15
|
/** Where canvases come from (the page's `document`). Needed only for signs and labels. */
|
|
57
16
|
document?: CanvasFactory;
|
|
@@ -60,19 +19,32 @@ type UrbanThreeOptions = {
|
|
|
60
19
|
vehicle?: PlacementResolver;
|
|
61
20
|
plant?: PlacementResolver;
|
|
62
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* The host's light budget: each `light` part becomes a source of it (it competes for a slot by distance; a flickering lamp and a sweeping searchlight update their source) instead of a real
|
|
24
|
+
* light of the scene. `DrawnUrban.lights` then lists the sources. Without it the lights are created here (deprecated, removed in the next major).
|
|
25
|
+
*/
|
|
26
|
+
lights?: LightBudget;
|
|
63
27
|
};
|
|
64
28
|
/** What a drawn scene gives back: the group to add to a scene, the per-frame animation and the cleanup. */
|
|
65
29
|
type DrawnUrban = {
|
|
66
|
-
root:
|
|
30
|
+
root: Obj;
|
|
67
31
|
/** Moves the animated parts to time `t` (seconds): flickering lamps and sweeping searchlights. */
|
|
68
32
|
animate(t: number): void;
|
|
69
|
-
/** Lights drawn, for a budget meter. */
|
|
70
|
-
readonly lights:
|
|
33
|
+
/** Lights drawn, for a budget meter: the lights of the scene, or (with `UrbanThreeOptions.lights`) a `BudgetedLamp` for each: its bulb in the scene and its source of the budget. */
|
|
34
|
+
readonly lights: DrawnLight[];
|
|
71
35
|
dispose(): void;
|
|
72
36
|
};
|
|
37
|
+
/** A light part drawn through the budget: the node it hangs from, the part that describes it (distance, colour...) and the source that competes for a slot. */
|
|
38
|
+
type BudgetedLamp = {
|
|
39
|
+
readonly bulb: Obj;
|
|
40
|
+
readonly part: LightPart;
|
|
41
|
+
readonly source: SourceHandle;
|
|
42
|
+
};
|
|
43
|
+
/** A light of `DrawnUrban.lights`: a light of the scene, or a lamp drawn through the budget. */
|
|
44
|
+
type DrawnLight = UrbanLight | BudgetedLamp;
|
|
73
45
|
type DrawOptions = {
|
|
74
46
|
/** Group the parts go into. Default a new `THREE.Group`. */
|
|
75
|
-
root?:
|
|
47
|
+
root?: Obj;
|
|
76
48
|
};
|
|
77
49
|
/**
|
|
78
50
|
* Draws urban scenes with three.js the way the team's page does: a mesh per part in the order they were added (boxes with the
|
|
@@ -80,91 +52,15 @@ type DrawOptions = {
|
|
|
80
52
|
* the small boxes and one for each kind of window. Materials are shared by colour. The instance matrices are the page's.
|
|
81
53
|
*/
|
|
82
54
|
declare function createUrbanThree(THREE: Three$1, options?: UrbanThreeOptions): {
|
|
83
|
-
THREE:
|
|
55
|
+
THREE: typeof THREE_NS;
|
|
84
56
|
draw: (scene: UrbanScene, drawOptions?: DrawOptions) => DrawnUrban;
|
|
85
57
|
};
|
|
86
58
|
type UrbanThree = ReturnType<typeof createUrbanThree>;
|
|
87
59
|
|
|
88
|
-
type Three =
|
|
60
|
+
type Three = typeof THREE_NS;
|
|
89
61
|
/** The team's rounded box: a 4x4x4 grid per face with the edge vertices pushed onto an arc of the given radius (smooth normals). A radius of 0 is a plain box. */
|
|
90
|
-
declare function createRoundedBox(THREE: Three, width: number, height: number, depth: number, radius: number):
|
|
62
|
+
declare function createRoundedBox(THREE: Three, width: number, height: number, depth: number, radius: number): THREE_NS.BufferGeometry;
|
|
91
63
|
/** Triangle prism: the triangle `width` wide and `height` high, extruded `depth` long and centred on z. Base at y = 0. */
|
|
92
|
-
declare function createPrism(THREE: Three, width: number, height: number, depth: number):
|
|
93
|
-
|
|
94
|
-
type UrbanTestOptions = {
|
|
95
|
-
/** `en` or `pt-BR` (default). The room asks `items(locale)` and `scenarios(locale)` itself; this is the language of the bench and of the signs of the neighbourhoods. */
|
|
96
|
-
readonly locale?: string;
|
|
97
|
-
/** Seed of the fixed samples of the area (default 7, the Galeria's). */
|
|
98
|
-
readonly seed?: number;
|
|
99
|
-
/** Options of the urban kit the area draws with (packs, patches, removals): a game's own catalogues show up in the area. */
|
|
100
|
-
readonly urban?: UrbanOptions;
|
|
101
|
-
/** The terrain of the terrain patch (default a small rolling plain with a river and a lake). */
|
|
102
|
-
readonly terrain?: TerrainOptions;
|
|
103
|
-
/** Where canvases come from for the signs; default the page's `document`. */
|
|
104
|
-
readonly document?: CanvasFactory;
|
|
105
|
-
/** Builds the vehicles of the fleet for the `vehicle` provider of the bench (`createVehiclesThree` of `game-vehicles-three`). Without it the bench parks no cars. */
|
|
106
|
-
readonly vehicles?: (THREE: unknown) => VehicleBuilder;
|
|
107
|
-
/** Where the bench draws its neighbourhood in the room, `[x, z]` (default `[0, -60]`). */
|
|
108
|
-
readonly benchOrigin?: readonly [number, number];
|
|
109
|
-
};
|
|
110
|
-
/** What a scenario needs of the room: the pass/fail line and time. The checks of this area are on the kit's own numbers, so no object of the room is touched. */
|
|
111
|
-
type UrbanContext = {
|
|
112
|
-
expect(condition: boolean, label: string, data?: Record<string, unknown>): void;
|
|
113
|
-
step(seconds: number): void;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
declare const URBAN_AREA_ID = "urban";
|
|
117
|
-
/** The default terrain patch of the area: a rolling plain 96 m wide with a river across it and a round lake. A game passes its own through `terrain`. */
|
|
118
|
-
declare const DEFAULT_TEST_TERRAIN: TerrainOptions;
|
|
119
|
-
/**
|
|
120
|
-
* The urban test area as a `TestableModule`: the five poles of the Galeria in a row, a street grid with a filled block, a patch of terrain and the ten neighbourhoods of the
|
|
121
|
-
* sample sheet in its cells, each drawn by the kit and `game-urban-three` (so a game that patches the catalogues sees its own). The bench draws any neighbourhood in front of the player with
|
|
122
|
-
* a seed, a share of lamps on, a light budget and, when asked, the vehicles of the fleet and the species of the region; its layers show the reach of the real lights and the box of each sample.
|
|
123
|
-
*/
|
|
124
|
-
declare function createUrbanTestModule(options?: UrbanTestOptions): TestableModule<UrbanContext> & {
|
|
125
|
-
readonly placed: ReadonlyMap<string, unknown>;
|
|
126
|
-
tick(t: number): void;
|
|
127
|
-
readonly itemIds: readonly string[];
|
|
128
|
-
};
|
|
129
|
-
/** What `loadUrbanTestModule` needs of a room: `TestRoom.loadModule` has it. */
|
|
130
|
-
type ModuleRoomLike = {
|
|
131
|
-
loadModule(module: never): unknown;
|
|
132
|
-
};
|
|
133
|
-
/** Loads the urban module into a room. */
|
|
134
|
-
declare function loadUrbanTestModule<Room extends ModuleRoomLike>(room: Room, options?: UrbanTestOptions): ReturnType<Room['loadModule']>;
|
|
135
|
-
|
|
136
|
-
/** Words and sentences of the urban area, by locale. `{0}`, `{1}`... are filled in order. */
|
|
137
|
-
type UrbanText = {
|
|
138
|
-
group: string;
|
|
139
|
-
name: string;
|
|
140
|
-
items: Record<string, string>;
|
|
141
|
-
controls: Record<'pattern' | 'seed' | 'lamps' | 'budget' | 'providers', string>;
|
|
142
|
-
hints: Record<'pattern' | 'seed' | 'lamps' | 'budget' | 'providers', string>;
|
|
143
|
-
options: {
|
|
144
|
-
lamps: Record<string, string>;
|
|
145
|
-
providers: Record<string, string>;
|
|
146
|
-
};
|
|
147
|
-
actions: Record<'compose' | 'clear', string>;
|
|
148
|
-
layers: Record<'light_radius' | 'bounds', string>;
|
|
149
|
-
metrics: Record<'samples' | 'draw_calls' | 'triangles' | 'real_lights' | 'instances' | 'bench_objects' | 'light_budget_left', string>;
|
|
150
|
-
log: Record<'composed' | 'cleared' | 'no_vehicles', string>;
|
|
151
|
-
scenarios: Record<string, string>;
|
|
152
|
-
checks: Record<string, string>;
|
|
153
|
-
};
|
|
154
|
-
declare const TEXT: Record<string, UrbanText>;
|
|
155
|
-
|
|
156
|
-
/** The heights of the five poles of the Galeria (m), the tops measured on the page's scenes. A game's own poles are not checked. */
|
|
157
|
-
declare const POLE_TOPS: Readonly<Record<string, number>>;
|
|
158
|
-
type ScenarioDeps = {
|
|
159
|
-
readonly text: UrbanText;
|
|
160
|
-
readonly urban: UrbanOptions | undefined;
|
|
161
|
-
readonly terrain: TerrainOptions;
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* The scenarios of the urban area: checks on the numbers the kit promises (the poles' heights, the light budget, the dashes of a road,
|
|
165
|
-
* the heights of a block, the determinism of a neighbourhood, burnt-out lamps, the terrain, the providers). They need no object of the
|
|
166
|
-
* room, so a game that patches the catalogues sees at once what it changed.
|
|
167
|
-
*/
|
|
168
|
-
declare const createScenarios: (deps: ScenarioDeps) => ModuleScenario<UrbanContext>[];
|
|
64
|
+
declare function createPrism(THREE: Three, width: number, height: number, depth: number): THREE_NS.BufferGeometry;
|
|
169
65
|
|
|
170
|
-
export { type
|
|
66
|
+
export { type BudgetedLamp, CanvasFactory, type DrawOptions, type DrawnLight, type DrawnUrban, PlacementResolver, type UrbanLight, type UrbanThree, type UrbanThreeOptions, createPrism, createRoundedBox, createUrbanThree };
|