@adatechnology/game-urban-three 0.2.1 → 0.2.3

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/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/draw.ts
2
+ import { markKitOrigin } from "@adatechnology/game-contracts";
2
3
  import { shapeGeometries as shapeGeometries2 } from "@adatechnology/game-shapes-three";
3
4
 
4
5
  // src/rounded-box.ts
@@ -308,7 +309,7 @@ function createUrbanThree(THREE, options = {}) {
308
309
  return mesh;
309
310
  };
310
311
  function draw(scene, drawOptions = {}) {
311
- const root = drawOptions.root ?? new THREE.Group();
312
+ const root = markKitOrigin(drawOptions.root ?? new THREE.Group(), { owner: "game-urban-three", kind: "urban" });
312
313
  const animators = [];
313
314
  const lights = [];
314
315
  const objects = [];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/draw.ts","../src/rounded-box.ts","../src/text.ts","../src/resolvers.ts","../src/test-area/module.ts","../src/test-area/scenarios.ts","../src/test-area/text.ts"],"sourcesContent":["import type { ItemBox, PartStyle, SilhouetteWindow, UrbanPart, UrbanScene } from '@adatechnology/game-urban'\nimport { shapeGeometries } from '@adatechnology/game-shapes-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 = any\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\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: any\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. */\n readonly lights: any[]\n dispose(): void\n}\n\nexport type DrawOptions = {\n /** Group the parts go into. Default a new `THREE.Group`. */\n root?: any\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) as Three\n const geometries = new Map<string, any>()\n const materials = new Map<string, any>()\n const disposables: any[] = []\n\n const standard = (color: number, style?: PartStyle, flat = false): any => {\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): any => {\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): any => {\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: any, 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): any => {\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: any): any => {\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 drawPart = (part: UrbanPart, animators: ((t: number) => void)[], lights: any[]): any[] => {\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 (part.kind === 'point') {\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 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[]): any => {\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: any): any => {\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 = drawOptions.root ?? new THREE.Group()\n const animators: ((t: number) => void)[] = []\n const lights: any[] = []\n const objects: any[][] = []\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 any[])[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 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\ntype Three = any\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): any {\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): any {\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","type Three = any\n\n/** What `document.createElement('canvas')` needs; a fake works in Node. */\nexport type CanvasFactory = { createElement(tag: string): any }\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): any {\n const canvas = document.createElement('canvas')\n canvas.width = o.width\n canvas.height = o.height\n const g = canvas.getContext('2d')\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 } from '@adatechnology/game-vegetation-species'\nimport type { BuildVehicleOptions } from '@adatechnology/game-vehicles-three'\nimport type { PlacementPart } from '@adatechnology/game-urban'\n\ntype Three = any\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) => any | null) & { dispose?: () => void }\n\nconst cssColor = (value: number): string => `#${value.toString(16).padStart(6, '0')}`\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?: BuildVehicleOptions['quality']\n}\n\n/** What the vehicle resolver needs of `createVehiclesThree`. */\nexport type VehicleBuilder = { build(key: string, options?: BuildVehicleOptions): { group: any; 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: any; 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 /** 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 of `game-vegetation-species`, 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, any | null>()\n const resolve: PlacementResolver = (part) => {\n const key = `${part.id}|${part.seed}`\n if (!made.has(key)) {\n try {\n const mesh = generate(toSpec(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: any) => o.geometry?.dispose?.())\n }\n made.clear()\n }\n return resolve\n}\n","import 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 = any\ntype Placed = { root: any; drawn: DrawnUrban }\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\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: any[] = []\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 })\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 = createPlantProvider()\n if ((choice === 'vehicles' || choice === 'both') && options.vehicles) providers.vehicle = createVehicleProvider()\n return providers\n }\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) }).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\n const made = sample(THREE as 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\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: any): 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) }).draw(b.scene())\n drawn.root.position.set(benchOrigin[0], FLOOR_Y, benchOrigin[1])\n ;(host.scene as any).add(drawn.root)\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 for (const helper of helpers) helper.parent?.remove(helper)\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: any, helper: any): 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 light of entry.drawn.lights) {\n if (!light.isPointLight && !light.isSpotLight) continue\n const reach = new three.Mesh(new (shapeGeometries(three) as any).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.position)\n mark(light.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) if (!entry.root.parent) placed.delete(id)\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: any) => {\n if (o.isLight) lights += 1\n if (!o.isMesh || o.userData.helper) return\n for (let p = o; p; p = p.parent) if (p.visible === false) return\n drawCalls += 1\n if (o.isInstancedMesh) instances += o.count\n const g = o.geometry\n const perInstance = (g.index ? g.index.count : g.attributes.position.count) / 3\n triangles += perInstance * (o.isInstancedMesh ? o.count : 1)\n })\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 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\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 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 { createPlantProvider, createUrban, createVehicleProvider, PARKED_VEHICLE_IDS } 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\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() } })\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) => PARKED_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() } })\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":["shapeGeometries","shapeGeometries","light","createPlantProvider","createUrban","createVehicleProvider","shapeGeometries","createUrban","createPlantProvider","createVehicleProvider","shapeGeometries","placements"]}
1
+ {"version":3,"sources":["../src/draw.ts","../src/rounded-box.ts","../src/text.ts","../src/resolvers.ts","../src/test-area/module.ts","../src/test-area/scenarios.ts","../src/test-area/text.ts"],"sourcesContent":["import { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { ItemBox, PartStyle, SilhouetteWindow, UrbanPart, UrbanScene } from '@adatechnology/game-urban'\nimport { shapeGeometries } from '@adatechnology/game-shapes-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 = any\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\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: any\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. */\n readonly lights: any[]\n dispose(): void\n}\n\nexport type DrawOptions = {\n /** Group the parts go into. Default a new `THREE.Group`. */\n root?: any\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) as Three\n const geometries = new Map<string, any>()\n const materials = new Map<string, any>()\n const disposables: any[] = []\n\n const standard = (color: number, style?: PartStyle, flat = false): any => {\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): any => {\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): any => {\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: any, 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): any => {\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: any): any => {\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 drawPart = (part: UrbanPart, animators: ((t: number) => void)[], lights: any[]): any[] => {\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 (part.kind === 'point') {\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 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[]): any => {\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: any): any => {\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: any[] = []\n const objects: any[][] = []\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 any[])[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 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\ntype Three = any\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): any {\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): any {\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","type Three = any\n\n/** What `document.createElement('canvas')` needs; a fake works in Node. */\nexport type CanvasFactory = { createElement(tag: string): any }\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): any {\n const canvas = document.createElement('canvas')\n canvas.width = o.width\n canvas.height = o.height\n const g = canvas.getContext('2d')\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 } from '@adatechnology/game-vegetation-species'\nimport type { BuildVehicleOptions } from '@adatechnology/game-vehicles-three'\nimport type { PlacementPart } from '@adatechnology/game-urban'\n\ntype Three = any\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) => any | null) & { dispose?: () => void }\n\nconst cssColor = (value: number): string => `#${value.toString(16).padStart(6, '0')}`\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?: BuildVehicleOptions['quality']\n}\n\n/** What the vehicle resolver needs of `createVehiclesThree`. */\nexport type VehicleBuilder = { build(key: string, options?: BuildVehicleOptions): { group: any; 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: any; 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 /** 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 of `game-vegetation-species`, 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, any | null>()\n const resolve: PlacementResolver = (part) => {\n const key = `${part.id}|${part.seed}`\n if (!made.has(key)) {\n try {\n const mesh = generate(toSpec(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: any) => o.geometry?.dispose?.())\n }\n made.clear()\n }\n return resolve\n}\n","import 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 = any\ntype Placed = { root: any; drawn: DrawnUrban }\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\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: any[] = []\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 })\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 = createPlantProvider()\n if ((choice === 'vehicles' || choice === 'both') && options.vehicles) providers.vehicle = createVehicleProvider()\n return providers\n }\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) }).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\n const made = sample(THREE as 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\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: any): 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) }).draw(b.scene())\n drawn.root.position.set(benchOrigin[0], FLOOR_Y, benchOrigin[1])\n ;(host.scene as any).add(drawn.root)\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 for (const helper of helpers) helper.parent?.remove(helper)\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: any, helper: any): 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 light of entry.drawn.lights) {\n if (!light.isPointLight && !light.isSpotLight) continue\n const reach = new three.Mesh(new (shapeGeometries(three) as any).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.position)\n mark(light.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) if (!entry.root.parent) placed.delete(id)\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: any) => {\n if (o.isLight) lights += 1\n if (!o.isMesh || o.userData.helper) return\n for (let p = o; p; p = p.parent) if (p.visible === false) return\n drawCalls += 1\n if (o.isInstancedMesh) instances += o.count\n const g = o.geometry\n const perInstance = (g.index ? g.index.count : g.attributes.position.count) / 3\n triangles += perInstance * (o.isInstancedMesh ? o.count : 1)\n })\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 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\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 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 { createPlantProvider, createUrban, createVehicleProvider, PARKED_VEHICLE_IDS } 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\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() } })\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) => PARKED_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() } })\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":["shapeGeometries","shapeGeometries","light","createPlantProvider","createUrban","createVehicleProvider","shapeGeometries","createUrban","createPlantProvider","createVehicleProvider","shapeGeometries","placements"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adatechnology/game-urban-three",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "license": "MIT",
5
5
  "description": "Draws the urban pattern of game-urban with three.js: parts as meshes with the team's rounded boxes, instanced road dashes and windows (lit and dark), canvas signs and labels, point and spot lights from the light budget, and the animations (flickering lamps, sweeping searchlights).",
6
6
  "keywords": [
@@ -38,13 +38,13 @@
38
38
  "dist"
39
39
  ],
40
40
  "dependencies": {
41
- "@adatechnology/game-contracts": "0.14.0",
41
+ "@adatechnology/game-contracts": "0.16.0",
42
42
  "@adatechnology/game-floorplan": "0.2.2",
43
43
  "@adatechnology/game-shapes-three": "0.1.1",
44
- "@adatechnology/game-urban": "0.2.1",
44
+ "@adatechnology/game-urban": "0.2.3",
45
45
  "@adatechnology/game-vegetation": "0.2.0",
46
46
  "@adatechnology/game-vegetation-species": "0.2.0",
47
- "@adatechnology/game-vehicles-three": "0.3.0"
47
+ "@adatechnology/game-vehicles-three": "0.3.2"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "^22.10.7",
@@ -54,8 +54,8 @@
54
54
  "tsup": "^8.5.1",
55
55
  "typescript": "^5.7.3",
56
56
  "vitest": "^3.2.4",
57
- "@adatechnology/game-test-room": "0.12.0",
58
- "@adatechnology/golden-tool": "0.0.0"
57
+ "@adatechnology/golden-tool": "0.0.0",
58
+ "@adatechnology/game-test-room": "0.15.0"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "three": ">=0.160.0"