@adatechnology/game-destruction-three 0.17.2 → 0.18.0

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/audio/impact-keys.ts","../src/renderer.ts","../src/fragments.ts","../src/fitted-boxes.ts","../src/math.ts","../src/fragment-shapes.ts","../src/ground.ts","../src/pieces.ts","../src/rebar.ts","../src/spec.ts","../src/heat.ts","../src/skin-dent.ts","../src/visual.ts","../src/audio/recipes.ts","../src/audio/blast-fire.ts","../src/audio/sound.ts","../src/audio/samples.ts"],"sourcesContent":["import type { DamageType, MaterialDef } from '@adatechnology/game-destruction'\n\nimport type { SoundDetail } from '../types'\n\n/**\n * The sound family of a material, from its tags: what it sounds like when something meets it. Finer than the five keys of `impactKey` (which stay the\n * last fallback): ceramic is not glass, the ground is not concrete, plastic and wax are not wood, leaves are not a sofa.\n */\nexport type ImpactFamily = 'metal' | 'glass' | 'ceramic' | 'soil' | 'masonry' | 'wood' | 'plant' | 'plastic' | 'rubber' | 'wax' | 'soft'\n\n/** Tag → family, in the order they are tried (`green_wood` is `plant` and `wood`: wood wins; `gravel` is `soil` and `masonry`: soil wins). */\nexport const IMPACT_FAMILY_TAGS: readonly (readonly [tag: string, family: ImpactFamily])[] = [\n ['metal', 'metal'],\n ['glass', 'glass'],\n ['ceramic', 'ceramic'],\n ['soil', 'soil'],\n ['masonry', 'masonry'],\n ['wood', 'wood'],\n ['plant', 'plant'],\n ['plastic', 'plastic'],\n ['rubber', 'rubber'],\n ['wax', 'wax'],\n ['fabric', 'soft'],\n]\n\n/** The family of a material, or `undefined` when none of its tags names one (the five legacy keys of `impactKey` then answer). */\nexport function impactFamily(def: MaterialDef | undefined): ImpactFamily | undefined {\n const tags = def?.tags ?? []\n for (const [tag, family] of IMPACT_FAMILY_TAGS) if (tags.includes(tag)) return family\n return undefined\n}\n\n/** What an impact or a break sends with its key: the keys to try before it, most specific first (material and blow, material, family and blow, family). */\nexport type ImpactKeys = SoundDetail & { readonly keys: readonly string[] }\n\nconst ordered = (prefix: string, material: string, family: ImpactFamily | undefined, blow: DamageType | undefined): string[] => {\n const keys: string[] = []\n if (material && blow) keys.push(`${prefix}_${material}_${blow}`)\n if (material) keys.push(`${prefix}_${material}`)\n if (family && blow) keys.push(`${prefix}_${family}_${blow}`)\n if (family) keys.push(`${prefix}_${family}`)\n return keys\n}\n\n/**\n * The impact keys for a blow on a material, most specific first: `impact_<material>_<blow>`, `impact_<material>`, `impact_<family>_<blow>`,\n * `impact_<family>` (blow is the `DamageType`: `ballistic`, `blunt`, `slash`, `explosive`...). The legacy `impactKey` is the last fallback the caller sends as the key.\n */\nexport function impactSoundKeys(material: string, def: MaterialDef | undefined, blow?: DamageType): ImpactKeys {\n return { keys: ordered('impact', material, impactFamily(def), blow) }\n}\n\n/** The keys for a part of this material breaking, most specific first: `break_<material>_<blow>`, `break_<material>`, `break_<family>_<blow>`, `break_<family>`. */\nexport function breakSoundKeys(material: string, def: MaterialDef | undefined, blow?: DamageType): ImpactKeys {\n return { keys: ordered('break', material, impactFamily(def), blow) }\n}\n\n/** The keys for a round glancing off a part of this material: `ricochet_<material>`, `ricochet_<family>` (then the plain `ricochet`). */\nexport function ricochetSoundKeys(material: string, def: MaterialDef | undefined): ImpactKeys {\n return { keys: ordered('ricochet', material, impactFamily(def), undefined) }\n}\n","import type * as THREE_NS from 'three'\nimport type { DamageType, DebrisKind, DestructionEvent, DestructionEventType, Fragment, MaterialDef, PartSpec, Vec3 } from '@adatechnology/game-destruction'\nimport { breakSoundKeys, impactSoundKeys, ricochetSoundKeys } from './audio/impact-keys'\nimport { DEFERRED_QUEUE_ID, blastShove, warnOnce } from '@adatechnology/game-contracts'\nimport { createVfx, effectForEvent, EVENT_EFFECTS_MAP } from '@adatechnology/game-vfx'\nimport type { GameEvent } from '@adatechnology/game-vfx'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport { createVfxRenderer } from '@adatechnology/game-vfx-three'\nimport type { VfxRenderer } from '@adatechnology/game-vfx-three'\nimport { FragmentSystem } from './fragments'\nimport { GroundSpots } from './ground'\nimport type { Bound, HostVis, MeshVis, PartVis, PieceBody } from './internal'\nimport { clamp, createRng, hashNumbers, hashString, mixHex } from './math'\nimport { PieceSystem } from './pieces'\nimport type { PieceSweepHit } from './pieces'\nimport { RebarCages } from './rebar'\nimport { partHintOf, specFrameInverse } from './spec'\nimport { kitOriginOf } from '@adatechnology/game-contracts'\nimport type { DeferredQueue, WarmUpProbes } from '@adatechnology/game-contracts'\nimport type { DestructionRenderer, BindOptions, ExplodeOptions, Mesh, MeshRange, Object3D, Piece, RendererOptions, SolidBox, SoundDetail, ThreeNamespace } from './types'\nimport { showCollapsedRanges, Visuals } from './visual'\n\nlet rendererCount = 0\n/** Mass (kg) a collapse of furniture must bring down to raise the collapse effect's cloud; less (a shelf with its books) raises a puff of dust. */\nconst COLLAPSE_CLOUD_KG = 1000\n/** Colour of bare rebar (the cages' material) and of a bar that came down; the steel of a bar weighs this much per cubic metre when the catalogue has no steel. */\nconst REBAR_COLOR = 0x74665c\nconst STEEL_DENSITY = 7850\n/** Metres around a unit that came out within which its decals go too: the plaster over it and the ragged edge that breaks with it. */\nconst CHIP_DECAL_EDGE = 0.05\n/** Radius of the rim of torn fibres around a hole in wood, in hole diameters. */\nconst WOOD_RIM = 1.5\nconst IMPACT_TAGS = ['metal', 'glass', 'wood'] as const\n\ntype Ev<T extends DestructionEvent['type']> = Extract<DestructionEvent, { type: T }>\n\nconst GLOW_FROM_C = 430\nconst QUEUE_CAP = 4000\n/**\n * Events the queue takes past `QUEUE_CAP`: what changes what is drawn (a part breaking off, a storey coming down, a fire starting or going out). A blast\n * floods the queue with damage, melt and drip events; dropping a collapse behind them leaves a fallen wall drawn standing.\n */\nconst STRUCTURAL_EVENTS: ReadonlySet<DestructionEventType> = new Set<DestructionEventType>([\n 'fracture', 'detach', 'collapse', 'settle', 'destroyed', 'expose', 'stage', 'hole', 'ignite', 'primed', 'extinguish', 'burnout', 'leak', 'explode',\n])\n/** Fragments of a fracture spawned in one go before the frame budget is looked at, so a small break is never split over frames. */\nconst MIN_FRAGMENTS_PER_SLICE = 8\n/** Seconds the boxes of the fixed objects the pieces land on are kept without an event (a host may move a root). */\nconst STATIC_REFRESH = 0.5\n/**\n * Milliseconds of the periodic re-measure per call: the refresh walks the objects a slice at a time (the dirty ones are measured at once).\n * Measuring every object in one call cost up to 88 ms in a frame of the horde chain (perf.mjs, software GL, 2026-11-03).\n */\nconst STATIC_REFRESH_SLICE_MS = 1\n/** Widest mesh (m, along x or z) a piece lands on by its box: furniture and things; a wider one (a roof, a merged room) would hold it on air. */\nconst STATIC_SPAN = 3\n/** What counts as a foot of a piece (m above its lowest point); from what height (m) it can fall over and how close its feet are for that (share of the height). */\nconst FEET_BAND = 0.03\nconst TIP_MIN_HEIGHT = 0.3\nconst TIP_NARROW = 0.3\n/** A part's fire lasts until the part stops burning (`stopFire`); this is only the ceiling the effects world needs. */\nconst FIRE_CEILING_SECONDS = 3600\n/** The `generic` explosion is the M67's (15 m injury radius): a blast with no effect id of its own scales with its radius. */\nconst GENERIC_REFERENCE_RADIUS = 15\n/** Largest half size (m) of the core of a piece swept for what it runs into: a sofa sweeps a small box at its centre, not the whole of it. */\nconst SWEEP_CORE = 0.15\n/** The small flame of a part that a bullet or fire primed: it burns until the part goes off. */\nconst PRIMED_FIRE_RADIUS = 0.2\n\ninterface FireEmitter {\n object: string\n part: string\n point: Vec3\n /** The burning part's position, moved every frame; the effects world's fire follows it. */\n follow: { x: number; y: number; z: number }\n /** Handle of the fire in the effects world, once the part's box is known. */\n handle?: number\n}\n\ninterface Leak {\n object: string\n part: string\n fluid: string\n point: Vec3\n direction: Vec3\n rate: number\n pressurized: boolean\n acc: number\n /** The part had a through opening when the leak began: the leak ends when it has none (a valve shut with `seal`). */\n opened: boolean\n localPoint?: Vec3\n localDirection?: Vec3\n lastLiters?: number\n idleSeconds?: number\n life?: number\n}\n\nconst FLUID_COLORS: Record<string, number> = {\n water: 0x8cc8ff,\n fuel: 0xd9a032,\n oil: 0x2a2018,\n gas: 0xf2f2f2,\n sap: 0xb89b3a,\n acid: 0x9bd23c,\n blood: 0x8a0a0a,\n soda: 0x3a1e12,\n coffee: 0x3b2414,\n beer: 0xd9953c,\n milk: 0xf4f1ea,\n wine: 0x6b101f,\n juice: 0xe8870b,\n}\nconst SMOKE_TONES: Record<string, number> = { white: 0xe6e6e6, grey: 0x8a8a8a, black: 0x2a2a2a }\n\nconst DEFAULT_SPEED: Record<string, number> = {\n sparks: 3,\n splinters: 2.5,\n dust: 1,\n shards: 2.5,\n fibers: 1.2,\n leaves: 1.2,\n drips: 0.5,\n ash: 0.8,\n chips: 2.5,\n smoke: 0.8,\n steam: 1,\n fire: 1.2,\n flash: 0,\n foam: 2.5,\n}\n\n/** Sound key for an impact on a material. */\nexport function impactKey(def: MaterialDef | undefined): string {\n if (!def) return 'impact_wood'\n const tags = def.tags ?? []\n if (tags.includes('metal')) return 'impact_metal'\n if (def.visual?.transparent || def.fracture === 'shatter') return 'impact_glass'\n if (def.fracture === 'crumble') return 'impact_masonry'\n if (def.fracture === 'tear') return 'impact_soft'\n return def.fracture === 'none' ? 'impact_metal' : 'impact_wood'\n}\n\n/** Sound key (`shot_*`) of a round striking this material: sharper than a blow (a tink on steel, a crack on glass); a host without it plays the `impact_*`. */\nexport const shotKey = (def: MaterialDef | undefined): string => impactKey(def).replace('impact_', 'shot_')\n\n/** Sound key (`drag_*`) of a base of this material dragged on a floor. */\nexport const dragSoundKey = (def: MaterialDef | undefined): string => impactKey(def).replace('impact_', 'drag_')\n\nfunction fractureKey(def: MaterialDef | undefined, style: string): string {\n switch (style) {\n case 'shatter':\n return 'shatter_glass'\n case 'crumble':\n return 'crumble'\n case 'splinter':\n return 'splinter'\n default:\n return impactKey(def)\n }\n}\n\nfunction fallbackColor(id: string, def: MaterialDef | undefined): number {\n if (def?.tags?.includes('metal')) return 0x8a8f96\n if (def?.visual?.transparent) return 0x9fd0e0\n const h = hashString(id)\n return mixHex(0x6b5a48, 0x9a9488, (h % 100) / 100)\n}\n\nfunction materialsOf(m: THREE_NS.Material | THREE_NS.Material[]): THREE_NS.Material[] {\n return Array.isArray(m) ? m : [m]\n}\n\nfunction isMeshRange(v: Object3D | MeshRange): v is MeshRange {\n const r = v as Partial<MeshRange>\n return !!r.mesh && Array.isArray(r.range)\n}\n\n/** Create the renderer. See `DestructionRenderer`. */\n/** The seed of the renderer's random stream; `reset` takes it back here. */\nconst RNG_SEED = 0xc0ffee\n\n/** The renderer this package makes always has its `deferredQueue`; a third-party `DestructionRenderer` may leave it out. */\nexport function createDestructionRenderer(THREE: ThreeNamespace, options: RendererOptions): DestructionRenderer & { deferredQueue(): DeferredQueue } {\n return new Renderer(THREE, options)\n}\n\nclass Renderer implements DestructionRenderer {\n private readonly world: RendererOptions['world']\n private readonly scene: THREE_NS.Scene\n private readonly quality: 'low' | 'medium' | 'high'\n private readonly low: boolean\n private readonly groundAt: (x: number, z: number) => number\n private readonly gravity: number\n private readonly autoSplit: boolean\n private readonly maxFragments: number\n private readonly eventBudgetMs: number\n private readonly bounds = new Map<string, Bound>()\n /** World boxes (min xyz, max xyz) of the drawn meshes of the bound objects that are not pieces, for the pieces to land on. */\n private readonly staticBoxes = new Map<string, number[]>()\n /** Objects to measure again; `staticAll` measures every one. */\n private readonly staticDirty = new Set<string>()\n private staticAll = true\n /** The periodic refresh: the objects still to measure again in this round, a slice per call. */\n private staticRound: string[] = []\n /** Boxes of the pieces' meshes (as `staticBoxes`), with the time they were measured. */\n private readonly pieceBoxes = new WeakMap<PieceBody, { at: number; boxes: number[] }>()\n private staticAt = 0\n private readonly queue: DestructionEvent[] = []\n /** The cover of each body around a part of the world that went off, read as the event is emitted: before the blast tore or moved anything. */\n private readonly coverWhenWentOff = new WeakMap<DestructionEvent, Map<string, number>>()\n /** Presentation work an event left for later frames (fragments still to spawn, loose groups still to split), run in order within the frame budget. */\n private readonly slices: Array<() => void> = []\n /** When the work of this frame must stop; `Infinity` outside a drain, where a call finishes what it started. */\n private sliceDeadline = Infinity\n /** The clock the drain reads; a budget lends its own while it runs the queue. */\n private drainClock: () => number = () => performance.now()\n /** true once a frame budget owns the draining: `update` no longer drains by itself. */\n private attached = false\n private readonly eventQueue: DeferredQueue = {\n id: DEFERRED_QUEUE_ID.DESTRUCTION_EVENTS,\n pending: () => this.queue.length + this.slices.length,\n run: (deadline, clock) => this.runBudgeted(deadline, clock),\n flush: () => {\n for (let guard = 0; guard < 16 && this.queue.length + this.slices.length > 0; guard++) this.runBudgeted(Infinity, () => 0)\n },\n attach: () => {\n this.attached = true\n },\n detach: () => {\n this.attached = false\n },\n }\n private readonly unsubscribe: () => void\n private readonly visuals: Visuals\n private readonly fragments: FragmentSystem\n private readonly ground: GroundSpots\n private readonly pieceSys: PieceSystem\n private readonly cages: RebarCages\n private readonly active = new Map<string, { object: string; part: string }>()\n private readonly fires = new Map<string, FireEmitter>()\n /** Primed parts burning in the effects world until they go off: their burn loop ends when they are put out. */\n private readonly primedBurning = new Set<string>()\n private readonly leaks: Leak[] = []\n private readonly homeTags: string[] = []\n private readonly throttles = new Map<string, number>()\n private rng = createRng(RNG_SEED)\n private readonly vfx: VfxWorld\n /** Names this renderer to the world's drips, so a shared world tells each renderer where its own landed. */\n private readonly owner = `destruction-${++rendererCount}`\n private readonly stopLanding: () => void\n /** The effects renderer made here when the host gave no shared world; it is stepped in `update`. */\n private readonly ownVfx: VfxRenderer | undefined\n private time = 0\n private scanTimer = 0\n private disposed = false\n private readonly box: THREE_NS.Box3\n private readonly tmpQ: THREE_NS.Quaternion\n private readonly v1: THREE_NS.Vector3\n private readonly v2: THREE_NS.Vector3\n\n constructor(\n private readonly THREE: ThreeNamespace,\n private readonly o: RendererOptions,\n ) {\n this.world = o.world\n this.scene = o.scene\n this.quality = o.quality ?? 'medium'\n this.low = this.quality === 'low'\n this.groundAt = o.groundAt ?? (() => 0)\n this.gravity = o.gravity ?? 9.81\n this.autoSplit = o.autoSplit !== false\n this.maxFragments = o.maxFragments ?? 160\n this.eventBudgetMs = o.eventBudgetMs ?? Infinity\n this.box = new THREE.Box3()\n this.tmpQ = new THREE.Quaternion()\n this.v1 = new THREE.Vector3()\n this.v2 = new THREE.Vector3()\n const maxParticles = Math.max(8, Math.floor((o.maxParticles ?? 2500) * (this.low ? 0.5 : 1)))\n this.visuals = new Visuals(THREE, this.low, 600)\n this.ground = new GroundSpots(THREE, o.scene, this.groundAt, 48)\n if (!o.vfx) warnOnce('game-destruction-three.own-effects-world', 'game-destruction-three made an effects world of its own because the host lent none (options.vfx); pass the host effects so the effects share one budget')\n this.vfx = o.vfx ?? createVfx({ profile: this.quality, gravity: this.gravity, groundAt: this.groundAt, sprites: { capacity: maxParticles, density: this.low ? 0.6 : 1 } })\n this.ownVfx = o.vfx ? undefined : createVfxRenderer(THREE, { scene: o.scene, camera: o.camera ?? new THREE.PerspectiveCamera(), vfx: this.vfx, pointScale: o.pointScale ?? 700 })\n this.stopLanding = this.vfx.onLand(this.owner, (x, _y, z, color, tag) => {\n const home = this.homeTags[tag - 1] ?? ''\n this.ground.add('puddle', x, z, 0.05 + this.rng() * 0.04, color, home)\n })\n this.fragments = new FragmentSystem(THREE, {\n scene: o.scene,\n groundAt: this.groundAt,\n gravity: this.gravity,\n max: this.maxFragments,\n life: o.fragmentLife ?? 12,\n formOf: (id) => this.world.materials.get(id)?.splitForm,\n })\n this.cages = new RebarCages(THREE, o.scene)\n this.pieceSys = new PieceSystem(THREE, {\n groundAt: this.groundAt,\n staticTopAt: (x, z, y, step) => this.staticTopAt(x, z, y, step),\n gravity: this.gravity,\n scene: o.scene,\n onHardLanding: (p, point, speed) => this.hardLanding(p, point, speed),\n sweep: (p, from, to) => this.sweepPiece(p, from, to),\n onSlam: (p, hit, speed) => this.slam(p, hit, speed),\n })\n this.unsubscribe = this.world.on('*', (ev) => {\n if (ev.type === 'explode') this.coverWhenWentOff.set(ev, this.coverAround(ev))\n if (this.queue.length < QUEUE_CAP || STRUCTURAL_EVENTS.has(ev.type)) this.queue.push(ev)\n })\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Binding\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n bind(objectId: string, root: Object3D, options: BindOptions = {}): void {\n this.staticDirty.add(objectId)\n if (this.bounds.has(objectId)) this.unbind(objectId)\n const state = this.world.state(objectId)\n const partIds = new Set((state?.parts ?? []).map((p) => p.id))\n const byPart = new Map<string, Array<{ mesh: Mesh; range?: [number, number] }>>()\n const taken = new Set<Mesh>()\n const put = (pid: string, e: { mesh: Mesh; range?: [number, number] }): void => {\n const l = byPart.get(pid)\n if (l) l.push(e)\n else byPart.set(pid, [e])\n }\n const add = (pid: string, m: Mesh): void => {\n if (taken.has(m)) return\n taken.add(m)\n put(pid, { mesh: m })\n }\n const addRange = (pid: string, r: MeshRange): void => {\n const n = (r.mesh.geometry.getAttribute('position')?.count ?? 0) as number\n const [v0, v1] = r.range\n if (!Number.isInteger(v0) || !Number.isInteger(v1) || v0 < 0 || v1 <= v0 || v1 > n) {\n throw new Error(`game-destruction-three: invalid vertex range [${v0}, ${v1}) for part \"${pid}\" (the mesh has ${n} vertices)`)\n }\n put(pid, { mesh: r.mesh, range: [v0, v1] })\n }\n const meshesIn = (o: Object3D): Mesh[] => {\n const out: Mesh[] = []\n o.traverse((c) => {\n if ((c as Mesh).isMesh) out.push(c as Mesh)\n })\n return out\n }\n if (options.parts) {\n for (const [pid, v] of Object.entries(options.parts)) {\n for (const o of Array.isArray(v) ? v : [v]) {\n if (isMeshRange(o)) addRange(pid, o)\n else for (const m of meshesIn(o)) add(pid, m)\n }\n }\n } else {\n const leftovers: Mesh[] = []\n for (const m of meshesIn(root)) {\n const ud = partHintOf(m.userData?.destructionPart)?.id\n if (ud !== undefined && partIds.has(ud)) add(ud, m)\n else if (partIds.has(m.name)) add(m.name, m)\n else leftovers.push(m)\n }\n if (leftovers.length) this.matchByBox(objectId, root, leftovers, add)\n }\n const bound: Bound = { id: objectId, root, sync: options.syncTransform !== false, parts: new Map(), lastPos: null, lastQuat: null, piece: null, isSplit: false }\n if (options.onFrame) bound.onFrame = options.onFrame\n const hosts = new Map<Mesh, HostVis>()\n for (const pid of partIds) bound.parts.set(pid, this.makePartVis(objectId, pid, state?.parts.find((p) => p.id === pid)?.material ?? '', byPart.get(pid) ?? [], hosts))\n for (const [pid, meshes] of byPart) {\n if (!bound.parts.has(pid)) bound.parts.set(pid, this.makePartVis(objectId, pid, this.world.part(objectId, pid)?.material ?? '', meshes, hosts))\n }\n this.bounds.set(objectId, bound)\n for (const pv of bound.parts.values()) this.tagPart(pv, objectId)\n }\n\n /**\n * Label the meshes of a part so a host can go from a raycast hit to the world: `userData.destructionPart` (the part id) and\n * `userData.destructionObject` (the id of the world object that part belongs to now; a loose piece has an id of its own). Parts drawn by a range\n * of a merged mesh share that mesh with others and are left alone until they get a mesh of their own. Decals are marked `destructionDebris`.\n */\n private tagPart(pv: PartVis, objectId: string): void {\n for (const mv of pv.meshes) {\n if (mv.merged && !mv.loose) continue\n mv.mesh.traverse((c) => {\n if (!(c as Mesh).isMesh) return\n const ud = c.userData as Record<string, unknown>\n if (ud.destructionDebris) return\n if (partHintOf(ud.destructionPart)?.id !== pv.id) ud.destructionPart = pv.id\n ud.destructionObject = objectId\n })\n }\n }\n\n private makePartVis(home: string, id: string, material: string, meshes: Array<{ mesh: Mesh; range?: [number, number] }>, hosts: Map<Mesh, HostVis>): PartVis {\n return { id, home, material, meshes: meshes.map((m) => this.visuals.makeMeshVis(m.mesh, home, m.range, hosts)), charApplied: 0, glowApplied: 0, meltApplied: 0, gone: 'none' }\n }\n\n /** Match unlabelled meshes to the part whose shape contains the centre of the mesh's bounding box. */\n private matchByBox(objectId: string, root: Object3D, meshes: Mesh[], add: (pid: string, m: Mesh) => void): void {\n let specParts: PartSpec[] | undefined\n try {\n specParts = this.world.serialize?.().objects.find((o) => o.id === objectId)?.spec.parts\n } catch {\n specParts = undefined\n }\n if (!specParts) return\n const frame = specFrameInverse(this.THREE, root)\n const e = new this.THREE.Euler()\n const q = new this.THREE.Quaternion()\n for (const m of meshes) {\n this.box.setFromObject(m)\n if (this.box.isEmpty()) continue\n const c = this.box.getCenter(this.v1).applyMatrix4(frame)\n let best: PartSpec | null = null\n let bestVol = Infinity\n for (const p of specParts) {\n const l = this.v2.set(c.x - p.position[0], c.y - p.position[1], c.z - p.position[2])\n if (p.rotation) l.applyQuaternion(q.setFromEuler(e.set(p.rotation[0], p.rotation[1], p.rotation[2], 'XYZ')).invert())\n let inside = false\n let vol = 0\n const s = p.shape\n if (s.kind === 'box') {\n inside = Math.abs(l.x) <= s.size[0] / 2 && Math.abs(l.y) <= s.size[1] / 2 && Math.abs(l.z) <= s.size[2] / 2\n vol = s.size[0] * s.size[1] * s.size[2]\n } else if (s.kind === 'cylinder') {\n inside = Math.hypot(l.x, l.z) <= s.radius && Math.abs(l.y) <= s.height / 2\n vol = Math.PI * s.radius * s.radius * s.height\n } else {\n inside = l.length() <= s.radius\n vol = (4 / 3) * Math.PI * s.radius ** 3\n }\n if (inside && vol < bestVol) {\n best = p\n bestVol = vol\n }\n }\n if (best) add(best.id, m)\n }\n }\n\n unbind(objectId: string): void {\n this.staticDirty.add(objectId)\n const b = this.bounds.get(objectId)\n if (!b) return\n this.restore(objectId)\n this.pieceSys.remove(objectId)\n this.bounds.delete(objectId)\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Pieces\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n /** Half extents and centre of the box around some meshes, in the metric frame of `root` (its pose removed, its scale kept). */\n private measure(root: Object3D, meshes: MeshVis[]): { half: Vec3; center: THREE_NS.Vector3 } {\n const inv = specFrameInverse(this.THREE, root)\n const total = new this.THREE.Box3()\n const m4 = new this.THREE.Matrix4()\n const lb = new this.THREE.Box3()\n for (const mv of meshes) {\n const m = mv.mesh\n m.updateWorldMatrix(true, false)\n this.visuals.localBox(mv, lb)\n if (lb.isEmpty()) continue\n total.union(lb.clone().applyMatrix4(m4.multiplyMatrices(inv, m.matrixWorld)))\n }\n if (total.isEmpty()) return { half: [0.25, 0.25, 0.25], center: new this.THREE.Vector3() }\n const size = total.getSize(new this.THREE.Vector3())\n return { half: [Math.max(0.02, size.x / 2), Math.max(0.02, size.y / 2), Math.max(0.02, size.z / 2)], center: total.getCenter(new this.THREE.Vector3()) }\n }\n\n private meshesOf(b: Bound): MeshVis[] {\n const out: MeshVis[] = []\n for (const pv of b.parts.values()) if (pv.gone === 'none') for (const mv of pv.meshes) out.push(mv)\n return out\n }\n\n private massOf(objectId: string): number {\n const st = this.world.state(objectId)\n if (!st) return 5\n let m = 0\n for (const p of st.parts) if (p.status !== 'broken' && p.status !== 'melted' && p.status !== 'ashes') m += p.mass\n return m > 0 ? m : 5\n }\n\n makePiece(objectId: string, options: { mass?: number; velocity?: Vec3 } = {}): Piece {\n this.staticDirty.add(objectId)\n const b = this.bounds.get(objectId)\n if (!b) throw new Error(`game-destruction-three: object \"${objectId}\" is not bound`)\n if (b.root.parent && b.root.parent !== this.scene) this.scene.attach(b.root)\n const { half, center } = this.measure(b.root, this.meshesOf(b))\n const piece = this.pieceSys.create(objectId, b.root, half, center, options.mass ?? this.massOf(objectId), options.velocity)\n b.piece = piece\n return piece\n }\n\n pieces(): Piece[] {\n return [...this.pieceSys.list]\n }\n\n piece(objectId: string): Piece | null {\n return this.pieceSys.get(objectId)\n }\n\n impulse(objectId: string, impulse: Vec3, point?: Vec3): void {\n const p = this.pieceSys.get(objectId)\n if (p) this.pieceSys.impulse(p, impulse, point)\n }\n\n /**\n * What a piece moving from `from` to `to` runs into: the core of its box (its thinnest half each way, at most `SWEEP_CORE`) swept through the world, the piece itself left out,\n * so a crate thrown by a blast stops at the wall instead of passing through it. Null for a world that cannot sweep.\n */\n private sweepPiece(p: PieceBody, from: Vec3, to: Vec3): PieceSweepHit | null {\n if (typeof this.world.sweepBox !== 'function') return null\n const d: Vec3 = [to[0] - from[0], to[1] - from[1], to[2] - from[2]]\n const travel = Math.hypot(d[0], d[1], d[2])\n if (travel < 1e-4) return null\n const core = Math.min(SWEEP_CORE, ...p.halfExtents)\n const box = { min: [from[0] - core, from[1] - core, from[2] - core] as Vec3, max: [from[0] + core, from[1] + core, from[2] + core] as Vec3 }\n const hit = this.world.sweepBox(box, d, travel, { ignore: p.objectId, spacing: Math.max(0.05, core) })\n if (!hit) return null\n return { object: hit.object, part: hit.part, distance: hit.distance, point: hit.point, normal: hit.normal }\n }\n\n /** A piece thrown into a wall: the wall takes the blow of its weight where it met it, the piece takes it too, and each sounds as its material does. */\n private slam(p: PieceBody, hit: PieceSweepHit, speed: number): void {\n const energy = 0.5 * p.mass * speed * speed\n const direction: Vec3 = [-hit.normal[0], -hit.normal[1], -hit.normal[2]]\n this.landingSound(hit.object, hit.point, clamp(speed / 10, 0.2, 1))\n this.syncBound(p.objectId)\n try {\n this.world.hitPart(hit.object, hit.part, { type: 'blunt', point: hit.point, energy, radius: 0.1, direction, normal: hit.normal, source: p.objectId })\n this.world.hit(p.objectId, { type: 'blunt', point: hit.point, energy, radius: 0.08, direction: hit.normal, source: 'slam' })\n } catch {\n // either may have left the world\n }\n }\n\n private hardLanding(p: PieceBody, point: Vec3, speed: number): void {\n this.landingSound(p.objectId, point, clamp(speed / 10, 0.2, 1))\n // the piece just moved this frame: the world must know where it is before the hit is resolved against its parts\n this.syncBound(p.objectId)\n try {\n this.world.hit(p.objectId, { type: 'blunt', point, energy: 0.5 * p.mass * speed * speed, radius: 0.08, direction: [0, -1, 0], source: 'fall' })\n } catch {\n // the object may have been removed from the world\n }\n }\n\n /** The impact of the heaviest part of an object (a piece landing): its material and the blunt blow of the fall. */\n private landingSound(objectId: string, point: Vec3, volume: number): void {\n const st = this.world.state(objectId)\n let best = ''\n let mass = -1\n for (const p of st?.parts ?? []) {\n if (p.mass > mass) {\n mass = p.mass\n best = p.material\n }\n }\n this.impactSound(best, point, volume, 'blunt')\n }\n\n /** The impact on a material by a blow: the legacy family key (`impactKey`) with the more specific keys to try first (`impactSoundKeys`). */\n private impactSound(material: string, point: Vec3, volume: number, blow?: DamageType): void {\n const def = this.world.materials.get(material)\n this.sound(impactKey(def), point, volume, impactSoundKeys(material, def, blow))\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Update\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n update(dt: number): void {\n if (this.disposed) return\n dt = clamp(dt, 0, 0.1)\n this.time += dt\n if (!this.attached) this.drainQueue()\n for (const b of this.bounds.values()) b.onFrame?.(dt)\n // a settling object keeps moving between its (throttled) `settle` events\n for (const b of this.bounds.values()) if (b.soilNode && this.world.state(b.id)?.soil?.status === 'yielding') this.onSettle(b.id)\n this.updateActive(dt)\n this.updateLeaks(dt)\n this.pieceSys.update(dt)\n this.fragments.update(dt)\n this.ground.update(dt)\n this.ownVfx?.update(dt)\n this.syncTransforms()\n }\n\n deferredQueue(): DeferredQueue {\n return this.eventQueue\n }\n\n private drainQueue(): void {\n this.runBudgeted(performance.now() + this.eventBudgetMs, () => performance.now())\n }\n\n /** Applies the waiting events in order until the deadline, after the slices earlier events left; always at least one unit when something waits. Returns the units run. */\n private runBudgeted(deadline: number, clock: () => number): number {\n // events produced while applying (a hard landing calls `hit`) wait for the next frame\n const batch = this.queue.splice(0, this.queue.length)\n const outerClock = this.drainClock\n this.drainClock = clock\n this.sliceDeadline = deadline\n let ran = 0\n try {\n ran = this.runSlices(deadline)\n for (let i = 0; i < batch.length; i++) {\n if ((i > 0 || (ran > 0 && this.attached)) && clock() >= deadline) {\n this.queue.unshift(...batch.slice(i))\n return ran\n }\n try {\n this.apply(batch[i]!)\n } catch (err) {\n if (typeof console !== 'undefined') console.error('game-destruction-three: failed to apply', batch[i]!.type, err)\n }\n ran++\n }\n } finally {\n this.sliceDeadline = Infinity\n this.drainClock = outerClock\n }\n return ran\n }\n\n /** Runs the work left by earlier frames until the deadline; at least one piece per frame, so it always finishes. */\n private runSlices(deadline: number): number {\n let ran = 0\n for (; this.slices.length > 0 && (ran === 0 || this.drainClock() < deadline); ran++) {\n try {\n this.slices.shift()!()\n } catch (err) {\n if (typeof console !== 'undefined') console.error('game-destruction-three: failed to run deferred work', err)\n }\n }\n return ran\n }\n\n /**\n * The ground under an object settled or tilted: its parts are drawn under a node with the soil's offset (`ObjectState.soil.offset`), so the host's\n * root keeps the pose the host gave and the world keeps getting it from `syncTransform`.\n */\n private onSettle(objectId: string): void {\n const b = this.bounds.get(objectId)\n const soil = this.world.state(objectId)?.soil\n if (!b || !soil) return\n let node = b.soilNode\n if (!node) {\n node = new this.THREE.Group()\n node.name = 'destruction-soil'\n for (const c of [...b.root.children]) node.add(c)\n b.root.add(node)\n b.soilNode = node\n }\n const { position: p, rotation: q } = soil.offset\n node.position.set(p[0], p[1], p[2])\n node.quaternion.set(q[0], q[1], q[2], q[3])\n node.updateMatrixWorld(true)\n }\n\n private syncTransforms(): void {\n for (const b of this.bounds.values()) this.syncOne(b)\n }\n\n /** Push the current transform of one bound object to the world right now (used before a landing hit). */\n private syncBound(objectId: string): void {\n const b = this.bounds.get(objectId)\n if (b) this.syncOne(b)\n }\n\n private syncOne(b: Bound): void {\n if (!b.sync) return\n const p = this.v1\n const q = this.tmpQ\n b.root.updateWorldMatrix(true, false)\n b.root.matrixWorld.decompose(p, q, this.v2)\n const last = b.lastPos\n const lq = b.lastQuat\n const moved = !last || !lq || Math.abs(p.x - last[0]) + Math.abs(p.y - last[1]) + Math.abs(p.z - last[2]) > 1e-5 || Math.abs(q.x - lq[0]) + Math.abs(q.y - lq[1]) + Math.abs(q.z - lq[2]) + Math.abs(q.w - lq[3]) > 1e-6\n if (!moved) return\n b.lastPos = [p.x, p.y, p.z]\n b.lastQuat = [q.x, q.y, q.z, q.w]\n if (this.world.has(b.id)) this.world.setTransform(b.id, [p.x, p.y, p.z], [q.x, q.y, q.z, q.w])\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Events\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n /**\n * The highest top of a bound object that is not a piece under (x, z) a corner at height `y` can land on (at most `step` above it). The world boxes\n * of their drawn meshes are kept until an event or a moved root changes them; parts drawn inside a merged mesh and meshes wider than `STATIC_SPAN`\n * are left out (walls, floors, roofs: the terrain under them is the host's `groundAt`).\n */\n private staticTopAt(x: number, z: number, y: number, step: number): number {\n let top = -Infinity\n for (const a of this.staticNow().values()) {\n // the first six numbers are the box around all of the object's boxes\n if (a.length === 0 || x < a[0] || x > a[3] || z < a[2] || z > a[5]) continue\n for (let i = 6; i < a.length; i += 6) {\n if (x < a[i] || x > a[i + 3] || z < a[i + 2] || z > a[i + 5]) continue\n const t = a[i + 4]\n if (t > top && t <= y + step) top = t\n }\n }\n return top\n }\n\n /** The boxes of the fixed objects (per object: the box around them all, then each one), each object measured again when an event touched it (all of them every `STATIC_REFRESH` s). */\n private staticNow(): Map<string, number[]> {\n if (this.time - this.staticAt > STATIC_REFRESH) {\n this.staticAt = this.time\n if (this.staticRound.length === 0) this.staticRound = [...this.bounds.keys()].reverse()\n }\n if (!this.staticAll && this.staticDirty.size === 0 && this.staticRound.length === 0) return this.staticBoxes\n const box = new this.THREE.Box3()\n const measure = (b: Bound): void => {\n if (b.piece || this.pieceSys.get(b.id)) {\n this.staticBoxes.delete(b.id)\n return\n }\n const out: number[] = [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity]\n for (const mv of this.meshesOf(b)) {\n if (mv.host || mv.loose || !this.visuals.shown(mv)) continue\n this.visuals.worldBox(mv, box)\n if (box.isEmpty() || box.max.x - box.min.x > STATIC_SPAN || box.max.z - box.min.z > STATIC_SPAN) continue\n this.visuals.fittedBoxes(mv, out)\n for (let k = 0; k < 3; k++) {\n out[k] = Math.min(out[k], box.min.getComponent(k))\n out[k + 3] = Math.max(out[k + 3], box.max.getComponent(k))\n }\n }\n this.staticBoxes.set(b.id, out.length > 6 ? out : [])\n }\n const measureId = (id: string): void => {\n const b = this.bounds.get(id)\n if (b) measure(b)\n else this.staticBoxes.delete(id)\n }\n if (this.staticAll) {\n this.staticBoxes.clear()\n for (const b of this.bounds.values()) measure(b)\n this.staticRound = []\n } else {\n for (const id of this.staticDirty) measureId(id)\n const until = performance.now() + STATIC_REFRESH_SLICE_MS\n while (this.staticRound.length > 0) {\n measureId(this.staticRound.pop() as string)\n if (performance.now() >= until) break\n }\n }\n this.staticAll = false\n this.staticDirty.clear()\n return this.staticBoxes\n }\n\n /** The boxes of a piece's drawn meshes, measured once per frame. */\n private pieceBoxesOf(pc: PieceBody): number[] {\n const cached = this.pieceBoxes.get(pc)\n if (cached && cached.at === this.time) return cached.boxes\n const boxes: number[] = []\n const b = this.bounds.get(pc.objectId)\n if (b) {\n for (const mv of this.meshesOf(b)) {\n if (this.visuals.shown(mv)) this.visuals.fittedBoxes(mv, boxes)\n }\n }\n this.pieceBoxes.set(pc, { at: this.time, boxes })\n return boxes\n }\n\n solidsNear(x: number, z: number, radius: number): SolidBox[] {\n const found: SolidBox[] = []\n const scan = (a: number[], id: string, piece: Piece | null, from: number): void => {\n if (from > 0 && (a.length === 0 || x < a[0] - radius || x > a[3] + radius || z < a[2] - radius || z > a[5] + radius)) return\n for (let i = from; i < a.length; i += 6) {\n if (x < a[i] - radius || x > a[i + 3] + radius || z < a[i + 2] - radius || z > a[i + 5] + radius) continue\n found.push({ objectId: id, min: [a[i], a[i + 1], a[i + 2]], max: [a[i + 3], a[i + 4], a[i + 5]], piece })\n }\n }\n for (const [id, a] of this.staticNow()) scan(a, id, null, 6)\n const c = this.v1\n for (const pc of this.pieceSys.list) {\n if (pc.held) continue\n // only the pieces whose box can reach the point are measured\n this.pieceSys.centerOf(pc, c)\n const reach = Math.hypot(pc.halfExtents[0], pc.halfExtents[1], pc.halfExtents[2]) + radius\n if (Math.abs(c.x - x) > reach || Math.abs(c.z - z) > reach) continue\n scan(this.pieceBoxesOf(pc), pc.objectId, pc, 0)\n }\n this.fragments.solidsNear(x, z, radius, (home, min, max, loose) => found.push({ objectId: home, min, max, piece: null, loose }))\n return found\n }\n\n private apply(ev: DestructionEvent): void {\n this.staticDirty.add(ev.object)\n switch (ev.type) {\n case 'damage':\n if (ev.damageType === 'heat' || ev.damageType === 'fire' || ev.damageType === 'explosive') this.activate(ev.object, ev.part)\n break\n case 'dent':\n this.onDent(ev)\n break\n case 'hole':\n this.onHole(ev)\n break\n case 'crack':\n this.onCrack(ev)\n break\n case 'ricochet': {\n const d = ev.direction\n this.vfx.burst('sparks', ev.point, d, 4 + Math.min(10, ev.energy / 150), 4)\n // the whine of a round off steel, the short crack off stone: by what the part it glanced off is made of\n const glanced = this.partVis(ev.object, ev.part)?.material ?? ''\n this.sound('ricochet', ev.point, 0.7, ricochetSoundKeys(glanced, this.world.materials.get(glanced)))\n break\n }\n case 'debris':\n this.vfx.burst(ev.kind, ev.point, ev.normal, ev.count, ev.speed > 0 ? ev.speed : DEFAULT_SPEED[ev.kind] ?? 1, this.debrisOptions(ev.kind, ev.object, ev.part, ev.material))\n break\n case 'fracture':\n this.onFracture(ev)\n break\n case 'detach':\n this.onDetach(ev)\n break\n case 'settle':\n this.onSettle(ev.object)\n break\n case 'collapse': {\n // a storey coming down raises the cloud of the collapse effect; a piece of furniture (a shelf and its books) only a puff\n const root = this.bounds.get(ev.object)?.root\n const furniture = !!root && kitOriginOf(root)?.kind === 'furniture'\n this.splitLoose(ev.object)\n if (!furniture || ev.mass >= COLLAPSE_CLOUD_KG) this.playEvent({ kind: 'collapse' }, this.rootPoint(ev.object))\n else this.vfx.burst('dust', this.rootPoint(ev.object), [0, 1, 0], clamp(Math.round(ev.mass / 4), 4, 24), 0.8)\n break\n }\n case 'disassemble_progress': {\n const k = `unscrew:${ev.joint}`\n if (this.time - (this.throttles.get(k) ?? -1) > 0.25) {\n this.throttles.set(k, this.time)\n this.sound('unscrew', this.rootPoint(ev.object), clamp(0.3 + ev.progress * 0.5, 0, 1))\n }\n break\n }\n case 'ignite':\n this.startFire(ev)\n this.activate(ev.object, ev.part)\n this.sound('ignite', ev.point, 0.7)\n this.sound('burn_loop', ev.point, 0.5, this.burning(ev.object, ev.part))\n break\n case 'primed':\n // a bullet or fire sets the part burning until its delay runs out; a blast nearby only waits for the explosion\n if (ev.trigger !== 'explosion') {\n this.vfx.fire({ point: ev.point, radius: PRIMED_FIRE_RADIUS, life: ev.delay })\n this.primedBurning.add(`${ev.object}|${ev.part}`)\n this.activate(ev.object, ev.part)\n // the vessel is venting until it bursts: the gas leak for as long as the delay, and the flame it feeds\n this.sound('primed', ev.point, 0.7, { seconds: ev.delay })\n this.sound('burn_loop', ev.point, 0.5, { fuel: 'gas' })\n }\n break\n case 'spall':\n this.onSpall(ev)\n break\n case 'stage':\n this.onStage(ev)\n break\n case 'chip':\n this.onChip(ev)\n break\n case 'expose':\n if (ev.bars.length > 0) this.cages.set(`${ev.object}|${ev.part}`, ev.bars, this.bounds.get(ev.object)?.root)\n else this.dropCage(ev.object, ev.part)\n if (ev.bars.length > 0) {\n const [a, b] = ev.bars[0] as [Vec3, Vec3]\n this.playEvent({ kind: 'expose' }, [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2])\n }\n break\n case 'extinguish': {\n const f = this.fires.get(`${ev.object}|${ev.part}`)\n const primed = this.primedBurning.delete(`${ev.object}|${ev.part}`)\n if (f) {\n this.stopFire(`${ev.object}|${ev.part}`)\n this.vfx.burst('steam', f.point, [0, 1, 0], 14, 1.2)\n }\n if (f || primed) this.sound('burn_end', f?.point ?? this.rootPoint(ev.object), 0.5, primed ? { fuel: 'gas' } : this.burning(ev.object, ev.part))\n this.activate(ev.object, ev.part)\n this.sound('extinguish', f?.point ?? this.rootPoint(ev.object), 0.6)\n break\n }\n case 'burnout': {\n this.stopFire(`${ev.object}|${ev.part}`)\n const primed = this.primedBurning.delete(`${ev.object}|${ev.part}`)\n this.sound('burn_end', ev.point, 0.5, primed ? { fuel: 'gas' } : this.burning(ev.object, ev.part))\n this.vfx.burst('ash', ev.point, [0, 1, 0], 16, 1)\n this.vfx.burst('smoke', ev.point, [0, 1, 0], 6, 0.8, { color: SMOKE_TONES.grey })\n const pv = this.partVis(ev.object, ev.part)\n if (pv) {\n const def = this.world.materials.get(pv.material)\n this.visuals.setChar(pv, 1, def?.visual?.charColor ?? 0x1a1410)\n }\n this.activate(ev.object, ev.part)\n break\n }\n case 'melt':\n this.activate(ev.object, ev.part)\n // one sizzle per melting object every 1.5 s, not one per part (a plastic bin has dozens)\n if (this.time - (this.throttles.get(`melt:${ev.object}`) ?? -9) > 1.5) {\n this.throttles.set(`melt:${ev.object}`, this.time)\n this.sound('melt_sizzle', this.rootPoint(ev.object), 0.4)\n }\n break\n case 'drip': {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n const def = this.world.materials.get(ev.material)\n const color = (pv && this.partColor(pv, def)) ?? fallbackColor(ev.material, def)\n let tag = this.homeTags.indexOf(ev.object) + 1\n if (tag === 0) tag = this.homeTags.push(ev.object)\n this.vfx.spawn('drips', ev.point, [(this.rng() - 0.5) * 0.1, -0.1, (this.rng() - 0.5) * 0.1], { color, tag, owner: this.owner })\n break\n }\n case 'leak': {\n const key = `${ev.object}|${ev.part}`\n const b = this.bounds.get(ev.object)\n let localPoint: Vec3 | undefined\n let localDirection: Vec3 | undefined\n if (b) {\n b.root.updateWorldMatrix(true, false)\n const inv = new this.THREE.Matrix4().copy(b.root.matrixWorld).invert()\n const lp = this.v1.set(ev.point[0], ev.point[1], ev.point[2]).applyMatrix4(inv)\n const ld = this.v2.set(ev.direction[0], ev.direction[1], ev.direction[2]).transformDirection(inv).normalize()\n localPoint = [lp.x, lp.y, lp.z]\n localDirection = [ld.x, ld.y, ld.z]\n }\n const same = this.leaks.find((l) => l.object === ev.object && l.part === ev.part && Math.hypot(l.point[0] - ev.point[0], l.point[1] - ev.point[1], l.point[2] - ev.point[2]) < 0.03)\n if (same) {\n same.rate = ev.rate\n same.direction = ev.direction\n if (localPoint) same.localPoint = localPoint\n if (localDirection) same.localDirection = localDirection\n } else {\n if (this.leaks.length >= 24) this.leaks.shift()\n this.leaks.push({\n object: ev.object,\n part: ev.part,\n fluid: ev.fluid,\n point: ev.point,\n direction: ev.direction,\n rate: ev.rate,\n pressurized: ev.pressurized,\n acc: 0,\n opened: this.world.part(ev.object, ev.part)?.holes.some((h) => h.through) ?? false,\n localPoint,\n localDirection,\n life: 0,\n })\n }\n void key\n break\n }\n case 'explode':\n // the vessel that vented into its flame bursts: the gas jet ends with it\n if (this.primedBurning.delete(`${ev.object}|${ev.part}`)) this.sound('burn_end', ev.point, 0.5, { fuel: 'gas' })\n this.onExplode(ev)\n break\n case 'destroyed':\n break\n }\n }\n\n private rootPoint(objectId: string): Vec3 {\n const b = this.bounds.get(objectId)\n return b ? [b.root.position.x, b.root.position.y, b.root.position.z] : [0, 0, 0]\n }\n\n private sound(key: string, point: Vec3, volume: number, detail?: SoundDetail): void {\n if (detail) this.o.onSound?.(key, point, volume, detail)\n else this.o.onSound?.(key, point, volume)\n }\n\n /** What a burning part is made of, for the fire's sound. */\n private burning(objectId: string, partId: string): SoundDetail | undefined {\n const material = this.partVis(objectId, partId)?.material || this.world.part(objectId, partId)?.material\n return material ? { material } : undefined\n }\n\n private partVis(objectId: string, partId: string): PartVis | null {\n return this.bounds.get(objectId)?.parts.get(partId) ?? null\n }\n\n private activate(objectId: string, partId: string): void {\n this.active.set(`${objectId}|${partId}`, { object: objectId, part: partId })\n }\n\n /** Current colour of the part's first mesh (char included), or null. */\n private partColor(pv: PartVis, def: MaterialDef | undefined): number | null {\n const mv = pv.meshes[0]\n if (!mv) return null\n const mat = materialsOf(mv.mesh.material)[0] as THREE_NS.MeshStandardMaterial | undefined\n const c = mat?.color\n if (c && (c as THREE_NS.Color).isColor) {\n const tint = this.visuals.vertexTint(mv)\n return tint ? c.clone().multiply(tint).getHex() : c.getHex()\n }\n return def ? fallbackColor(def.id, def) : null\n }\n\n private debrisOptions(kind: DebrisKind, objectId: string, partId: string, material?: string): { color?: number } | undefined {\n const pv = this.partVis(objectId, partId)\n const def = this.world.materials.get(material ?? pv?.material ?? '')\n if (kind === 'smoke') return { color: SMOKE_TONES[def?.thermal.smoke ?? 'grey'] }\n // crushed masonry is the colour of its inside (brick orange, plaster light, concrete grey), not of the paint over it\n if ((kind === 'dust' || kind === 'chips') && def?.visual?.innerColor !== undefined) return { color: def.visual.innerColor }\n if (kind === 'fibers' || kind === 'leaves') {\n if (def?.visual?.innerColor !== undefined) return { color: def.visual.innerColor }\n const c = pv ? this.visuals.baseColorHex(pv.meshes[0] ?? ({} as never)) : -1\n return c >= 0 ? { color: c } : undefined\n }\n if (kind === 'dust' || kind === 'chips') {\n const c = pv && pv.meshes[0] ? this.visuals.baseColorHex(pv.meshes[0]) : -1\n return c >= 0 && kind === 'chips' ? { color: c } : undefined\n }\n return undefined\n }\n\n /** Mesh of the part closest to a world point. */\n private nearestMesh(pv: PartVis, p: THREE_NS.Vector3): PartVis['meshes'][number] | null {\n let best: PartVis['meshes'][number] | null = null\n let bd = Infinity\n for (const mv of pv.meshes) {\n if (!this.visuals.shown(mv)) continue\n const d = this.visuals.worldBox(mv, this.box).distanceToPoint(p)\n if (d < bd) {\n bd = d\n best = mv\n }\n }\n return best\n }\n\n private worldDir(b: Bound, v: Vec3): THREE_NS.Vector3 {\n b.root.updateWorldMatrix(true, false)\n return new this.THREE.Vector3(v[0], v[1], v[2]).applyQuaternion(b.root.getWorldQuaternion(this.tmpQ)).normalize()\n }\n\n private onDent(ev: Ev<'dent'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n if (!b || !pv) return\n const def = this.world.materials.get(pv.material)\n const wp = new this.THREE.Vector3(ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2])\n const wn = this.worldDir(b, ev.dent.normal)\n const shown = pv.meshes.filter((mv) => this.visuals.shown(mv))\n const reach = shown.reduce((widest, mv) => Math.max(widest, this.visuals.dentReach(mv, wp, ev.dent)), ev.dent.radius)\n this.visuals.applyPartDent(shown, wp, wn, ev.dent, reach)\n if (def?.tags?.includes('metal')) this.vfx.burst('sparks', ev.worldPoint, [wn.x, wn.y, wn.z], 4 + Math.min(8, ev.dent.depth * 150), 3.2)\n this.impactSound(pv.material, ev.worldPoint, clamp(0.3 + ev.dent.depth * 12, 0.3, 1), ev.blow)\n }\n\n private onHole(ev: Ev<'hole'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n if (!b || !pv) return\n const def = this.world.materials.get(pv.material)\n const n = this.worldDir(b, ev.hole.normal)\n const draw = (point: Vec3, normal: THREE_NS.Vector3): void => {\n const wp = new this.THREE.Vector3(point[0], point[1], point[2])\n const mv = this.nearestMesh(pv, wp)\n if (!mv) return\n if (def?.visual?.transparent) {\n const seed = hashNumbers(ev.time, point[0], point[1], point[2])\n this.visuals.addCrack(mv, wp, normal, 7, Math.max(0.05, ev.hole.diameter * 5), 0xe8f4ff, seed)\n } else {\n // wood tears its fibres around the hole: a ragged rim of fresh wood under it\n const fresh = def?.penetrationClass === 'wood' ? def.visual?.innerColor : undefined\n if (fresh !== undefined) this.visuals.addSpall(mv, wp, normal, Math.max(0.006, ev.hole.diameter * WOOD_RIM), fresh)\n this.visuals.addHole(mv, wp, normal, ev.hole.diameter)\n }\n }\n draw(ev.worldPoint, n)\n if (ev.hole.through && ev.exitPoint) draw(ev.exitPoint, n.clone().negate())\n if (def?.tags?.includes('metal')) this.vfx.burst('sparks', ev.worldPoint, [n.x, n.y, n.z], 6, 3.5)\n if (ev.powder) {\n // what the part holds loose (flakes, flour) puffs out: a little back out of the entry, most out of the exit along the shot\n const puff = { color: ev.powder.color, size: 0.6, life: 1.6, alpha: 1.3 }\n this.vfx.burst('dust', ev.worldPoint, [n.x, n.y, n.z], this.low ? 5 : 10, 0.7, puff)\n if (ev.hole.through && ev.exitPoint) this.vfx.burst('dust', ev.exitPoint, [-n.x, -n.y, -n.z], this.low ? 10 : 20, 1.3, puff)\n }\n // the blow's own keys first (`impact_steel_ballistic`...), then the round's per-family key (`shot_metal`), which falls back to the plain impact\n this.sound(shotKey(def), ev.worldPoint, 0.6, impactSoundKeys(pv.material, def, ev.blow))\n }\n\n private onCrack(ev: Ev<'crack'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n if (!b || !pv) return\n const def = this.world.materials.get(pv.material)\n // only glass shows a crack as lines (the break runs inside a clear body); an opaque body shows its damage as chips, holes and dents, never lines drawn over it\n if (def?.visual?.transparent) {\n const wp = new this.THREE.Vector3(ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2])\n const mv = this.nearestMesh(pv, wp)\n const seed = hashNumbers(ev.time, ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2])\n if (mv) this.visuals.addCrack(mv, wp, this.worldDir(b, ev.crack.normal), ev.crack.rays, ev.crack.length, 0xe8f4ff, seed)\n }\n this.impactSound(pv.material, ev.worldPoint, 0.5, ev.blow)\n }\n\n /** Outward normal of the face of `mv` nearest to a world point: the thin axis of its world box (right for a wall; a sloped face is left to the vertex-range binding). */\n private faceNormal(mv: PartVis['meshes'][number], point: THREE_NS.Vector3): THREE_NS.Vector3 {\n const box = this.visuals.worldBox(mv, this.box)\n const size = box.getSize(this.v1)\n const axis = size.x <= size.y && size.x <= size.z ? 'x' : size.y <= size.z ? 'y' : 'z'\n const side = point[axis] >= (box.min[axis] + box.max[axis]) / 2 ? 1 : -1\n return new this.THREE.Vector3(axis === 'x' ? side : 0, axis === 'y' ? side : 0, axis === 'z' ? side : 0)\n }\n\n /** The material an impact effect is chosen by: the tags of the material (`metal`, `glass`, `wood`), else stone and the like are `concrete`. */\n private impactMaterial(def: MaterialDef | undefined): string {\n for (const tag of IMPACT_TAGS) if (def?.tags?.includes(tag)) return tag\n return 'concrete'\n }\n\n /**\n * Plays the effect the event map names for a destruction event (`data/event-effects.json` of `game-vfx`, or `RendererOptions.eventEffects`) at a point.\n * Answers whether one played, so the caller can leave out the burst it replaces.\n */\n private playEvent(event: GameEvent, point: Vec3): boolean {\n const id = effectForEvent(event, this.o.eventEffects ?? EVENT_EFFECTS_MAP)\n if (!id) return false\n return this.vfx.play(id, point, { seed: hashNumbers(point[0], point[1], point[2], this.time) }) !== null\n }\n\n /** A coat came off: a patch in the colour of the core under it, below the bullet holes and cracks. */\n private onSpall(ev: Ev<'spall'>): void {\n const pv = this.partVis(ev.object, ev.part)\n if (!pv) return\n const wp = new this.THREE.Vector3(ev.point[0], ev.point[1], ev.point[2])\n const mv = this.nearestMesh(pv, wp)\n if (!mv) return\n const def = this.world.materials.get(pv.material)\n const normal = this.faceNormal(mv, wp)\n const core = def?.visual?.innerColor\n // masonry crumbles in the colour of what is under the coat (brick orange, concrete grey); the generic impact would throw dark grey chips\n if (core !== undefined) this.vfx.burst('chips', ev.point, [normal.x, normal.y, normal.z], 5, 2.5, { color: core })\n else this.playEvent({ kind: 'spall', material: this.impactMaterial(def) }, ev.point)\n // a drawing that shows the coat coming off itself (the house renderer cuts its plaster and draws the bricks under it) takes no flat patch\n if ((mv.mesh.userData.drawnSpalls as string[] | undefined)?.includes(ev.part)) return\n this.visuals.addSpall(mv, wp, normal, Math.sqrt(ev.area / Math.PI), core ?? fallbackColor(pv.material, def))\n }\n\n /**\n * Stage 2 of a staged part: the unit-sized fragments come out and the part stays drawn (hiding it is what `fracture` does). The opening itself\n * (cutting the wall's faces) is not drawn yet: it needs the per-vertex binding of the house renderer.\n */\n private onStage(ev: Ev<'stage'>): void {\n const played = this.playEvent({ kind: 'stage', stage: ev.stage }, ev.opening?.center ?? this.rootPoint(ev.object))\n if (!ev.fragments || !ev.opening) return\n const pv = this.partVis(ev.object, ev.part)\n const def = pv ? this.world.materials.get(pv.material) : undefined\n const color = (pv ? this.partColor(pv, def) : null) ?? fallbackColor(pv?.material ?? '', def)\n const maxAlive = this.low ? Math.floor(this.maxFragments / 2) : this.maxFragments\n const step = this.low ? 2 : 1\n for (let i = 0; i < ev.fragments.length; i += step) {\n const fr = ev.fragments[i] as Fragment\n const fdef = this.world.materials.get(fr.material)\n this.fragments.spawn(fr, this.fragments.materialFor(fr.material, fdef === def || !fdef ? color : fallbackColor(fr.material, fdef), false), ev.object, maxAlive)\n }\n if (!played) this.vfx.burst('dust', ev.opening.center, [0, 1, 0], 14, 1.2, { color })\n this.impactSound(pv?.material ?? '', ev.opening.center, 0.8, ev.blow)\n }\n\n /**\n * A unit came out of a wall of units: the unit flies as a fragment with a puff of its dust, and the marks drawn on it (bullet holes, spalls, the impact\n * marks of the effects) go with it. The gap itself is the drawing's (the house renderer cuts the wall where the unit was); a part drawn as one box\n * keeps its box.\n */\n private onChip(ev: Ev<'chip'>): void {\n const pv = this.partVis(ev.object, ev.part)\n const def = pv ? this.world.materials.get(pv.material) : undefined\n const color = (pv ? this.partColor(pv, def) : null) ?? fallbackColor(pv?.material ?? '', def)\n const maxAlive = this.low ? Math.floor(this.maxFragments / 2) : this.maxFragments\n for (const fr of ev.fragments) {\n const fdef = this.world.materials.get(fr.material)\n // the inside of the material (fresh wood) when the piece came from it, else the part's colour\n const tone = fr.inner && fdef?.visual?.innerColor !== undefined ? fdef.visual.innerColor : fdef === def ? color : fallbackColor(fr.material, fdef)\n this.fragments.spawn(fr as Fragment, this.fragments.materialFor(fr.material, tone, false), ev.object, maxAlive)\n }\n // what a blow tore off a face leaves the hole it made where it is\n if (ev.torn) {\n this.impactSound(pv?.material ?? '', ev.center, 0.5, ev.blow)\n return\n }\n // the holes and spalls drawn on the unit leave with it (also those on the wall a beam is drawn inside), and on the ragged edge of plaster around it\n const T = this.THREE\n const center = new T.Vector3(ev.center[0], ev.center[1], ev.center[2])\n const half = new T.Vector3(ev.size[0] / 2 + CHIP_DECAL_EDGE, ev.size[1] / 2 + CHIP_DECAL_EDGE, ev.size[2] / 2 + CHIP_DECAL_EDGE)\n const rotation = new T.Quaternion(ev.rotation[0], ev.rotation[1], ev.rotation[2], ev.rotation[3])\n for (const part of this.bounds.get(ev.object)?.parts.values() ?? []) for (const mv of part.meshes) this.visuals.clearDecals(mv, center, half, rotation)\n this.vfx.peekWorkshop()?.decals.clearInside(ev.center, [half.x, half.y, half.z], ev.rotation)\n // a puff of the unit's own dust; not the bullet impact effect, which would leave its black mark on the hole the unit left\n this.vfx.burst('dust', ev.center, [0, 1, 0], ev.units ? Math.min(40, 8 + ev.units.length) : 8, ev.units ? 1.6 : 0.8, { color })\n this.impactSound(pv?.material ?? '', ev.center, 0.7, ev.blow)\n }\n\n private onFracture(ev: Ev<'fracture'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n const matId = pv?.material || (ev.fragments[0]?.material ?? '')\n const def = this.world.materials.get(matId)\n let color = fallbackColor(matId, def)\n let opacity = 0.5\n const transparent = def?.visual?.transparent === true\n if (pv) {\n const c = this.partColor(pv, def)\n if (c !== null) color = c\n const m = pv.meshes[0] ? (materialsOf(pv.meshes[0].origMaterial)[0] as THREE_NS.Material | undefined) : undefined\n if (m && m.transparent) opacity = clamp(m.opacity, 0.2, 0.8)\n this.visuals.hide(pv, 'broken')\n }\n this.spawnFragments(ev, 0, { def, color, opacity, transparent })\n this.loosenIfFootless(ev.object)\n const up: Vec3 = [0, 1, 0]\n const sizeK = clamp(ev.fragments.length / 10, 0.5, 2)\n switch (ev.style) {\n case 'shatter':\n this.vfx.burst('shards', ev.point, up, 18 * sizeK, 3)\n break\n case 'crumble':\n this.vfx.burst('dust', ev.point, up, 16 * sizeK, 1.2, { color: pv ? (this.partColor(pv, def) ?? undefined) : undefined })\n this.vfx.burst('chips', ev.point, up, 6, 3)\n break\n case 'splinter':\n this.vfx.burst('splinters', ev.point, up, 14 * sizeK, 3)\n this.vfx.burst('dust', ev.point, up, 5, 0.8, { color: 0xb59a74 })\n break\n case 'tear':\n this.vfx.burst('fibers', ev.point, up, 12 * sizeK, 1.6, { color: def?.visual?.innerColor ?? color })\n break\n case 'snap':\n this.vfx.burst('chips', ev.point, up, 8 * sizeK, 3)\n break\n default:\n this.vfx.burst('sparks', ev.point, up, 10, 4)\n }\n this.sound(fractureKey(def, ev.style), ev.point, clamp(0.4 + ev.fragments.length * 0.03, 0.4, 1), breakSoundKeys(matId, def, ev.blow))\n }\n\n /** Spawns the fragments of a fracture from index `from`; what does not fit in this frame's budget is spawned by the next frames. */\n private spawnFragments(ev: Ev<'fracture'>, from: number, look: { def: MaterialDef | undefined; color: number; opacity: number; transparent: boolean }): void {\n const maxAlive = this.low ? Math.floor(this.maxFragments / 2) : this.maxFragments\n const step = this.low ? 2 : 1\n for (let i = from; i < ev.fragments.length; i += step) {\n if (i - from >= MIN_FRAGMENTS_PER_SLICE * step && this.drainClock() >= this.sliceDeadline) {\n this.slices.push(() => this.spawnFragments(ev, i, look))\n return\n }\n const fr = ev.fragments[i]\n const fdef = this.world.materials.get(fr.material)\n const tone = fr.inner && fdef?.visual?.innerColor !== undefined ? fdef.visual.innerColor : fdef === look.def || !fdef ? look.color : fallbackColor(fr.material, fdef)\n const mat = this.fragments.materialFor(fr.material, tone, look.transparent || fdef?.visual?.transparent === true, look.opacity)\n this.fragments.spawn(fr, mat, ev.object, maxAlive)\n }\n }\n\n private onDetach(ev: Ev<'detach'>): void {\n this.sound('detach', this.rootPoint(ev.object), 0.5)\n this.splitLoose(ev.object)\n }\n\n /**\n * The cage of a part gave way (`expose` with no bars): nothing holds its bars any more, so each comes down where it is, as steel debris that stays on the\n * ground with a body (`FragmentSystem.spawn` with `lasting`), not as bars left standing in the air.\n */\n private dropCage(objectId: string, partId: string): void {\n const bars = this.cages.take(`${objectId}|${partId}`)\n if (bars.length === 0) return\n const radius = this.cages.barRadius\n const density = this.world.materials.get('steel')?.density ?? STEEL_DENSITY\n const material = this.fragments.materialFor('steel', REBAR_COLOR, false)\n const rnd = createRng(hashString(`${objectId}|${partId}`))\n bars.forEach((bar, i) => {\n const fragment: Fragment = {\n id: `${partId}#bar${i}`, part: partId, material: 'steel', shape: 'chunk', center: bar.center, size: [2 * radius, bar.length, 2 * radius], rotation: bar.rotation,\n velocity: [(rnd() - 0.5) * 0.4, 0, (rnd() - 0.5) * 0.4], angularVelocity: [(rnd() - 0.5) * 1.5, (rnd() - 0.5) * 0.5, (rnd() - 0.5) * 1.5],\n mass: density * Math.PI * radius * radius * bar.length,\n }\n this.fragments.spawn(fragment, material, objectId, this.maxFragments, true)\n })\n }\n\n /** Turn every loose group of the object (a detach, a collapse) into a piece of its own. */\n private splitLoose(objectId: string): void {\n if (!this.autoSplit) return\n const b = this.bounds.get(objectId)\n if (!b) return\n const st = this.world.state(objectId)\n if (!st || st.groups.length < 2) return\n const loose = st.groups.length - 1\n for (let i = 0; i < loose; i++) {\n if (i > 0 && this.drainClock() >= this.sliceDeadline) {\n this.slices.push(() => {\n this.staticDirty.add(objectId)\n this.splitLoose(objectId)\n })\n return\n }\n // the loose groups are always read from index 1: each split renumbers the rest\n let newId: string\n try {\n newId = this.world.splitGroup(objectId, 1)\n } catch {\n break\n }\n this.adoptSplit(b, newId)\n }\n const old = b.piece\n if (old) {\n const { half, center } = this.measure(b.root, this.meshesOf(b))\n old.halfExtents = half\n this.pieceSys.setCenter(old, center)\n old.mass = Math.max(0.05, this.massOf(objectId))\n old.sleeping = false\n } else if (kitOriginOf(b.root)?.kind === 'furniture') {\n // furniture only stands on the floor: what stayed (a leg, two legs and a board) is loose too, and what cannot stand on its own topples\n const piece = this.makePiece(objectId)\n this.tipIfTopHeavy(b)\n // the host stops keeping the footprint it had where it stood: it is a body that moves now\n this.o.onLoosened?.(objectId, piece, 'apart')\n }\n }\n\n /** The renderer side of `splitGroup`: a new group holding the meshes of the new object, made a piece. */\n private adoptSplit(from: Bound, newId: string): void {\n const state = this.world.state(newId)\n const root = from.root\n root.updateWorldMatrix(true, false)\n const group = new this.THREE.Group()\n group.name = `destruction-piece-${newId}`\n root.getWorldPosition(group.position)\n root.getWorldQuaternion(group.quaternion)\n this.scene.add(group)\n group.updateMatrixWorld(true)\n const nb: Bound = { id: newId, root: group, sync: true, parts: new Map(), lastPos: null, lastQuat: null, piece: null, isSplit: true }\n for (const p of state?.parts ?? []) {\n const pv = from.parts.get(p.id)\n if (!pv) continue\n from.parts.delete(p.id)\n nb.parts.set(p.id, pv)\n // its bare bars go with it\n this.cages.move(`${from.id}|${p.id}`, `${newId}|${p.id}`, group)\n for (const mv of pv.meshes) {\n // a part drawn by a range of a merged mesh leaves its faces behind: it gets a mesh of its own\n if (mv.host && !mv.loose) this.visuals.extract(mv, group)\n else {\n group.attach(mv.mesh)\n showCollapsedRanges(mv.mesh)\n mv.moved = true\n }\n }\n }\n this.bounds.set(newId, nb)\n for (const pv of nb.parts.values()) this.tagPart(pv, newId)\n const meshes = this.meshesOf(nb)\n if (meshes.length === 0) return\n const { half, center } = this.measure(group, meshes)\n let vel: Vec3 = [0, 0, 0]\n let ang: Vec3 = [0, 0, 0]\n const op = from.piece\n if (op) {\n vel = [...op.velocity]\n ang = [...op.angularVelocity]\n // linear velocity at the loose piece's centre\n const c = this.pieceSys.centerOf(op, new this.THREE.Vector3())\n const nc = center.clone().applyQuaternion(group.quaternion).add(group.position)\n vel[0] += ang[1] * (nc.z - c.z) - ang[2] * (nc.y - c.y)\n vel[1] += ang[2] * (nc.x - c.x) - ang[0] * (nc.z - c.z)\n vel[2] += ang[0] * (nc.y - c.y) - ang[1] * (nc.x - c.x)\n }\n const piece = this.pieceSys.create(newId, group, half, center, this.massOf(newId), vel, ang)\n nb.piece = piece\n if (kitOriginOf(from.root)?.kind === 'furniture') this.tipIfTopHeavy(nb)\n this.o.onPiece?.(piece)\n }\n\n /**\n * Furniture that lost what it stood on falls: with every leg of a table broken the top is loose, and with the legs of one side gone what is left topples. Feet are the\n * meshes at the bottom of the object as it was whole; while the ones left still span the same floor (a cupboard with a broken door, a table missing one leg) it stands.\n */\n private loosenIfFootless(objectId: string): void {\n const b = this.bounds.get(objectId)\n if (!b || !this.autoSplit) return\n const left = this.meshesOf(b).filter((mv) => this.visuals.shown(mv))\n if (left.length === 0) return\n const body = b.piece ?? this.pieceSys.get(objectId)\n if (body) {\n // a piece is the box of what is left of it: the legs that broke off no longer hold it up\n const { half, center } = this.measure(b.root, left)\n body.halfExtents = half\n this.pieceSys.setCenter(body, center)\n body.mass = Math.max(0.05, this.massOf(objectId))\n body.sleeping = false\n return\n }\n if (kitOriginOf(b.root)?.kind !== 'furniture') return\n const boxOf = (mv: MeshVis): THREE_NS.Box3 => this.visuals.worldBox(mv, new this.THREE.Box3())\n const whole = [...b.parts.values()].flatMap((pv) => pv.meshes).map(boxOf).filter((one) => !one.isEmpty())\n const floor = Math.min(...whole.map((one) => one.min.y))\n const feetOf = (boxes: THREE_NS.Box3[]): THREE_NS.Box3 => boxes.filter((one) => one.min.y < floor + FEET_BAND).reduce((feet, one) => feet.union(one), new this.THREE.Box3())\n const was = feetOf(whole)\n const now = feetOf(left.map(boxOf).filter((one) => !one.isEmpty()))\n const same = !now.isEmpty() && now.min.x <= was.min.x + FEET_BAND && now.max.x >= was.max.x - FEET_BAND && now.min.z <= was.min.z + FEET_BAND && now.max.z >= was.max.z - FEET_BAND\n if (same) return\n if (!now.isEmpty()) {\n const box = left.map(boxOf).reduce((all, one) => all.union(one), new this.THREE.Box3())\n const centreX = (box.min.x + box.max.x) / 2\n const centreZ = (box.min.z + box.max.z) / 2\n const height = box.max.y - box.min.y\n const narrow = height >= TIP_MIN_HEIGHT && Math.min(now.max.x - now.min.x, now.max.z - now.min.z) < TIP_NARROW * height\n if (!narrow && centreX > now.min.x && centreX < now.max.x && centreZ > now.min.z && centreZ < now.max.z) return\n }\n const piece = this.makePiece(objectId)\n this.tipIfTopHeavy(b)\n // the host stops keeping the footprint it had where it stood: it is a body that moves now\n this.o.onLoosened?.(objectId, piece, 'apart')\n }\n\n /**\n * A piece of furniture standing on feet too close for its height (a board on two legs in a line, a lone leg) does not stay up: the box of a piece hides that its weight is up\n * high and its feet are thin, so it gets the start of the fall, across the line of its feet.\n */\n private tipIfTopHeavy(b: Bound): void {\n const piece = b.piece\n if (!piece) return\n const box = new this.THREE.Box3()\n const boxes = this.meshesOf(b).filter((mv) => this.visuals.shown(mv)).map((mv) => this.visuals.worldBox(mv, new this.THREE.Box3()))\n if (boxes.length === 0) return\n for (const one of boxes) box.union(one)\n const height = box.max.y - box.min.y\n const feet = new this.THREE.Box3()\n for (const one of boxes) if (one.min.y < box.min.y + FEET_BAND) feet.union(one)\n const spanX = feet.max.x - feet.min.x\n const spanZ = feet.max.z - feet.min.z\n if (height < TIP_MIN_HEIGHT || Math.min(spanX, spanZ) >= TIP_NARROW * height) return\n const across = spanX <= spanZ ? 0 : 2\n const lean = across === 0 ? box.min.x + box.max.x - feet.min.x - feet.max.x : box.min.z + box.max.z - feet.min.z - feet.max.z\n const away = lean < 0 ? -1 : 1\n // rotating about -z moves the top toward +x; rotating about +x moves it toward +z\n if (across === 0) this.pieceSys.tip(piece, 0, -away)\n else this.pieceSys.tip(piece, away, 0)\n }\n\n private onExplode(ev: Ev<'explode'>, options: ExplodeOptions = {}): void {\n const p = ev.point\n if (options.visual !== false) this.playExplosion(ev, options)\n this.vfx.push(p, ev.radius, 4)\n // shove pieces and fragments\n const c = this.v1\n const report = options.report\n const confinement = report?.find((r) => r.blast !== undefined)?.blast?.confinement ?? 1\n const energy = ev.energy * confinement\n // the energy that got to an object after what stood in the way: the world's shelter of this blast when it carries one, else the cover between the centre and the\n // object's centre (`blastReach`, always on: a wall, a car or a cupboard between them takes the push), as it stood when the part went off: the cupboard the wave\n // tears apart still met it, and the stove it throws was not in the way yet\n const wentOff = this.coverWhenWentOff.get(ev)\n const reachOf = (objectId: string, at: Vec3): number =>\n report?.find((r) => r.object === objectId)?.blast?.shelter ??\n wentOff?.get(objectId) ??\n this.world.blastReach?.(p, at, { ignore: ev.object ? [ev.object, objectId] : [objectId] }) ??\n 1\n const shove = (pc: PieceBody): void => {\n this.pieceSys.centerOf(pc, c)\n if (c.distanceTo(this.v2.set(p[0], p[1], p[2])) > ev.radius) return\n const hit = blastShove({ point: p, energy, radius: ev.radius, reach: reachOf(pc.objectId, [c.x, c.y, c.z]) }, { position: [c.x, c.y, c.z], mass: pc.mass }, this.o.blastShove)\n if (!hit) return\n const spread = pc.halfExtents[0]\n const momentum = hit.speed * pc.mass\n this.pieceSys.impulse(pc, [hit.direction[0] * momentum, hit.direction[1] * momentum, hit.direction[2] * momentum], [c.x + (this.rng() - 0.5) * spread, c.y + spread * 0.5, c.z + (this.rng() - 0.5) * spread])\n }\n for (const pc of [...this.pieceSys.list]) shove(pc)\n if (this.o.shoveable) this.loosen(p, ev.radius, energy, reachOf)\n this.fragments.blast(p, ev.radius, Math.min(20, Math.sqrt(energy) * 0.08))\n this.sound('explode', p, clamp(0.5 + ev.radius / 10, 0.5, 1), {\n radius: ev.radius,\n ...(ev.effect !== undefined ? { effect: ev.effect } : {}),\n ...(options.effect !== undefined ? { effect: options.effect } : {}),\n ...(report ? { confinement } : {}),\n })\n }\n\n /** The cover between a part of the world that goes off and the centre of each piece and each shoveable body within its radius, as the world stands at that moment. */\n private coverAround(ev: Ev<'explode'>): Map<string, number> {\n const cover = new Map<string, number>()\n const reach = this.world.blastReach\n if (!reach) return cover\n const point = new this.THREE.Vector3(ev.point[0], ev.point[1], ev.point[2])\n const centre = new this.THREE.Vector3()\n const read = (objectId: string): void => {\n if (centre.distanceTo(point) <= ev.radius) cover.set(objectId, reach.call(this.world, ev.point, [centre.x, centre.y, centre.z], { ignore: [ev.object, objectId] }))\n }\n for (const pc of this.pieceSys.list) {\n this.pieceSys.centerOf(pc, centre)\n read(pc.objectId)\n }\n const shoveable = this.o.shoveable\n if (!shoveable) return cover\n for (const b of this.bounds.values()) {\n if (b.piece || cover.has(b.id) || !shoveable(b.id) || !this.world.has(b.id)) continue\n centre.copy(this.measure(b.root, this.meshesOf(b)).center).applyQuaternion(b.root.quaternion).add(b.root.position)\n read(b.id)\n }\n return cover\n }\n\n /** The bound objects without a piece that the host lets a blast move (`shoveable`): the ones it reaches with enough speed become pieces and get the shove. */\n private loosen(point: Vec3, radius: number, energy: number, reachOf: (objectId: string, at: Vec3) => number): void {\n const shoveable = this.o.shoveable\n if (!shoveable) return\n for (const b of [...this.bounds.values()]) {\n if (b.piece || this.pieceSys.get(b.id) || !shoveable(b.id) || !this.world.has(b.id)) continue\n const { half, center } = this.measure(b.root, this.meshesOf(b))\n const world = center.clone().applyQuaternion(b.root.quaternion).add(b.root.position)\n const mass = this.massOf(b.id)\n if (world.distanceTo(this.v2.set(point[0], point[1], point[2])) > radius) continue\n const hit = blastShove({ point, energy, radius, reach: reachOf(b.id, [world.x, world.y, world.z]) }, { position: [world.x, world.y, world.z], mass }, this.o.blastShove)\n if (!hit) continue\n const piece = this.makePiece(b.id, { mass })\n const body = this.pieceSys.get(b.id)\n if (!body) continue\n this.o.onLoosened?.(b.id, piece, 'blast')\n const spread = half[0]\n const momentum = hit.speed * mass\n this.pieceSys.impulse(body, [hit.direction[0] * momentum, hit.direction[1] * momentum, hit.direction[2] * momentum], [world.x + (this.rng() - 0.5) * spread, world.y + spread * 0.5, world.z + (this.rng() - 0.5) * spread])\n }\n }\n\n private playExplosion(ev: Ev<'explode'>, options: ExplodeOptions): void {\n const named = options.effect ?? ev.effect\n const direction = options.direction\n const scale = clamp(ev.radius / GENERIC_REFERENCE_RADIUS, 0.2, 3)\n if (named !== undefined && this.vfx.explosion(named, ev.point, direction ? { direction } : {}) !== null) return\n this.vfx.explosion('generic', ev.point, { scale, ...(direction ? { direction } : {}) })\n }\n\n private startFire(ev: { object: string; part: string; point: Vec3 }): void {\n const key = `${ev.object}|${ev.part}`\n this.stopFire(key)\n this.fires.set(key, { object: ev.object, part: ev.part, point: ev.point, follow: { x: ev.point[0], y: ev.point[1], z: ev.point[2] } })\n }\n\n private stopFire(key: string): void {\n const fire = this.fires.get(key)\n if (!fire) return\n if (fire.handle !== undefined) this.vfx.stop(fire.handle)\n this.fires.delete(key)\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Fire, heat, char, melt, leaks\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n private updateActive(dt: number): void {\n this.scanTimer += dt\n if (this.scanTimer >= 0.4) {\n this.scanTimer = 0\n for (const b of this.bounds.values()) {\n for (const pv of b.parts.values()) {\n if (pv.gone !== 'none' && pv.gone !== 'broken') continue\n const ps = this.world.part(b.id, pv.id)\n if (!ps) continue\n const def = this.world.materials.get(pv.material)\n if (\n ps.burning ||\n (def?.visual?.glows && ps.temperature > GLOW_FROM_C) ||\n Math.abs(ps.char - pv.charApplied) > 0.01 ||\n Math.abs(ps.melt - pv.meltApplied) > 0.01 ||\n (pv.gone === 'none' && (ps.status === 'melted' || ps.status === 'ashes'))\n ) {\n this.activate(b.id, pv.id)\n }\n }\n }\n }\n for (const [key, a] of this.active) {\n const pv = this.partVis(a.object, a.part)\n const ps = pv ? this.world.part(a.object, a.part) : null\n if (!pv || !ps) {\n this.active.delete(key)\n continue\n }\n const def = this.world.materials.get(pv.material)\n if (pv.gone === 'none') {\n this.visuals.setChar(pv, ps.char, def?.visual?.charColor ?? 0x1a1410)\n if (def?.visual?.glows) this.visuals.setGlow(pv, ps.temperature)\n this.visuals.setMelt(pv, ps.melt)\n if (ps.status === 'melted') this.onGone(a.object, pv, 'melted', def)\n else if (ps.status === 'ashes') this.onGone(a.object, pv, 'ashes', def)\n }\n const fire = this.fires.get(key)\n if (fire) {\n if (ps.burning && ps.status !== 'broken' && ps.status !== 'ashes' && ps.status !== 'melted') this.emitFire(fire, pv, def)\n else this.stopFire(key)\n }\n const hot = def?.visual?.glows === true && ps.temperature > GLOW_FROM_C\n if (!ps.burning && !hot && Math.abs(ps.char - pv.charApplied) < 0.01 && Math.abs(ps.melt - pv.meltApplied) < 0.01) {\n if (def?.visual?.glows && pv.gone === 'none') this.visuals.setGlow(pv, 0)\n this.active.delete(key)\n }\n }\n }\n\n private onGone(objectId: string, pv: PartVis, reason: 'melted' | 'ashes', def: MaterialDef | undefined): void {\n const bb = new this.THREE.Box3()\n for (const mv of pv.meshes) bb.union(this.visuals.worldBox(mv, this.box))\n this.visuals.hide(pv, reason)\n if (bb.isEmpty()) return\n const c = bb.getCenter(new this.THREE.Vector3())\n const s = bb.getSize(new this.THREE.Vector3())\n const footprint = Math.sqrt(Math.max(s.x * s.z, 1e-4))\n if (reason === 'melted') {\n this.ground.add('puddle', c.x, c.z, clamp(footprint * 0.55, 0.05, 1), this.partColor(pv, def) ?? fallbackColor(pv.material, def), objectId)\n } else {\n this.ground.add('ash', c.x, c.z, clamp(footprint * 0.35, 0.04, 0.5), 0x1d1a18, objectId)\n this.vfx.burst('ash', [c.x, bb.max.y, c.z], [0, 1, 0], 10, 0.8)\n }\n }\n\n private emitFire(f: FireEmitter, pv: PartVis, def: MaterialDef | undefined): void {\n const bb = this.box\n bb.makeEmpty()\n const tmp = new this.THREE.Box3()\n for (const mv of pv.meshes) if (this.visuals.shown(mv)) bb.union(this.visuals.worldBox(mv, tmp))\n if (!bb.isEmpty()) {\n const c = bb.getCenter(this.v1)\n f.follow.x = c.x\n f.follow.y = bb.min.y\n f.follow.z = c.z\n }\n if (f.handle !== undefined) return\n const size = bb.isEmpty() ? this.v2.set(0.2, 0.2, 0.2) : bb.getSize(this.v2)\n const radius = clamp(Math.max(size.x, size.z) * 0.5, 0.12, 1.2)\n const smokeColor = SMOKE_TONES[def?.thermal.smoke ?? 'grey']\n f.handle = this.vfx.fire({ point: [f.follow.x, f.follow.y, f.follow.z], radius, life: FIRE_CEILING_SECONDS, follow: f.follow, ...(smokeColor !== undefined ? { smokeColor } : {}) })\n }\n\n private updateLeaks(dt: number): void {\n for (let i = this.leaks.length - 1; i >= 0; i--) {\n const l = this.leaks[i]\n const b = this.bounds.get(l.object)\n const ps = this.world.part(l.object, l.part)\n // a leak ends when the container is empty or the opening is closed (a valve shut, `seal`)\n if (!b || !ps || ps.liters === undefined || ps.liters <= 1e-4 || (l.opened && !ps.holes.some((h) => h.through))) {\n this.leaks.splice(i, 1)\n continue\n }\n l.life = (l.life ?? 0) + dt\n if (l.pressurized && l.life > 0.8) l.pressurized = false\n\n if (l.lastLiters !== undefined && Math.abs(ps.liters - l.lastLiters) < 1e-5) {\n l.idleSeconds = (l.idleSeconds ?? 0) + dt\n if (l.idleSeconds > 0.4) {\n this.leaks.splice(i, 1)\n continue\n }\n } else {\n l.idleSeconds = 0\n l.lastLiters = ps.liters\n }\n\n let pt = l.point\n let dir = l.direction\n if (l.localPoint && l.localDirection) {\n b.root.updateWorldMatrix(true, false)\n const wp = this.v1.set(l.localPoint[0], l.localPoint[1], l.localPoint[2]).applyMatrix4(b.root.matrixWorld)\n const wd = this.v2.set(l.localDirection[0], l.localDirection[1], l.localDirection[2]).transformDirection(b.root.matrixWorld).normalize()\n pt = [wp.x, wp.y, wp.z]\n dir = [wd.x, wd.y, wd.z]\n l.point = pt\n l.direction = dir\n }\n\n l.acc += clamp(20 + l.rate * 400, 15, 120) * dt\n const color = FLUID_COLORS[l.fluid] ?? 0xaaaaaa\n const dl = Math.hypot(dir[0], dir[1], dir[2]) || 1\n const sp = l.pressurized ? 2.5 + this.rng() * 1.5 : 0.3 + this.rng() * 0.3\n while (l.acc >= 1) {\n l.acc -= 1\n const vel: Vec3 = [(dir[0] / dl) * sp + (this.rng() - 0.5) * 0.25, (dir[1] / dl) * sp + (this.rng() - 0.5) * 0.25, (dir[2] / dl) * sp + (this.rng() - 0.5) * 0.25]\n if (l.fluid === 'gas') this.vfx.spawn('steam', pt, vel, { color, size: 0.5, alpha: 0.5 })\n else this.vfx.spawn('drips', pt, vel, { color, tag: this.rng() < 0.03 ? this.tagOf(l.object) : 0, owner: this.owner })\n }\n }\n }\n\n private tagOf(object: string): number {\n let tag = this.homeTags.indexOf(object) + 1\n if (tag === 0) tag = this.homeTags.push(object)\n return tag\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Emit, clear, restore, stats, dispose\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n emit(kind: DebrisKind | 'fire' | 'flash' | 'foam', point: Vec3, normal: Vec3, count: number, speed?: number): void {\n this.vfx.burst(kind, point, normal, count, speed ?? DEFAULT_SPEED[kind] ?? 1, kind === 'smoke' ? { color: SMOKE_TONES.grey } : undefined)\n }\n\n explode(point: Vec3, energy: number, radius: number, options?: ExplodeOptions): void {\n this.onExplode({ type: 'explode', object: '', part: '', time: this.time, point, energy, radius }, options)\n }\n\n restore(objectId: string): void {\n const homes = new Set<string>([objectId])\n const self = this.bounds.get(objectId)\n if (self?.isSplit) for (const pv of self.parts.values()) homes.add(pv.home)\n for (const home of homes) this.restoreHome(home)\n for (const [key, a] of [...this.active]) if (homes.has(a.object)) this.active.delete(key)\n for (const [key, f] of [...this.fires]) if (homes.has(f.object)) this.stopFire(key)\n for (let i = this.leaks.length - 1; i >= 0; i--) if (homes.has(this.leaks[i].object)) this.leaks.splice(i, 1)\n for (const home of homes) {\n this.fragments.removeHome(home)\n this.ground.removeHome(home)\n this.cages.removeObject(home)\n }\n }\n\n private restoreHome(home: string): void {\n const homeBound = this.bounds.get(home)\n for (const b of [...this.bounds.values()]) {\n for (const [pid, pv] of [...b.parts]) {\n if (pv.home !== home) continue\n this.visuals.restorePart(pv)\n this.tagPart(pv, home)\n if (b !== homeBound && homeBound) {\n b.parts.delete(pid)\n homeBound.parts.set(pid, pv)\n }\n }\n if (b.isSplit && b.parts.size === 0) {\n this.scene.remove(b.root)\n this.pieceSys.remove(b.id)\n this.bounds.delete(b.id)\n // its box leaves now: the periodic round only walks the objects still bound\n this.staticDirty.add(b.id)\n }\n }\n }\n\n clear(): void {\n // what was bound is gone: the next read measures what is left, all of it\n this.staticAll = true\n this.queue.length = 0\n this.slices.length = 0\n this.active.clear()\n for (const key of [...this.fires.keys()]) this.stopFire(key)\n this.leaks.length = 0\n for (const id of [...this.bounds.keys()]) if (this.bounds.has(id)) this.restore(id)\n // anything left of a split object whose home is gone\n for (const b of [...this.bounds.values()]) {\n if (b.isSplit) {\n for (const pv of b.parts.values()) this.visuals.restorePart(pv)\n this.scene.remove(b.root)\n this.pieceSys.remove(b.id)\n this.bounds.delete(b.id)\n }\n }\n this.fragments.clear()\n this.ground.clear()\n this.cages.clear()\n this.primedBurning.clear()\n this.vfx.sprites().clear()\n this.ownVfx?.world.clear()\n }\n\n reset(): void {\n this.clear()\n this.rng = createRng(RNG_SEED)\n this.time = 0\n this.staticAt = 0\n this.staticRound = []\n this.staticAll = true\n this.throttles.clear()\n this.fragments.reset()\n this.pieceSys.reset()\n }\n\n wakeRegion(x: number, z: number, radius: number): void {\n this.fragments.wakeRegion(x, z, radius)\n this.pieceSys.wakeRegion(x, z, radius)\n }\n\n stats(): { fragments: number; particles: number; pieces: number; decals: number } {\n return { fragments: this.fragments.count, particles: this.vfx.sprites().live + this.ownedVfxParticles(), pieces: this.pieceSys.list.length, decals: this.visuals.decalCount + this.ground.count }\n }\n\n private ownedVfxParticles(): number {\n if (!this.ownVfx) return 0\n const { puffs, sparks, glows, chunks } = this.vfx.stats()\n return puffs + sparks + glows + chunks\n }\n\n // The last warm-up keeps its materials until the next one: a material that does not use lights keeps the program of the lights it was first drawn with, so each warm-up needs materials of its own.\n private warmProbes: { readonly group: THREE_NS.Group; readonly geometry: THREE_NS.BufferGeometry; readonly materials: THREE_NS.Material[] } | undefined\n\n warmUpProbes(): WarmUpProbes {\n this.releaseWarmProbes()\n const { kit } = this.visuals\n const T = this.THREE\n const geometry = new T.BufferGeometry()\n geometry.setAttribute('position', new T.BufferAttribute(new Float32Array(6), 3))\n const materials = [kit.discMaterial().clone(), kit.patchMaterial(0x808080).clone(), kit.lineMaterial(0x000000).clone()]\n const group = new T.Group()\n group.add(new T.Mesh(kit.discGeometry(), materials[0]), new T.Mesh(kit.discGeometry(), materials[1]), new T.LineSegments(geometry, materials[2] as THREE_NS.LineBasicMaterial))\n group.add(...this.fragments.warmMeshes())\n for (const probe of group.children) probe.frustumCulled = false\n this.warmProbes = { group, geometry, materials }\n return { group, dispose: () => {} }\n }\n\n private releaseWarmProbes(): void {\n if (!this.warmProbes) return\n this.warmProbes.geometry.dispose()\n for (const material of this.warmProbes.materials) material.dispose()\n this.warmProbes = undefined\n }\n\n rebarCount(): number {\n return this.cages.count\n }\n\n dispose(): void {\n this.releaseWarmProbes()\n if (this.disposed) return\n this.unsubscribe()\n this.clear()\n for (const id of [...this.bounds.keys()]) this.unbind(id)\n this.fragments.dispose()\n this.ground.dispose()\n this.cages.dispose()\n this.stopLanding()\n this.visuals.dispose()\n this.ownVfx?.dispose()\n this.disposed = true\n }\n}\n","import type * as THREE_NS from 'three'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { Fragment, SplitForm } from '@adatechnology/game-destruction'\n\nimport { pushFittedBoxes } from './fitted-boxes'\nimport { FRAGMENT_SHAPE_VARIANTS, buildBrokenBoardGeometry, buildLumpGeometry, buildSliverGeometry, buildVeneerGeometry } from './fragment-shapes'\nimport { clamp, createRng, hashString } from './math'\nimport type { LooseBody } from './types'\n\ninterface Live {\n mesh: THREE_NS.Mesh\n home: string\n vel: THREE_NS.Vector3\n ang: THREE_NS.Vector3\n half: THREE_NS.Vector3\n baseScale: THREE_NS.Vector3\n still: number\n asleep: boolean\n /** Seconds at rest. */\n rest: number\n /** 1 while alive; counts down to 0 while shrinking away. */\n fade: number\n dying: boolean\n /** Air drag per second: a loose sheet (a page) glides and flutters down instead of dropping. */\n air: number\n /** A big one (`isBig`): it stays where it lies, and what walks steps on it or kicks it. */\n body: LooseBody | null\n /** The `update` count when it was made. */\n born: number\n /** Seconds it stays at rest before it fades (0 = forever). */\n life: number\n}\n\n/** What a fragment's resting time can depend on: the fragment (its material, size, shape) and the id of the object it came from. */\nexport type FragmentLifeRule = (fragment: Fragment, objectId: string) => number\n\nexport interface FragmentSystemOptions {\n scene: THREE_NS.Scene\n groundAt: (x: number, z: number) => number\n gravity: number\n max: number\n /** Seconds a resting fragment stays before it fades (0 = forever), or a rule that gives it per fragment. */\n life: number | FragmentLifeRule\n /** How a material comes apart (`MaterialDef.splitForm`): MDF lumps and plywood veneer get shapes of their own. Default: none. */\n formOf?: (materialId: string) => SplitForm | undefined\n}\n\nconst BUILDERS: Record<Exclude<SharedShape, 'shard'>, (THREE: typeof THREE_NS, seed: number) => THREE_NS.BufferGeometry> = {\n sliver: buildSliverGeometry,\n lump: buildLumpGeometry,\n veneer: buildVeneerGeometry,\n board: buildBrokenBoardGeometry,\n}\n\n/** The shared shapes a fragment can take besides the box: glass shards, wood splinters, MDF lumps, plywood veneer and the torn stub of a broken board. */\ntype SharedShape = 'shard' | 'sliver' | 'lump' | 'veneer' | 'board'\n\n/** Thickest scrap that flies as a sheet (m), its air drag (1/s) and how hard it sways (m/s²). */\nconst SHEET_MAX = 0.004\nconst SHEET_AIR = 2.5\nconst SHEET_SWAY = 3\n/** A fragment at least this long (m) and this wide is a piece of the thing (half a board), not a splinter; a shard of glass never is. */\nconst BIG_LENGTH = 0.2\nconst BIG_WIDTH = 0.03\n/** The seed of the fragments' random stream (their spin and sway); `reset` takes it back here. */\nconst FRAGMENT_SEED = 0x51ed270b\n\n/** Fragments asleep whose ground is looked at again each update, in turn, and how far (m) over it one may lie before it falls: the table it lay on broke. */\nconst SUPPORT_CHECKS = 32\nconst SUPPORT_GAP = 0.02\n\n/** How many shard shapes there are; a fragment takes one by the hash of its id. */\nconst SHARD_SHAPES = 6\n\nconst isBig = (size: readonly number[]): boolean => {\n const [, middle, longest] = [...size].sort((a, b) => a - b)\n return longest >= BIG_LENGTH && middle >= BIG_WIDTH\n}\n\n/** Light physics for fracture debris: gravity, ground bounce and friction, spin damping, settling flat, sleep, shrink-away and removal. */\nexport class FragmentSystem {\n private readonly list: Live[] = []\n private readonly box: THREE_NS.BoxGeometry\n /** The mesh box of a fragment before its scale. */\n private readonly unitBox = { min: { x: -0.5, y: -0.5, z: -0.5 }, max: { x: 0.5, y: 0.5, z: 0.5 } }\n private shardGeos: THREE_NS.BufferGeometry[] = []\n private readonly shapeGeos = new Map<Exclude<SharedShape, 'shard'>, THREE_NS.BufferGeometry[]>()\n private readonly materials = new Map<string, THREE_NS.Material>()\n private readonly q: THREE_NS.Quaternion\n private readonly dq: THREE_NS.Quaternion\n private readonly m: THREE_NS.Matrix4\n private readonly v: THREE_NS.Vector3\n private readonly w: THREE_NS.Vector3\n private rng = createRng(FRAGMENT_SEED)\n /** Count of `update` calls: what makes the fragments of one burst tell apart from older ones. */\n private tick = 0\n private supportTurn = 0\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly o: FragmentSystemOptions,\n ) {\n this.box = new THREE.BoxGeometry(1, 1, 1)\n this.q = new THREE.Quaternion()\n this.dq = new THREE.Quaternion()\n this.m = new THREE.Matrix4()\n this.v = new THREE.Vector3()\n this.w = new THREE.Vector3()\n }\n\n get count(): number {\n return this.list.length\n }\n\n /** Meshes of every live fragment (tests and picking). */\n meshes(): THREE_NS.Mesh[] {\n return this.list.map((f) => f.mesh)\n }\n\n /** One shared material per source material id + colour (+ transparency). */\n materialFor(materialId: string, color: number, transparent: boolean, opacity = 0.5): THREE_NS.Material {\n const key = `${materialId}:${color}:${transparent ? 1 : 0}`\n let m = this.materials.get(key)\n if (!m) {\n m = transparent\n ? new this.THREE.MeshStandardMaterial({ color, roughness: 0.15, metalness: 0.1, transparent: true, opacity, side: this.THREE.DoubleSide, depthWrite: false })\n : new this.THREE.MeshLambertMaterial({ color })\n this.materials.set(key, m)\n }\n return m\n }\n\n private shardGeometry(seed: number): THREE_NS.BufferGeometry {\n const idx = seed % SHARD_SHAPES\n let g = this.shardGeos[idx]\n if (!g) {\n const r = createRng(1000 + idx)\n const n = 3 + Math.floor(r() * 3) // triangle, quad or pentagon, irregular\n const shape = new this.THREE.Shape()\n const pts: Array<[number, number]> = []\n for (let i = 0; i < n; i++) {\n const a = (i / n) * Math.PI * 2 + (r() - 0.5) * 0.7\n const rad = 0.35 + r() * 0.15\n pts.push([Math.cos(a) * rad, Math.sin(a) * rad])\n }\n shape.moveTo(pts[0][0], pts[0][1])\n for (let i = 1; i < n; i++) shape.lineTo(pts[i][0], pts[i][1])\n shape.closePath()\n g = new this.THREE.ExtrudeGeometry(shape, { depth: 1, bevelEnabled: false })\n g.translate(0, 0, -0.5)\n this.shardGeos[idx] = g\n }\n return g\n }\n\n private sharedGeometry(shape: Exclude<SharedShape, 'shard'>, seed: number): THREE_NS.BufferGeometry {\n const idx = seed % FRAGMENT_SHAPE_VARIANTS\n let variants = this.shapeGeos.get(shape)\n if (!variants) {\n variants = []\n this.shapeGeos.set(shape, variants)\n }\n let g = variants[idx]\n if (!g) {\n g = BUILDERS[shape](this.THREE, idx)\n variants[idx] = g\n }\n return g\n }\n\n /**\n * The geometry a fragment is drawn with: a splinter is a pointed, frayed sliver; MDF breaks in lumps, plywood peels in ragged veneer, the stub of a broken\n * board ends in torn strands at +x; the rest are boxes.\n */\n private geometryOf(f: Fragment): THREE_NS.BufferGeometry {\n const seed = hashString(f.id)\n if (f.shape === 'shard') return this.shardGeometry(seed)\n if (f.shape === 'splinter') return this.sharedGeometry('sliver', seed)\n const form = this.o.formOf?.(f.material)\n if (f.shape === 'chunk' && form === 'granules') return this.sharedGeometry('lump', seed)\n if (f.shape === 'scrap' && form === 'plies') return this.sharedGeometry('veneer', seed)\n if (f.shape === 'slab' && (form === 'slivers' || form === 'plies')) return this.sharedGeometry('board', seed)\n return this.box\n }\n\n private markGeometry: THREE_NS.CircleGeometry | null = null\n private markMaterial: THREE_NS.MeshBasicMaterial | null = null\n\n private markParts(): { geometry: THREE_NS.CircleGeometry; material: THREE_NS.MeshBasicMaterial } {\n this.markGeometry ??= new this.THREE.CircleGeometry(1, 10)\n this.markMaterial ??= new this.THREE.MeshBasicMaterial({ color: 0x0b0a09, depthWrite: false, polygonOffset: true, polygonOffsetFactor: -4, polygonOffsetUnits: -4 })\n return { geometry: this.markGeometry, material: this.markMaterial }\n }\n\n /**\n * Meshes, never put in a scene by this class, that draw every shared piece of a fragment once: the box, the six shards, the wood splinters, MDF lumps and plywood veneer, the bullet-hole disc, and the opaque and\n * glass materials. A host draws them at load so the first blast does not upload these buffers in the middle of a frame.\n */\n warmMeshes(): THREE_NS.Mesh[] {\n const opaque = this.materialFor('warm', 0x808080, false)\n const glass = this.materialFor('warm', 0x808080, true)\n const geometries = [this.box, ...Array.from({ length: SHARD_SHAPES }, (_, index) => this.shardGeometry(index))]\n const wood = (['sliver', 'lump', 'veneer', 'board'] as const).flatMap((shape) => Array.from({ length: FRAGMENT_SHAPE_VARIANTS }, (_, index) => this.sharedGeometry(shape, index)))\n const { geometry, material } = this.markParts()\n return [\n ...geometries.flatMap((shared) => [new this.THREE.Mesh(shared, opaque), new this.THREE.Mesh(shared, glass)]),\n ...wood.map((shared) => new this.THREE.Mesh(shared, opaque)),\n new this.THREE.Mesh(geometry, material),\n ]\n }\n\n /**\n * Bullet holes that stay on a fragment (`Fragment.marks`): dark discs that are children of its mesh, so they fall, spin and settle with it. The mesh is\n * a unit box scaled to the fragment, so each disc is scaled back; exact for a mark on a face, which is where a bullet hole is.\n */\n addMarks(mesh: THREE_NS.Mesh, f: Fragment): void {\n if (!f.marks?.length) return\n const { geometry, material } = this.markParts()\n const sc = mesh.scale\n for (const mark of f.marks) {\n const disc = new this.THREE.Mesh(geometry, material)\n const radius = Math.max(0.004, mark.diameter) * 0.6\n const n = this.v.set(mark.normal[0], mark.normal[1], mark.normal[2]).normalize()\n disc.position.set(mark.point[0] / sc.x + (n.x * 0.002) / sc.x, mark.point[1] / sc.y + (n.y * 0.002) / sc.y, mark.point[2] / sc.z + (n.z * 0.002) / sc.z)\n disc.quaternion.setFromUnitVectors(this.w.set(0, 0, 1), n)\n disc.scale.set(radius / sc.x, radius / sc.y, radius / sc.z)\n mesh.add(disc)\n }\n }\n\n /**\n * Create the mesh of a fragment and start its motion. `maxAllowed` is the live budget: over it the oldest fragment still showing fades out to make room, and a burst\n * bigger than the budget (every live fragment was made in this same frame) does not make the rest at all, so a blast never builds a thousand meshes only to fade them\n * out. Returns null when the fragment was not made.\n */\n /**\n * Throws `f` into the scene, within `maxAllowed` live fragments (the oldest small ones make room first). A `lasting` fragment (a steel bar) is debris that\n * stays: it has a body the player and the pieces run into, however thin it is, and it never fades.\n */\n spawn(f: Fragment, material: THREE_NS.Material, home: string, maxAllowed: number, lasting = false): THREE_NS.Mesh | null {\n if (this.list.length >= maxAllowed) {\n let alive = 0\n let oldest: Live | undefined\n let oldestSmall: Live | undefined\n for (const l of this.list) {\n if (l.dying) continue\n alive++\n oldest ??= l\n if (!l.body) oldestSmall ??= l\n }\n // the splinters go first; the big ones only when nothing else is left\n oldest = oldestSmall ?? oldest\n if (alive >= maxAllowed) {\n if (!oldest || oldest.born === this.tick) return null\n oldest.dying = true\n }\n }\n const geo = this.geometryOf(f)\n const mesh = new this.THREE.Mesh(geo, material)\n mesh.position.set(f.center[0], f.center[1], f.center[2])\n mesh.quaternion.set(f.rotation[0], f.rotation[1], f.rotation[2], f.rotation[3]).normalize()\n const sz = f.size\n const sc = new this.THREE.Vector3(Math.max(0.005, sz[0]), Math.max(0.005, sz[1]), Math.max(0.003, sz[2]))\n mesh.scale.copy(sc)\n mesh.castShadow = true\n // pure visual debris: a host that picks with a raycast can skip it\n mesh.userData.destructionDebris = true\n mesh.name = 'fragment'\n markKitOrigin(mesh, { owner: 'game-destruction-three', kind: 'fragment', id: f.material })\n this.o.scene.add(mesh)\n const live: Live = {\n mesh,\n home,\n vel: new this.THREE.Vector3(f.velocity[0], f.velocity[1], f.velocity[2]),\n ang: new this.THREE.Vector3(f.angularVelocity[0], f.angularVelocity[1], f.angularVelocity[2]),\n // shards are thin: the contact extent uses the real (small) thickness, the chunk uses half of each side\n half: sc.clone().multiplyScalar(0.5),\n baseScale: sc,\n still: 0,\n asleep: false,\n rest: 0,\n fade: 1,\n dying: false,\n air: f.shape === 'scrap' && sz[2] <= SHEET_MAX ? SHEET_AIR : 0,\n body: null,\n born: this.tick,\n life: lasting ? 0 : Math.max(0, typeof this.o.life === 'function' ? this.o.life(f, home) : this.o.life),\n }\n if (lasting || (f.shape !== 'shard' && isBig(f.size))) {\n live.body = {\n mass: f.mass,\n push: (x, z) => {\n live.vel.x = x\n live.vel.z = z\n live.vel.y = Math.max(live.vel.y, 0.3)\n this.rouse(live)\n },\n }\n }\n this.list.push(live)\n this.addMarks(mesh, f)\n return mesh\n }\n\n /** The boxes of the big fragments around (x, z). */\n solidsNear(x: number, z: number, radius: number, found: (home: string, min: [number, number, number], max: [number, number, number], body: LooseBody) => void): void {\n const boxes: number[] = []\n for (const f of this.list) {\n if (!f.body || f.dying) continue\n const reach = f.half.length() + radius\n if (Math.abs(f.mesh.position.x - x) > reach || Math.abs(f.mesh.position.z - z) > reach) continue\n f.mesh.updateMatrixWorld()\n boxes.length = 0\n pushFittedBoxes(this.unitBox, f.mesh.matrixWorld, boxes)\n for (let i = 0; i < boxes.length; i += 6) {\n if (x < boxes[i] - radius || x > boxes[i + 3] + radius || z < boxes[i + 2] - radius || z > boxes[i + 5] + radius) continue\n found(f.home, [boxes[i], boxes[i + 1], boxes[i + 2]], [boxes[i + 3], boxes[i + 4], boxes[i + 5]], f.body)\n }\n }\n }\n\n /** Add velocity to every fragment within `radius` of a point (blasts). */\n blast(point: [number, number, number], radius: number, speed: number): void {\n for (const f of this.list) {\n const d = this.v.copy(f.mesh.position).sub(this.w.set(point[0], point[1], point[2]))\n const dist = d.length()\n if (dist > radius || f.dying) continue\n const k = (1 - dist / radius) ** 2 * speed\n d.normalize().multiplyScalar(k)\n d.y += k * 0.4\n f.vel.add(d)\n f.ang.add(this.w.set(this.rng() - 0.5, this.rng() - 0.5, this.rng() - 0.5).multiplyScalar(k))\n this.rouse(f)\n }\n }\n\n /** A fragment that came to rest stops having its matrix recomputed on every frame; whatever moves it again calls this first. */\n private rouse(f: Live): void {\n f.asleep = false\n f.rest = 0\n f.mesh.matrixAutoUpdate = true\n }\n\n /** What lies inside the disc looks at the ground again: it was dug or heaped under it. */\n wakeRegion(x: number, z: number, radius: number): void {\n for (const f of this.list) {\n if (!f.asleep || Math.hypot(f.mesh.position.x - x, f.mesh.position.z - z) > radius) continue\n this.rouse(f)\n }\n }\n\n update(dt: number): void {\n this.tick++\n this.wakeUnsupported()\n const g = this.o.gravity\n for (let i = this.list.length - 1; i >= 0; i--) {\n const f = this.list[i]\n if (f.dying) {\n f.mesh.matrixAutoUpdate = true\n f.fade -= dt / 0.6\n if (f.fade <= 0) {\n this.o.scene.remove(f.mesh)\n this.list.splice(i, 1)\n continue\n }\n f.mesh.scale.copy(f.baseScale).multiplyScalar(f.fade)\n }\n if (f.asleep) {\n f.rest += dt\n if (f.life > 0 && f.rest > f.life && !f.body) {\n f.dying = true\n f.mesh.matrixAutoUpdate = true\n }\n continue\n }\n this.step(f, dt, g)\n }\n }\n\n /** A few fragments asleep each update (`SUPPORT_CHECKS`, in turn) look at the ground under them again: one left over air falls. */\n private wakeUnsupported(): void {\n const n = this.list.length\n for (let k = 0; k < Math.min(SUPPORT_CHECKS, n); k++) {\n this.supportTurn = (this.supportTurn + 1) % n\n const f = this.list[this.supportTurn]\n if (!f.asleep || f.dying) continue\n const e = this.m.makeRotationFromQuaternion(f.mesh.quaternion).elements\n const ext = Math.abs(e[1]) * f.half.x + Math.abs(e[5]) * f.half.y + Math.abs(e[9]) * f.half.z\n if (f.mesh.position.y - ext > this.o.groundAt(f.mesh.position.x, f.mesh.position.z) + SUPPORT_GAP) this.rouse(f)\n }\n }\n\n private step(f: Live, dt: number, g: number): void {\n const mesh = f.mesh\n f.vel.y -= g * dt\n mesh.position.addScaledVector(f.vel, dt)\n const w = f.ang.length()\n if (w > 1e-5) {\n this.dq.setFromAxisAngle(this.v.copy(f.ang).multiplyScalar(1 / w), w * dt)\n mesh.quaternion.premultiply(this.dq).normalize()\n }\n // ground contact: lowest point of the oriented box\n this.m.makeRotationFromQuaternion(mesh.quaternion)\n const e = this.m.elements\n const h = f.half\n const sc = f.dying ? f.fade : 1\n const ext = (Math.abs(e[1]) * h.x + Math.abs(e[5]) * h.y + Math.abs(e[9]) * h.z) * sc\n const gy = this.o.groundAt(mesh.position.x, mesh.position.z)\n let contact = false\n if (mesh.position.y - ext < gy) {\n contact = true\n mesh.position.y = gy + ext\n if (f.vel.y < -0.6) {\n f.vel.y = -f.vel.y * 0.25\n f.vel.x *= 0.7\n f.vel.z *= 0.7\n f.ang.multiplyScalar(0.55)\n // a hit on a corner makes it tumble a little\n f.ang.x += (this.rng() - 0.5) * 2\n f.ang.z += (this.rng() - 0.5) * 2\n } else {\n f.vel.y = 0\n const fr = Math.exp(-7 * dt)\n f.vel.x *= fr\n f.vel.z *= fr\n f.ang.multiplyScalar(Math.exp(-6 * dt))\n }\n } else {\n f.ang.multiplyScalar(Math.exp(-0.15 * dt))\n if (f.air > 0) this.flutter(f, dt)\n }\n if (contact && f.vel.lengthSq() < 4) this.settle(f, dt)\n const slow = f.vel.lengthSq() < 0.012 && f.ang.lengthSq() < 0.2\n if (contact && slow) {\n f.still += dt\n if (f.still > 0.4) {\n f.asleep = true\n f.mesh.updateMatrix()\n f.mesh.matrixAutoUpdate = false\n f.vel.set(0, 0, 0)\n f.ang.set(0, 0, 0)\n }\n } else {\n f.still = 0\n }\n }\n\n /** A sheet in the air: drag slows it to a slow fall, and it sways and turns over as it goes. */\n private flutter(f: Live, dt: number): void {\n f.vel.multiplyScalar(Math.exp(-f.air * dt))\n f.vel.x += (this.rng() - 0.5) * SHEET_SWAY * dt\n f.vel.z += (this.rng() - 0.5) * SHEET_SWAY * dt\n f.ang.x += (this.rng() - 0.5) * SHEET_SWAY * 4 * dt\n f.ang.z += (this.rng() - 0.5) * SHEET_SWAY * 4 * dt\n }\n\n /** Tip the fragment towards lying on its flattest face. */\n private settle(f: Live, dt: number): void {\n const mesh = f.mesh\n this.m.makeRotationFromQuaternion(mesh.quaternion)\n const e = this.m.elements\n const up = [e[1], e[5], e[9]] // world-y component of each local axis\n const half = [f.half.x, f.half.y, f.half.z]\n let small = 0\n for (let i = 1; i < 3; i++) if (half[i] < half[small]) small = i\n let axis = small\n // a broken board does not stand on its end\n if (Math.abs(up[small]) < 0.35 && !f.body) {\n axis = 0\n for (let i = 1; i < 3; i++) if (Math.abs(up[i]) > Math.abs(up[axis])) axis = i\n }\n const sign = up[axis] >= 0 ? 1 : -1\n this.v.set(e[axis * 4], e[axis * 4 + 1], e[axis * 4 + 2]).multiplyScalar(sign)\n this.w.set(0, 1, 0)\n this.dq.setFromUnitVectors(this.v, this.w)\n this.q.copy(this.dq).multiply(mesh.quaternion)\n mesh.quaternion.slerp(this.q, clamp(dt * 7, 0, 1))\n }\n\n /** Remove the fragments of one object (after `restore`). */\n removeHome(home: string): void {\n for (let i = this.list.length - 1; i >= 0; i--) {\n if (this.list[i].home === home) {\n this.o.scene.remove(this.list[i].mesh)\n this.list.splice(i, 1)\n }\n }\n }\n\n clear(): void {\n for (const f of this.list) this.o.scene.remove(f.mesh)\n this.list.length = 0\n }\n\n /** `clear`, the random stream back to its seed and the tick to 0: what comes next flies as on a new system. */\n reset(): void {\n this.clear()\n this.rng = createRng(FRAGMENT_SEED)\n this.tick = 0\n }\n\n dispose(): void {\n this.clear()\n this.box.dispose()\n this.markGeometry?.dispose()\n this.markMaterial?.dispose()\n for (const g of this.shardGeos) g?.dispose()\n this.shardGeos = []\n for (const variants of this.shapeGeos.values()) for (const g of variants) g?.dispose()\n this.shapeGeos.clear()\n for (const m of this.materials.values()) m.dispose()\n this.materials.clear()\n }\n}\n","import type * as THREE_NS from 'three'\n\n/** Slice length (m) of a turned mesh and the most slices of one mesh. */\nconst SLICE_LENGTH = 0.12\nconst MAX_SLICES = 12\n/** A mesh whose axis box is at most this many times its own volume counts as not turned. */\nconst SNUG_RATIO = 1.1\n\ntype Corner = { readonly x: number; readonly y: number; readonly z: number }\ntype Local = { readonly min: Corner; readonly max: Corner }\n\n/**\n * Appends world axis boxes (min x, y, z, max x, y, z) around the local box of a mesh: one when it lies square, else slices along its longest side. The axis box of a board\n * lying askew is a wide square that holds mostly air, and what walks would hit that air.\n */\nexport function pushFittedBoxes(local: Local, matrix: THREE_NS.Matrix4, out: number[]): void {\n const e = matrix.elements\n const sizes = [0, 1, 2].map((k) => (k === 0 ? local.max.x - local.min.x : k === 1 ? local.max.y - local.min.y : local.max.z - local.min.z))\n const lengths = [0, 1, 2].map((k) => sizes[k] * Math.hypot(e[k * 4], e[k * 4 + 1], e[k * 4 + 2]))\n const longest = lengths.indexOf(Math.max(...lengths))\n const whole = worldBoxOf(local, matrix, longest, 0, 1)\n const span = (whole[3] - whole[0]) * (whole[4] - whole[1]) * (whole[5] - whole[2])\n const volume = lengths[0] * lengths[1] * lengths[2]\n const slices = span <= volume * SNUG_RATIO ? 1 : Math.min(MAX_SLICES, Math.ceil(lengths[longest] / SLICE_LENGTH))\n if (slices <= 1) {\n out.push(...whole)\n return\n }\n for (let i = 0; i < slices; i++) out.push(...worldBoxOf(local, matrix, longest, i / slices, (i + 1) / slices))\n}\n\nfunction worldBoxOf(local: Local, matrix: THREE_NS.Matrix4, axis: number, from: number, to: number): number[] {\n const e = matrix.elements\n const low = [local.min.x, local.min.y, local.min.z]\n const high = [local.max.x, local.max.y, local.max.z]\n const start = low[axis]\n const size = high[axis] - start\n low[axis] = start + size * from\n high[axis] = start + size * to\n const box = [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity]\n for (const x of [low[0], high[0]]) for (const y of [low[1], high[1]]) for (const z of [low[2], high[2]]) {\n for (let k = 0; k < 3; k++) {\n const v = e[k] * x + e[k + 4] * y + e[k + 8] * z + e[k + 12]\n box[k] = Math.min(box[k], v)\n box[k + 3] = Math.max(box[k + 3], v)\n }\n }\n return box\n}\n","import type { Vec3 } from '@adatechnology/game-destruction'\n\n/** Small deterministic PRNG (mulberry32): returns a function giving numbers in [0, 1). */\nexport function createRng(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** Hash of a few numbers into an unsigned 32-bit seed. */\nexport function hashNumbers(...values: number[]): number {\n let h = 2166136261\n for (const v of values) {\n const n = Math.round(v * 1000) | 0\n h = Math.imul(h ^ n, 16777619)\n h ^= h >>> 13\n }\n return h >>> 0\n}\n\nexport function hashString(s: string): number {\n let h = 2166136261\n for (let i = 0; i < s.length; i++) h = Math.imul(h ^ s.charCodeAt(i), 16777619)\n return h >>> 0\n}\n\nexport const clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v)\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t\n\nexport function vec3Length(v: Vec3): number {\n return Math.hypot(v[0], v[1], v[2])\n}\n\nexport function normalize3(v: Vec3): Vec3 {\n const l = Math.hypot(v[0], v[1], v[2])\n return l > 1e-9 ? [v[0] / l, v[1] / l, v[2] / l] : [0, 1, 0]\n}\n\n/** `0xRRGGBB` -> `[r, g, b]` in 0..1. */\nexport function hexToRgb(hex: number): [number, number, number] {\n return [((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255]\n}\n\nexport function mixHex(a: number, b: number, t: number): number {\n const ar = (a >> 16) & 255\n const ag = (a >> 8) & 255\n const ab = a & 255\n const r = Math.round(ar + (((b >> 16) & 255) - ar) * t)\n const g = Math.round(ag + (((b >> 8) & 255) - ag) * t)\n const bl = Math.round(ab + ((b & 255) - ab) * t)\n return (r << 16) | (g << 8) | bl\n}\n","import type * as THREE_NS from 'three'\n\nimport { createRng } from './math'\n\n/** How many shapes of each kind there are; a fragment takes one by the hash of its id, so a burst shares a handful of buffers. */\nexport const FRAGMENT_SHAPE_VARIANTS = 6\n\n/** Cross-sections along a sliver (the last one is its point) and how much each corner may stray in or out (the torn fibres). */\nconst SLIVER_STATIONS = 6\nconst SLIVER_FRAY = 0.3\n\n/** Corners of a sliver's cross-section in the unit box: the four corners and a ridge on each wide face. */\nconst SLIVER_SECTION: ReadonlyArray<readonly [number, number]> = [[0.5, 0.5], [0, 0.5], [-0.5, 0.5], [-0.5, -0.5], [0, -0.5], [0.5, -0.5]]\n\n/** Width of the section along a sliver (0 at the broken end, 1 at the point): ragged and narrower at the break, full in the middle, tapering to the point. */\nconst sliverWidth = (t: number): number => (t < 0.25 ? 0.6 + 1.6 * t : t > 0.5 ? Math.max(0, (1 - t) / 0.5) ** 0.85 : 1)\n\nconst pushTriangle = (out: number[], a: readonly number[], b: readonly number[], c: readonly number[]): void => {\n out.push(a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2])\n}\n\nconst faceted = (THREE: typeof THREE_NS, positions: number[]): THREE_NS.BufferGeometry => {\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n geometry.computeVertexNormals()\n return geometry\n}\n\n/**\n * A splinter of wood in the unit box, long along x: a ragged broken end, a body whose corners stray in and out from section to section (the torn fibres\n * along its edges), bending a little, and a point at the other end that is off its axis. About 60 triangles, shared by every splinter of the variant.\n */\nexport function buildSliverGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(7000 + seed)\n const rings: number[][][] = []\n const bendY = (rnd() - 0.5) * 0.3\n const bendZ = (rnd() - 0.5) * 0.3\n for (let i = 0; i < SLIVER_STATIONS - 1; i++) {\n const t = i / (SLIVER_STATIONS - 1)\n const x = -0.5 + t + (i > 0 ? (rnd() - 0.5) * 0.08 : 0)\n const width = sliverWidth(t)\n const lift = Math.sin(t * Math.PI)\n rings.push(SLIVER_SECTION.map(([y, z]) => {\n const fray = 1 - SLIVER_FRAY + SLIVER_FRAY * 1.4 * rnd()\n return [x, Math.max(-0.5, Math.min(0.5, y * width * fray + bendY * lift)), Math.max(-0.5, Math.min(0.5, z * width * fray + bendZ * lift))]\n }))\n }\n const tip = [0.5, (rnd() - 0.5) * 0.5, (rnd() - 0.5) * 0.3]\n // the broken end is torn, not cut: its centre stands out or sinks in\n const torn = [-0.5 + rnd() * 0.12, (rnd() - 0.5) * 0.2, (rnd() - 0.5) * 0.2]\n const sides = SLIVER_SECTION.length\n const positions: number[] = []\n for (let k = 0; k < sides; k++) {\n const next = (k + 1) % sides\n pushTriangle(positions, torn, rings[0][next], rings[0][k])\n for (let i = 0; i < rings.length - 1; i++) {\n const a = rings[i][k], b = rings[i][next], c = rings[i + 1][next], d = rings[i + 1][k]\n pushTriangle(positions, a, b, c)\n pushTriangle(positions, a, c, d)\n }\n const last = rings[rings.length - 1]\n pushTriangle(positions, last[k], last[next], tip)\n }\n return faceted(THREE, positions)\n}\n\n/**\n * A crumbly lump of pressed fibre (MDF) in the unit box: an icosahedron whose corners are pushed in and out by where they are (so the faces stay\n * closed), squashed to fill the box. 20 triangles.\n */\nexport function buildLumpGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(8000 + seed)\n const base = new THREE.IcosahedronGeometry(0.5, 0)\n const source = base.getAttribute('position')\n const pushOf = new Map<string, number>()\n const positions: number[] = []\n for (let i = 0; i < source.count; i++) {\n const x = source.getX(i), y = source.getY(i), z = source.getZ(i)\n const key = `${x.toFixed(3)},${y.toFixed(3)},${z.toFixed(3)}`\n let push = pushOf.get(key)\n if (push === undefined) {\n push = 0.6 + 0.55 * rnd()\n pushOf.set(key, push)\n }\n positions.push(x * push, y * push, z * push)\n }\n base.dispose()\n const extent = [0, 0, 0]\n for (let i = 0; i < positions.length; i++) extent[i % 3] = Math.max(extent[i % 3], Math.abs(positions[i]))\n for (let i = 0; i < positions.length; i++) positions[i] *= 0.5 / Math.max(extent[i % 3], 1e-3)\n return faceted(THREE, positions)\n}\n\n/** Points along each long edge of a peeled sheet of veneer. */\nconst VENEER_EDGE = 11\n\n/**\n * A sheet of veneer peeled off plywood in the unit box (thin along z): long edges torn along the grain in fine teeth (now and then a deeper notch) and\n * the short ends broken across with a sliver standing out, extruded to its thickness.\n */\nexport function buildVeneerGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(9000 + seed)\n const shape = new THREE.Shape()\n const outline: Array<[number, number]> = []\n // the long edges tear along the grain in fine teeth; each short end breaks across with one long sliver of veneer standing out\n const edge = (y: number, inward: number): number => y - inward * (rnd() * 0.16 + (rnd() < 0.15 ? 0.12 : 0))\n for (let i = 0; i <= VENEER_EDGE; i++) outline.push([-0.5 + i / VENEER_EDGE, edge(0.5, 1)])\n outline.push([0.5 - rnd() * 0.12, 0.2 * rnd()], [0.5, -0.1 + 0.2 * rnd()], [0.5 - rnd() * 0.12, -0.25 * rnd()])\n for (let i = VENEER_EDGE; i >= 0; i--) outline.push([-0.5 + i / VENEER_EDGE, edge(-0.5, -1)])\n outline.push([-0.5 + rnd() * 0.12, -0.2 * rnd()], [-0.5, 0.1 * rnd()], [-0.5 + rnd() * 0.12, 0.25 * rnd()])\n shape.moveTo(outline[0][0], outline[0][1])\n for (let i = 1; i < outline.length; i++) shape.lineTo(outline[i][0], outline[i][1])\n shape.closePath()\n const geometry = new THREE.ExtrudeGeometry(shape, { depth: 1, bevelEnabled: false })\n geometry.translate(0, 0, -0.5)\n return geometry\n}\n\n/** Share of a broken board's length its torn end takes, and how many strands of fibre (at least, at most) the end splits into across its width. */\nconst TORN_END = 0.24\nconst TORN_STRANDS: readonly [number, number] = [4, 7]\n\n/** Pushes the two triangles of the quad a-b-c-d, wound so that it faces where (b - a) x (c - b) points. */\nconst pushQuad = (out: number[], quad: ReadonlyArray<readonly number[]>): void => {\n pushTriangle(out, quad[0], quad[1], quad[2])\n pushTriangle(out, quad[0], quad[2], quad[3])\n}\n\n/** Uneven cuts of [-0.5, 0.5] into `count` widths, each between a third and twice the mean. */\nconst unevenCuts = (count: number, rnd: () => number): number[] => {\n const shares = Array.from({ length: count }, () => 0.35 + 1.65 * rnd())\n const total = shares.reduce((sum, share) => sum + share, 0)\n const cuts = [-0.5]\n for (const share of shares) cuts.push(cuts[cuts.length - 1] + share / total)\n cuts[cuts.length - 1] = 0.5\n return cuts\n}\n\n/**\n * The stub of a wooden board broken across, in the unit box, long along x: the sound part of the board, and at its +x end the break, torn into strands\n * of fibre of uneven widths and lengths that bend a little and fray before they come to points, not a clean saw cut. 58 to 94 triangles.\n */\nexport function buildBrokenBoardGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(10000 + seed)\n const end = 0.5 - TORN_END\n const positions: number[] = []\n const lo = -0.5, hi = 0.5\n // the sound part of the board: a box from the far end to where the break starts (its face at the break is closed by the strands)\n pushQuad(positions, [[lo, lo, hi], [end, lo, hi], [end, hi, hi], [lo, hi, hi]])\n pushQuad(positions, [[lo, hi, lo], [end, hi, lo], [end, lo, lo], [lo, lo, lo]])\n pushQuad(positions, [[lo, hi, hi], [end, hi, hi], [end, hi, lo], [lo, hi, lo]])\n pushQuad(positions, [[lo, lo, lo], [end, lo, lo], [end, lo, hi], [lo, lo, hi]])\n pushQuad(positions, [[lo, lo, lo], [lo, lo, hi], [lo, hi, hi], [lo, hi, lo]])\n const count = TORN_STRANDS[0] + Math.floor(rnd() * (TORN_STRANDS[1] - TORN_STRANDS[0] + 1))\n const cuts = unevenCuts(count, rnd)\n for (let k = 0; k < count; k++) {\n const y0 = cuts[k], y1 = cuts[k + 1]\n const length = TORN_END * (0.15 + 0.85 * rnd())\n // halfway out the strand has narrowed and strays a little sideways and up or down; then it comes to a point off its middle\n const midX = end + length * (0.35 + 0.3 * rnd())\n const narrow = 0.55 + 0.35 * rnd()\n const shiftY = (rnd() - 0.5) * (y1 - y0) * 0.6\n const shiftZ = (rnd() - 0.5) * 0.5\n const cy = (y0 + y1) / 2 + shiftY, hy = ((y1 - y0) / 2) * narrow, hz = 0.5 * (0.4 + 0.5 * rnd())\n const base = [[end, y0, lo], [end, y1, lo], [end, y1, hi], [end, y0, hi]]\n const clampZ = (z: number): number => Math.max(lo, Math.min(hi, z))\n const mid = [[midX, cy - hy, clampZ(shiftZ - hz)], [midX, cy + hy, clampZ(shiftZ - hz)], [midX, cy + hy, clampZ(shiftZ + hz)], [midX, cy - hy, clampZ(shiftZ + hz)]]\n const tip = [end + length, y0 + (y1 - y0) * rnd(), clampZ(shiftZ + (rnd() - 0.5) * 0.4)]\n for (let i = 0; i < 4; i++) {\n const next = (i + 1) % 4\n pushQuad(positions, [base[i], base[next], mid[next], mid[i]])\n pushTriangle(positions, mid[i], mid[next], tip)\n }\n }\n return faceted(THREE, positions)\n}\n","import type * as THREE_NS from 'three'\nimport { lerp } from './math'\n\ninterface Spot {\n mesh: THREE_NS.Mesh\n kind: 'puddle' | 'ash'\n home: string\n x: number\n z: number\n radius: number\n target: number\n}\n\nconst MAX_RADIUS = 1.2\n\n/** Flat discs on the ground: puddles of melted material and piles of ash. Nearby ones merge; the oldest go when the cap is reached. */\nexport class GroundSpots {\n private readonly spots: Spot[] = []\n private readonly geometry: THREE_NS.CircleGeometry\n private readonly materials = new Map<string, THREE_NS.MeshBasicMaterial>()\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly scene: THREE_NS.Scene,\n private readonly groundAt: (x: number, z: number) => number,\n private readonly cap: number,\n ) {\n this.geometry = new THREE.CircleGeometry(1, 20)\n this.geometry.rotateX(-Math.PI / 2)\n }\n\n get count(): number {\n return this.spots.length\n }\n\n private material(kind: 'puddle' | 'ash', color: number): THREE_NS.MeshBasicMaterial {\n const key = `${kind}:${color}`\n let m = this.materials.get(key)\n if (!m) {\n m = new this.THREE.MeshBasicMaterial({\n color,\n transparent: true,\n opacity: kind === 'puddle' ? 0.88 : 0.95,\n depthWrite: false,\n polygonOffset: true,\n polygonOffsetFactor: -2,\n polygonOffsetUnits: -2,\n })\n this.materials.set(key, m)\n }\n return m\n }\n\n /** Add (or grow) a spot at (x, z). `radius` is the radius this addition contributes. */\n add(kind: 'puddle' | 'ash', x: number, z: number, radius: number, color: number, home: string): void {\n for (const s of this.spots) {\n if (s.kind !== kind) continue\n const d = Math.hypot(s.x - x, s.z - z)\n if (d < Math.max(s.target, radius) * 0.9) {\n s.target = Math.min(MAX_RADIUS, Math.sqrt(s.target * s.target + radius * radius * 0.5))\n return\n }\n }\n while (this.spots.length >= this.cap) this.remove(this.spots[0])\n const mesh = new this.THREE.Mesh(this.geometry, this.material(kind, color))\n const y = this.groundAt(x, z) + 0.004 + (this.spots.length % 8) * 0.0004\n mesh.position.set(x, y, z)\n mesh.scale.setScalar(0.001)\n mesh.renderOrder = 1\n mesh.userData.destructionDebris = true\n this.scene.add(mesh)\n this.spots.push({ mesh, kind, home, x, z, radius: 0.001, target: Math.min(MAX_RADIUS, radius) })\n }\n\n private remove(s: Spot): void {\n const i = this.spots.indexOf(s)\n if (i >= 0) this.spots.splice(i, 1)\n this.scene.remove(s.mesh)\n }\n\n update(dt: number): void {\n const k = Math.min(1, dt * 3)\n for (const s of this.spots) {\n if (Math.abs(s.radius - s.target) < 1e-4) continue\n s.radius = lerp(s.radius, s.target, k)\n s.mesh.scale.setScalar(s.radius)\n }\n }\n\n /** Remove the spots made for one object (after its `restore`). */\n removeHome(home: string): void {\n for (const s of [...this.spots]) if (s.home === home) this.remove(s)\n }\n\n clear(): void {\n for (const s of [...this.spots]) this.remove(s)\n }\n\n dispose(): void {\n this.clear()\n this.geometry.dispose()\n for (const m of this.materials.values()) m.dispose()\n this.materials.clear()\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { Vec3 } from '@adatechnology/game-destruction'\nimport type { PieceBody } from './internal'\nimport { clamp } from './math'\n\nexport interface PieceSystemOptions {\n groundAt: (x: number, z: number) => number\n /**\n * The highest top of what does not move (furniture, scenery) under `(x, z)` that a corner at height `y` can land on (at most `step` above it),\n * `-Infinity` when none. The ground and the other pieces are added by the system.\n */\n staticTopAt?: (x: number, z: number, y: number, step: number) => number\n gravity: number\n /** A piece hit the ground faster than 3 m/s (throttled per piece). */\n onHardLanding: (piece: PieceBody, point: Vec3, speed: number) => void\n /** Notified when a piece is about to be removed. */\n scene: THREE_NS.Scene\n /**\n * What a piece moving from `from` to `to` (its centre, world) runs into on the way: a wall, a car, a cupboard (`distance` along the way, the `normal` of what it met).\n * Without it a piece only meets the ground, the tops of fixed things and the other pieces.\n */\n sweep?: (piece: PieceBody, from: Vec3, to: Vec3) => PieceSweepHit | null\n /** A piece ran into something (`sweep`) faster than `SLAM_MIN_SPEED` m/s into it (throttled per piece): for the blow on both and the sound. */\n onSlam?: (piece: PieceBody, hit: PieceSweepHit, speed: number) => void\n}\n\n/** What a moving piece ran into (`PieceSystemOptions.sweep`). */\nexport interface PieceSweepHit {\n readonly object: string\n readonly part: string\n /** Metres along the way from the centre where the piece meets it. */\n readonly distance: number\n readonly point: Vec3\n readonly normal: Vec3\n}\n\n/** Slower than this (m/s) into a wall a piece only stops against it: no blow, no sound. */\nexport const SLAM_MIN_SPEED = 2\n/** Share of the speed into a wall a piece keeps, bouncing back. */\nconst SLAM_BOUNCE = 0.2\n/** Normals steeper than this (y) are a floor or a top: the support of the pieces answers those, not the sweep. */\nconst SLAM_FLOOR_NORMAL = 0.7\n\nconst SUB_DT = 1 / 120\nconst MU = 0.7\nconst SLEEP_AFTER = 0.5\n/**\n * A piece on the ground that neither moves farther than `CALM_DRIFT` (m) nor turns more than `CALM_TURN` (rad) in `CALM_SLEEP_AFTER` seconds sleeps, however\n * its speed flickers: a book propped on another, or trembling where its corners rest on two pieces, stays in place; a fall or a slide leaves the window sooner.\n */\nconst CALM_DRIFT = 0.01\nconst CALM_TURN = 0.05\nconst CALM_SLEEP_AFTER = 1.5\nconst HARD_LANDING = 3\n/** Contact tolerance in metres: corners this close to the ground count as touching, which keeps the contact set (and a resting box) stable. */\nconst SLOP = 0.002\n/** A resting support narrower than this fraction of the centre-of-mass height is a balancing act, not a rest: the piece topples. */\nconst NARROW = 0.3\n/** Angular acceleration (rad/s^2 per metre of height) that pushes a balancing piece off its edge, toward the side its centre of mass leans to. */\nconst TOPPLE = 3\n/** Angular acceleration (rad/s^2) of a piece that falls over (`tip`), beyond what the box of its bounds would allow, and the height of the centre of mass (m) at which it lies. */\nconst TIP_ACCELERATION = 30\nconst TIP_LYING = 0.25\nconst TIP_SECONDS = 3\n/** How far (m) above a corner a top may be and still catch it (on top of what the corner falls in one sub-step): higher is beside it, not under it. */\nconst STEP = 0.03\n/** Slots of the warm start: the 8 corners and the points along the 12 edges. */\nconst WARM_SLOTS = 8 + 12 * 7\n/** Passes of the contact solver over the points that touch the ground, each substep. */\nconst SOLVER_PASSES = 10\n/** Restitution of a piece against the side of a step of the ground. */\nconst SIDE_BOUNCE = 0.1\n/**\n * Points along each edge of the box, between its corners (fractions of the half edge), that also touch the ground when the support under the corners is not level\n * (the piece is over a step): the edge of a table under a box's bottom is a support between its corners. On level ground the corners are enough.\n */\nconst EDGE_POINTS = [-0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75]\n/** Sleeping pieces whose support is looked at again each update, in turn: what held one up may have broken, fallen over or been carried off. */\nconst SUPPORT_CHECKS = 16\n/** A sleeping piece none of whose lowest points has a support within this many metres under it wakes and falls. */\nconst SUPPORT_GAP = 0.02\n\n/** Box of a piece in the world: centre, rotation columns (`Matrix4.elements`) and half extents. */\ninterface Solid {\n body: PieceBody\n c: Vec3\n e: number[]\n half: Vec3\n /** Radius of the box around its centre: a point farther than it on the ground plane misses it. */\n r: number\n}\n\n/** Height where the vertical line through `(x, z)` leaves the top of a box, or -Infinity when it misses the box. */\nconst boxTopAt = (s: Solid, x: number, z: number): number => {\n const e = s.e\n const dx = x - s.c[0], dz = z - s.c[2]\n let t0 = -Infinity, t1 = Infinity\n for (let k = 0; k < 3; k++) {\n // the line is c + (dx, t, dz) with t the height over the centre; along axis k: p + t d\n const p = e[k * 4] * dx + e[k * 4 + 2] * dz\n const d = e[k * 4 + 1]\n const h = s.half[k]\n if (Math.abs(d) < 1e-9) {\n if (Math.abs(p) > h) return -Infinity\n continue\n }\n let a = (-h - p) / d, b = (h - p) / d\n if (a > b) [a, b] = [b, a]\n t0 = Math.max(t0, a)\n t1 = Math.min(t1, b)\n if (t0 > t1) return -Infinity\n }\n return s.c[1] + t1\n}\n\n/**\n * Light rigid-body physics for loose pieces: gravity, the 8 corners of the local box against the ground with an impulse (restitution, friction,\n * angular response), damping, sleeping, and a gentle horizontal separation between pieces side by side. The ground a corner lands on is the\n * highest of the terrain, the top of any other piece under it and what the host reports as fixed (`staticTopAt`): a falling shelf lands on the books\n * below it, a tipping panel on the chair in front of it. Over a step (a table's edge) points along the box's edges touch too, so the edge holds the box between\n * its corners, and the side of a step of the ground is a wall: a corner that comes at it from the side stops there. The contacts are solved together, warm started.\n * Not a general solver: what lies under a corner holds it, what stands beside it does not.\n */\nexport class PieceSystem {\n readonly list: PieceBody[] = []\n private time = 0\n private readonly p: THREE_NS.Vector3\n private readonly q: THREE_NS.Quaternion\n private readonly dq: THREE_NS.Quaternion\n private readonly m: THREE_NS.Matrix4\n private readonly ax: THREE_NS.Vector3\n private solids: Solid[] = []\n private supportTurn = 0\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly o: PieceSystemOptions,\n ) {\n this.p = new THREE.Vector3()\n this.q = new THREE.Quaternion()\n this.dq = new THREE.Quaternion()\n this.m = new THREE.Matrix4()\n this.ax = new THREE.Vector3()\n }\n\n get(objectId: string): PieceBody | null {\n return this.list.find((b) => b.objectId === objectId) ?? null\n }\n\n /** Sets a piece falling over, about the world axes x and z (a unit axis): its feet are thinner than the box that stands for it, so the box alone would hold it up. */\n tip(body: PieceBody, x: number, z: number): void {\n body.tipping = { x, z, seconds: TIP_SECONDS }\n body.sleeping = false\n }\n\n create(objectId: string, root: THREE_NS.Object3D, halfExtents: Vec3, localCenter: THREE_NS.Vector3, mass: number, velocity?: Vec3, angular?: Vec3): PieceBody {\n const existing = this.get(objectId)\n if (existing) {\n existing.root = root\n existing.halfExtents = halfExtents\n existing.mass = mass\n this.setCenter(existing, localCenter)\n if (velocity) existing.velocity = [...velocity]\n existing.sleeping = false\n return existing\n }\n const body: PieceBody = {\n objectId,\n tipping: null,\n root,\n velocity: velocity ? [...velocity] : [0, 0, 0],\n angularVelocity: angular ? [...angular] : [0, 0, 0],\n halfExtents: [Math.max(0.01, halfExtents[0]), Math.max(0.01, halfExtents[1]), Math.max(0.01, halfExtents[2])],\n mass: Math.max(0.05, mass),\n sleeping: false,\n held: false,\n localCenter: [localCenter.x, localCenter.y, localCenter.z],\n centerV: localCenter.clone(),\n still: 0,\n calmAt: null,\n calm: 0,\n lastHit: -1,\n onGround: false,\n }\n this.list.push(body)\n return body\n }\n\n /** Move the centre of mass (after a part broke off). */\n setCenter(b: PieceBody, c: THREE_NS.Vector3): void {\n b.centerV.copy(c)\n b.localCenter = [c.x, c.y, c.z]\n }\n\n remove(objectId: string): void {\n const i = this.list.findIndex((b) => b.objectId === objectId)\n if (i >= 0) this.list.splice(i, 1)\n }\n\n clear(): void {\n this.list.length = 0\n }\n\n /** `clear` and the clock back to 0. */\n reset(): void {\n this.clear()\n this.time = 0\n }\n\n /** World position of the centre of mass. */\n centerOf(b: PieceBody, out: THREE_NS.Vector3): THREE_NS.Vector3 {\n return out.copy(b.centerV).applyQuaternion(b.root.quaternion).add(b.root.position)\n }\n\n impulse(b: PieceBody, impulse: Vec3, point?: Vec3): void {\n const inv = 1 / b.mass\n b.velocity[0] += impulse[0] * inv\n b.velocity[1] += impulse[1] * inv\n b.velocity[2] += impulse[2] * inv\n if (point) {\n const c = this.centerOf(b, this.p)\n const rx = point[0] - c.x\n const ry = point[1] - c.y\n const rz = point[2] - c.z\n // torque = r x J, angular velocity change = I^-1 torque\n const tx = ry * impulse[2] - rz * impulse[1]\n const ty = rz * impulse[0] - rx * impulse[2]\n const tz = rx * impulse[1] - ry * impulse[0]\n const w = this.mulInvInertia(b, tx, ty, tz)\n b.angularVelocity[0] += w[0]\n b.angularVelocity[1] += w[1]\n b.angularVelocity[2] += w[2]\n }\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n }\n\n /** I^-1 * (x, y, z) in world space for a box with the body's half extents and mass (needs `this.m` to hold the body's rotation). */\n private mulInvInertia(b: PieceBody, x: number, y: number, z: number): Vec3 {\n this.m.makeRotationFromQuaternion(b.root.quaternion)\n return this.mulInvInertiaWith(b, this.m.elements, x, y, z)\n }\n\n private mulInvInertiaWith(b: PieceBody, e: ArrayLike<number>, x: number, y: number, z: number): Vec3 {\n const [hx, hy, hz] = b.halfExtents\n const k = 3 / b.mass\n const ix = k / (hy * hy + hz * hz)\n const iy = k / (hx * hx + hz * hz)\n const iz = k / (hx * hx + hy * hy)\n // local = R^T v (columns of R are the local axes in world space)\n const lx = (e[0] * x + e[1] * y + e[2] * z) * ix\n const ly = (e[4] * x + e[5] * y + e[6] * z) * iy\n const lz = (e[8] * x + e[9] * y + e[10] * z) * iz\n return [e[0] * lx + e[4] * ly + e[8] * lz, e[1] * lx + e[5] * ly + e[9] * lz, e[2] * lx + e[6] * ly + e[10] * lz]\n }\n\n /** The points of the box that touch the ground, in its own frame: the 8 corners, then (with `edges`) `EDGE_POINTS` along each of its 12 edges. */\n private samples(b: PieceBody, edges: boolean): Vec3[] {\n const [hx, hy, hz] = b.halfExtents\n const out: Vec3[] = []\n for (let i = 0; i < 8; i++) out.push([i & 1 ? hx : -hx, i & 2 ? hy : -hy, i & 4 ? hz : -hz])\n if (!edges) return out\n const h = [hx, hy, hz]\n for (let axis = 0; axis < 3; axis++) {\n const a1 = (axis + 1) % 3\n const a2 = (axis + 2) % 3\n for (let k = 0; k < 4; k++) {\n for (const f of EDGE_POINTS) {\n const p: Vec3 = [0, 0, 0]\n p[axis] = f * h[axis]\n p[a1] = k & 1 ? h[a1] : -h[a1]\n p[a2] = k & 2 ? h[a2] : -h[a2]\n out.push(p)\n }\n }\n }\n return out\n }\n\n /**\n * An impulse along the unit normal `n` at `r` (from the centre of mass, world) that stops the point closing in along `n` (with `bounce`); `e` holds the body's rotation.\n */\n private contactImpulse(b: PieceBody, e: ArrayLike<number>, r: Vec3, n: Vec3, bounce: number): void {\n const v = b.velocity\n const w = b.angularVelocity\n const vn = (v[0] + w[1] * r[2] - w[2] * r[1]) * n[0] + (v[1] + w[2] * r[0] - w[0] * r[2]) * n[1] + (v[2] + w[0] * r[1] - w[1] * r[0]) * n[2]\n if (vn >= 0) return\n // I^-1 (r x n), then (I^-1 (r x n) x r) . n\n const a = this.mulInvInertiaWith(b, e, r[1] * n[2] - r[2] * n[1], r[2] * n[0] - r[0] * n[2], r[0] * n[1] - r[1] * n[0])\n const k = (a[1] * r[2] - a[2] * r[1]) * n[0] + (a[2] * r[0] - a[0] * r[2]) * n[1] + (a[0] * r[1] - a[1] * r[0]) * n[2]\n const j = (-(1 + bounce) * vn) / (1 / b.mass + k)\n for (let i = 0; i < 3; i++) {\n v[i] += (j * n[i]) / b.mass\n w[i] += a[i] * j\n }\n }\n\n /** What lies inside the disc looks at the ground again: it was dug or heaped under it. */\n wakeRegion(x: number, z: number, radius: number): void {\n for (const b of this.list) {\n if (!b.sleeping || b.held || Math.hypot(b.root.position.x - x, b.root.position.z - z) > radius) continue\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n }\n }\n\n update(dt: number): void {\n this.time += dt\n this.solids = this.list.map((body) => {\n const c = this.centerOf(body, new this.THREE.Vector3())\n const h = body.halfExtents\n return { body, c: [c.x, c.y, c.z] as Vec3, e: [...new this.THREE.Matrix4().makeRotationFromQuaternion(body.root.quaternion).elements], half: h, r: Math.hypot(h[0], h[1], h[2]) }\n })\n this.wakeUnsupported()\n for (const b of this.list) {\n if (b.held) {\n b.velocity = [0, 0, 0]\n b.angularVelocity = [0, 0, 0]\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n continue\n }\n if (b.sleeping) continue\n this.integrate(b, dt)\n }\n this.separate(dt)\n }\n\n /** A few sleeping pieces each update (`SUPPORT_CHECKS`, in turn) look under them again: one whose table broke, or whose shelf fell over, falls. */\n private wakeUnsupported(): void {\n const n = this.list.length\n for (let k = 0; k < Math.min(SUPPORT_CHECKS, n); k++) {\n this.supportTurn = (this.supportTurn + 1) % n\n const b = this.list[this.supportTurn]\n if (!b.sleeping || b.held || this.supported(b, false) || this.supported(b, true)) continue\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n }\n }\n\n /**\n * Whether a point of `b` (its corners, or with `edges` the points along its edges too) has the ground, a piece or a fixed top under it. Any point, not only the lowest:\n * a book propped on a fallen case rests by a corner high on it while its lowest one hangs beside it.\n */\n private supported(b: PieceBody, edges: boolean): boolean {\n const c = this.centerOf(b, this.p)\n const e = this.m.makeRotationFromQuaternion(b.root.quaternion).elements\n for (const [sx, sy, sz] of this.samples(b, edges)) {\n const y = c.y + e[1] * sx + e[5] * sy + e[9] * sz\n const x = c.x + e[0] * sx + e[4] * sy + e[8] * sz\n const z = c.z + e[2] * sx + e[6] * sy + e[10] * sz\n if (this.supportAt(b, x, y, z, STEP) >= y - SUPPORT_GAP) return true\n }\n return false\n }\n\n /** Where a corner of `self` at `(x, y, z)` lands: the ground, the top of another piece or of something fixed under it. */\n private supportAt(self: PieceBody, x: number, y: number, z: number, step: number): number {\n let top = this.o.groundAt(x, z)\n for (const s of this.solids) {\n if (s.body === self || s.body.held || Math.abs(x - s.c[0]) > s.r || Math.abs(z - s.c[2]) > s.r) continue\n const t = boxTopAt(s, x, z)\n if (t > top && t <= y + step) top = t\n }\n const fixed = this.o.staticTopAt?.(x, z, y, step) ?? -Infinity\n return Math.max(top, fixed)\n }\n\n /** Stops a piece that ran into something on its way from `start` to `pos` (`sweep`): moves it back to where it met it and takes the speed into it. */\n private sweepOn(b: PieceBody, start: Vec3, pos: Vec3): void {\n const travel = Math.hypot(pos[0] - start[0], pos[1] - start[1], pos[2] - start[2])\n if (travel < 1e-3) return\n const hit = this.o.sweep?.(b, start, pos)\n if (!hit || hit.normal[1] > SLAM_FLOOR_NORMAL) return\n const v = b.velocity\n const n = hit.normal\n const into = -(v[0] * n[0] + v[1] * n[1] + v[2] * n[2])\n if (into <= 0) return\n const k = Math.min(1, hit.distance / travel)\n for (let i = 0; i < 3; i++) {\n pos[i] = start[i] + (pos[i] - start[i]) * k\n v[i] += (1 + SLAM_BOUNCE) * into * n[i]\n }\n const w = b.angularVelocity\n w[0] *= 0.5\n w[1] *= 0.5\n w[2] *= 0.5\n if (into >= SLAM_MIN_SPEED && this.time - b.lastHit > 0.15) {\n b.lastHit = this.time\n this.o.onSlam?.(b, hit, into)\n }\n }\n\n private integrate(b: PieceBody, dt: number): void {\n const c = this.centerOf(b, this.p)\n const pos: Vec3 = [c.x, c.y, c.z]\n const start: Vec3 = [c.x, c.y, c.z]\n const q = this.q.copy(b.root.quaternion)\n const v = b.velocity\n const w = b.angularVelocity\n const invM = 1 / b.mass\n const steps = clamp(Math.ceil(dt / SUB_DT), 1, 8)\n const h = dt / steps\n let landing = 0\n let landPoint: Vec3 = [pos[0], pos[1], pos[2]]\n let contactedLast = false\n let touched = false\n let unstable = false\n\n // over a step of the ground (the corners find it at different heights: a table's edge under it) the points along the edges touch too\n const corners = this.samples(b, false)\n this.m.makeRotationFromQuaternion(q)\n let gLow = Infinity\n let gHigh = -Infinity\n for (const [sx, sy, sz] of corners) {\n const e0 = this.m.elements\n const y = pos[1] + e0[1] * sx + e0[5] * sy + e0[9] * sz\n const x = pos[0] + e0[0] * sx + e0[4] * sy + e0[8] * sz\n const z = pos[2] + e0[2] * sx + e0[6] * sy + e0[10] * sz\n // only the fixed ground counts here: other pieces touching it (a pile, things spawned together) keep the corners\n const g = Math.max(this.o.groundAt(x, z), this.o.staticTopAt?.(x, z, y, STEP) ?? -Infinity)\n gLow = Math.min(gLow, g)\n gHigh = Math.max(gHigh, g)\n }\n const local = gHigh - gLow > STEP ? this.samples(b, true) : corners\n const prev: Vec3[] = local.map(() => [0, 0, 0])\n\n for (let s = 0; s < steps; s++) {\n // where each point was before this substep: a point that comes at a higher ground from below it hit the side of the step\n this.m.makeRotationFromQuaternion(q)\n const e0 = this.m.elements\n for (let i = 0; i < local.length; i++) {\n const [sx, sy, sz] = local[i]\n prev[i][0] = pos[0] + e0[0] * sx + e0[4] * sy + e0[8] * sz\n prev[i][1] = pos[1] + e0[1] * sx + e0[5] * sy + e0[9] * sz\n prev[i][2] = pos[2] + e0[2] * sx + e0[6] * sy + e0[10] * sz\n }\n v[1] -= this.o.gravity * h\n pos[0] += v[0] * h\n pos[1] += v[1] * h\n pos[2] += v[2] * h\n const wl = Math.hypot(w[0], w[1], w[2])\n if (wl > 1e-6) {\n this.dq.setFromAxisAngle(this.ax.set(w[0] / wl, w[1] / wl, w[2] / wl), wl * h)\n q.premultiply(this.dq).normalize()\n }\n const damp = Math.exp(-0.15 * h)\n w[0] *= damp\n w[1] *= damp\n w[2] *= damp\n\n this.m.makeRotationFromQuaternion(q)\n const e = this.m.elements\n const rs: Vec3[] = []\n const ids: number[] = []\n let maxPen = 0\n const rise = STEP + Math.max(0, -v[1]) * h * 2\n // the side of a step of the ground: how far back the piece goes (metres along -dir) and the point that hit it\n let side: { back: number; dir: [number, number]; r: Vec3 } | null = null\n let lowest = Infinity\n for (let i = 0; i < local.length; i++) {\n const [sx, sy, sz] = local[i]\n const r: Vec3 = [e[0] * sx + e[4] * sy + e[8] * sz, e[1] * sx + e[5] * sy + e[9] * sz, e[2] * sx + e[6] * sy + e[10] * sz]\n const px = pos[0] + r[0]\n const pz = pos[2] + r[2]\n const cy = pos[1] + r[1]\n // the ground's own step (a table, a counter) that the point was more than a step below before this substep: it came at its side or is\n // under it, and does not stand on it (nor ratchets up onto it as the rest of the piece is lifted)\n const was = prev[i]\n const raw = this.o.groundAt(px, pz)\n if (raw > cy - SLOP && was[1] < raw - STEP) {\n // under a top it was already beneath (put under an overhang), or coming at its side: either way that top does not hold it\n if (this.o.groundAt(was[0], was[2]) >= raw - STEP) {\n // beneath it, the point stands on the floor the piece last stood on (the height field cannot see under a top)\n const floor = b.floor\n if (floor !== undefined && floor - cy > -SLOP && floor < raw - STEP) {\n rs.push(r)\n ids.push(i)\n maxPen = Math.max(maxPen, floor - cy)\n }\n continue\n }\n const dx = px - was[0]\n const dz = pz - was[2]\n const len = Math.hypot(dx, dz)\n if (len > 1e-6) {\n // where along its move the point met the side: the first place the ground is up at this top\n let lo = 0\n let hi = 1\n for (let it = 0; it < 6; it++) {\n const mid = (lo + hi) / 2\n if (this.o.groundAt(was[0] + dx * mid, was[2] + dz * mid) >= raw - STEP) hi = mid\n else lo = mid\n }\n const back = (1 - lo) * len + 0.001\n if (!side || back > side.back) side = { back, dir: [dx / len, dz / len], r }\n }\n continue\n }\n // the points along the edges are there for the step of the ground; on other pieces only the corners stand, as everywhere else\n const gy = i < 8 ? this.supportAt(b, px, cy, pz, rise) : Math.max(raw, this.o.staticTopAt?.(px, pz, cy, rise) ?? -Infinity)\n const pen = gy - cy\n if (pen > -SLOP) {\n rs.push(r)\n ids.push(i)\n if (pen > maxPen) maxPen = pen\n lowest = Math.min(lowest, gy)\n }\n }\n if (lowest < Infinity) b.floor = lowest\n if (side) {\n // the side of the step stops the piece: back out of it, and the point loses the speed it had into the side\n pos[0] -= side.dir[0] * side.back\n pos[2] -= side.dir[1] * side.back\n this.contactImpulse(b, e, side.r, [-side.dir[0], 0, -side.dir[1]], SIDE_BOUNCE)\n }\n contactedLast = rs.length > 0\n if (contactedLast) touched = true\n if (!contactedLast) continue\n pos[1] += Math.max(0, maxPen - SLOP * 0.5)\n let impact = 0\n for (const r of rs) impact = Math.max(impact, -(v[1] + w[2] * r[0] - w[0] * r[2]))\n const restitution = impact > 2 ? 0.25 : 0\n if (impact > landing) {\n landing = impact\n let sx = 0\n let sz = 0\n for (const r of rs) {\n sx += r[0]\n sz += r[2]\n }\n const lx = pos[0] + sx / rs.length\n const lz = pos[2] + sz / rs.length\n landPoint = [lx, pos[1] - Math.max(...rs.map((r) => -r[1])), lz]\n }\n // Contact impulses, solved together: each point keeps the impulse it has given so far (pushing only, never pulling) and the friction it has\n // given (within the paper's grip times that push), and every pass corrects them. Points spread unevenly under the box (a table's edge under\n // half of it) then share the weight as they should, instead of the first ones handled kicking the box into a spin.\n const goal = rs.map((r) => {\n const vy = v[1] + (w[2] * r[0] - w[0] * r[2])\n return vy < 0 ? -restitution * vy : 0\n })\n // the step moved the piece at the speed it had before the contacts: what they took from it along the ground is taken from the move too, so\n // a push the floor's grip holds does not creep the piece along\n const vx0 = v[0]\n const vz0 = v[2]\n // warm start: each point starts from what it gave in the last substep (a resting box carries its weight from the first pass)\n if (!b.warm || b.warm.length !== WARM_SLOTS * 3) b.warm = new Float64Array(WARM_SLOTS * 3)\n const warm = b.warm\n const accN = ids.map((id) => (id < WARM_SLOTS ? warm[id * 3] : 0))\n const accT = ids.map((id): [number, number] => (id < WARM_SLOTS ? [warm[id * 3 + 1], warm[id * 3 + 2]] : [0, 0]))\n for (let k = 0; k < rs.length; k++) {\n const r = rs[k]\n const jn = accN[k]\n const [fx, fz] = accT[k]\n if (jn === 0 && fx === 0 && fz === 0) continue\n v[0] += fx * invM\n v[1] += jn * invM\n v[2] += fz * invM\n // r x (fx, jn, fz)\n const dw = this.mulInvInertiaWith(b, e, r[1] * fz - r[2] * jn, r[2] * fx - r[0] * fz, r[0] * jn - r[1] * fx)\n w[0] += dw[0]\n w[1] += dw[1]\n w[2] += dw[2]\n }\n for (let it = 0; it < SOLVER_PASSES; it++) {\n for (let k = 0; k < rs.length; k++) {\n const r = rs[k]\n // normal impulse (n = +y): r x n = (-rz, 0, rx)\n const vy = v[1] + (w[2] * r[0] - w[0] * r[2])\n const a = this.mulInvInertiaWith(b, e, -r[2], 0, r[0])\n const denom = invM + (a[2] * r[0] - a[0] * r[2])\n const total = Math.max(0, accN[k] + (goal[k] - vy) / denom)\n const j = total - accN[k]\n accN[k] = total\n if (j !== 0) {\n v[1] += j * invM\n w[0] += a[0] * j\n w[1] += a[1] * j\n w[2] += a[2] * j\n }\n // friction in the contact plane, up to MU times the push the point gives\n const vx = v[0] + (w[1] * r[2] - w[2] * r[1])\n const vz = v[2] + (w[0] * r[1] - w[1] * r[0])\n const vt = Math.hypot(vx, vz)\n if (vt < 1e-6 && accT[k][0] === 0 && accT[k][1] === 0) continue\n let fx = accT[k][0]\n let fz = accT[k][1]\n if (vt > 1e-6) {\n const tx = vx / vt\n const tz = vz / vt\n // r x t with t = (tx, 0, tz) -> (ry*tz, rz*tx - rx*tz, -ry*tx)\n const at = this.mulInvInertiaWith(b, e, r[1] * tz, r[2] * tx - r[0] * tz, -r[1] * tx)\n const cx = at[1] * r[2] - at[2] * r[1]\n const cz = at[0] * r[1] - at[1] * r[0]\n const jt = vt / (invM + cx * tx + cz * tz)\n fx -= tx * jt\n fz -= tz * jt\n }\n const most = MU * accN[k]\n const f = Math.hypot(fx, fz)\n if (f > most) {\n fx *= most / f\n fz *= most / f\n }\n const dx = fx - accT[k][0]\n const dz = fz - accT[k][1]\n accT[k] = [fx, fz]\n if (dx === 0 && dz === 0) continue\n v[0] += dx * invM\n v[2] += dz * invM\n // r x f with f = (dx, 0, dz)\n const dw = this.mulInvInertiaWith(b, e, r[1] * dz, r[2] * dx - r[0] * dz, -r[1] * dx)\n w[0] += dw[0]\n w[1] += dw[1]\n w[2] += dw[2]\n }\n }\n pos[0] += (v[0] - vx0) * h\n pos[2] += (v[2] - vz0) * h\n warm.fill(0)\n for (let k = 0; k < rs.length; k++) {\n const id = ids[k]\n if (id >= WARM_SLOTS) continue\n warm[id * 3] = accN[k]\n warm[id * 3 + 1] = accT[k][0]\n warm[id * 3 + 2] = accT[k][1]\n }\n // Support check. The corner contacts above are relative to the centre of mass, so they already give a torque when the centre of mass is\n // outside the support. What they cannot do is end a balancing act: a tall thin piece on its edge (or a single corner) is in equilibrium\n // with the centre of mass above a very small support, so it must not rest there. It gets a gentle topple push toward the side it leans\n // to (or toward the wider side when it leans nowhere), and it may not sleep.\n let x0 = Infinity, x1 = -Infinity, z0 = Infinity, z1 = -Infinity, low = 0\n for (const r of rs) {\n x0 = Math.min(x0, r[0]); x1 = Math.max(x1, r[0])\n z0 = Math.min(z0, r[2]); z1 = Math.max(z1, r[2])\n low = Math.min(low, r[1])\n }\n const height = -low\n const wx = x1 - x0\n const wz = z1 - z0\n unstable = Math.min(wx, wz) < NARROW * height || x0 > 0 || x1 < 0 || z0 > 0 || z1 < 0\n if (b.tipping) {\n b.tipping.seconds -= h\n // lying is measured on the box as it is turned: a top corner held from above (a board it was joined to) says nothing of how it stands\n const [hx, hy, hz] = b.halfExtents\n const upHalf = Math.abs(e[1]) * hx + Math.abs(e[5]) * hy + Math.abs(e[9]) * hz\n if (upHalf < TIP_LYING || b.tipping.seconds <= 0) b.tipping = null\n else {\n w[0] += b.tipping.x * TIP_ACCELERATION * h\n w[2] += b.tipping.z * TIP_ACCELERATION * h\n unstable = true\n }\n }\n if (unstable) {\n // the support centre relative to the centre of mass: the piece falls away from it (toward +axis when it is centred)\n const dirX = x0 + x1 > 0 ? -1 : 1\n const dirZ = z0 + z1 > 0 ? -1 : 1\n const k = TOPPLE * Math.min(height, 1) * h\n // rotating about -z moves the top toward +x; rotating about +x moves it toward +z\n if (wx <= wz) w[2] -= dirX * k\n else w[0] += dirZ * k\n }\n // rolling / spinning resistance while touching the ground\n const rd = Math.exp((rs.length >= 3 ? -3 : -1.5) * h)\n w[0] *= rd\n w[1] *= rd\n w[2] *= rd\n const fd = Math.exp(-0.3 * h)\n v[0] *= fd\n v[2] *= fd\n }\n\n // what stands in the way (a wall, a car): the piece stops against it, bounces a little and both take the blow\n if (this.o.sweep && !b.held) this.sweepOn(b, start, pos)\n\n // write back\n b.root.quaternion.copy(q)\n const off = this.ax.copy(b.centerV).applyQuaternion(q)\n b.root.position.set(pos[0] - off.x, pos[1] - off.y, pos[2] - off.z)\n b.root.updateMatrixWorld(true)\n b.onGround = contactedLast\n\n if (landing > HARD_LANDING && this.time - b.lastHit > 0.15) {\n b.lastHit = this.time\n this.o.onHardLanding(b, landPoint, landing)\n }\n\n const still = touched && !unstable && Math.hypot(v[0], v[1], v[2]) < 0.12 && Math.hypot(w[0], w[1], w[2]) < 0.45\n if (still) b.still += dt\n else b.still = 0\n if (b.still >= SLEEP_AFTER || this.staysInPlace(b, touched && !b.tipping, pos, q, dt)) {\n b.sleeping = true\n b.calmAt = null\n v[0] = v[1] = v[2] = 0\n w[0] = w[1] = w[2] = 0\n }\n }\n\n /** Whether the piece has kept to the same spot on the ground for `CALM_SLEEP_AFTER` (see `CALM_DRIFT`). */\n private staysInPlace(b: PieceBody, touched: boolean, center: Vec3, q: THREE_NS.Quaternion, dt: number): boolean {\n const at = b.calmAt\n const turned = at ? 2 * Math.acos(Math.min(1, Math.abs(at.quaternion[0] * q.x + at.quaternion[1] * q.y + at.quaternion[2] * q.z + at.quaternion[3] * q.w))) : Infinity\n if (!touched || !at || Math.hypot(center[0] - at.center[0], center[1] - at.center[1], center[2] - at.center[2]) > CALM_DRIFT || turned > CALM_TURN) {\n b.calmAt = touched ? { center: [center[0], center[1], center[2]], quaternion: [q.x, q.y, q.z, q.w] } : null\n b.calm = 0\n return false\n }\n b.calm += dt\n return b.calm >= CALM_SLEEP_AFTER\n }\n\n /** Half the height of the box of a piece as it is turned now. */\n private halfHeight(b: PieceBody): number {\n const e = this.m.makeRotationFromQuaternion(b.root.quaternion).elements\n return Math.abs(e[1]) * b.halfExtents[0] + Math.abs(e[5]) * b.halfExtents[1] + Math.abs(e[9]) * b.halfExtents[2]\n }\n\n /** Push overlapping pieces apart (horizontal bounding circles), gently, so they do not interpenetrate forever. */\n private separate(dt: number): void {\n const n = this.list.length\n if (n < 2) return\n const maxMove = 1.5 * dt\n const ca = new this.THREE.Vector3()\n const cb = new this.THREE.Vector3()\n for (let i = 0; i < n; i++) {\n const a = this.list[i]\n for (let j = i + 1; j < n; j++) {\n const b = this.list[j]\n const fixedA = a.held || a.sleeping\n const fixedB = b.held || b.sleeping\n if (fixedA && fixedB) continue\n const ra = Math.hypot(a.halfExtents[0], a.halfExtents[1], a.halfExtents[2])\n const rb = Math.hypot(b.halfExtents[0], b.halfExtents[1], b.halfExtents[2])\n this.centerOf(a, ca)\n this.centerOf(b, cb)\n if (Math.abs(ca.y - cb.y) > ra + rb) continue\n // one lies on the other (a book on a shelf): the corners hold them apart, a sideways push would slide it off\n if (Math.abs(ca.y - cb.y) >= (this.halfHeight(a) + this.halfHeight(b)) * 0.9) continue\n const rh = (Math.max(a.halfExtents[0], a.halfExtents[2]) + Math.max(b.halfExtents[0], b.halfExtents[2])) * 0.8\n let dx = cb.x - ca.x\n let dz = cb.z - ca.z\n let d = Math.hypot(dx, dz)\n if (d >= rh) continue\n if (d < 1e-5) {\n dx = 1\n dz = 0\n d = 1\n }\n const push = Math.min(maxMove, (rh - d) * 0.5)\n const wa = fixedA ? 0 : fixedB ? 1 : b.mass / (a.mass + b.mass)\n const wb = fixedB ? 0 : fixedA ? 1 : a.mass / (a.mass + b.mass)\n const ux = dx / (d || 1)\n const uz = dz / (d || 1)\n if (!fixedA) {\n a.root.position.x -= ux * push * 2 * wa\n a.root.position.z -= uz * push * 2 * wa\n }\n if (!fixedB) {\n b.root.position.x += ux * push * 2 * wb\n b.root.position.z += uz * push * 2 * wb\n }\n }\n }\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { Vec3 } from '@adatechnology/game-destruction'\n\n/** A bar of a cage, in world space. */\nexport interface RebarBar {\n readonly center: Vec3\n readonly rotation: [number, number, number, number]\n readonly length: number\n}\n\n/** Bare rebar of reinforced parts: one instanced cylinder mesh per part, replaced whenever the part exposes more (or less) of its cage. */\nexport class RebarCages {\n private readonly cages = new Map<string, THREE_NS.InstancedMesh>()\n private readonly geometry: THREE_NS.CylinderGeometry\n private readonly material: THREE_NS.MeshStandardMaterial\n private readonly up: THREE_NS.Vector3\n private readonly dir: THREE_NS.Vector3\n private readonly mid: THREE_NS.Vector3\n private readonly q: THREE_NS.Quaternion\n private readonly scale: THREE_NS.Vector3\n private readonly m: THREE_NS.Matrix4\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly scene: THREE_NS.Scene,\n private readonly radius = 0.004,\n ) {\n this.geometry = new THREE.CylinderGeometry(radius, radius, 1, 6)\n this.material = new THREE.MeshStandardMaterial({ color: 0x74665c, roughness: 0.55, metalness: 0.6 })\n this.up = new THREE.Vector3(0, 1, 0)\n this.dir = new THREE.Vector3()\n this.mid = new THREE.Vector3()\n this.q = new THREE.Quaternion()\n this.scale = new THREE.Vector3()\n this.m = new THREE.Matrix4()\n }\n\n /** Bars drawn now, over every part. */\n get count(): number {\n let n = 0\n for (const mesh of this.cages.values()) n += mesh.count\n return n\n }\n\n /** Meshes of the live cages (tests and picking). */\n meshes(): THREE_NS.InstancedMesh[] {\n return [...this.cages.values()]\n }\n\n /**\n * Draw `bars` (world space) as the cage of `key`; an empty list removes it. The cage is a child of `holder` (the drawing of the part's object, the scene\n * by default), so it goes where the part goes: a beam that comes down takes its bare bars with it.\n */\n set(key: string, bars: ReadonlyArray<readonly [Vec3, Vec3]>, holder?: THREE_NS.Object3D): void {\n this.remove(key)\n if (bars.length === 0) return\n const parent = holder ?? this.scene\n parent.updateWorldMatrix(true, false)\n const toParent = new this.THREE.Matrix4().copy(parent.matrixWorld).invert()\n const mesh = new this.THREE.InstancedMesh(this.geometry, this.material, bars.length)\n bars.forEach(([a, b], i) => {\n this.dir.set(b[0] - a[0], b[1] - a[1], b[2] - a[2])\n const length = this.dir.length()\n this.mid.set((a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2)\n this.q.setFromUnitVectors(this.up, length > 1e-9 ? this.dir.divideScalar(length) : this.up)\n this.m.compose(this.mid, this.q, this.scale.set(1, Math.max(length, 1e-4), 1)).premultiply(toParent)\n mesh.setMatrixAt(i, this.m)\n })\n mesh.instanceMatrix.needsUpdate = true\n mesh.castShadow = true\n mesh.name = 'rebar-cage'\n parent.add(mesh)\n this.cages.set(key, mesh)\n }\n\n /** The cage of `from` now belongs to `to` (a part that left its object for one of its own) and hangs from `holder`, where it is in the world now. */\n move(from: string, to: string, holder: THREE_NS.Object3D): void {\n const mesh = this.cages.get(from)\n if (!mesh) return\n this.cages.delete(from)\n this.remove(to)\n holder.attach(mesh)\n this.cages.set(to, mesh)\n }\n\n /** Takes the cage of `key` away and gives its bars, where they are in the world now: centre, turn (the bar along its y) and length. */\n take(key: string): RebarBar[] {\n const mesh = this.cages.get(key)\n if (!mesh) return []\n mesh.updateWorldMatrix(true, false)\n const bars: RebarBar[] = []\n for (let i = 0; i < mesh.count; i++) {\n mesh.getMatrixAt(i, this.m)\n this.m.premultiply(mesh.matrixWorld).decompose(this.mid, this.q, this.scale)\n bars.push({ center: [this.mid.x, this.mid.y, this.mid.z], rotation: [this.q.x, this.q.y, this.q.z, this.q.w], length: this.scale.y })\n }\n this.remove(key)\n return bars\n }\n\n /** Radius of the bars drawn, metres. */\n get barRadius(): number {\n return this.radius\n }\n\n remove(key: string): void {\n const mesh = this.cages.get(key)\n if (!mesh) return\n mesh.removeFromParent()\n mesh.dispose()\n this.cages.delete(key)\n }\n\n /** Remove the cages of every part of `object` (keys are `object|part`). */\n removeObject(object: string): void {\n for (const key of [...this.cages.keys()]) if (key.startsWith(`${object}|`)) this.remove(key)\n }\n\n clear(): void {\n for (const key of [...this.cages.keys()]) this.remove(key)\n }\n\n dispose(): void {\n this.clear()\n this.geometry.dispose()\n this.material.dispose()\n }\n}\n","import type * as THREE_NS from 'three'\nimport { guessMaterial, inferJoints, MATERIALS, partMass } from '@adatechnology/game-destruction'\nimport type { JointKind, JointSpec, MaterialId, PartSpec } from '@adatechnology/game-destruction'\nimport type { Mesh, Object3D, SpecFromObjectOptions, SpecFromObjectResult, ThreeNamespace } from './types'\n\ninterface Entry {\n key: string\n meshes: Mesh[]\n box: THREE_NS.Box3\n material: MaterialId\n explicitId: string | null\n fill?: number\n hollow: boolean\n /** `userData.destructionSkin`: a layer drawn on a part (a label, a coat), never a part of its own. */\n skin: boolean\n tags?: string[]\n /** `userData.destructionContains`: the fluid the part holds (a hole in it makes it leak). */\n contains?: { fluid: string; liters: number }\n /** `userData.destructionPowder`: the loose dry contents the part holds (`PartSpec.powder`). */\n powder?: { color: number }\n /** `userData.destructionThickness`: the real wall thickness in metres (a can is a tenth of a millimetre, far less than its box says). */\n thickness?: number\n /** Part id wished by the host (`userData.destructionPart`). */\n fixedId: boolean\n name: string\n /** `parent` / `kind` of an object-valued `destructionPart`: the part is attached to `parent` by a joint of that kind. */\n parent?: string\n jointKind?: JointKind\n}\n\n/** What `userData.destructionPart` says: a string (the part id) or an object `{ id, material?, parent?, kind? }`. */\nexport interface PartHint {\n id: string\n material?: string\n parent?: string\n kind?: string\n}\n\n/** Read `userData.destructionContains` (`{ fluid, liters }`); undefined when it holds nothing. */\nfunction containsOf(value: unknown): { fluid: string; liters: number } | undefined {\n if (!value || typeof value !== 'object') return undefined\n const v = value as Record<string, unknown>\n return typeof v.fluid === 'string' && typeof v.liters === 'number' && v.liters > 0 ? { fluid: v.fluid, liters: v.liters } : undefined\n}\n\n/** Read `userData.destructionPart` (string or object with an `id`); null when it names no part. */\nexport function partHintOf(value: unknown): PartHint | null {\n if (typeof value === 'string') return value ? { id: value } : null\n if (!value || typeof value !== 'object') return null\n const v = value as Record<string, unknown>\n if (typeof v.id !== 'string' || !v.id) return null\n const str = (x: unknown): string | undefined => (typeof x === 'string' && x ? x : undefined)\n return { id: v.id, material: str(v.material), parent: str(v.parent), kind: str(v.kind) }\n}\n\nconst METAL = /steel|iron|metal|alumin|copper|brass|bronze|tin|titan|chrome|zinc|lead/i\n\nfunction sanitizeId(name: string): string {\n let id = name\n .trim()\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '')\n if (id && /^[0-9]/.test(id)) id = `p_${id}`\n return id\n}\n\nfunction isMesh(o: Object3D): o is Mesh {\n return (o as Mesh).isMesh === true\n}\n\nfunction sizeOf(box: THREE_NS.Box3): [number, number, number] {\n return [box.max.x - box.min.x, box.max.y - box.min.y, box.max.z - box.min.z]\n}\n\n/** Inverse of the root's world pose without its scale: world space to the metric frame the spec and the world's `setTransform` use. */\nexport function specFrameInverse(THREE: ThreeNamespace, root: Object3D): THREE_NS.Matrix4 {\n root.updateMatrixWorld(true)\n const position = new THREE.Vector3()\n const quaternion = new THREE.Quaternion()\n root.matrixWorld.decompose(position, quaternion, new THREE.Vector3())\n return new THREE.Matrix4().compose(position, quaternion, new THREE.Vector3(1, 1, 1)).invert()\n}\n\n/**\n * Build a `DestructibleSpec` from a three.js object: one part per mesh (meshes sharing `userData.destructionPart` become one part), each an\n * axis-aligned box in metres in the root's frame (its position and rotation removed, its world scale kept; rotation omitted), with the material taken from `options.materialOf`, `userData.destructionMaterial`\n * or a guess from the names. Tiny meshes are merged into the part they overlap most; joints are inferred from touching parts.\n *\n * `userData.destructionContains` (`{ fluid, liters }`) makes the part a container: a hole through it leaks. `userData.destructionPowder` (`{ color }`) fills it with a dry powder or flakes that puff out of a hole. `root.userData.destructionMass` (kg) fixes the total mass, split between the parts in proportion to their volume, density and fill.\n * A mesh with `userData.destructionSkin` (a label, a coat) joins the part it overlaps most instead of becoming a part: it stays drawn and bound to that part (decals, dents) but never breaks off.\n * Meshes that are invisible or have `userData.destructionIgnore` (or sit under such an object) are skipped. The result also tells which meshes\n * became which part, ready to be passed to `bind`.\n */\nexport function specFromObject3D(THREE: ThreeNamespace, root: Object3D, options: SpecFromObjectOptions = {}): SpecFromObjectResult {\n const fallback = options.fallback ?? 'plastic'\n const minSize = options.minSize ?? 0.015\n const inv = specFrameInverse(THREE, root)\n\n // 1. collect meshes -> entries (grouped by an explicit part name)\n const entries: Entry[] = []\n const byKey = new Map<string, Entry>()\n const visit = (o: Object3D): void => {\n if (!o.visible || o.userData?.destructionIgnore) return\n if (isMesh(o) && o.geometry) {\n const geom = o.geometry\n if (!geom.boundingBox) geom.computeBoundingBox()\n if (geom.boundingBox && !geom.boundingBox.isEmpty()) {\n const box = geom.boundingBox.clone().applyMatrix4(new THREE.Matrix4().multiplyMatrices(inv, o.matrixWorld))\n const mats = Array.isArray(o.material) ? o.material : [o.material]\n const matName = mats[0]?.name ?? ''\n const ud = o.userData ?? {}\n const hint = partHintOf(ud.destructionPart)\n const material =\n options.materialOf?.(o) ??\n (typeof ud.destructionMaterial === 'string' ? (ud.destructionMaterial as string) : undefined) ??\n hint?.material ??\n guessMaterial(`${o.name} ${matName} ${typeof ud.material === 'string' ? ud.material : ''}`) ??\n fallback\n const explicit = hint?.id ?? null\n const hollow = ud.hollow === true || /hollow/i.test(o.name)\n const skin = ud.destructionSkin === true\n const fill = options.fillOf?.(o, material)\n const tags = Array.isArray(ud.destructionTags) ? (ud.destructionTags as string[]) : undefined\n const contains = containsOf(ud.destructionContains)\n const powder = typeof (ud.destructionPowder as { color?: unknown } | undefined)?.color === 'number' ? { color: (ud.destructionPowder as { color: number }).color } : undefined\n const thickness = typeof ud.destructionThickness === 'number' && ud.destructionThickness > 0 ? (ud.destructionThickness as number) : undefined\n const existing = explicit ? byKey.get(explicit) : undefined\n if (existing) {\n const before = sizeOf(existing.box)\n const bv = before[0] * before[1] * before[2]\n const ns = sizeOf(box)\n existing.box.union(box)\n existing.meshes.push(o)\n if (ns[0] * ns[1] * ns[2] > bv) existing.material = material\n existing.hollow = existing.hollow || hollow\n existing.skin = existing.skin && skin\n if (fill !== undefined) existing.fill = fill\n if (contains) existing.contains = contains\n if (powder) existing.powder = powder\n if (thickness !== undefined) existing.thickness = Math.min(existing.thickness ?? thickness, thickness)\n } else {\n const e: Entry = { key: explicit ?? `m${entries.length}`, meshes: [o], box, material, explicitId: explicit, fill, hollow, skin, tags, fixedId: !!explicit, ...(contains ? { contains } : {}), ...(powder ? { powder } : {}), ...(thickness !== undefined ? { thickness } : {}), name: o.name, parent: hint?.parent, jointKind: hint?.kind as JointKind | undefined }\n entries.push(e)\n if (explicit) byKey.set(explicit, e)\n }\n }\n }\n for (const c of o.children) visit(c)\n }\n visit(root)\n\n // 2. merge tiny meshes and skins into the touching part they overlap most\n const eps = 0.005\n const overlapVolume = (a: THREE_NS.Box3, b: THREE_NS.Box3): number => {\n const x = Math.min(a.max.x, b.max.x) - Math.max(a.min.x, b.min.x) + eps\n const y = Math.min(a.max.y, b.max.y) - Math.max(a.min.y, b.min.y) + eps\n const z = Math.min(a.max.z, b.max.z) - Math.max(a.min.z, b.min.z) + eps\n return x > 0 && y > 0 && z > 0 ? x * y * z : 0\n }\n const largest = (e: Entry) => Math.max(...sizeOf(e.box))\n const kept: Entry[] = []\n const tiny: Entry[] = []\n for (const e of entries) (e.skin || (!e.fixedId && largest(e) < minSize) ? tiny : kept).push(e)\n for (const t of tiny) {\n let best: Entry | null = null\n let bestV = 0\n for (const k of kept) {\n const v = overlapVolume(t.box, k.box)\n if (v > bestV) {\n bestV = v\n best = k\n }\n }\n if (!best) {\n // not touching anything: join the nearest part within a small distance\n let bd = 0.05\n for (const k of kept) {\n const d = k.box.distanceToPoint(t.box.getCenter(new THREE.Vector3()))\n if (d < bd) {\n bd = d\n best = k\n }\n }\n }\n if (best) {\n best.meshes.push(...t.meshes) // the box stays: a tiny mesh sits inside or on the surface of its part\n } else {\n kept.push(t) // isolated crumb: keep it as its own part\n }\n }\n\n // 3. ids, parts\n const used = new Set<string>()\n const parts: PartSpec[] = []\n const meshesOf: Record<string, Object3D[]> = {}\n let counter = 0\n for (const e of kept) {\n counter++\n let base = (e.explicitId ? sanitizeId(e.explicitId) : '') || sanitizeId(e.name) || `part_${counter}`\n let id = base\n for (let n = 2; used.has(id); n++) id = `${base}_${n}`\n used.add(id)\n base = id\n const size = sizeOf(e.box)\n const center = e.box.getCenter(new THREE.Vector3())\n const part: PartSpec = {\n id,\n material: e.material,\n shape: { kind: 'box', size: [Math.max(size[0], 0.002), Math.max(size[1], 0.002), Math.max(size[2], 0.002)] },\n position: [center.x, center.y, center.z],\n }\n const minSide = Math.min(...size)\n if (e.fill !== undefined) part.fill = e.fill\n else if (e.hollow) part.fill = 0.05\n if (e.thickness !== undefined) part.thickness = e.thickness\n else if (minSide < 0.01 && METAL.test(e.material)) {\n part.fill = e.fill ?? 1\n part.thickness = Math.max(minSide, 0.0005)\n }\n if (e.tags) part.tags = [...e.tags]\n if (e.contains) part.contains = { ...e.contains }\n if (e.powder) part.powder = { ...e.powder }\n const ao = options.anchorBelow ?? -1\n if (ao >= 0 && e.box.min.y <= ao) part.anchored = true\n parts.push(part)\n meshesOf[id] = e.meshes\n }\n\n const knownMass = root.userData?.destructionMass\n if (typeof knownMass === 'number' && knownMass > 0) {\n const shares = parts.map((p) => {\n const material = MATERIALS.find((m) => m.id === p.material)\n return material ? partMass(p, material) : 0\n })\n const total = shares.reduce((a, b) => a + b, 0)\n if (total > 0) parts.forEach((p, i) => (p.mass = (knownMass * shares[i]) / total))\n }\n\n const spec: SpecFromObjectResult['spec'] = { parts }\n if (options.name !== undefined) spec.name = options.name\n else if (root.name) spec.name = root.name\n if (options.tags) spec.tags = [...options.tags]\n spec.joints = options.joints === false ? [] : inferJoints(parts)\n // explicit attachments from `destructionPart: { parent, kind }` win over the inferred joint between the same two parts\n if (options.joints !== false) {\n const finalId = new Map<Entry, string>()\n kept.forEach((e, i) => finalId.set(e, parts[i].id))\n const idOf = new Map<string, string>()\n for (const e of kept) if (e.explicitId) idOf.set(e.explicitId, finalId.get(e)!)\n const joints: JointSpec[] = spec.joints\n for (const e of kept) {\n if (!e.parent) continue\n const id = finalId.get(e)!\n const parent = idOf.get(e.parent) ?? (used.has(sanitizeId(e.parent)) ? sanitizeId(e.parent) : null)\n if (!parent || parent === id) continue\n const at = joints.findIndex((j) => (j.a === parent && j.b === id) || (j.a === id && j.b === parent))\n const kind = e.jointKind ?? (at >= 0 ? joints[at].kind : 'resting')\n const joint: JointSpec = { id: `${parent}~${id}`, a: parent, b: id, kind }\n if (at >= 0) joints[at] = joint\n else joints.push(joint)\n }\n }\n return { spec, parts: meshesOf }\n}\n","import { mixHex } from './math'\n\n/** Blackbody-ish stops: [temperature °C, colour]. Luminance grows with the temperature. */\nconst STOPS: Array<[number, number]> = [\n [450, 0x000000],\n [500, 0x2a0400],\n [650, 0x8a1500],\n [800, 0xd84a08],\n [950, 0xff8c14],\n [1100, 0xffc23a],\n [1250, 0xffe8a0],\n [1400, 0xffffff],\n]\n\n/**\n * Glow colour of a hot surface as `0xRRGGBB`: black (no glow) below about 450 °C, dark red around 500, orange around 800, yellow around 1100 and\n * white from 1400 °C. Brightness never decreases as the temperature rises. Use it as an emissive colour.\n */\nexport function heatColor(temperatureC: number): number {\n if (!(temperatureC > STOPS[0][0])) return 0\n const last = STOPS[STOPS.length - 1]\n if (temperatureC >= last[0]) return last[1]\n for (let i = 1; i < STOPS.length; i++) {\n const [t1, c1] = STOPS[i]\n if (temperatureC <= t1) {\n const [t0, c0] = STOPS[i - 1]\n return mixHex(c0, c1, (temperatureC - t0) / (t1 - t0))\n }\n }\n return last[1]\n}\n","import type * as THREE_NS from 'three'\n\n/** A shell mesh with its vertex positions before and after a dent, both in its own local space. */\nexport type ShellSnapshot = {\n readonly mesh: THREE_NS.Mesh\n readonly before: ArrayLike<number>\n readonly after: ArrayLike<number>\n}\n\n/**\n * How far the surface of the shells moved where `worldPoint` (a vertex of a skin: a label, a coat) lies on it, as a world vector: the displacement of the\n * nearest shell triangle, interpolated by barycentric weights. A skin that takes it moves with the shell, whatever the two meshes' vertex grids are.\n * Returns the distance (world metres) from the point to that triangle, how high above the shell the skin lies.\n */\nexport function shellDisplacementAt(THREE: typeof THREE_NS, worldPoint: THREE_NS.Vector3, shells: readonly ShellSnapshot[], out: THREE_NS.Vector3): number {\n const triangle = new THREE.Triangle()\n const corners = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()] as const\n const local = new THREE.Vector3()\n const closest = new THREE.Vector3()\n const weights = new THREE.Vector3()\n const moved = new THREE.Vector3()\n let nearest = Infinity\n out.set(0, 0, 0)\n let nearestScale = 1\n for (const shell of shells) {\n shell.mesh.updateWorldMatrix(true, false)\n shell.mesh.worldToLocal(local.copy(worldPoint))\n const index = shell.mesh.geometry.index\n const triangles = index ? index.count / 3 : shell.before.length / 9\n for (let t = 0; t < triangles; t++) {\n const ids = [0, 1, 2].map((corner) => (index ? index.getX(t * 3 + corner) : t * 3 + corner))\n ids.forEach((id, corner) => corners[corner]!.set(shell.before[id * 3]!, shell.before[id * 3 + 1]!, shell.before[id * 3 + 2]!))\n triangle.set(corners[0], corners[1], corners[2])\n // a degenerate triangle (the tip of a lathe on its axis, the doubled rim of a can) has no surface to follow and no closest point (NaN must never win)\n if (triangle.getArea() <= 1e-14) continue\n triangle.closestPointToPoint(local, closest)\n const distance = closest.distanceToSquared(local)\n if (!(distance < nearest)) continue\n nearest = distance\n nearestScale = shell.mesh.matrixWorld.getMaxScaleOnAxis() || 1\n triangle.getBarycoord(closest, weights)\n moved.set(0, 0, 0)\n ids.forEach((id, corner) => {\n const weight = corner === 0 ? weights.x : corner === 1 ? weights.y : weights.z\n moved.x += weight * (shell.after[id * 3]! - shell.before[id * 3]!)\n moved.y += weight * (shell.after[id * 3 + 1]! - shell.before[id * 3 + 1]!)\n moved.z += weight * (shell.after[id * 3 + 2]! - shell.before[id * 3 + 2]!)\n })\n out.copy(moved).transformDirection(shell.mesh.matrixWorld)\n out.multiplyScalar(moved.length() * (shell.mesh.matrixWorld.getMaxScaleOnAxis() || 1))\n }\n }\n return Math.sqrt(nearest) * nearestScale\n}\n","import type * as THREE_NS from 'three'\nimport type { Dent } from '@adatechnology/game-destruction'\nimport { heatColor } from './heat'\nimport type { Decal, HostVis, MeshVis, PartVis } from './internal'\nimport { clamp, createRng, lerp } from './math'\nimport { shellDisplacementAt, type ShellSnapshot } from './skin-dent'\nimport { pushFittedBoxes } from './fitted-boxes'\n\ntype Mesh = THREE_NS.Mesh\n\nconst POS_ATTR = 'position'\n\nfunction positionAttr(geo: THREE_NS.BufferGeometry): THREE_NS.BufferAttribute | null {\n const a = geo.getAttribute(POS_ATTR) as THREE_NS.BufferAttribute | THREE_NS.InterleavedBufferAttribute | undefined\n return a && !(a as THREE_NS.InterleavedBufferAttribute).isInterleavedBufferAttribute ? (a as THREE_NS.BufferAttribute) : null\n}\n\nfunction materialsOf(m: THREE_NS.Material | THREE_NS.Material[]): THREE_NS.Material[] {\n return Array.isArray(m) ? m : [m]\n}\n\nfunction colorOf(m: THREE_NS.Material): THREE_NS.Color | null {\n const c = (m as THREE_NS.MeshStandardMaterial).color\n return c && (c as THREE_NS.Color).isColor ? c : null\n}\n\n/** Shared resources for decals (one geometry, a few materials) created lazily and disposed together. */\nexport class DecalKit {\n private disc: THREE_NS.CircleGeometry | null = null\n private discMat: THREE_NS.MeshBasicMaterial | null = null\n private lineMats = new Map<number, THREE_NS.LineBasicMaterial>()\n private patchMats = new Map<number, THREE_NS.MeshBasicMaterial>()\n constructor(private readonly THREE: typeof THREE_NS) {}\n\n discGeometry(): THREE_NS.CircleGeometry {\n return (this.disc ??= new this.THREE.CircleGeometry(1, 14))\n }\n\n discMaterial(): THREE_NS.MeshBasicMaterial {\n return (this.discMat ??= new this.THREE.MeshBasicMaterial({\n color: 0x050505,\n transparent: true,\n opacity: 0.92,\n depthWrite: false,\n polygonOffset: true,\n polygonOffsetFactor: -4,\n polygonOffsetUnits: -4,\n side: this.THREE.DoubleSide,\n }))\n }\n\n /** Opaque patch in the colour of what shows under a spalled coat. */\n patchMaterial(color: number): THREE_NS.MeshBasicMaterial {\n let m = this.patchMats.get(color)\n if (!m) {\n m = new this.THREE.MeshBasicMaterial({ color, depthWrite: false, polygonOffset: true, polygonOffsetFactor: -3, polygonOffsetUnits: -3 })\n this.patchMats.set(color, m)\n }\n return m\n }\n\n lineMaterial(color: number): THREE_NS.LineBasicMaterial {\n let m = this.lineMats.get(color)\n if (!m) {\n m = new this.THREE.LineBasicMaterial({ color, transparent: true, opacity: 0.9, depthWrite: false })\n this.lineMats.set(color, m)\n }\n return m\n }\n\n dispose(): void {\n this.disc?.dispose()\n this.discMat?.dispose()\n for (const m of this.lineMats.values()) m.dispose()\n for (const m of this.patchMats.values()) m.dispose()\n this.patchMats.clear()\n this.disc = null\n this.discMat = null\n this.lineMats.clear()\n }\n}\n\nconst tmpV = (THREE: typeof THREE_NS) => new THREE.Vector3()\n\n/**\n * The positions a host drew a range with before it took the range out of the merged mesh to draw it another way (the house renderer collapses the range of a\n * wall it draws with holes, `userData.collapsedRanges`, and keeps the first positions in `userData.plainPositions`): a part that leaves the mesh takes those,\n * or it would leave as a collapsed, invisible range that still carries its decals and is still shot at.\n */\nexport function plainPositions(mesh: THREE_NS.Mesh, v0: number, v1: number): Float32Array | null {\n const { collapsedRanges, plainPositions: plain } = mesh.userData as { collapsedRanges?: ReadonlyArray<readonly [number, number]>; plainPositions?: Float32Array }\n if (!plain || !collapsedRanges?.some(([a, b]) => a < v1 && b > v0)) return null\n return plain\n}\n\n/** A whole mesh that leaves with its part draws again the ranges its host collapsed (`plainPositions`): it is the part now, and the part is still there. */\nexport function showCollapsedRanges(mesh: THREE_NS.Mesh): void {\n const data = mesh.userData as { collapsedRanges?: Array<[number, number]>; plainPositions?: Float32Array }\n const plain = data.plainPositions\n const position = mesh.geometry?.getAttribute(POS_ATTR) as THREE_NS.BufferAttribute | undefined\n if (!plain || !data.collapsedRanges?.length || !position) return\n const array = position.array as Float32Array\n for (const [v0, v1] of data.collapsedRanges) array.set(plain.subarray(v0 * 3, v1 * 3), v0 * 3)\n data.collapsedRanges = []\n position.needsUpdate = true\n mesh.geometry.computeBoundingBox()\n mesh.geometry.computeBoundingSphere()\n}\n\n/** Mesh-level visual changes: copy-on-write geometry and materials, dents, decals, char, glow, melt, hiding, restoring. */\n/** A dent reaches at least this many vertices of a mesh: fewer and the mesh cannot show its curve (it would be invisible or a sharp spike). */\nconst MIN_DENT_VERTICES = 10\n/** The reach of a dent that had to widen is this many times the distance to the farthest of those vertices, so they all get a falloff above zero. */\nconst WIDEN_MARGIN = 1.1\n/** A skin follows its shell this share of the way in: the two meshes triangulate the dent differently, and a skin left a bit outside never lets the shell through. */\nconst SKIN_FOLLOW = 0.85\n/** And stays this many metres outside, so the thin gap of a label (a millimetre) survives the two meshes triangulating the rim differently. */\nconst SKIN_SLACK = 0.0005\n/** Extra slack per metre a skin lies above its shell: skins stacked on one another (a label and its band) keep their order while the dent bends them. */\nconst SKIN_LAYER_SLACK = 4\n/** And at least this many times the distance to the nearest vertex, so even the nearest one is pushed visibly. */\nconst NEAREST_MARGIN = 1.5\n/**\n * The first positions of a merged mesh: `userData._p0` when another drawing keeps them there (the house renderer, which collapses the ranges of what it\n * draws itself, `userData.collapsedRanges`), else those of the geometry it was bound with.\n */\nconst basePositions = (host: { mesh: Mesh; origGeometry: THREE_NS.BufferGeometry }): Float32Array | null => {\n const p0 = host.mesh.userData._p0 as Float32Array | undefined\n if (p0) return p0\n const op = positionAttr(host.origGeometry)\n return op ? (op.array as unknown as Float32Array) : null\n}\n\n/** Collapses in `arr` the ranges another drawing hides on the mesh (`userData.collapsedRanges`, each to its first vertex). */\nconst collapseForeign = (mesh: Mesh, arr: Float32Array): void => {\n for (const [v0, v1] of (mesh.userData.collapsedRanges as Array<[number, number]> | undefined) ?? []) {\n for (let k = v0 + 1; k < v1; k++) {\n arr[k * 3] = arr[v0 * 3]!\n arr[k * 3 + 1] = arr[v0 * 3 + 1]!\n arr[k * 3 + 2] = arr[v0 * 3 + 2]!\n }\n }\n}\n\n/** Metres along its normal a mark looks for the drawn face under it (`onFace`). */\nconst DECAL_SNAP = 0.03\n\nexport class Visuals {\n readonly kit: DecalKit\n private readonly a: THREE_NS.Vector3\n private readonly b: THREE_NS.Vector3\n private readonly m4: THREE_NS.Matrix4\n private readonly ray: THREE_NS.Raycaster\n private readonly box: THREE_NS.Box3\n private readonly t: THREE_NS.Vector3\n private readonly lbox: THREE_NS.Box3\n /** Total live decals across meshes (kept in sync by add/remove). */\n decalCount = 0\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly lowQuality: boolean,\n private readonly decalCap: number,\n ) {\n this.kit = new DecalKit(THREE)\n this.a = tmpV(THREE)\n this.b = tmpV(THREE)\n this.m4 = new THREE.Matrix4()\n this.ray = new THREE.Raycaster()\n // batched meshes leave the camera layer (createStaticBatcher), not the world: rays still find them\n this.ray.layers.enableAll()\n this.box = new THREE.Box3()\n this.t = tmpV(THREE)\n this.lbox = new THREE.Box3()\n }\n\n /**\n * @param range vertex range `[v0, v1)` of a merged mesh this part is drawn by (see `MeshRange`); `hosts` caches the shared state per mesh for one `bind`.\n */\n makeMeshVis(mesh: Mesh, home: string, range?: [number, number], hosts?: Map<Mesh, HostVis>): MeshVis {\n let host: HostVis | null = null\n if (range) {\n host = hosts?.get(mesh) ?? null\n if (!host) {\n host = { mesh, origGeometry: mesh.geometry, origMaterial: mesh.material, ownGeo: false, work: null, ownMat: false, sharers: [] }\n hosts?.set(mesh, host)\n }\n }\n const mv: MeshVis = {\n mesh,\n home,\n origGeometry: mesh.geometry,\n origMaterial: mesh.material,\n origVisible: mesh.visible,\n origParent: mesh.parent,\n origPosition: mesh.position.clone(),\n origQuaternion: mesh.quaternion.clone(),\n origScale: mesh.scale.clone(),\n ownMat: false,\n ownGeo: false,\n work: null,\n baseColors: null,\n decals: [],\n meltApplied: 0,\n bottomY: 0,\n moved: false,\n host,\n range: range ? [range[0], range[1]] : null,\n merged: host && range ? { host, range: [range[0], range[1]] } : null,\n loose: false,\n collapsed: false,\n hidden: false,\n touched: false,\n charK: 0,\n charHex: 0,\n glowHex: 0,\n glowK: 0,\n }\n host?.sharers.push(mv)\n return mv\n }\n\n vertexCount(mv: MeshVis): number {\n if (mv.range) return mv.range[1] - mv.range[0]\n return mv.mesh.geometry.getAttribute(POS_ATTR)?.count ?? 0\n }\n\n /** Is the part drawn? (A ranged part shares its mesh, so `mesh.visible` says nothing about it.) */\n shown(mv: MeshVis): boolean {\n return mv.host ? !mv.hidden : mv.mesh.visible\n }\n\n /** Box of the part's vertices in the space of its mesh (the whole geometry for a plain mesh). */\n localBox(mv: MeshVis, out: THREE_NS.Box3): THREE_NS.Box3 {\n out.makeEmpty()\n if (!mv.host || !mv.range) {\n const geo = mv.mesh.geometry\n if (!geo.boundingBox) geo.computeBoundingBox()\n return geo.boundingBox ? out.copy(geo.boundingBox) : out\n }\n const arr = mv.host.work ?? (positionAttr(mv.mesh.geometry)?.array as unknown as ArrayLike<number> | undefined)\n if (!arr) return out\n for (let i = mv.range[0] * 3; i < mv.range[1] * 3; i += 3) out.expandByPoint(this.t.set(arr[i], arr[i + 1], arr[i + 2]))\n return out\n }\n\n /** Box of the part in world space. */\n /** Appends the boxes that follow the mesh in the world (`pushFittedBoxes`) to `out`. */\n fittedBoxes(mv: MeshVis, out: number[]): void {\n const box = new this.THREE.Box3()\n if (mv.host) this.localBox(mv, box)\n else {\n const geometry = mv.mesh.geometry\n if (!geometry.boundingBox) geometry.computeBoundingBox()\n if (geometry.boundingBox) box.copy(geometry.boundingBox)\n else box.makeEmpty()\n }\n if (box.isEmpty()) return\n mv.mesh.updateWorldMatrix(true, false)\n pushFittedBoxes(box, mv.mesh.matrixWorld, out)\n }\n\n worldBox(mv: MeshVis, out: THREE_NS.Box3): THREE_NS.Box3 {\n if (!mv.host) return out.setFromObject(mv.mesh)\n this.localBox(mv, out)\n mv.mesh.updateWorldMatrix(true, false)\n return out.isEmpty() ? out : out.applyMatrix4(mv.mesh.matrixWorld)\n }\n\n private readonly tints = new WeakMap<MeshVis, THREE_NS.Color | null>()\n\n /**\n * Average vertex colour of a mesh whose material uses `vertexColors` (computed once per mesh, from its original geometry), else null. Fragments\n * and debris of such a mesh multiply it by `material.color`; without it they come out white.\n */\n vertexTint(mv: MeshVis): THREE_NS.Color | null {\n if (this.tints.has(mv)) return this.tints.get(mv) ?? null\n let tint: THREE_NS.Color | null = null\n const used = materialsOf(mv.origMaterial).some((m) => (m as THREE_NS.MeshStandardMaterial).vertexColors === true)\n const attr = used ? (mv.origGeometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined) : undefined\n if (attr && attr.count > 0 && attr.itemSize >= 3) {\n // a ranged part averages its own vertices only\n const from = mv.merged ? mv.merged.range[0] : 0\n const to = mv.merged ? Math.min(attr.count, mv.merged.range[1]) : attr.count\n let r = 0, g = 0, b = 0\n for (let i = from; i < to; i++) {\n r += attr.getX(i)\n g += attr.getY(i)\n b += attr.getZ(i)\n }\n const n = Math.max(1, to - from)\n tint = new this.THREE.Color(r / n, g / n, b / n)\n }\n this.tints.set(mv, tint)\n return tint\n }\n\n /** Colour of the original material (before any char) times the vertex tint, `0xRRGGBB`, or -1. */\n baseColorHex(mv: MeshVis): number {\n const c = mv.baseColors?.[0] ?? colorOf(materialsOf(mv.origMaterial)[0])\n if (!c) return -1\n const tint = this.vertexTint(mv)\n return tint ? c.clone().multiply(tint).getHex() : c.getHex()\n }\n\n /** Is the original material transparent? */\n isTransparent(mv: MeshVis): boolean {\n return materialsOf(mv.origMaterial).some((m) => m.transparent && m.opacity < 1)\n }\n\n ownMaterial(mv: MeshVis): void {\n if (mv.ownMat) return\n mv.ownMat = true\n const src = materialsOf(mv.origMaterial)\n const cloned = src.map((m) => m.clone())\n mv.baseColors = src.map((m) => colorOf(m)?.clone() ?? new this.THREE.Color(0x888888))\n mv.mesh.material = Array.isArray(mv.origMaterial) ? cloned : cloned[0]\n }\n\n /** Clone the geometry (vertex edits); false when its positions cannot be edited. */\n ownGeometry(mv: MeshVis): boolean {\n if (mv.host) return this.ownHostGeometry(mv.host)\n if (mv.ownGeo) return true\n const pos = positionAttr(mv.mesh.geometry)\n if (!pos) return false\n mv.ownGeo = true\n const g = mv.mesh.geometry.clone()\n mv.mesh.geometry = g\n mv.work = new Float32Array((positionAttr(g) as THREE_NS.BufferAttribute).array as ArrayLike<number>)\n return true\n }\n\n private ownHostGeometry(host: HostVis): boolean {\n if (host.ownGeo) return true\n const pos = positionAttr(host.mesh.geometry)\n if (!pos) return false\n host.ownGeo = true\n const g = host.mesh.geometry.clone()\n host.mesh.geometry = g\n host.work = new Float32Array(basePositions(host) ?? ((positionAttr(g) as THREE_NS.BufferAttribute).array as ArrayLike<number>))\n return true\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Dents\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /**\n * Push the vertices of the mesh within `dent.radius` of `worldPoint` inwards along `worldNormal` by `depth * (1 - (d/r)^2)^2`.\n * Returns false when nothing was changed (too far, low quality on a heavy mesh, or no editable positions).\n */\n applyDent(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, dent: Dent, reachWorld = 0): boolean {\n const mesh = mv.mesh\n if (this.lowQuality && this.vertexCount(mv) > 20000) return false\n mesh.updateWorldMatrix(true, false)\n const s = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n const lp = mesh.worldToLocal(this.a.copy(worldPoint))\n const ln = this.b.copy(worldNormal).transformDirection(this.m4.copy(mesh.matrixWorld).invert()).normalize()\n const r = Math.max(dent.radius, reachWorld) / s\n const depth = dent.depth / s\n // quick reject: the point must be near the mesh bounds\n const geo = mesh.geometry\n let bb: THREE_NS.Box3 | null\n if (mv.host) bb = this.localBox(mv, this.lbox)\n else {\n if (!geo.boundingBox) geo.computeBoundingBox()\n bb = geo.boundingBox\n }\n if (bb && !bb.isEmpty() && bb.distanceToPoint(lp) > r) return false\n if (!this.ownGeometry(mv)) return false\n const work = (mv.host ? mv.host.work : mv.work) as Float32Array\n const pos = positionAttr(mesh.geometry) as THREE_NS.BufferAttribute\n const from = mv.range ? mv.range[0] * 3 : 0\n const to = mv.range ? mv.range[1] * 3 : work.length\n const reach = r\n const reach2 = reach * reach\n for (let i = from; i < to; i += 3) {\n const dx = work[i] - lp.x\n const dy = work[i + 1] - lp.y\n const dz = work[i + 2] - lp.z\n const d2 = dx * dx + dy * dy + dz * dz\n if (d2 >= reach2) continue\n const f = 1 - d2 / reach2\n const k = depth * f * f\n work[i] -= ln.x * k\n work[i + 1] -= ln.y * k\n work[i + 2] -= ln.z * k\n }\n mv.touched = true\n this.writePositions(mv, pos)\n return true\n }\n\n /**\n * World radius a dent needs on this mesh to reach `MIN_DENT_VERTICES` vertices (the dent's own radius when the mesh is fine enough). A part with several meshes\n * (a shell and its label) must dent them all with the largest of these, so the skin and the shell follow the same smooth surface and never cross.\n */\n dentReach(mv: MeshVis, worldPoint: THREE_NS.Vector3, dent: Dent): number {\n const mesh = mv.mesh\n mesh.updateWorldMatrix(true, false)\n const s = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n const lp = mesh.worldToLocal(this.a.copy(worldPoint))\n const source = (mv.host ? mv.host.work : mv.work) ?? ((positionAttr(mesh.geometry) as THREE_NS.BufferAttribute | undefined)?.array as ArrayLike<number> | undefined)\n if (!source) return dent.radius\n // a mesh the dent does not touch (the far cap of a can) must not widen it\n let bounds: THREE_NS.Box3 | null\n if (mv.host) bounds = this.localBox(mv, this.lbox)\n else {\n if (!mesh.geometry.boundingBox) mesh.geometry.computeBoundingBox()\n bounds = mesh.geometry.boundingBox\n }\n if (bounds && !bounds.isEmpty() && bounds.distanceToPoint(lp) > dent.radius / s) return dent.radius\n const from = mv.range ? mv.range[0] * 3 : 0\n const to = mv.range ? mv.range[1] * 3 : source.length\n const r2 = (dent.radius / s) ** 2\n const distances: number[] = []\n let inside = 0\n for (let i = from; i < to; i += 3) {\n const dx = source[i]! - lp.x\n const dy = source[i + 1]! - lp.y\n const dz = source[i + 2]! - lp.z\n const d2 = dx * dx + dy * dy + dz * dz\n if (d2 < r2) inside++\n distances.push(d2)\n }\n if (inside >= MIN_DENT_VERTICES || distances.length < MIN_DENT_VERTICES) return dent.radius\n distances.sort((x, y) => x - y)\n const nearest = Math.sqrt(distances[0]!)\n return Math.max(dent.radius, Math.sqrt(distances[MIN_DENT_VERTICES - 1]!) * s * WIDEN_MARGIN, nearest * s * NEAREST_MARGIN)\n }\n\n /**\n * Dent all the meshes of a part. The shells take the dent as `applyDent` gives it; a skin (label, coat: `userData.destructionSkin`) sits a hair above its shell\n * and moves with the shell's surface instead (see `shellDisplacementAt`), so the shell never shows through it whatever the two meshes' vertex grids are.\n */\n applyPartDent(meshes: readonly MeshVis[], worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, dent: Dent, reachWorld: number): void {\n const isSkin = (mv: MeshVis): boolean => mv.mesh.userData.destructionSkin === true && !mv.host\n const shells = meshes.filter((mv) => !isSkin(mv))\n const snapshots: ShellSnapshot[] = []\n for (const mv of shells) {\n const heavy = this.lowQuality && this.vertexCount(mv) > 20000\n const plain = !mv.host && !heavy && this.ownGeometry(mv) && mv.work\n const before = plain ? new Float32Array(mv.work as Float32Array) : null\n this.applyDent(mv, worldPoint, worldNormal, dent, reachWorld)\n if (before) snapshots.push({ mesh: mv.mesh, before, after: mv.work as Float32Array })\n }\n const displacement = this.t\n const vertex = this.a\n for (const mv of meshes) {\n if (!isSkin(mv)) continue\n if (snapshots.length === 0) {\n this.applyDent(mv, worldPoint, worldNormal, dent, reachWorld)\n continue\n }\n if (!this.ownGeometry(mv)) continue\n const work = mv.work as Float32Array\n const mesh = mv.mesh\n mesh.updateWorldMatrix(true, false)\n const toLocal = this.m4.copy(mesh.matrixWorld).invert()\n const scale = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n let touched = false\n for (let i = 0; i < work.length; i += 3) {\n vertex.set(work[i]!, work[i + 1]!, work[i + 2]!).applyMatrix4(mesh.matrixWorld)\n if (vertex.distanceTo(worldPoint) > reachWorld) continue\n const height = shellDisplacementAt(this.THREE, vertex, snapshots, displacement)\n const length = displacement.length()\n if (length === 0) continue\n // the shell's facets lie outside a dip (deeper than the shell, the skin would sink under it) and inside a rim (the smooth dent is shallower there): take the shallower of the two\n const falloff = 1 - (vertex.distanceTo(worldPoint) / reachWorld) ** 2\n const smooth = dent.depth * falloff * falloff\n const pull = Math.max(0, Math.min(length, smooth) * SKIN_FOLLOW - SKIN_SLACK - height * SKIN_LAYER_SLACK)\n displacement.transformDirection(toLocal).multiplyScalar(pull / scale)\n work[i] += displacement.x\n work[i + 1] += displacement.y\n work[i + 2] += displacement.z\n touched = true\n }\n if (touched) this.writePositions(mv, positionAttr(mesh.geometry) as THREE_NS.BufferAttribute)\n }\n }\n\n /** Copy `work` (dents) into the geometry, adding the melt sag when the mesh is melting. */\n private writePositions(mv: MeshVis, pos: THREE_NS.BufferAttribute): void {\n if (mv.host) {\n this.rebuildHost(mv.host)\n return\n }\n const work = mv.work as Float32Array\n const arr = pos.array as unknown as Float32Array\n const melt = mv.meltApplied\n if (melt <= 0 || (this.lowQuality && work.length / 3 > 20000)) {\n arr.set(work)\n } else {\n const geo = mv.mesh.geometry\n if (!geo.boundingBox) geo.computeBoundingBox()\n const bb = geo.boundingBox as THREE_NS.Box3\n const h = Math.max(1e-4, bb.max.y - bb.min.y)\n const minY = bb.min.y\n for (let i = 0, v = 0; i < work.length; i += 3, v++) {\n const n = ((Math.imul(v + 1, 2654435761) >>> 0) % 1000) / 1000\n const n2 = ((Math.imul(v + 7, 40503) >>> 0) % 1000) / 1000\n const lowness = 1 - (work[i + 1] - minY) / h // 1 at the bottom, 0 at the top\n const spread = 1 + 0.12 * melt * (0.4 + n2) * (0.3 + lowness)\n arr[i] = work[i] * spread\n arr[i + 2] = work[i + 2] * spread\n arr[i + 1] = Math.max(minY, work[i + 1] - n * melt * h * 0.08)\n }\n }\n pos.needsUpdate = true\n const geo = mv.mesh.geometry\n geo.computeVertexNormals()\n geo.boundingBox = null\n geo.boundingSphere = null\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Decals\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /**\n * The point on the drawn face of `mesh` under a world point, within `DECAL_SNAP` metres along the normal: the world's box of a part and the face\n * the renderer drew (a coat of plaster, a merged house mesh) can be a few millimetres apart, and a mark behind the drawn face does not show.\n */\n private onFace(mesh: Mesh, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3): THREE_NS.Vector3 {\n if (!(mesh as { isMesh?: boolean }).isMesh || !mesh.geometry?.attributes?.position) return worldPoint\n const n = worldNormal.clone().normalize()\n this.ray.set(worldPoint.clone().addScaledVector(n, DECAL_SNAP), n.clone().negate())\n this.ray.near = 0\n this.ray.far = 2 * DECAL_SNAP\n const hits: THREE_NS.Intersection[] = []\n mesh.raycast(this.ray, hits)\n // a wall the house cut where it was shot is drawn by a mesh of its own next to the merged one (`breach-shell` of the house renderer); where it is\n // cut (`userData.cutAt`), the mark goes on what shows through (`userData.behind`: the bricks)\n for (const c of mesh.parent?.children ?? []) {\n if (c === mesh || c.name !== 'breach-shell') continue\n c.raycast(this.ray, hits)\n const behind = (c.userData.behind as (() => THREE_NS.Object3D | null) | undefined)?.()\n if (behind) behind.raycast(this.ray, hits)\n }\n let best: THREE_NS.Intersection | null = null\n for (const h of hits) {\n if ((h.object.userData.cutAt as ((p: THREE_NS.Vector3) => boolean) | undefined)?.(h.point)) continue\n if (h.face && h.face.normal.clone().transformDirection(h.object.matrixWorld).dot(n) <= 0.3) continue\n if (!best || Math.abs(h.distance - DECAL_SNAP) < Math.abs(best.distance - DECAL_SNAP)) best = h\n }\n return best ? best.point : worldPoint\n }\n\n /** Decal pose in mesh space: position and a rotation taking +Z to the surface normal. */\n private decalPose(mesh: Mesh, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, lift: number): { s: number; pos: THREE_NS.Vector3; quat: THREE_NS.Quaternion } {\n mesh.updateWorldMatrix(true, false)\n const s = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n const ln = worldNormal.clone().transformDirection(this.m4.copy(mesh.matrixWorld).invert()).normalize()\n const pos = mesh.worldToLocal(this.onFace(mesh, worldPoint, worldNormal).clone()).addScaledVector(ln, lift / s)\n const quat = new this.THREE.Quaternion().setFromUnitVectors(new this.THREE.Vector3(0, 0, 1), ln)\n return { s, pos, quat }\n }\n\n private addDecal(mv: MeshVis, decal: Decal): void {\n decal.obj.userData.destructionDebris = true\n mv.mesh.add(decal.obj)\n mv.decals.push(decal)\n this.decalCount++\n while (mv.decals.length > 48 || this.decalCount > this.decalCap) {\n const old = mv.decals.shift()\n if (!old) break\n this.disposeDecal(old)\n }\n }\n\n private disposeDecal(d: Decal): void {\n d.obj.parent?.remove(d.obj)\n d.geometry?.dispose()\n this.decalCount = Math.max(0, this.decalCount - 1)\n }\n\n /**\n * Takes away the decals of a mesh that sit inside a box (world `center`, `half` extents along the axes of the world `rotation`): the surface they\n * marked is gone (a unit came out of the wall with its bullet holes and spalls).\n */\n clearDecals(mv: MeshVis, center: THREE_NS.Vector3, half: THREE_NS.Vector3, rotation: THREE_NS.Quaternion): void {\n const inv = rotation.clone().invert()\n const p = new this.THREE.Vector3()\n for (let i = mv.decals.length - 1; i >= 0; i--) {\n const d = mv.decals[i]!\n d.obj.getWorldPosition(p).sub(center).applyQuaternion(inv)\n if (Math.abs(p.x) > half.x || Math.abs(p.y) > half.y || Math.abs(p.z) > half.z) continue\n this.disposeDecal(d)\n mv.decals.splice(i, 1)\n }\n }\n\n addHole(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, diameter: number): void {\n const { s, pos, quat } = this.decalPose(mv.mesh, worldPoint, worldNormal, 0.0025)\n const work = (mv.host ? mv.host.work : mv.work) as Float32Array | undefined\n if (work && mv.touched) {\n const ln = worldNormal.clone().transformDirection(this.m4.copy(mv.mesh.matrixWorld).invert()).normalize()\n let minDistSq = Infinity\n let nearestDisp = 0\n const from = mv.range ? mv.range[0] * 3 : 0\n const to = mv.range ? mv.range[1] * 3 : work.length\n for (let i = from; i < to; i += 3) {\n const dx = work[i]! - pos.x\n const dy = work[i + 1]! - pos.y\n const dz = work[i + 2]! - pos.z\n const d2 = dx * dx + dy * dy + dz * dz\n if (d2 < minDistSq) {\n minDistSq = d2\n nearestDisp = dx * ln.x + dy * ln.y + dz * ln.z\n }\n }\n if (minDistSq < (0.06 / s) ** 2 && nearestDisp < 0) {\n pos.addScaledVector(ln, nearestDisp)\n }\n }\n const disc = new this.THREE.Mesh(this.kit.discGeometry(), this.kit.discMaterial())\n disc.position.copy(pos)\n disc.quaternion.copy(quat)\n disc.scale.setScalar((Math.max(0.004, diameter) * 0.5 * 1.25) / s)\n disc.renderOrder = 2\n this.addDecal(mv, { obj: disc })\n }\n\n /** A patch where a surface coat came off, in the colour of the core under it; drawn under the bullet holes. */\n addSpall(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, radius: number, color: number): void {\n const { s, pos, quat } = this.decalPose(mv.mesh, worldPoint, worldNormal, 0.0015)\n const disc = new this.THREE.Mesh(this.kit.discGeometry(), this.kit.patchMaterial(color))\n disc.position.copy(pos)\n disc.quaternion.copy(quat)\n disc.scale.setScalar(Math.max(0.01, radius) / s)\n disc.renderOrder = 1\n this.addDecal(mv, { obj: disc })\n }\n\n /** A star of jagged lines: `rays` rays up to `length` metres, seeded so the same event always draws the same star. */\n addCrack(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, rays: number, length: number, color: number, seed: number): void {\n const { s, pos, quat } = this.decalPose(mv.mesh, worldPoint, worldNormal, 0.002)\n const rnd = createRng(seed)\n const verts: number[] = []\n const n = clamp(Math.round(rays), 3, 16)\n const L = Math.max(0.02, length) / s\n for (let r = 0; r < n; r++) {\n let ang = (r / n) * Math.PI * 2 + (rnd() - 0.5) * 0.5\n let x = 0\n let y = 0\n const segs = 3\n const total = L * (0.6 + 0.4 * rnd())\n for (let k = 0; k < segs; k++) {\n const step = (total / segs) * (0.7 + 0.6 * rnd())\n ang += (rnd() - 0.5) * 0.45\n const nx = x + Math.cos(ang) * step\n const ny = y + Math.sin(ang) * step\n verts.push(x, y, 0, nx, ny, 0)\n if (k > 0 && rnd() < 0.5) {\n const ba = ang + (rnd() < 0.5 ? -1 : 1) * (0.5 + rnd() * 0.5)\n const bl = step * (0.6 + 0.6 * rnd())\n verts.push(nx, ny, 0, nx + Math.cos(ba) * bl, ny + Math.sin(ba) * bl, 0)\n }\n x = nx\n y = ny\n }\n }\n // a faint ring around the impact\n const ringR = L * 0.12\n for (let k = 0; k < 8; k++) {\n const a0 = (k / 8) * Math.PI * 2\n const a1 = ((k + 1) / 8) * Math.PI * 2\n if (rnd() < 0.75) verts.push(Math.cos(a0) * ringR, Math.sin(a0) * ringR, 0, Math.cos(a1) * ringR, Math.sin(a1) * ringR, 0)\n }\n const geo = new this.THREE.BufferGeometry()\n geo.setAttribute('position', new this.THREE.Float32BufferAttribute(verts, 3))\n const lines = new this.THREE.LineSegments(geo, this.kit.lineMaterial(color))\n lines.position.copy(pos)\n lines.quaternion.copy(quat)\n lines.renderOrder = 2\n this.addDecal(mv, { obj: lines, geometry: geo })\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Char and heat glow\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n setChar(pv: PartVis, char: number, charColor: number): void {\n if (Math.abs(char - pv.charApplied) < 0.004) return\n pv.charApplied = char\n const target = new this.THREE.Color(charColor)\n for (const mv of pv.meshes) {\n if (mv.host) {\n mv.charK = clamp(char, 0, 1)\n mv.charHex = charColor\n this.paint(mv)\n continue\n }\n this.ownMaterial(mv)\n const mats = materialsOf(mv.mesh.material)\n mats.forEach((m, i) => {\n const c = colorOf(m)\n const base = mv.baseColors?.[i]\n if (c && base) c.copy(base).lerp(target, clamp(char, 0, 1))\n })\n }\n }\n\n /** Emissive glow of a hot part. `temperature` below the glow threshold switches it off. */\n setGlow(pv: PartVis, temperatureC: number): void {\n const hex = heatColor(temperatureC)\n const key = hex === 0 ? 0 : Math.round(temperatureC / 5) * 5\n if (key === pv.glowApplied) return\n pv.glowApplied = key\n const intensity = hex === 0 ? 0 : clamp(0.35 + (temperatureC - 450) / 900, 0, 1.4)\n for (const mv of pv.meshes) {\n if (mv.host) {\n mv.glowHex = hex\n mv.glowK = intensity\n this.paint(mv)\n continue\n }\n this.ownMaterial(mv)\n for (const m of materialsOf(mv.mesh.material)) {\n const e = (m as THREE_NS.MeshStandardMaterial).emissive\n if (e && (e as THREE_NS.Color).isColor) {\n e.setHex(hex)\n ;(m as THREE_NS.MeshStandardMaterial).emissiveIntensity = intensity\n }\n }\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Melt\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /** Sag the part: shorter in Y (down to 25 %), a bit wider, vertices pushed down with noise, the bottom stays put. */\n setMelt(pv: PartVis, melt: number): void {\n const m = clamp(melt, 0, 1)\n if (Math.abs(m - pv.meltApplied) < 0.01) return\n pv.meltApplied = m\n for (const mv of pv.meshes) {\n const mesh = mv.mesh\n if (mv.host) {\n // a range of a shared mesh cannot scale the mesh: squash and widen its own vertices\n mv.meltApplied = m\n mv.touched = true\n if (!(this.lowQuality && this.vertexCount(mv) > 20000) && this.ownGeometry(mv)) this.rebuildHost(mv.host)\n continue\n }\n if (mv.meltApplied === 0 && m > 0) {\n mesh.updateWorldMatrix(true, false)\n mv.bottomY = this.box.setFromObject(mesh).min.y\n }\n mv.meltApplied = m\n mv.moved = true\n const sy = lerp(1, 0.25, m)\n const sxz = 1 + 0.18 * m\n mesh.scale.set(mv.origScale.x * sxz, mv.origScale.y * sy, mv.origScale.z * sxz)\n mesh.position.copy(mv.origPosition)\n mesh.updateWorldMatrix(true, false)\n const bottom = this.box.setFromObject(mesh).min.y\n const dy = mv.bottomY - bottom\n if (Math.abs(dy) > 1e-6 && mesh.parent) {\n mesh.parent.updateWorldMatrix(true, false)\n const inv = this.m4.copy(mesh.parent.matrixWorld).invert()\n this.a.set(0, dy, 0).applyMatrix4(inv)\n this.b.set(0, 0, 0).applyMatrix4(inv)\n mesh.position.copy(mv.origPosition).add(this.a.sub(this.b))\n }\n if (!(this.lowQuality && this.vertexCount(mv) > 20000) && this.ownGeometry(mv)) {\n this.writePositions(mv, positionAttr(mesh.geometry) as THREE_NS.BufferAttribute)\n }\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Visibility and restore\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n hide(pv: PartVis, reason: PartVis['gone']): void {\n pv.gone = reason\n for (const mv of pv.meshes) {\n if (!mv.host || mv.loose) {\n mv.mesh.visible = false\n mv.hidden = true\n continue\n }\n // a range of a shared mesh: collapse its vertices to a point and hide what was drawn on it\n mv.hidden = true\n for (const d of mv.decals) d.obj.visible = false\n this.collapse(mv)\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Parts drawn by a vertex range of a merged mesh\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /** Collapse the part's vertices in the merged mesh to one point (its triangles become degenerate and vanish). */\n private collapse(mv: MeshVis): void {\n if (!mv.merged || !this.ownHostGeometry(mv.merged.host)) return\n mv.collapsed = true\n mv.touched = true\n this.rebuildHost(mv.merged.host)\n }\n\n /** Write `work` into the geometry again with the melt of ranged parts and the collapsed ranges applied. */\n private rebuildHost(host: HostVis): void {\n const geo = host.mesh.geometry\n const pos = positionAttr(geo)\n const work = host.work\n if (!pos || !work) return\n const arr = pos.array as unknown as Float32Array\n arr.set(work)\n collapseForeign(host.mesh, arr)\n for (const s of host.sharers) {\n if (s.merged && s.merged.host === host) {\n if (s.collapsed) this.collapseRange(arr, s.merged.range)\n else if (s.meltApplied > 0 && !s.loose) this.meltRange(arr, work, s.merged.range, s.meltApplied)\n } else if (s.host === host && s.range && s.meltApplied > 0) this.meltRange(arr, work, s.range, s.meltApplied)\n }\n pos.needsUpdate = true\n geo.computeVertexNormals()\n geo.boundingBox = null\n geo.boundingSphere = null\n }\n\n private collapseRange(arr: Float32Array, range: [number, number]): void {\n const x = arr[range[0] * 3]\n const y = arr[range[0] * 3 + 1]\n const z = arr[range[0] * 3 + 2]\n for (let i = range[0] * 3; i < range[1] * 3; i += 3) {\n arr[i] = x\n arr[i + 1] = y\n arr[i + 2] = z\n }\n }\n\n /** Melt of one range: shorter in Y (down to 25 %) with the bottom fixed, a bit wider around its centre, with the same noise as a whole mesh. */\n private meltRange(arr: Float32Array, work: Float32Array, range: [number, number], melt: number): void {\n let minY = Infinity\n let maxY = -Infinity\n let cx = 0\n let cz = 0\n const n = Math.max(1, range[1] - range[0])\n for (let i = range[0] * 3; i < range[1] * 3; i += 3) {\n minY = Math.min(minY, work[i + 1])\n maxY = Math.max(maxY, work[i + 1])\n cx += work[i]\n cz += work[i + 2]\n }\n cx /= n\n cz /= n\n const h = Math.max(1e-4, maxY - minY)\n const sy = lerp(1, 0.25, melt)\n const sxz = 1 + 0.18 * melt\n for (let i = range[0] * 3, v = 0; i < range[1] * 3; i += 3, v++) {\n const noise = ((Math.imul(v + 1, 2654435761) >>> 0) % 1000) / 1000\n arr[i] = cx + (work[i] - cx) * sxz\n arr[i + 2] = cz + (work[i + 2] - cz) * sxz\n arr[i + 1] = Math.max(minY, minY + (work[i + 1] - minY) * sy - noise * melt * h * 0.04)\n }\n }\n\n /** The colour attribute of the host's current geometry (created white when there is none) with vertex colours switched on in its material. */\n private ensureColors(host: HostVis): THREE_NS.BufferAttribute | null {\n if (!this.ownHostGeometry(host)) return null\n const geo = host.mesh.geometry\n let attr = geo.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n if (!attr) {\n const n = geo.getAttribute(POS_ATTR).count\n attr = new this.THREE.BufferAttribute(new Float32Array(n * 3).fill(1), 3)\n geo.setAttribute('color', attr)\n }\n if (!host.ownMat) {\n host.ownMat = true\n const src = materialsOf(host.mesh.material)\n const cloned = src.map((m) => m.clone())\n host.mesh.material = Array.isArray(host.mesh.material) ? cloned : cloned[0]\n }\n for (const m of materialsOf(host.mesh.material)) {\n if ((m as THREE_NS.MeshStandardMaterial).vertexColors !== true) {\n ;(m as THREE_NS.MeshStandardMaterial).vertexColors = true\n m.needsUpdate = true\n }\n }\n return attr\n }\n\n /** Colour of the part's vertices from the original colours, its char and its heat. Only the part's range is written. */\n private paint(mv: MeshVis): void {\n if (!mv.host || !mv.range || !mv.merged) return\n const idle = mv.charK <= 0 && mv.glowK <= 0\n if (idle && !mv.touched) return\n const attr = this.ensureColors(mv.host)\n if (!attr) return\n const size = attr.itemSize\n const arr = attr.array as unknown as Float32Array\n const orig = mv.merged.host.origGeometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n const oSize = orig?.itemSize ?? 3\n const oArr = orig?.array as unknown as ArrayLike<number> | undefined\n const shift = mv.merged.range[0] - mv.range[0]\n const ch = new this.THREE.Color(mv.charHex)\n const heat = new this.THREE.Color(mv.glowHex)\n const k = clamp(mv.charK, 0, 1)\n const gk = clamp(mv.glowK, 0, 1)\n const boost = 1 + Math.max(0, mv.glowK - 1)\n for (let i = mv.range[0]; i < mv.range[1]; i++) {\n const o = (i + shift) * oSize\n let r = oArr ? oArr[o] : 1\n let g = oArr ? oArr[o + 1] : 1\n let b = oArr ? oArr[o + 2] : 1\n if (k > 0) {\n r = lerp(r, ch.r, k)\n g = lerp(g, ch.g, k)\n b = lerp(b, ch.b, k)\n }\n if (gk > 0) {\n r = lerp(r, heat.r * boost, gk)\n g = lerp(g, heat.g * boost, gk)\n b = lerp(b, heat.b * boost, gk)\n }\n arr[i * size] = r\n arr[i * size + 1] = g\n arr[i * size + 2] = b\n }\n mv.touched = true\n attr.needsUpdate = true\n }\n\n /**\n * Move a ranged part to a mesh of its own: the faces whose vertices all lie in its range are copied (with the current dents and colours) into a\n * new mesh that takes the merged mesh's transform and material, then attached to `group`; the range is collapsed in the merged mesh. Decals\n * go with it.\n */\n extract(mv: MeshVis, group: THREE_NS.Object3D): void {\n if (!mv.host || !mv.range || !mv.merged || mv.loose) return\n const host = mv.host\n const [v0, v1] = mv.range\n const src = host.mesh.geometry\n const geo = new this.THREE.BufferGeometry()\n const count = v1 - v0\n for (const name of Object.keys(src.attributes)) {\n const a = src.getAttribute(name) as THREE_NS.BufferAttribute\n if ((a as unknown as { isInterleavedBufferAttribute?: boolean }).isInterleavedBufferAttribute) continue\n const size = a.itemSize\n const from = (name === POS_ATTR ? plainPositions(host.mesh, v0, v1) ?? host.work : null) ?? (a.array as unknown as Float32Array)\n const slice = (from as unknown as { slice(a: number, b: number): ArrayLike<number> }).slice(v0 * size, v1 * size)\n const Ctor = (a.array as unknown as { constructor: new (x: ArrayLike<number>) => ArrayLike<number> }).constructor\n geo.setAttribute(name, new this.THREE.BufferAttribute(new Ctor(slice) as never, size, a.normalized))\n }\n const index = src.getIndex()\n if (index) {\n const out: number[] = []\n for (let i = 0; i + 2 < index.count; i += 3) {\n const a = index.getX(i)\n const b = index.getX(i + 1)\n const c = index.getX(i + 2)\n if (a >= v0 && a < v1 && b >= v0 && b < v1 && c >= v0 && c < v1) out.push(a - v0, b - v0, c - v0)\n }\n geo.setIndex(count > 65535 ? new this.THREE.Uint32BufferAttribute(out, 1) : new this.THREE.Uint16BufferAttribute(out, 1))\n }\n const mats = materialsOf(host.mesh.material).map((m) => m.clone())\n const loose = new this.THREE.Mesh(geo, mats[0])\n loose.name = `${host.mesh.name || 'mesh'}:${v0}-${v1}`\n loose.castShadow = host.mesh.castShadow\n loose.receiveShadow = host.mesh.receiveShadow\n loose.renderOrder = host.mesh.renderOrder\n loose.frustumCulled = host.mesh.frustumCulled\n loose.layers.mask = host.mesh.layers.mask\n loose.position.copy(host.mesh.position)\n loose.quaternion.copy(host.mesh.quaternion)\n loose.scale.copy(host.mesh.scale)\n const parent = host.mesh.parent\n if (parent) parent.add(loose)\n loose.updateMatrixWorld(true)\n // the merged mesh loses the range; the decals and the part's state follow the new mesh\n this.collapse(mv)\n for (const d of mv.decals) {\n d.obj.visible = true\n loose.add(d.obj)\n }\n const lp = positionAttr(geo) as THREE_NS.BufferAttribute\n const lh: HostVis = {\n mesh: loose,\n origGeometry: geo,\n origMaterial: loose.material,\n ownGeo: true,\n work: new Float32Array(lp.array as ArrayLike<number>),\n ownMat: true,\n sharers: [mv],\n }\n mv.host = lh\n mv.range = [0, count]\n mv.mesh = loose\n mv.loose = true\n mv.moved = true\n group.attach(loose)\n for (const m of materialsOf(loose.material)) m.needsUpdate = true\n }\n\n private restoreRanged(mv: MeshVis): void {\n const merged = mv.merged as NonNullable<MeshVis['merged']>\n const host = merged.host\n for (const d of mv.decals) this.disposeDecal(d)\n mv.decals.length = 0\n if (mv.loose) {\n const loose = mv.mesh\n loose.parent?.remove(loose)\n loose.geometry.dispose()\n for (const m of materialsOf(loose.material)) m.dispose()\n mv.host = host\n mv.range = [merged.range[0], merged.range[1]]\n mv.mesh = host.mesh\n mv.loose = false\n mv.moved = false\n }\n mv.collapsed = false\n mv.hidden = false\n mv.meltApplied = 0\n mv.charK = 0\n mv.glowK = 0\n mv.touched = false\n if (!host.ownGeo) return\n // positions and colours of the range go back to the original ones\n const work = host.work as Float32Array\n const op = basePositions(host)\n const [v0, v1] = merged.range\n if (op) work.set(op.subarray(v0 * 3, v1 * 3), v0 * 3)\n const attr = host.mesh.geometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n if (attr) {\n const orig = host.origGeometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n const size = attr.itemSize\n const a = attr.array as unknown as Float32Array\n for (let i = v0; i < v1; i++) {\n for (let c = 0; c < 3; c++) a[i * size + c] = orig ? orig.array[i * orig.itemSize + c] : 1\n }\n attr.needsUpdate = true\n }\n if (host.sharers.every((s) => !s.touched)) {\n host.mesh.geometry.dispose()\n host.mesh.geometry = host.origGeometry\n // the original geometry as it is now: its first positions, with what another drawing keeps collapsed\n const base = basePositions(host), back = positionAttr(host.origGeometry)\n if (base && back) {\n const arr = back.array as unknown as Float32Array\n arr.set(base)\n collapseForeign(host.mesh, arr)\n back.needsUpdate = true\n }\n host.work = null\n host.ownGeo = false\n if (host.ownMat) {\n for (const m of materialsOf(host.mesh.material)) m.dispose()\n host.mesh.material = host.origMaterial\n host.ownMat = false\n }\n } else this.rebuildHost(host)\n }\n\n /** Bring one mesh back to how it was when it was bound. */\n restoreMesh(mv: MeshVis): void {\n if (mv.merged) {\n this.restoreRanged(mv)\n return\n }\n const mesh = mv.mesh\n for (const d of mv.decals) this.disposeDecal(d)\n mv.decals.length = 0\n if (mv.ownGeo) {\n mesh.geometry.dispose()\n mesh.geometry = mv.origGeometry\n mv.ownGeo = false\n mv.work = null\n }\n if (mv.ownMat) {\n for (const m of materialsOf(mesh.material)) m.dispose()\n mesh.material = mv.origMaterial\n mv.ownMat = false\n mv.baseColors = null\n }\n mesh.visible = mv.origVisible\n if (mv.origParent && mesh.parent !== mv.origParent) {\n mv.origParent.add(mesh)\n mv.moved = true\n }\n if (mv.moved) {\n mesh.position.copy(mv.origPosition)\n mesh.quaternion.copy(mv.origQuaternion)\n mesh.scale.copy(mv.origScale)\n mv.moved = false\n }\n mv.meltApplied = 0\n }\n\n restorePart(pv: PartVis): void {\n for (const mv of pv.meshes) this.restoreMesh(mv)\n pv.charApplied = 0\n pv.glowApplied = 0\n pv.meltApplied = 0\n pv.gone = 'none'\n }\n\n dispose(): void {\n this.kit.dispose()\n }\n}\n","// The sounds of materials breaking, as recipes of @adatechnology/game-audio. The art scene's `sfx.*` (cena L1354-L1367) are ported literally: the same\n// filters, frequencies, lengths, volumes and reverb sends, and the same random numbers drawn in the same order, so a recipe leaves the trace of the team\n// code. The game's `boom` (jogo L68278) is here too, as the game's explosion.\nimport { DISTANCE_CURVES, sceneMany as many, sceneNoise as noise, sceneRecipe, sceneTone as tone } from '@adatechnology/game-audio'\nimport type { Layer, LoopRecipe, SoundBank, SoundRecipe } from '@adatechnology/game-audio'\n\nimport { BLAST_SOUNDS, FIRE_FUEL_LOOPS, FIRE_LOOP, FIRE_SOUNDS } from './blast-fire'\n\nconst scene = (id: string, layers: readonly Layer[], line: string, vars?: SoundRecipe['vars'], group?: string): SoundRecipe =>\n sceneRecipe(id, layers, line, { ...(vars ? { vars } : {}), ...(group ? { group } : {}) })\n\nconst boomLayers = (big: boolean): Layer[] => [\n noise({ f: 1200, f2: 120, d: 1.8, vol: 2, wet: 1.2 }),\n tone({ f: 65, f2: 24, d: 1.0, vol: 1.8 }),\n noise({ type: 'highpass', f: 1500, d: 0.2, vol: 0.8 }),\n ...(big ? [noise({ f: 500, f2: 90, a: 0.2, d: 2.4, vol: 1.2, wet: 1, delay: 0.15 })] : []),\n ...many(8, () => tone({ f: [2600, 5600], d: 0.05, vol: 0.08, delay: [0.4, 1.6] })),\n]\n\n/** The art scene's destruction sounds, each with the team name in its `sources`. */\nexport const SCENE_SOUNDS: readonly SoundRecipe[] = [\n scene(\n 'glass_shatter',\n [noise({ type: 'highpass', f: 2800, d: 0.45, vol: 0.9, wet: 0.5 }), ...many(12, () => tone({ f: [3000, 7500], d: [0.06, 0.14], vol: 0.18, delay: [0, 0.55] }))],\n 'L1359 glass',\n ),\n scene(\n 'wood_hit',\n [noise({ type: 'bandpass', f: 850, q: 1, d: 0.25, vol: 0.9, wet: 0.3 }), tone({ f: 210, f2: 90, d: 0.1, vol: 0.6 }), noise({ type: 'highpass', f: 2000, d: 0.04, vol: 0.5 })],\n 'L1360 wood',\n ),\n // many parts coming loose at once share the `debris_knock` voices (game-audio voice-groups.json)\n scene('thunk', [noise({ type: 'bandpass', f: 700, q: 2, d: 0.07, vol: 0.4 })], 'L1361 thunk', undefined, 'debris_knock'),\n scene('ping', [tone({ f: [2600, 3500], f2: 1400, d: 0.14, vol: 0.18, wet: 0.3 })], 'L1362 ping'),\n scene('clang', [tone({ f: [520, 720], f2: 480, d: 0.5, vol: 0.35, wet: 0.4 }), tone({ f: 1370, f2: 1300, d: 0.3, vol: 0.15 }), noise({ type: 'highpass', f: 2000, d: 0.05, vol: 0.5 })], 'L1363 clang'),\n scene('chip', [noise({ type: 'bandpass', f: 1600, q: 1.2, d: 0.06, vol: 0.5 })], 'L1364 chip'),\n scene(\n 'crumble',\n [noise({ f: 900, f2: 200, d: 0.6, vol: 0.9, wet: 0.3 }), ...many(5, () => noise({ type: 'bandpass', f: [500, 1400], q: 2, d: 0.05, vol: 0.4, delay: [0.1, 0.5] }))],\n 'L1365 crumble',\n ),\n // `thud(x, z, v)`: `v` is the `scale` param (default 1)\n scene('thud', [tone({ f: 75, f2: 38, d: 0.22, vol: { param: 'scale', scale: 0.6 } }), noise({ f: 420, d: 0.16, vol: { param: 'scale', scale: 0.45 } })], 'L1358 thud', { scale: 1 }),\n // `hiss(x, z, d)`: `seconds` is the param `d` (default 1.2)\n // every melting part shares one `sizzle` voice\n scene('hiss', [noise({ type: 'highpass', f: 3500, a: 0.05, d: { param: 'seconds' }, vol: 0.35 })], 'L1366 hiss', { seconds: 1.2 }, 'sizzle'),\n scene('boom', boomLayers(false), 'L1367 boom'),\n scene('boom_big', boomLayers(true), 'L1367 boom (big)'),\n scene('burst', [noise({ f: 700, f2: 120, d: 0.7, vol: 1.4, wet: 0.5 }), noise({ type: 'highpass', f: 3000, a: 0.05, d: 1.2, vol: 0.4, delay: 0.1 })], 'L1357 burst'),\n scene('crack', [noise({ type: 'highpass', f: 1800, d: 0.05, vol: 0.8 }), tone({ f: 420, f2: 180, d: 0.06, vol: 0.4 })], 'L1354 crack'),\n]\n\n/** The game's explosion thump: a sine from 70 to 28 Hz over 1.2 s, `1.4 / (1 + d² × 0.002)` (jogo L68278). */\nexport const EXPLOSION_BOOM: SoundRecipe = {\n id: 'explosion_boom',\n bus: 'world',\n order: 'boom',\n duration: 1.6,\n tail: 0.1,\n layers: [\n {\n source: { kind: 'osc', wave: 'sine', frequency: { from: 70, to: 28, curve: 'exp', over: 1.2 } },\n envelope: [\n [0, 1, 'set'],\n ['1d', 0.001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: DISTANCE_CURVES.game_boom,\n sources: ['jogo:L68278-68285 boom'],\n}\n\n/**\n * The fire loop of the art scene (cena L1316): noise through a 1800 Hz bandpass (Q 0.6) into a gain that starts at 0. The page never raises it, so it is\n * silent there; here `createDestructionSound` raises it while something burns (the level is the kit's, in `fire`).\n */\nexport const BURN_LOOP: LoopRecipe = {\n id: 'burn_loop',\n bus: 'world',\n order: 'chain_loop',\n source: { kind: 'noise', loop: true },\n filters: { mode: 'serial', bank: [{ type: 'bandpass', frequency: { set: 1800 }, q: 0.6 }] },\n volume: 0,\n sources: ['cena:L1316 fire loop (silent in the page: its gain is never raised)', 'sdk: the level while burning'],\n}\n\nconst drag = (id: string, layers: readonly Layer[]): SoundRecipe => ({ ...sceneRecipe(id, layers, ''), sources: ['sdk: a base dragged on a floor, one grain per stretch'] })\n\n/** Something heavy dragged on a floor, by what its base is made of. */\nexport const DRAG_SOUNDS: readonly SoundRecipe[] = [\n drag('drag_wood', [noise({ type: 'bandpass', f: 380, q: 1.4, d: 0.28, vol: 0.5 }), noise({ type: 'bandpass', f: [900, 1300], q: 3, d: 0.08, vol: 0.14 })]),\n drag('drag_metal', [noise({ type: 'bandpass', f: 1500, q: 4, d: 0.26, vol: 0.32 }), tone({ f: [880, 1240], f2: 760, d: 0.18, vol: 0.05 })]),\n drag('drag_glass', [noise({ type: 'bandpass', f: 2600, q: 5, d: 0.2, vol: 0.22 })]),\n drag('drag_masonry', [noise({ type: 'bandpass', f: 260, q: 0.9, d: 0.3, vol: 0.62 }), ...many(3, () => noise({ type: 'bandpass', f: [600, 1200], q: 2, d: 0.04, vol: 0.14, delay: [0, 0.2] }))]),\n drag('drag_soft', [noise({ type: 'lowpass', f: 420, d: 0.28, vol: 0.3 })]),\n]\n\nconst leaf = (id: string, layers: readonly Layer[]): SoundRecipe => ({ ...sceneRecipe(id, layers, ''), sources: ['sdk: a door, lid or drawer worked by hand'] })\n\n/** A leaf worked by hand: the latch, the hinge as it turns (by what the leaf is made of), the leaf meeting its frame, a locked leaf shaken, a drawer on its runners. */\nexport const LEAF_SOUNDS: readonly SoundRecipe[] = [\n leaf('latch', [noise({ type: 'bandpass', f: 2400, q: 4, d: 0.03, vol: 0.35 }), tone({ f: 1900, f2: 1500, d: 0.025, vol: 0.06, delay: 0.035 })]),\n leaf('creak_wood', [tone({ f: [190, 240], f2: 310, d: 0.5, vol: 0.05 }), noise({ type: 'bandpass', f: 520, q: 6, a: 0.05, d: 0.45, vol: 0.12 })]),\n leaf('creak_metal', [tone({ f: [620, 760], f2: 900, d: 0.35, vol: 0.035 }), noise({ type: 'bandpass', f: 1400, q: 8, a: 0.04, d: 0.3, vol: 0.08 })]),\n leaf('shut_wood', [tone({ f: 120, f2: 60, d: 0.14, vol: 0.5 }), noise({ type: 'bandpass', f: 600, q: 1.2, d: 0.1, vol: 0.55, wet: 0.25 }), noise({ type: 'bandpass', f: 2400, q: 4, d: 0.03, vol: 0.25, delay: 0.02 })]),\n leaf('shut_metal', [tone({ f: 160, f2: 85, d: 0.18, vol: 0.55 }), noise({ type: 'bandpass', f: 900, q: 1.6, d: 0.12, vol: 0.45, wet: 0.3 }), tone({ f: 1250, f2: 1150, d: 0.12, vol: 0.06 })]),\n leaf('shut_soft', [tone({ f: 95, f2: 55, d: 0.12, vol: 0.35 }), noise({ type: 'lowpass', f: 500, d: 0.1, vol: 0.3 })]),\n leaf('rattle', many(5, () => noise({ type: 'bandpass', f: [1600, 2600], q: 3, d: 0.035, vol: 0.32, delay: [0, 0.45] }))),\n leaf('slide', [noise({ type: 'bandpass', f: 700, q: 2, a: 0.04, d: 0.35, vol: 0.22 }), noise({ type: 'bandpass', f: 2200, q: 5, d: 0.3, vol: 0.05 })]),\n // an item taken in the hand: the fingers on a hard surface and the sleeve moving, or a soft thing gathered up (the kit's recordings answer these ids)\n leaf('grab_hard', [noise({ type: 'bandpass', f: 1800, q: 3, d: 0.03, vol: 0.18 }), noise({ type: 'bandpass', f: 900, q: 1.2, a: 0.02, d: 0.14, vol: 0.08 })]),\n leaf('grab_soft', [noise({ type: 'lowpass', f: 1400, a: 0.02, d: 0.16, vol: 0.14 })]),\n]\n\nconst impact = (id: string, layers: readonly Layer[]): SoundRecipe => ({ ...sceneRecipe(id, layers, ''), sources: ['sdk: a blow on a material, by material and kind of blow (synthesised until the recorded samples arrive)'] })\n\n/**\n * A blow on a material, by what it is made of and what met it (`impactSoundKeys`): a bullet, a blunt blow (a punch, a kick, a fall), a blade. Each\n * is drawn from how the real thing sounds (checklist 5.3): a bullet rings steel and goes \"tchak\" on concrete with pebbles after it, a fist on steel is a\n * low \"bong\", a knife scrapes it; the ground is a dull \"tuf\", ceramic a dry \"tic\", plastic a hollow \"toc\", a sofa a \"fump\". Levels are matched so a\n * bullet on concrete is as loud as on wood.\n */\nexport const IMPACT_SOUNDS: readonly SoundRecipe[] = [\n // metal\n impact('metal_bullet', [noise({ type: 'highpass', f: 3000, d: 0.03, vol: 0.8 }), tone({ f: [2600, 3400], f2: 1800, d: 0.14, vol: 0.28, wet: 0.35 }), tone({ f: [520, 720], f2: 480, d: 0.35, vol: 0.22, wet: 0.35 })]),\n impact('metal_blunt', [noise({ type: 'bandpass', f: 800, q: 1, d: 0.05, vol: 0.5 }), tone({ f: [150, 210], f2: 120, d: 0.6, vol: 0.5, wet: 0.4 }), tone({ f: [420, 520], f2: 400, d: 0.4, vol: 0.12 })]),\n impact('metal_blade', [noise({ type: 'bandpass', f: [3500, 4500], q: 6, a: 0.01, d: 0.18, vol: 0.45 }), tone({ f: [2200, 2800], f2: 3000, d: 0.15, vol: 0.06 })]),\n impact('metal_thin', [noise({ type: 'highpass', f: 2500, d: 0.04, vol: 0.6 }), tone({ f: [900, 1300], f2: 700, d: 0.25, vol: 0.22, wet: 0.3 }), noise({ type: 'bandpass', f: 1200, q: 2, d: 0.08, vol: 0.3 })]),\n // wood (the bullet keeps the art scene's `wood_hit`)\n impact('wood_blunt', [tone({ f: [110, 150], f2: 70, d: 0.14, vol: 0.6 }), noise({ type: 'bandpass', f: 500, q: 1.2, d: 0.12, vol: 0.55, wet: 0.2 })]),\n impact('wood_blade', [noise({ type: 'bandpass', f: [1800, 2400], q: 2, a: 0.01, d: 0.12, vol: 0.5 }), ...many(3, () => noise({ type: 'bandpass', f: [2500, 4000], q: 3, d: 0.02, vol: 0.22, delay: [0.02, 0.1] }))]),\n impact('mdf_puff', [noise({ type: 'lowpass', f: 900, d: 0.08, vol: 1 }), tone({ f: [180, 230], f2: 110, d: 0.06, vol: 0.3 }), noise({ type: 'highpass', f: 3000, a: 0.01, d: 0.2, vol: 0.1 })]),\n // glass and ceramic\n impact('glass_bullet', [noise({ type: 'highpass', f: 4000, d: 0.05, vol: 0.7 }), tone({ f: [3200, 4200], f2: 2600, d: 0.2, vol: 0.14, wet: 0.3 }), ...many(4, () => tone({ f: [4000, 7000], d: 0.05, vol: 0.07, delay: [0.02, 0.2] }))]),\n impact('glass_blunt', [noise({ type: 'bandpass', f: 2200, q: 3, d: 0.05, vol: 0.8 }), tone({ f: [1400, 1800], f2: 1300, d: 0.2, vol: 0.16, wet: 0.3 })]),\n impact('glass_blade', [noise({ type: 'bandpass', f: 5000, q: 8, a: 0.02, d: 0.25, vol: 0.3 })]),\n impact('ceramic_hit', [noise({ type: 'bandpass', f: 3000, q: 2, d: 0.03, vol: 0.6 }), tone({ f: [1800, 2400], f2: 1600, d: 0.1, vol: 0.2 })]),\n impact('ceramic_bullet', [noise({ type: 'highpass', f: 2500, d: 0.06, vol: 0.85 }), ...many(5, () => tone({ f: [2500, 5000], d: 0.04, vol: 0.09, delay: [0, 0.15] }))]),\n // masonry and the ground\n impact('masonry_bullet', [noise({ type: 'bandpass', f: [1600, 2000], q: 1, d: 0.05, vol: 1.8 }), noise({ type: 'lowpass', f: 600, d: 0.12, vol: 0.9, wet: 0.2 }), ...many(4, () => noise({ type: 'bandpass', f: [2000, 4000], q: 3, d: 0.02, vol: 0.28, delay: [0.03, 0.3] }))]),\n impact('masonry_blunt', [tone({ f: [70, 95], f2: 45, d: 0.12, vol: 0.55 }), noise({ type: 'lowpass', f: 400, d: 0.1, vol: 0.5 })]),\n impact('masonry_blade', [noise({ type: 'bandpass', f: [2500, 3500], q: 4, a: 0.01, d: 0.15, vol: 0.4 })]),\n impact('plaster_puff', [noise({ type: 'lowpass', f: 900, d: 0.09, vol: 0.7 }), noise({ type: 'highpass', f: 3000, a: 0.01, d: 0.2, vol: 0.14 })]),\n impact('soil_bullet', [noise({ type: 'lowpass', f: 700, d: 0.08, vol: 2.2 }), ...many(3, () => noise({ type: 'bandpass', f: [1200, 2200], q: 2, d: 0.03, vol: 0.18, delay: [0.02, 0.2] }))]),\n impact('soil_blunt', [tone({ f: [55, 70], f2: 40, d: 0.1, vol: 0.45 }), noise({ type: 'lowpass', f: 300, d: 0.08, vol: 0.4 })]),\n impact('sand_hit', [noise({ type: 'bandpass', f: 3500, q: 0.8, a: 0.005, d: 0.15, vol: 0.45 }), noise({ type: 'lowpass', f: 500, d: 0.06, vol: 0.45 })]),\n impact('gravel_hit', [noise({ type: 'lowpass', f: 500, d: 0.06, vol: 0.45 }), ...many(6, () => noise({ type: 'bandpass', f: [1500, 3500], q: 3, d: 0.025, vol: 0.28, delay: [0, 0.18] }))]),\n // plastic, rubber, wax\n impact('plastic_hit', [noise({ type: 'bandpass', f: 1600, q: 3, d: 0.04, vol: 0.5 }), tone({ f: [380, 520], f2: 300, d: 0.08, vol: 0.32 })]),\n impact('plastic_bullet', [noise({ type: 'bandpass', f: 2500, q: 2, d: 0.03, vol: 1.3 }), tone({ f: [600, 800], f2: 450, d: 0.06, vol: 0.4 })]),\n impact('rubber_hit', [tone({ f: [90, 130], f2: 60, d: 0.1, vol: 0.45 }), noise({ type: 'lowpass', f: 350, d: 0.06, vol: 0.28 })]),\n impact('wax_hit', [noise({ type: 'lowpass', f: 800, d: 0.05, vol: 0.45 }), tone({ f: [240, 280], f2: 180, d: 0.05, vol: 0.22 })]),\n // soft things, paper, plants\n impact('soft_bullet', [noise({ type: 'lowpass', f: 450, a: 0.003, d: 0.1, vol: 1.8 }), noise({ type: 'bandpass', f: 900, q: 1, d: 0.05, vol: 0.5 })]),\n impact('fabric_rip', [noise({ type: 'bandpass', f: [2000, 2800], q: 1.5, a: 0.02, d: 0.25, vol: 0.4 }), ...many(4, () => noise({ type: 'bandpass', f: [3000, 5000], q: 4, d: 0.02, vol: 0.14, delay: [0, 0.22] }))]),\n impact('paper_hit', [noise({ type: 'bandpass', f: 2200, q: 1, d: 0.05, vol: 0.45 })]),\n impact('paper_tear', [noise({ type: 'highpass', f: 2500, a: 0.02, d: 0.3, vol: 0.15 })]),\n impact('leaf_rustle', many(6, () => noise({ type: 'bandpass', f: [2500, 6000], q: 2, d: 0.05, vol: 0.16, delay: [0, 0.3] }))),\n impact('branch_cut', [noise({ type: 'bandpass', f: 1500, q: 2, d: 0.04, vol: 0.55 }), tone({ f: [260, 340], f2: 150, d: 0.05, vol: 0.22 })]),\n impact('fruit_splat', [noise({ type: 'lowpass', f: 1200, d: 0.12, vol: 0.55 }), noise({ type: 'bandpass', f: 600, q: 0.7, d: 0.2, vol: 0.32 })]),\n // a round glancing off: steel whines down in pitch (\"piiuu\"), stone and concrete give a short crack with grit\n impact('ricochet_metal', [noise({ type: 'highpass', f: 3000, d: 0.02, vol: 0.6 }), tone({ f: [2800, 3600], f2: 900, d: 0.38, vol: 0.2, wet: 0.4 }), tone({ f: [5200, 6400], f2: 2000, d: 0.2, vol: 0.05 })]),\n impact('ricochet_stone', [noise({ type: 'bandpass', f: [2200, 2800], q: 2, d: 0.04, vol: 0.8 }), tone({ f: [1800, 2400], f2: 1200, d: 0.08, vol: 0.1 }), ...many(3, () => noise({ type: 'bandpass', f: [2500, 4500], q: 3, d: 0.015, vol: 0.2, delay: [0.02, 0.12] }))]),\n // breaks a material has of its own (the rest keep the art scene's shatter, crumble and splinter)\n impact('ceramic_break', [noise({ type: 'highpass', f: 1800, d: 0.3, vol: 0.85, wet: 0.4 }), ...many(8, () => tone({ f: [1800, 4500], d: [0.04, 0.1], vol: 0.15, delay: [0, 0.4] }))]),\n impact('tempered_burst', [noise({ type: 'highpass', f: 3500, d: 0.6, vol: 0.9, wet: 0.4 }), ...many(16, () => tone({ f: [4000, 8000], d: 0.04, vol: 0.08, delay: [0, 0.8] }))]),\n impact('plastic_crack', [noise({ type: 'bandpass', f: 1800, q: 2, d: 0.06, vol: 0.75 }), tone({ f: [450, 550], f2: 250, d: 0.05, vol: 0.22 })]),\n impact('mdf_crumble', [noise({ type: 'lowpass', f: 700, d: 0.25, vol: 0.75, wet: 0.2 }), ...many(4, () => noise({ type: 'lowpass', f: 500, d: 0.05, vol: 0.32, delay: [0.05, 0.3] }))]),\n]\n\nexport const DESTRUCTION_SOUND_BANK: SoundBank = { id: 'destruction_three', sounds: [...SCENE_SOUNDS, ...DRAG_SOUNDS, ...LEAF_SOUNDS, ...IMPACT_SOUNDS, EXPLOSION_BOOM, ...BLAST_SOUNDS, ...FIRE_SOUNDS], loops: [BURN_LOOP, FIRE_LOOP, ...FIRE_FUEL_LOOPS] }\n","// Blasts and fire: the kit's synthesized sounds for each family of explosive (grenade, big charge, fuel, car, pipe bomb, rocket, flashbang, molotov),\n// the far and the indoor versions of a blast, and the fire (ignition, roar, crackle, gas leak, put out). Synthesized until recorded files reach the\n// SDK; each recipe is built so the loudest moment is the first few milliseconds (the crack of the blast lands on the frame of the event), the body\n// and the debris follow, and every frequency and timing is a range so no two plays sound alike.\nimport { sceneMany as many, sceneNoise as noise, sceneRecipe, sceneTone as tone } from '@adatechnology/game-audio'\nimport type { Falloff, FilterSpec, Layer, LoopRecipe, SoundRecipe } from '@adatechnology/game-audio'\n\n/** A blast near the listener: loud for tens of metres; lowpass cutoffs fall with distance. */\nexport const BLAST_FALLOFF: Falloff = { model: 'inverse_square', k: 0.0012, cutoffK: 0.006, minGain: 0.002 }\n/** A blast far away (past `BLAST_FAR_DISTANCE`): heard for hundreds of metres. */\nexport const BLAST_FAR_FALLOFF: Falloff = { model: 'inverse_square', k: 0.00008, scale: 0.3, minGain: 0.001 }\n/** Fire, ignition and crackles: a room-size sound. */\nexport const FIRE_FALLOFF: Falloff = { model: 'inverse_square', k: 0.01, cutoffK: 0.01, minGain: 0.005 }\n/** Metres from the listener past which a blast plays its far version. */\nexport const BLAST_FAR_DISTANCE = 60\n\n/** The explosion families, each with its own sound. */\nexport const BLAST_KINDS = ['grenade', 'big', 'fuel', 'car', 'pipe_bomb', 'rocket', 'flashbang', 'molotov'] as const\nexport type BlastKind = (typeof BLAST_KINDS)[number]\n\n/**\n * Which family each named explosion of `@adatechnology/game-vfx` (`explosions.json`, the `effect` of an explosive part) belongs to. Data: a game adds\n * or changes entries through `DestructionSoundOptions.blastKinds`. An explosion without a known effect is a grenade below `BIG_BLAST_RADIUS` and a big\n * charge above it.\n */\nexport const BLAST_KIND_OF: Readonly<Record<string, BlastKind>> = {\n m67: 'grenade',\n vog_25: 'grenade',\n m79_40mm: 'grenade',\n claymore: 'grenade',\n generic: 'grenade',\n c4: 'big',\n dynamite: 'big',\n fuel_station_tank: 'big',\n propane_p13: 'fuel',\n fuel_barrel: 'fuel',\n fuel_pump: 'fuel',\n car_fuel_tank: 'car',\n pipe_bomb: 'pipe_bomb',\n m72_66mm: 'rocket',\n at4_84mm: 'rocket',\n carl_gustaf_84mm: 'rocket',\n pg7v: 'rocket',\n flashbang: 'flashbang',\n molotov: 'molotov',\n}\n\n/** Blast radius (metres) from which an explosion with no known effect is a big charge. */\nexport const BIG_BLAST_RADIUS = 8\n\nconst blast = (id: string, layers: readonly Layer[], sources: readonly string[], falloff: Falloff = BLAST_FALLOFF): SoundRecipe => ({\n ...sceneRecipe(id, layers, ''),\n falloff,\n sources,\n})\n\n// the instant crack of the shock front: the loudest part, in the first milliseconds\nconst crack = (f: readonly [number, number], d: number, vol: number): Layer => noise({ type: 'highpass', f, a: 0.001, d, vol })\n// stones, wood and metal falling back after the blast, spread over `[from, to]` seconds\nconst debris = (count: number, from: number, to: number, vol: readonly [number, number]): Layer[] => [\n ...many(count, () => noise({ type: 'bandpass', f: [300, 1400], q: 2.5, d: [0.03, 0.09], vol, delay: [from, to] })),\n ...many(Math.ceil(count / 3), () => noise({ type: 'bandpass', f: [1800, 3600], q: 5, d: [0.02, 0.04], vol: [vol[0] * 0.6, vol[1] * 0.6] as const, delay: [from + 0.1, to] })),\n]\n// steel fragments whizzing and striking around the blast\nconst shrapnel = (count: number, to: number): Layer[] => many(count, () => noise({ type: 'bandpass', f: [2500, 6000], q: 6, d: [0.015, 0.045], vol: [0.08, 0.16], delay: [0.02, to] }))\n// glass panes breaking and their shards falling\nconst glass = (count: number, from: number): Layer[] => [\n noise({ type: 'highpass', f: [2600, 3000], d: 0.4, vol: 0.7, wet: 0.5, delay: from }),\n ...many(count, () => tone({ f: [3000, 7500], d: [0.05, 0.13], vol: 0.12, delay: [from, from + 0.7] })),\n]\n\n/** One sound per explosion family, the far and the indoor versions. */\nexport const BLAST_SOUNDS: readonly SoundRecipe[] = [\n blast(\n 'explosion_grenade',\n [\n crack([2300, 2700], 0.06, 2.4),\n noise({ f: [2500, 3000], f2: 160, d: 0.7, vol: 2, wet: 0.35 }),\n tone({ f: [80, 92], f2: 32, d: 0.5, vol: 1.6 }),\n noise({ type: 'bandpass', f: [620, 760], q: 0.8, d: 0.18, vol: 1.1 }),\n ...shrapnel(14, 0.7),\n ...debris(10, 0.35, 1.8, [0.1, 0.2]),\n ],\n ['sdk: frag grenade (M67, VOG-25, 40 mm): sharp crack, short body, fragments striking, a little debris'],\n ),\n blast(\n 'explosion_big',\n [\n crack([1900, 2300], 0.08, 2.4),\n noise({ f: [2200, 2600], f2: 90, d: 1.6, vol: 2.2, wet: 0.45 }),\n tone({ f: [52, 60], f2: 22, d: 1.6, vol: 1.9 }),\n noise({ f: [280, 330], f2: 60, a: 0.25, d: 2.8, vol: 0.8, wet: 0.6, delay: 0.05 }),\n ...debris(24, 0.5, 3.6, [0.12, 0.25]),\n ],\n ['sdk: big charge (C4, dynamite, a fuel station tank): crack, long deep roar, debris falling for 2 to 4 s'],\n ),\n blast(\n 'explosion_fuel',\n [\n noise({ type: 'highpass', f: [1700, 2000], a: 0.001, d: 0.05, vol: 1 }),\n tone({ f: [380, 450], f2: 300, d: 0.4, vol: 0.3 }),\n noise({ f: [1700, 2000], f2: 150, a: 0.03, d: 1.4, vol: 2.1, wet: 0.4 }),\n tone({ f: [48, 56], f2: 25, d: 1.2, vol: 1.7 }),\n noise({ type: 'bandpass', f: [450, 560], q: 0.6, a: 0.15, d: 2.2, vol: 0.85, wet: 0.5, delay: 0.1 }),\n ...debris(10, 0.5, 2.6, [0.08, 0.16]),\n ],\n ['sdk: a fuel vessel bursting (propane P13, fuel barrel, pump): the shell tearing, a fireball \"whoomp\" and its roar'],\n ),\n blast(\n 'explosion_car',\n [\n noise({ type: 'highpass', f: [1700, 2000], a: 0.001, d: 0.06, vol: 1.1 }),\n noise({ f: [1600, 1900], f2: 140, a: 0.03, d: 1.6, vol: 2.1, wet: 0.4 }),\n tone({ f: [44, 52], f2: 24, d: 1.4, vol: 1.8 }),\n noise({ type: 'bandpass', f: [420, 520], q: 0.6, a: 0.15, d: 2.6, vol: 0.9, wet: 0.5, delay: 0.1 }),\n ...glass(10, 0.04),\n tone({ f: [130, 150], f2: 85, d: 1.1, vol: 0.18, delay: [0.3, 0.5] }),\n ...debris(16, 0.6, 3.2, [0.1, 0.2]),\n ],\n ['sdk: a car going up: the fuel tank fireball, every window breaking, the body groaning, parts falling'],\n ),\n blast(\n 'explosion_pipe_bomb',\n [\n crack([2000, 2400], 0.07, 2.2),\n noise({ f: [2000, 2400], f2: 150, d: 0.8, vol: 1.9, wet: 0.35 }),\n tone({ f: [70, 82], f2: 30, d: 0.6, vol: 1.5 }),\n ...many(6, () => tone({ f: [1800, 3200], f2: 1200, d: [0.06, 0.12], vol: 0.06, delay: [0.05, 0.6] })),\n ...shrapnel(18, 0.9),\n ...debris(8, 0.4, 1.8, [0.08, 0.16]),\n ],\n ['sdk: pipe bomb: crack, body, the steel pipe flying apart in ringing pieces'],\n ),\n blast(\n 'explosion_rocket',\n [\n crack([2100, 2500], 0.08, 2.4),\n noise({ f: [2400, 2800], f2: 120, d: 1.1, vol: 2.1, wet: 0.4 }),\n tone({ f: [60, 70], f2: 26, d: 0.9, vol: 1.8 }),\n noise({ f: [350, 420], f2: 80, a: 0.08, d: 1.8, vol: 0.9, wet: 0.6, delay: 0.05 }),\n ...shrapnel(10, 0.8),\n ...debris(16, 0.4, 2.6, [0.1, 0.2]),\n ],\n ['sdk: rocket or anti-tank warhead (M72, AT4, RPG): hard crack, heavy body, debris'],\n ),\n blast(\n 'explosion_flashbang',\n [crack([1400, 1700], 0.12, 2.8), noise({ f: [1900, 2200], f2: 300, d: 0.35, vol: 1.3, wet: 0.3 }), tone({ f: [110, 130], f2: 60, d: 0.2, vol: 0.8 })],\n ['sdk: flashbang: a deafening crack with almost no body and no fragments'],\n ),\n blast(\n 'molotov_break_ignite',\n [\n ...glass(8, 0),\n noise({ f: [280, 340], f2: 2200, a: 0.12, d: 0.9, vol: 1.5, wet: 0.6, delay: 0.05 }),\n tone({ f: [85, 95], f2: 55, d: 0.4, vol: 0.5, delay: 0.08 }),\n ],\n ['sdk: molotov: the bottle breaking and the fuel catching with a \"fuuush\"'],\n FIRE_FALLOFF,\n ),\n blast(\n 'explosion_far',\n [\n noise({ f: [550, 650], f2: 80, a: 0.03, d: 2.5, vol: 2, wet: 1.4 }),\n tone({ f: [42, 48], f2: 25, d: 1.8, vol: 1.2 }),\n noise({ f: [350, 420], f2: 70, a: 0.1, d: 1.6, vol: 0.6, wet: 1.5, delay: [0.6, 1] }),\n ],\n ['sdk: any blast far away: no crack left, a dull thud and the echo rolling back'],\n BLAST_FAR_FALLOFF,\n ),\n blast(\n 'explosion_indoor_tail',\n [\n ...many(3, () => noise({ f: [650, 800], d: 0.12, vol: 0.5, delay: [0.04, 0.2] })),\n noise({ f: [850, 950], f2: 120, a: 0.05, d: 2.6, vol: 0.9, wet: 1.6, delay: 0.08 }),\n ],\n ['sdk: the room answering a blast inside it: slaps off the walls and a boomy tail'],\n ),\n]\n\n/** Fire: ignition, gas leaking from a vessel about to burst, a fire put out, and the crackles that ride on the fire loop. */\nexport const FIRE_SOUNDS: readonly SoundRecipe[] = [\n {\n ...blast(\n 'fire_ignite',\n [noise({ f: [230, 270], f2: 1500, a: 0.07, d: 0.5, vol: 1.6 }), tone({ f: [80, 90], f2: 55, d: 0.3, vol: 0.45 }), noise({ type: 'highpass', f: 3000, d: 0.3, vol: 0.1, delay: 0.1 })],\n ['sdk: fire catching, a soft \"fuuump\"'],\n FIRE_FALLOFF,\n ),\n group: 'fire_ignite',\n },\n {\n ...blast('gas_leak', [noise({ type: 'bandpass', f: [3200, 3800], q: 0.7, a: 0.08, d: { param: 'seconds' }, vol: 0.3 })], ['sdk: gas jetting from a punctured vessel'], FIRE_FALLOFF),\n vars: { seconds: 2 },\n },\n {\n ...blast(\n 'fire_extinguish',\n [noise({ type: 'highpass', f: [2300, 2700], a: 0.03, d: { param: 'seconds' }, vol: 0.3 }), noise({ type: 'bandpass', f: [800, 1000], q: 0.5, d: 0.5, vol: 0.25 })],\n ['sdk: water or foam on a fire: a steam puff and a sizzle'],\n FIRE_FALLOFF,\n ),\n vars: { seconds: 1.2 },\n },\n { ...blast('fire_crackle', [noise({ type: 'highpass', f: [1500, 3000], d: [0.01, 0.025], vol: [1.2, 2.2] })], ['sdk: a crackle of the fire'], FIRE_FALLOFF), group: 'fire_crackle' },\n { ...blast('fire_pop', [noise({ type: 'bandpass', f: [500, 1100], q: 1, d: [0.03, 0.06], vol: [3, 4.5] })], ['sdk: a log or a resin pocket popping'], FIRE_FALLOFF), group: 'fire_crackle' },\n]\n\n/** The roar of the fires: low, soft noise; `createDestructionSound` raises it with every part that burns and sprinkles crackles on it. */\nexport const FIRE_LOOP: LoopRecipe = {\n id: 'fire_loop',\n bus: 'world',\n order: 'chain_loop',\n source: { kind: 'noise', loop: true },\n filters: { mode: 'serial', bank: [{ type: 'lowpass', frequency: { set: 950 }, q: 0.5 }] },\n volume: 0,\n sources: ['sdk: the roar under the crackles of a fire'],\n}\n\n/**\n * What is burning, for the sound: each fuel has its own roar (a gas jet, a fuel pool, wood, plastic) and its own share of crackles. The rules are the\n * same for all (the level grows with how much burns, fades with distance, never clips); only the timbre comes from the fuel.\n */\nexport const FIRE_FUELS = ['wood', 'fabric', 'plastic', 'gas', 'liquid'] as const\nexport type FireFuel = (typeof FIRE_FUELS)[number]\n\n/** The fuel of a burning material (`materials.json` of game-destruction). Data: a game adds its own materials through `DestructionSoundOptions.fuels`. */\nexport const FIRE_FUEL_OF: Readonly<Record<string, FireFuel>> = {\n wood_soft: 'wood',\n wood_hard: 'wood',\n plywood: 'wood',\n mdf: 'wood',\n green_wood: 'wood',\n foliage: 'wood',\n cactus: 'wood',\n paper: 'fabric',\n fabric: 'fabric',\n leather: 'fabric',\n foam: 'plastic',\n plastic: 'plastic',\n rubber: 'plastic',\n wax: 'plastic',\n}\n\n/** The loop each fuel plays. Fabric and paper share the wood roar until they have their own. */\nexport const FIRE_LOOP_OF: Readonly<Record<FireFuel, string>> = {\n wood: 'fire_loop',\n fabric: 'fire_loop',\n plastic: 'fire_loop_plastic',\n gas: 'fire_loop_gas',\n liquid: 'fire_loop_liquid',\n}\n\n/** How much each fuel crackles (0..1): wood snaps and pops, plastic now and then, a gas jet and a fuel pool not at all. */\nexport const FIRE_CRACKLE_OF: Readonly<Record<FireFuel, number>> = { wood: 1, fabric: 0.5, plastic: 0.35, gas: 0, liquid: 0 }\n\nconst roar = (id: string, bank: readonly FilterSpec[], source: string): LoopRecipe => ({\n id,\n bus: 'world',\n order: 'chain_loop',\n source: { kind: 'noise', loop: true },\n filters: { mode: 'serial', bank },\n volume: 0,\n sources: [source],\n})\n\n/** The synthesized roar of each fuel other than wood: the fallback of the recorded loops of the same id. */\nexport const FIRE_FUEL_LOOPS: readonly LoopRecipe[] = [\n // a gas jet: a steady, broad roar, brighter than wood and without crackles\n roar('fire_loop_gas', [{ type: 'highpass', frequency: { set: 220 }, q: 0.7 }, { type: 'lowpass', frequency: { set: 2400 }, q: 0.6 }], 'sdk: a gas jet burning (a vessel venting into the flame)'),\n // a fuel pool: a soft, low, rolling roar\n roar('fire_loop_liquid', [{ type: 'highpass', frequency: { set: 90 }, q: 0.7 }, { type: 'lowpass', frequency: { set: 650 }, q: 0.9 }], 'sdk: a pool of fuel burning'),\n // plastic and rubber: a thin sizzle over a low burn\n roar('fire_loop_plastic', [{ type: 'bandpass', frequency: { set: 1800 }, q: 0.6 }], 'sdk: plastic and rubber melting in the fire'),\n]\n\n/** The sound of a blast family. */\nexport const BLAST_SOUND_OF: Readonly<Record<BlastKind, string>> = {\n grenade: 'explosion_grenade',\n big: 'explosion_big',\n fuel: 'explosion_fuel',\n car: 'explosion_car',\n pipe_bomb: 'explosion_pipe_bomb',\n rocket: 'explosion_rocket',\n flashbang: 'explosion_flashbang',\n molotov: 'molotov_break_ignite',\n}\n","import type { Vec3 } from '@adatechnology/game-contracts'\nimport { FOLEY_BANK, GAME_SFX_BANK } from '@adatechnology/game-audio'\nimport type { AudioEngine, AudioLoopHandle } from '@adatechnology/game-audio'\n\nimport { BIG_BLAST_RADIUS, BLAST_FAR_DISTANCE, BLAST_KIND_OF, BLAST_SOUND_OF, FIRE_CRACKLE_OF, FIRE_FUEL_OF, FIRE_LOOP_OF } from './blast-fire'\nimport type { BlastKind, FireFuel } from './blast-fire'\nimport { DESTRUCTION_SOUND_BANK } from './recipes'\nimport type { SoundDetail } from '../types'\n\n/**\n * What a sound key plays: the recipe, its params, a scale on the volume the renderer gives, and (optionally) a louder recipe above a volume\n * (a big blast gets the long boom).\n */\nexport type SoundKeyRule = {\n readonly sound: string\n readonly params?: Readonly<Record<string, number>>\n readonly volumeScale?: number\n readonly above?: { readonly volume: number; readonly sound: string }\n /** A sound of this bank played when the engine does not know `sound` (a vehicle door without the vehicle bank registered shuts like metal). */\n readonly fallback?: string\n}\n\nexport type DestructionSoundStyle = 'art_scene' | 'game'\n\n/**\n * The keys of a blow on a material (`impactSoundKeys`, `breakSoundKeys`): `impact_<family>_<blow>`, `impact_<material>[_<blow>]`, `break_<...>`. The renderer\n * sends them before its legacy family key, so the first one with a rule plays; a game replaces any of them in `keys`.\n */\nexport const IMPACT_SOUND_KEYS: Readonly<Record<string, SoundKeyRule>> = {\n impact_metal_ballistic: { sound: 'metal_bullet' },\n impact_metal_blunt: { sound: 'metal_blunt' },\n impact_metal_slash: { sound: 'metal_blade' },\n impact_aluminium_ballistic: { sound: 'metal_thin' },\n impact_aluminium_blunt: { sound: 'metal_thin' },\n impact_copper_ballistic: { sound: 'metal_thin' },\n impact_copper_blunt: { sound: 'metal_thin' },\n impact_wood_ballistic: { sound: 'wood_hit' },\n impact_wood_blunt: { sound: 'wood_blunt' },\n impact_wood_slash: { sound: 'wood_blade' },\n impact_mdf_ballistic: { sound: 'mdf_puff' },\n impact_mdf_blunt: { sound: 'mdf_puff', volumeScale: 0.8 },\n impact_glass_ballistic: { sound: 'glass_bullet' },\n impact_glass_blunt: { sound: 'glass_blunt' },\n impact_glass_slash: { sound: 'glass_blade' },\n impact_ceramic: { sound: 'ceramic_hit' },\n impact_ceramic_ballistic: { sound: 'ceramic_bullet' },\n impact_masonry_ballistic: { sound: 'masonry_bullet' },\n impact_masonry_blunt: { sound: 'masonry_blunt' },\n impact_masonry_slash: { sound: 'masonry_blade' },\n impact_plaster: { sound: 'plaster_puff' },\n impact_soil: { sound: 'soil_blunt' },\n impact_soil_ballistic: { sound: 'soil_bullet' },\n impact_sand: { sound: 'sand_hit' },\n impact_gravel: { sound: 'gravel_hit' },\n impact_plastic: { sound: 'plastic_hit' },\n impact_plastic_ballistic: { sound: 'plastic_bullet' },\n impact_rubber: { sound: 'rubber_hit' },\n impact_wax: { sound: 'wax_hit' },\n impact_soft_ballistic: { sound: 'soft_bullet' },\n impact_soft_slash: { sound: 'fabric_rip' },\n impact_paper: { sound: 'paper_hit' },\n impact_paper_slash: { sound: 'paper_tear' },\n impact_plant: { sound: 'leaf_rustle' },\n impact_plant_slash: { sound: 'branch_cut' },\n impact_flesh_fruit: { sound: 'fruit_splat' },\n ricochet_metal: { sound: 'ricochet_metal' },\n ricochet_masonry: { sound: 'ricochet_stone' },\n ricochet_soil: { sound: 'ricochet_stone' },\n ricochet_ceramic: { sound: 'ricochet_stone' },\n break_ceramic: { sound: 'ceramic_break' },\n break_tempered_glass: { sound: 'tempered_burst' },\n break_plastic: { sound: 'plastic_crack' },\n break_mdf: { sound: 'mdf_crumble' },\n break_soft: { sound: 'fabric_rip' },\n break_paper: { sound: 'paper_tear' },\n break_plant: { sound: 'branch_cut' },\n}\n\n/**\n * Every sound a blow, ricochet or break on a material can play (`sound`, `above.sound` and `fallback` of each rule of `rules`): a game preloads them on\n * the first input, so even the first ricochet or impact plays the recording instead of the synthesized recipe while the file is still loading.\n */\nexport const impactSoundIds = (rules: Readonly<Record<string, SoundKeyRule>> = IMPACT_SOUND_KEYS): string[] => {\n const ids = new Set<string>()\n for (const rule of Object.values(rules)) {\n ids.add(rule.sound)\n if (rule.above) ids.add(rule.above.sound)\n if (rule.fallback) ids.add(rule.fallback)\n }\n return [...ids]\n}\n\n/**\n * The keys `createDestructionRenderer` sends to `onSound`, mapped to the sounds the teams delivered. The Cena de Arte has a sound for every material\n * (clang, wood, glass, crumble, thud...); the game has four classes (impact, glass, wood, explosion) and its own explosion thump. Which team sound answers\n * which key is the kit's choice (the teams call the sounds, not the renderer's keys), so it is data: `keys` replaces any entry.\n */\nexport const DESTRUCTION_SOUND_KEYS: Readonly<Record<DestructionSoundStyle, Readonly<Record<string, SoundKeyRule>>>> = {\n art_scene: {\n impact_metal: { sound: 'clang' },\n impact_wood: { sound: 'wood_hit' },\n impact_glass: { sound: 'ping' },\n impact_masonry: { sound: 'chip' },\n impact_soft: { sound: 'thud' },\n // a round strikes: the steel rings high, glass cracks, wood and masonry chip, a soft part takes a dull thunk\n shot_metal: { sound: 'ping' },\n shot_wood: { sound: 'chip' },\n shot_glass: { sound: 'crack' },\n shot_masonry: { sound: 'chip' },\n shot_soft: { sound: 'thunk' },\n drag_wood: { sound: 'drag_wood' },\n drag_metal: { sound: 'drag_metal' },\n drag_glass: { sound: 'drag_glass' },\n drag_masonry: { sound: 'drag_masonry' },\n drag_soft: { sound: 'drag_soft' },\n // a leaf worked by hand (doors, lids, drawers): the latch, the hinge turning, the leaf meeting the frame, a locked one shaken\n leaf_latch: { sound: 'latch' },\n leaf_creak_wood: { sound: 'creak_wood' },\n leaf_creak_metal: { sound: 'creak_metal' },\n leaf_shut_wood: { sound: 'shut_wood' },\n leaf_shut_metal: { sound: 'shut_metal' },\n leaf_shut_glass: { sound: 'shut_metal', volumeScale: 0.6 },\n leaf_shut_masonry: { sound: 'shut_wood' },\n leaf_shut_soft: { sound: 'shut_soft' },\n leaf_rattle: { sound: 'rattle' },\n leaf_slide: { sound: 'slide' },\n // the keys of the item clips (furniture and vehicle doors, hoods, trunks, drawers)\n door_latch: { sound: 'latch' },\n hood_latch: { sound: 'latch' },\n trunk_latch: { sound: 'latch' },\n door_open: { sound: 'latch' },\n door_shut: { sound: 'shut_metal' },\n hood_shut: { sound: 'shut_metal' },\n trunk_shut: { sound: 'shut_metal' },\n door_close: { sound: 'shut_wood', volumeScale: 0.7 },\n // a vehicle's leaves (the vehicle bank of game-vehicles-three): a car door shuts with a padded thump and a latch, not like a fridge\n vehicle_door_open: { sound: 'car_door_open', fallback: 'latch' },\n vehicle_door_shut: { sound: 'car_door_close', fallback: 'shut_metal' },\n vehicle_trunk_open: { sound: 'car_door_open', fallback: 'latch' },\n vehicle_trunk_shut: { sound: 'car_trunk_close', fallback: 'shut_metal' },\n vehicle_hood_open: { sound: 'car_door_open', fallback: 'latch' },\n vehicle_hood_shut: { sound: 'car_hood_close', fallback: 'shut_metal' },\n drawer_open: { sound: 'slide' },\n drawer_close: { sound: 'slide' },\n lid_open: { sound: 'latch' },\n lid_close: { sound: 'shut_soft' },\n flap_open: { sound: 'latch' },\n flap_close: { sound: 'shut_soft' },\n // an item taken in the hand, by what it is made of (game-audio's KIT_SAMPLE_ALIASES puts recordings on these ids)\n grab_metal: { sound: 'grab_hard' },\n grab_wood: { sound: 'grab_hard' },\n grab_glass: { sound: 'grab_hard', volumeScale: 0.7 },\n grab_masonry: { sound: 'grab_hard' },\n grab_soft: { sound: 'grab_soft' },\n shatter_glass: { sound: 'glass_shatter' },\n crumble: { sound: 'crumble' },\n splinter: { sound: 'crack' },\n ricochet: { sound: 'ping' },\n unscrew: { sound: 'chip' },\n detach: { sound: 'thunk' },\n ignite: { sound: 'fire_ignite' },\n primed: { sound: 'gas_leak' },\n extinguish: { sound: 'fire_extinguish' },\n melt_sizzle: { sound: 'hiss', params: { seconds: 0.6 } },\n // the blast family comes from the explosion's effect (`BLAST_KIND_OF`); this rule answers only an explosion the kit cannot place\n explode: { sound: 'explosion_grenade', above: { volume: 0.9, sound: 'explosion_big' } },\n ...IMPACT_SOUND_KEYS,\n },\n game: {\n impact_metal: { sound: 'sfx_impact' },\n impact_wood: { sound: 'sfx_wood' },\n impact_glass: { sound: 'sfx_glass' },\n impact_masonry: { sound: 'sfx_impact' },\n impact_soft: { sound: 'sfx_flesh' },\n shatter_glass: { sound: 'sfx_glass' },\n crumble: { sound: 'sfx_impact' },\n splinter: { sound: 'sfx_wood' },\n explode: { sound: 'explosion_boom' },\n },\n}\n\nexport type DestructionSoundOptions = {\n /** Which team answers the keys (default `art_scene`, the kit mix). `game` falls back to the art scene for the keys the game has no sound for. */\n readonly style?: DestructionSoundStyle\n /** Replaces or adds a key's rule; `null` silences it. A key without a rule that is the id of a registered sound (the foley bank's) plays that sound. */\n readonly keys?: Readonly<Record<string, SoundKeyRule | null>>\n /** The fire loop: the volume each burning part adds and the most it reaches (the page never raises it, so these are the kit's). */\n readonly fire?: { readonly perFire?: number; readonly max?: number }\n /** Burn loop on or off (default on). */\n readonly burnLoop?: boolean\n /** The loop of the wood fire (default `fire_loop`; `burn_loop` is the art scene's bright one). */\n readonly fireLoop?: string\n /** Adds to or changes `FIRE_FUEL_OF`: which fuel a burning material sounds like. */\n readonly fuels?: Readonly<Record<string, FireFuel>>\n /** Adds to or changes `FIRE_LOOP_OF`: the loop of each fuel. */\n readonly fireLoops?: Partial<Readonly<Record<FireFuel, string>>>\n /** The fuel of a fire whose material is not in the table (default `wood`). */\n readonly defaultFuel?: FireFuel\n /** Crackles per second over the fire loop: `base + perSqrtFire × √(parts burning)`, at most `max` (default 2, 3, 14). `false` turns them off. */\n readonly crackles?: false | { readonly base?: number; readonly perSqrtFire?: number; readonly max?: number; readonly volume?: number }\n /** Adds to or changes `BLAST_KIND_OF`: which family a named explosion (`effect`) sounds like. */\n readonly blastKinds?: Readonly<Record<string, BlastKind>>\n /** Metres past which a blast plays `explosion_far` instead of its own sound (default `BLAST_FAR_DISTANCE`). */\n readonly blastFarDistance?: number\n /** `confinement` of a blast (from its report) from which the indoor tail plays too (default 1.3). */\n readonly indoorConfinement?: number\n /** Seed of the crackle timing (default 1). */\n readonly seed?: number\n}\n\nexport type DestructionSound = {\n /** Pass to `createDestructionRenderer({ onSound })`. */\n readonly onSound: (key: string, point: Vec3, volume: number, detail?: SoundDetail) => void\n /** Moves the fire crackles on; call once per frame with the frame time in seconds. */\n update(dt: number): void\n /** The sound an explosion plays (`explode` with its detail), for a listener at the engine's listener position. */\n blastSound(point: Vec3, volume: number, detail?: SoundDetail): string\n /** The rule a key resolves to, if any; with `detail`, the rule `onSound` would play (the first of `detail.keys` that has one, else `key`'s). */\n rule(key: string, detail?: SoundDetail): SoundKeyRule | undefined\n /** Parts burning now. */\n readonly burning: () => number\n /** Parts burning now, by fuel. */\n readonly burningBy: () => Readonly<Partial<Record<FireFuel, number>>>\n /** Puts every fire sound out (the scene was cleared); the engine and the bank stay. */\n reset(): void\n dispose(): void\n}\n\nexport const DEFAULT_FIRE = { perFire: 0.08, max: 0.45 } as const\nexport const DEFAULT_CRACKLES = { base: 2, perSqrtFire: 3, max: 14, volume: 0.5 } as const\nexport const DEFAULT_INDOOR_CONFINEMENT = 1.3\n\n/**\n * Plays the renderer's sound keys on a game-audio engine: the bank is registered in the engine, a key becomes a positional sound at the point, and\n * `burn_loop` / `burn_end` (a part starts to burn, a part burns out or is put out) drive one fire loop whose volume follows how many parts burn, with\n * crackles at the burning points (`update`). An explosion plays the sound of its family (`BLAST_KIND_OF` by its effect), the far rumble past\n * `blastFarDistance` and the indoor tail when the blast was confined.\n */\nexport function createDestructionSound(engine: AudioEngine, options: DestructionSoundOptions = {}): DestructionSound {\n engine.register(DESTRUCTION_SOUND_BANK)\n engine.register(GAME_SFX_BANK)\n // the foley of the hand (doors, lids, drawers, items): its ids are keys of their own, played as they are\n engine.register(FOLEY_BANK)\n const fire = { ...DEFAULT_FIRE, ...options.fire }\n const crackles = options.crackles === false ? null : { ...DEFAULT_CRACKLES, ...options.crackles }\n const fireLoop = options.fireLoop ?? 'fire_loop'\n const kinds: Readonly<Record<string, BlastKind>> = { ...BLAST_KIND_OF, ...options.blastKinds }\n const farDistance = options.blastFarDistance ?? BLAST_FAR_DISTANCE\n const indoorFrom = options.indoorConfinement ?? DEFAULT_INDOOR_CONFINEMENT\n const rules: Record<string, SoundKeyRule | null | undefined> = { ...DESTRUCTION_SOUND_KEYS.art_scene, ...(options.style === 'game' ? DESTRUCTION_SOUND_KEYS.game : {}), ...options.keys }\n // a blast takes its family's sound unless the host chose the explode rule itself (a style or a key of its own)\n const blastByKind = options.style !== 'game' && !(options.keys && 'explode' in options.keys)\n const channel = engine.channel({ seed: options.seed ?? 1 })\n const fuelOf: Readonly<Record<string, FireFuel>> = { ...FIRE_FUEL_OF, ...options.fuels }\n const loopOf: Readonly<Record<FireFuel, string>> = { ...FIRE_LOOP_OF, ...(options.fireLoop ? { wood: fireLoop, fabric: fireLoop } : {}), ...options.fireLoops }\n const defaultFuel = options.defaultFuel ?? 'wood'\n // one loop per sound (fuels that share a loop share its level); a loop stops when nothing of its fuels burns\n const loops = new Map<string, AudioLoopHandle>()\n // where the fires are and what burns there: the crackles come from the points whose fuel crackles\n const fires: { readonly point: Vec3; readonly fuel: FireFuel }[] = []\n let nextCrackle = 0\n\n const fuelFor = (detail: SoundDetail | undefined): FireFuel => detail?.fuel ?? (detail?.material !== undefined ? fuelOf[detail.material] : undefined) ?? defaultFuel\n\n const setFire = (): void => {\n if (options.burnLoop === false) return\n const count = new Map<string, number>()\n for (const f of fires) {\n const id = loopOf[f.fuel]\n count.set(id, (count.get(id) ?? 0) + 1)\n }\n for (const [id, handle] of loops) {\n if (count.has(id)) continue\n handle.stop()\n loops.delete(id)\n }\n for (const [id, n] of count) {\n let handle = loops.get(id)\n if (!handle) {\n handle = engine.loop(id)\n loops.set(id, handle)\n }\n handle.set({ volume: Math.min(fire.max, fire.perFire * n) })\n }\n }\n\n // the nearest fire of that fuel goes out (any fuel when the end does not say)\n const forget = (point: Vec3, fuel: FireFuel | undefined): void => {\n let best = -1\n let bestD = Infinity\n fires.forEach((f, i) => {\n if (fuel !== undefined && f.fuel !== fuel) return\n const d = (f.point[0] - point[0]) ** 2 + (f.point[1] - point[1]) ** 2 + (f.point[2] - point[2]) ** 2\n if (d < bestD) {\n bestD = d\n best = i\n }\n })\n if (best < 0 && fuel !== undefined) forget(point, undefined)\n else if (best >= 0) fires.splice(best, 1)\n }\n\n const reset = (): void => {\n for (const handle of loops.values()) handle.stop()\n loops.clear()\n fires.length = 0\n }\n\n const blastSound = (point: Vec3, volume: number, detail?: SoundDetail): string => {\n const named = detail?.effect === undefined ? undefined : kinds[detail.effect]\n const kind = named ?? ((detail?.radius ?? 0) >= BIG_BLAST_RADIUS || volume >= 0.9 ? 'big' : 'grenade')\n const sound = BLAST_SOUND_OF[kind]\n const distance = engine.plan(sound, { position: point, seed: 1 })?.distance ?? 0\n // a molotov is a fire, not a blast: it never turns into the far rumble\n return kind !== 'molotov' && distance > farDistance ? 'explosion_far' : sound\n }\n\n return {\n onSound(key, point, volume, detail) {\n if (key === 'burn_loop') {\n fires.push({ point, fuel: fuelFor(detail) })\n setFire()\n return\n }\n if (key === 'burn_end') {\n forget(point, detail?.fuel ?? (detail?.material !== undefined ? fuelOf[detail.material] : undefined))\n setFire()\n return\n }\n if (key === 'explode' && blastByKind) {\n const sound = blastSound(point, volume, detail)\n engine.play(sound, { position: point, volume })\n if (sound !== 'explosion_far' && sound !== 'molotov_break_ignite' && (detail?.confinement ?? 1) >= indoorFrom) engine.play('explosion_indoor_tail', { position: point, volume })\n return\n }\n // the most specific key that has a rule (material and blow, material, family and blow, family), else the key itself (a `shot_` key with no rule\n // falls back to its `impact_` one); `null` on a specific key silences it\n let rule: SoundKeyRule | null | undefined\n for (const k of detail?.keys ?? []) {\n if (k in rules) {\n rule = rules[k]\n break\n }\n }\n if (rule === undefined) rule = key in rules ? rules[key] : rules[key.replace(/^shot_/, 'impact_')]\n if (rule === null) return\n if (!rule) {\n // a key with no rule that names a registered sound plays that sound (the foley ids: `door_wood_close`, `item_pickup_metal`...)\n if (engine.registry.sound(key)) engine.play(key, { position: point, volume })\n return\n }\n const wanted = rule.above && volume >= rule.above.volume ? rule.above.sound : rule.sound\n const sound = rule.fallback && !engine.registry.sound(wanted) ? rule.fallback : wanted\n const params = detail?.seconds === undefined ? rule.params : { ...rule.params, seconds: detail.seconds }\n engine.play(sound, { position: point, volume: volume * (rule.volumeScale ?? 1), ...(params ? { params } : {}) })\n },\n update(dt) {\n if (!crackles || fires.length === 0 || options.burnLoop === false) return\n // only the fuels that crackle count: a gas jet or a fuel pool roars without snapping\n const weight = fires.reduce((sum, f) => sum + FIRE_CRACKLE_OF[f.fuel], 0)\n if (weight <= 0) return\n nextCrackle -= dt\n // at most a few crackles per frame, even after a long one\n for (let i = 0; i < 4 && nextCrackle <= 0; i++) {\n const rate = Math.min(crackles.max, crackles.base * Math.min(1, weight) + crackles.perSqrtFire * Math.sqrt(weight))\n nextCrackle += (0.4 + channel.random() * 1.2) / rate\n let pick = channel.random() * weight\n const at = fires.find((f) => (pick -= FIRE_CRACKLE_OF[f.fuel]) <= 0) ?? (fires[fires.length - 1] as (typeof fires)[number])\n engine.play(channel.random() < 0.18 ? 'fire_pop' : 'fire_crackle', { position: at.point, volume: crackles.volume })\n }\n if (nextCrackle < 0) nextCrackle = 0\n },\n blastSound,\n rule(key, detail) {\n for (const k of detail?.keys ?? []) if (k in rules) return rules[k] ?? undefined\n return rules[key] ?? undefined\n },\n burning: () => fires.length,\n burningBy: () => {\n const by: Partial<Record<FireFuel, number>> = {}\n for (const f of fires) by[f.fuel] = (by[f.fuel] ?? 0) + 1\n return by\n },\n reset,\n dispose: reset,\n }\n}\n","// The recorded files of the blasts and the fire (`@adatechnology/game-audio/assets/sfx/explosoes-fogo`, field recordings): the numbers each sound id\n// needs on top of its files. Same ids as the synthesized recipes of `blast-fire.ts`, which stay as the fallback while the files load, when they fail,\n// and for every family that has no recording yet (fuel, pipe bomb, rocket, the indoor tail).\nimport { sampleBankFromManifest } from '@adatechnology/game-audio'\nimport type { SampleDefaults, SampleSound, SfxManifest, SoundBank } from '@adatechnology/game-audio'\nimport { BLAST_FALLOFF, BLAST_FAR_FALLOFF, FIRE_FALLOFF } from './blast-fire'\n\n/** The numbers of one recorded sound, plus whether it loops (the fire's roar). */\nexport type BlastFireSampleDefaults = SampleDefaults & { readonly loop?: boolean | { readonly crossfade?: number } }\n\nconst blast = (gain: number): BlastFireSampleDefaults => ({ bus: 'world', gain, falloff: BLAST_FALLOFF, cutoffK: 0.006, priority: 3 })\nconst fire = (gain: number, group?: string): BlastFireSampleDefaults => ({ bus: 'world', gain, falloff: FIRE_FALLOFF, cutoffK: 0.01, ...(group ? { group } : {}) })\n\n/**\n * The sounds of the blasts and the fire that have recorded takes, with their bus, level and distance curve (the recipes' own curves, so a file and its\n * fallback fade alike with distance). Data: a game passes its own table to `blastFireSampleBank`.\n */\nexport const BLAST_FIRE_SAMPLES: Readonly<Record<string, BlastFireSampleDefaults>> = {\n explosion_grenade: blast(1),\n explosion_big: blast(1),\n explosion_car: blast(1),\n explosion_flashbang: blast(1),\n molotov_break_ignite: blast(0.8),\n // the far takes are already muffled: no extra distance lowpass\n explosion_far: { bus: 'world', gain: 1, falloff: BLAST_FAR_FALLOFF, cutoffK: 0, priority: 2 },\n fire_ignite: fire(0.8, 'fire_ignite'),\n fire_crackle: fire(0.8, 'fire_crackle'),\n fire_pop: fire(0.6, 'fire_crackle'),\n fire_extinguish: fire(0.7),\n gas_leak: fire(0.5),\n // the roar: recorded fires chained with a crossfade (the level comes from `createDestructionSound`, by how much burns)\n fire_loop: { bus: 'world', gain: 4, loop: { crossfade: 1 } },\n // each fuel has its own roar: a gas jet (burners and torches), a pool of fuel, plastic and rubber sizzling under the flames\n fire_loop_gas: { bus: 'world', gain: 6, loop: { crossfade: 1 } },\n fire_loop_liquid: { bus: 'world', gain: 3.5, loop: { crossfade: 1 } },\n fire_loop_plastic: { bus: 'world', gain: 1, loop: { crossfade: 0.6 } },\n}\n\nexport type BlastFireSampleBankOptions = {\n /** Bank id (default 'destruction-samples'). */\n readonly id?: string\n /** Where the manifest's folder is served (`/sfx/`); default ''. */\n readonly baseUrl?: string\n /** Numbers per id (default `BLAST_FIRE_SAMPLES`). */\n readonly sounds?: Readonly<Record<string, BlastFireSampleDefaults>>\n}\n\n/**\n * A bank of the recorded blasts and fire from the kit's sound manifest. Register it with the engine next to `DESTRUCTION_SOUND_BANK`: each id plays\n * its files once loaded and its synthesized recipe until then.\n */\nexport function blastFireSampleBank(manifest: SfxManifest, options: BlastFireSampleBankOptions = {}): SoundBank {\n const sounds = options.sounds ?? BLAST_FIRE_SAMPLES\n const bank = sampleBankFromManifest(manifest, { id: options.id ?? 'destruction-samples', ...(options.baseUrl === undefined ? {} : { baseUrl: options.baseUrl }), sounds })\n const samples: SampleSound[] = (bank.samples ?? []).map((sample) => {\n const loop = sounds[sample.id]?.loop\n return loop === undefined ? sample : { ...sample, loop }\n })\n return { ...bank, samples }\n}\n"],"mappings":"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","names":["glass","scene","SUPPORT_CHECKS","SUPPORT_GAP","impact","scene","geo","noise","materialsOf","tone","fire","many","noise","sceneRecipe","tone","sceneRecipe","noise","tone","many","fire","sound","blast"]}
1
+ {"version":3,"sources":["../src/audio/impact-keys.ts","../src/renderer.ts","../src/fragments.ts","../src/fitted-boxes.ts","../src/math.ts","../src/fragment-shapes.ts","../src/ground.ts","../src/pieces.ts","../src/rebar.ts","../src/spec.ts","../src/heat.ts","../src/skin-dent.ts","../src/visual.ts","../src/audio/recipes.ts","../src/audio/blast-fire.ts","../src/audio/sound.ts","../src/audio/samples.ts"],"sourcesContent":["import type { DamageType, MaterialDef } from '@adatechnology/game-destruction'\n\nimport type { SoundDetail } from '../types'\n\n/**\n * The sound family of a material, from its tags: what it sounds like when something meets it. Finer than the five keys of `impactKey` (which stay the\n * last fallback): ceramic is not glass, the ground is not concrete, plastic and wax are not wood, leaves are not a sofa.\n */\nexport type ImpactFamily = 'metal' | 'glass' | 'ceramic' | 'soil' | 'masonry' | 'wood' | 'plant' | 'plastic' | 'rubber' | 'wax' | 'soft'\n\n/** Tag → family, in the order they are tried (`green_wood` is `plant` and `wood`: wood wins; `gravel` is `soil` and `masonry`: soil wins). */\nexport const IMPACT_FAMILY_TAGS: readonly (readonly [tag: string, family: ImpactFamily])[] = [\n ['metal', 'metal'],\n ['glass', 'glass'],\n ['ceramic', 'ceramic'],\n ['soil', 'soil'],\n ['masonry', 'masonry'],\n ['wood', 'wood'],\n ['plant', 'plant'],\n ['plastic', 'plastic'],\n ['rubber', 'rubber'],\n ['wax', 'wax'],\n ['fabric', 'soft'],\n]\n\n/** The family of a material, or `undefined` when none of its tags names one (the five legacy keys of `impactKey` then answer). */\nexport function impactFamily(def: MaterialDef | undefined): ImpactFamily | undefined {\n const tags = def?.tags ?? []\n for (const [tag, family] of IMPACT_FAMILY_TAGS) if (tags.includes(tag)) return family\n return undefined\n}\n\n/** What an impact or a break sends with its key: the keys to try before it, most specific first (material and blow, material, family and blow, family). */\nexport type ImpactKeys = SoundDetail & { readonly keys: readonly string[] }\n\nconst ordered = (prefix: string, material: string, family: ImpactFamily | undefined, blow: DamageType | undefined): string[] => {\n const keys: string[] = []\n if (material && blow) keys.push(`${prefix}_${material}_${blow}`)\n if (material) keys.push(`${prefix}_${material}`)\n if (family && blow) keys.push(`${prefix}_${family}_${blow}`)\n if (family) keys.push(`${prefix}_${family}`)\n return keys\n}\n\n/**\n * The impact keys for a blow on a material, most specific first: `impact_<material>_<blow>`, `impact_<material>`, `impact_<family>_<blow>`,\n * `impact_<family>` (blow is the `DamageType`: `ballistic`, `blunt`, `slash`, `explosive`...). The legacy `impactKey` is the last fallback the caller sends as the key.\n */\nexport function impactSoundKeys(material: string, def: MaterialDef | undefined, blow?: DamageType): ImpactKeys {\n return { keys: ordered('impact', material, impactFamily(def), blow) }\n}\n\n/** The keys for a part of this material breaking, most specific first: `break_<material>_<blow>`, `break_<material>`, `break_<family>_<blow>`, `break_<family>`. */\nexport function breakSoundKeys(material: string, def: MaterialDef | undefined, blow?: DamageType): ImpactKeys {\n return { keys: ordered('break', material, impactFamily(def), blow) }\n}\n\n/** The keys for a round glancing off a part of this material: `ricochet_<material>`, `ricochet_<family>` (then the plain `ricochet`). */\nexport function ricochetSoundKeys(material: string, def: MaterialDef | undefined): ImpactKeys {\n return { keys: ordered('ricochet', material, impactFamily(def), undefined) }\n}\n","import type * as THREE_NS from 'three'\nimport type { DamageType, DebrisKind, DestructionEvent, DestructionEventType, Fragment, MaterialDef, PartSpec, Vec3 } from '@adatechnology/game-destruction'\nimport { breakSoundKeys, impactSoundKeys, ricochetSoundKeys } from './audio/impact-keys'\nimport { DEFERRED_QUEUE_ID, blastShove, warnOnce } from '@adatechnology/game-contracts'\nimport { createVfx, effectForEvent, EVENT_EFFECTS_MAP } from '@adatechnology/game-vfx'\nimport type { GameEvent } from '@adatechnology/game-vfx'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport { createVfxRenderer } from '@adatechnology/game-vfx-three'\nimport type { VfxRenderer } from '@adatechnology/game-vfx-three'\nimport { FragmentSystem } from './fragments'\nimport { GroundSpots } from './ground'\nimport type { Bound, HostVis, MeshVis, PartVis, PieceBody } from './internal'\nimport { clamp, createRng, hashNumbers, hashString, mixHex } from './math'\nimport { PieceSystem } from './pieces'\nimport type { PieceSweepHit } from './pieces'\nimport { RebarCages } from './rebar'\nimport { partHintOf, specFrameInverse } from './spec'\nimport { kitOriginOf } from '@adatechnology/game-contracts'\nimport type { DeferredQueue, WarmUpProbes } from '@adatechnology/game-contracts'\nimport type { DestructionRenderer, BindOptions, ExplodeOptions, Mesh, MeshRange, Object3D, Piece, RendererOptions, SolidBox, SoundDetail, ThreeNamespace } from './types'\nimport { showCollapsedRanges, Visuals } from './visual'\n\nlet rendererCount = 0\n/** Mass (kg) a collapse of furniture must bring down to raise the collapse effect's cloud; less (a shelf with its books) raises a puff of dust. */\nconst COLLAPSE_CLOUD_KG = 1000\n/** Colour of bare rebar (the cages' material) and of a bar that came down; the steel of a bar weighs this much per cubic metre when the catalogue has no steel. */\nconst REBAR_COLOR = 0x74665c\nconst STEEL_DENSITY = 7850\n/** Metres around a unit that came out within which its decals go too: the plaster over it and the ragged edge that breaks with it. */\nconst CHIP_DECAL_EDGE = 0.05\n/** Radius of the rim of torn fibres around a hole in wood, in hole diameters. */\nconst WOOD_RIM = 1.5\nconst IMPACT_TAGS = ['metal', 'glass', 'wood'] as const\n\ntype Ev<T extends DestructionEvent['type']> = Extract<DestructionEvent, { type: T }>\n\nconst GLOW_FROM_C = 430\nconst QUEUE_CAP = 4000\n/** Seconds the grit of a broken hard face keeps falling (least, most), how often a pinch of it at first, and how many places at once. */\nconst TRICKLE_SECONDS: readonly [number, number] = [2, 5]\nconst TRICKLE_EVERY = 0.25\nconst TRICKLE_MAX = 24\n/**\n * Events the queue takes past `QUEUE_CAP`: what changes what is drawn (a part breaking off, a storey coming down, a fire starting or going out). A blast\n * floods the queue with damage, melt and drip events; dropping a collapse behind them leaves a fallen wall drawn standing.\n */\nconst STRUCTURAL_EVENTS: ReadonlySet<DestructionEventType> = new Set<DestructionEventType>([\n 'fracture', 'detach', 'collapse', 'settle', 'destroyed', 'expose', 'stage', 'hole', 'ignite', 'primed', 'extinguish', 'burnout', 'leak', 'explode',\n])\n/** Fragments of a fracture spawned in one go before the frame budget is looked at, so a small break is never split over frames. */\nconst MIN_FRAGMENTS_PER_SLICE = 8\n/** Seconds the boxes of the fixed objects the pieces land on are kept without an event (a host may move a root). */\nconst STATIC_REFRESH = 0.5\n/**\n * Milliseconds of the periodic re-measure per call: the refresh walks the objects a slice at a time (the dirty ones are measured at once).\n * Measuring every object in one call cost up to 88 ms in a frame of the horde chain (perf.mjs, software GL, 2026-11-03).\n */\nconst STATIC_REFRESH_SLICE_MS = 1\n/** Widest mesh (m, along x or z) a piece lands on by its box: furniture and things; a wider one (a roof, a merged room) would hold it on air. */\nconst STATIC_SPAN = 3\n/** What counts as a foot of a piece (m above its lowest point); from what height (m) it can fall over and how close its feet are for that (share of the height). */\nconst FEET_BAND = 0.03\nconst TIP_MIN_HEIGHT = 0.3\nconst TIP_NARROW = 0.3\n/** Most meshes a loose piece of furniture touches the ground by, each by its own corners (`setContacts`); one with more stands on its box. */\nconst CONTACT_MESHES = 12\n/** How far (m) over its support what is left of a broken object may be and still stand; where under its lowest boxes the support is looked for (shares of the box). */\nconst BROKEN_GAP = 0.03\nconst BROKEN_SAMPLES: ReadonlyArray<readonly [number, number]> = [[0.5, 0.5], [0.1, 0.1], [0.9, 0.1], [0.1, 0.9], [0.9, 0.9]]\n/** Kinds of object that answer to a load path of their own (a house, a wall, the ground), not to `checkBroken`. */\nconst UNCHECKED_KINDS: ReadonlySet<string> = new Set(['structure', 'room', 'ground'])\n/** A part's fire lasts until the part stops burning (`stopFire`); this is only the ceiling the effects world needs. */\nconst FIRE_CEILING_SECONDS = 3600\n/** The `generic` explosion is the M67's (15 m injury radius): a blast with no effect id of its own scales with its radius. */\nconst GENERIC_REFERENCE_RADIUS = 15\n/** Largest half size (m) of the core of a piece swept for what it runs into: a sofa sweeps a small box at its centre, not the whole of it. */\nconst SWEEP_CORE = 0.15\n/** The small flame of a part that a bullet or fire primed: it burns until the part goes off. */\nconst PRIMED_FIRE_RADIUS = 0.2\n\ninterface FireEmitter {\n object: string\n part: string\n point: Vec3\n /** The burning part's position, moved every frame; the effects world's fire follows it. */\n follow: { x: number; y: number; z: number }\n /** Handle of the fire in the effects world, once the part's box is known. */\n handle?: number\n}\n\ninterface Leak {\n object: string\n part: string\n fluid: string\n point: Vec3\n direction: Vec3\n rate: number\n pressurized: boolean\n acc: number\n /** The part had a through opening when the leak began: the leak ends when it has none (a valve shut with `seal`). */\n opened: boolean\n localPoint?: Vec3\n localDirection?: Vec3\n lastLiters?: number\n idleSeconds?: number\n life?: number\n}\n\nconst FLUID_COLORS: Record<string, number> = {\n water: 0x8cc8ff,\n fuel: 0xd9a032,\n oil: 0x2a2018,\n gas: 0xf2f2f2,\n sap: 0xb89b3a,\n acid: 0x9bd23c,\n blood: 0x8a0a0a,\n soda: 0x3a1e12,\n coffee: 0x3b2414,\n beer: 0xd9953c,\n milk: 0xf4f1ea,\n wine: 0x6b101f,\n juice: 0xe8870b,\n}\nconst SMOKE_TONES: Record<string, number> = { white: 0xe6e6e6, grey: 0x8a8a8a, black: 0x2a2a2a }\n\nconst DEFAULT_SPEED: Record<string, number> = {\n sparks: 3,\n splinters: 2.5,\n dust: 1,\n shards: 2.5,\n fibers: 1.2,\n leaves: 1.2,\n drips: 0.5,\n ash: 0.8,\n chips: 2.5,\n smoke: 0.8,\n steam: 1,\n fire: 1.2,\n flash: 0,\n foam: 2.5,\n}\n\n/** Sound key for an impact on a material. */\nexport function impactKey(def: MaterialDef | undefined): string {\n if (!def) return 'impact_wood'\n const tags = def.tags ?? []\n if (tags.includes('metal')) return 'impact_metal'\n if (def.visual?.transparent || def.fracture === 'shatter') return 'impact_glass'\n if (def.fracture === 'crumble') return 'impact_masonry'\n if (def.fracture === 'tear') return 'impact_soft'\n return def.fracture === 'none' ? 'impact_metal' : 'impact_wood'\n}\n\n/** Sound key (`shot_*`) of a round striking this material: sharper than a blow (a tink on steel, a crack on glass); a host without it plays the `impact_*`. */\nexport const shotKey = (def: MaterialDef | undefined): string => impactKey(def).replace('impact_', 'shot_')\n\n/** Sound key (`drag_*`) of a base of this material dragged on a floor. */\nexport const dragSoundKey = (def: MaterialDef | undefined): string => impactKey(def).replace('impact_', 'drag_')\n\nfunction fractureKey(def: MaterialDef | undefined, style: string): string {\n switch (style) {\n case 'shatter':\n return 'shatter_glass'\n case 'crumble':\n return 'crumble'\n case 'splinter':\n return 'splinter'\n default:\n return impactKey(def)\n }\n}\n\nfunction fallbackColor(id: string, def: MaterialDef | undefined): number {\n if (def?.tags?.includes('metal')) return 0x8a8f96\n if (def?.visual?.transparent) return 0x9fd0e0\n const h = hashString(id)\n return mixHex(0x6b5a48, 0x9a9488, (h % 100) / 100)\n}\n\nfunction materialsOf(m: THREE_NS.Material | THREE_NS.Material[]): THREE_NS.Material[] {\n return Array.isArray(m) ? m : [m]\n}\n\nfunction isMeshRange(v: Object3D | MeshRange): v is MeshRange {\n const r = v as Partial<MeshRange>\n return !!r.mesh && Array.isArray(r.range)\n}\n\n/** Create the renderer. See `DestructionRenderer`. */\n/** The seed of the renderer's random stream; `reset` takes it back here. */\nconst RNG_SEED = 0xc0ffee\n\n/** The renderer this package makes always has its `deferredQueue`; a third-party `DestructionRenderer` may leave it out. */\nexport function createDestructionRenderer(THREE: ThreeNamespace, options: RendererOptions): DestructionRenderer & { deferredQueue(): DeferredQueue } {\n return new Renderer(THREE, options)\n}\n\nclass Renderer implements DestructionRenderer {\n private readonly world: RendererOptions['world']\n private readonly scene: THREE_NS.Scene\n private readonly quality: 'low' | 'medium' | 'high'\n private readonly low: boolean\n private readonly groundAt: (x: number, z: number) => number\n private readonly gravity: number\n private readonly autoSplit: boolean\n private readonly maxFragments: number\n private readonly eventBudgetMs: number\n private readonly bounds = new Map<string, Bound>()\n /** World boxes (min xyz, max xyz) of the drawn meshes of the bound objects that are not pieces, for the pieces to land on. */\n private readonly staticBoxes = new Map<string, number[]>()\n /** Objects to measure again; `staticAll` measures every one. */\n private readonly staticDirty = new Set<string>()\n private staticAll = true\n /** The periodic refresh: the objects still to measure again in this round, a slice per call. */\n private staticRound: string[] = []\n /** Boxes of the pieces' meshes (as `staticBoxes`), with the time they were measured. */\n private readonly pieceBoxes = new WeakMap<PieceBody, { at: number; boxes: number[] }>()\n /** Objects broken since the last update: `checkBroken` looks at what is left of them. */\n private readonly broken = new Set<string>()\n private staticAt = 0\n private readonly queue: DestructionEvent[] = []\n /** The cover of each body around a part of the world that went off, read as the event is emitted: before the blast tore or moved anything. */\n private readonly coverWhenWentOff = new WeakMap<DestructionEvent, Map<string, number>>()\n /** Places a blow broke a hard face at: grit and dust keep coming off them for a few seconds, less and less (`TRICKLE_SECONDS`). */\n private readonly trickles: Array<{ point: Vec3; normal: Vec3; color: number | undefined; left: number; total: number; next: number }> = []\n /** Presentation work an event left for later frames (fragments still to spawn, loose groups still to split), run in order within the frame budget. */\n private readonly slices: Array<() => void> = []\n /** When the work of this frame must stop; `Infinity` outside a drain, where a call finishes what it started. */\n private sliceDeadline = Infinity\n /** The clock the drain reads; a budget lends its own while it runs the queue. */\n private drainClock: () => number = () => performance.now()\n /** true once a frame budget owns the draining: `update` no longer drains by itself. */\n private attached = false\n private readonly eventQueue: DeferredQueue = {\n id: DEFERRED_QUEUE_ID.DESTRUCTION_EVENTS,\n pending: () => this.queue.length + this.slices.length,\n run: (deadline, clock) => this.runBudgeted(deadline, clock),\n flush: () => {\n for (let guard = 0; guard < 16 && this.queue.length + this.slices.length > 0; guard++) this.runBudgeted(Infinity, () => 0)\n },\n attach: () => {\n this.attached = true\n },\n detach: () => {\n this.attached = false\n },\n }\n private readonly unsubscribe: () => void\n private readonly visuals: Visuals\n private readonly fragments: FragmentSystem\n private readonly ground: GroundSpots\n private readonly pieceSys: PieceSystem\n private readonly cages: RebarCages\n private readonly active = new Map<string, { object: string; part: string }>()\n private readonly fires = new Map<string, FireEmitter>()\n /** Primed parts burning in the effects world until they go off: their burn loop ends when they are put out. */\n private readonly primedBurning = new Set<string>()\n private readonly leaks: Leak[] = []\n private readonly homeTags: string[] = []\n private readonly throttles = new Map<string, number>()\n private rng = createRng(RNG_SEED)\n private readonly vfx: VfxWorld\n /** Names this renderer to the world's drips, so a shared world tells each renderer where its own landed. */\n private readonly owner = `destruction-${++rendererCount}`\n private readonly stopLanding: () => void\n /** The effects renderer made here when the host gave no shared world; it is stepped in `update`. */\n private readonly ownVfx: VfxRenderer | undefined\n private time = 0\n private scanTimer = 0\n private disposed = false\n private readonly box: THREE_NS.Box3\n private readonly tmpQ: THREE_NS.Quaternion\n private readonly v1: THREE_NS.Vector3\n private readonly v2: THREE_NS.Vector3\n\n constructor(\n private readonly THREE: ThreeNamespace,\n private readonly o: RendererOptions,\n ) {\n this.world = o.world\n this.scene = o.scene\n this.quality = o.quality ?? 'medium'\n this.low = this.quality === 'low'\n this.groundAt = o.groundAt ?? (() => 0)\n this.gravity = o.gravity ?? 9.81\n this.autoSplit = o.autoSplit !== false\n this.maxFragments = o.maxFragments ?? 160\n this.eventBudgetMs = o.eventBudgetMs ?? Infinity\n this.box = new THREE.Box3()\n this.tmpQ = new THREE.Quaternion()\n this.v1 = new THREE.Vector3()\n this.v2 = new THREE.Vector3()\n const maxParticles = Math.max(8, Math.floor((o.maxParticles ?? 2500) * (this.low ? 0.5 : 1)))\n this.visuals = new Visuals(THREE, this.low, 600)\n this.ground = new GroundSpots(THREE, o.scene, this.groundAt, 48)\n if (!o.vfx) warnOnce('game-destruction-three.own-effects-world', 'game-destruction-three made an effects world of its own because the host lent none (options.vfx); pass the host effects so the effects share one budget')\n this.vfx = o.vfx ?? createVfx({ profile: this.quality, gravity: this.gravity, groundAt: this.groundAt, sprites: { capacity: maxParticles, density: this.low ? 0.6 : 1 } })\n this.ownVfx = o.vfx ? undefined : createVfxRenderer(THREE, { scene: o.scene, camera: o.camera ?? new THREE.PerspectiveCamera(), vfx: this.vfx, pointScale: o.pointScale ?? 700 })\n this.stopLanding = this.vfx.onLand(this.owner, (x, _y, z, color, tag) => {\n const home = this.homeTags[tag - 1] ?? ''\n this.ground.add('puddle', x, z, 0.05 + this.rng() * 0.04, color, home)\n })\n this.fragments = new FragmentSystem(THREE, {\n scene: o.scene,\n groundAt: this.groundAt,\n gravity: this.gravity,\n max: this.maxFragments,\n life: o.fragmentLife ?? 12,\n formOf: (id) => this.world.materials.get(id)?.splitForm,\n })\n this.cages = new RebarCages(THREE, o.scene)\n this.pieceSys = new PieceSystem(THREE, {\n groundAt: this.groundAt,\n staticTopAt: (x, z, y, step) => this.staticTopAt(x, z, y, step),\n gravity: this.gravity,\n scene: o.scene,\n onHardLanding: (p, point, speed) => this.hardLanding(p, point, speed),\n sweep: (p, from, to) => this.sweepPiece(p, from, to),\n onSlam: (p, hit, speed) => this.slam(p, hit, speed),\n })\n this.unsubscribe = this.world.on('*', (ev) => {\n if (ev.type === 'explode') this.coverWhenWentOff.set(ev, this.coverAround(ev))\n if (this.queue.length < QUEUE_CAP || STRUCTURAL_EVENTS.has(ev.type)) this.queue.push(ev)\n })\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Binding\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n bind(objectId: string, root: Object3D, options: BindOptions = {}): void {\n this.staticDirty.add(objectId)\n if (this.bounds.has(objectId)) this.unbind(objectId)\n const state = this.world.state(objectId)\n const partIds = new Set((state?.parts ?? []).map((p) => p.id))\n const byPart = new Map<string, Array<{ mesh: Mesh; range?: [number, number] }>>()\n const taken = new Set<Mesh>()\n const put = (pid: string, e: { mesh: Mesh; range?: [number, number] }): void => {\n const l = byPart.get(pid)\n if (l) l.push(e)\n else byPart.set(pid, [e])\n }\n const add = (pid: string, m: Mesh): void => {\n if (taken.has(m)) return\n taken.add(m)\n put(pid, { mesh: m })\n }\n const addRange = (pid: string, r: MeshRange): void => {\n const n = (r.mesh.geometry.getAttribute('position')?.count ?? 0) as number\n const [v0, v1] = r.range\n if (!Number.isInteger(v0) || !Number.isInteger(v1) || v0 < 0 || v1 <= v0 || v1 > n) {\n throw new Error(`game-destruction-three: invalid vertex range [${v0}, ${v1}) for part \"${pid}\" (the mesh has ${n} vertices)`)\n }\n put(pid, { mesh: r.mesh, range: [v0, v1] })\n }\n const meshesIn = (o: Object3D): Mesh[] => {\n const out: Mesh[] = []\n o.traverse((c) => {\n if ((c as Mesh).isMesh) out.push(c as Mesh)\n })\n return out\n }\n if (options.parts) {\n for (const [pid, v] of Object.entries(options.parts)) {\n for (const o of Array.isArray(v) ? v : [v]) {\n if (isMeshRange(o)) addRange(pid, o)\n else for (const m of meshesIn(o)) add(pid, m)\n }\n }\n } else {\n const leftovers: Mesh[] = []\n for (const m of meshesIn(root)) {\n const ud = partHintOf(m.userData?.destructionPart)?.id\n if (ud !== undefined && partIds.has(ud)) add(ud, m)\n else if (partIds.has(m.name)) add(m.name, m)\n else leftovers.push(m)\n }\n if (leftovers.length) this.matchByBox(objectId, root, leftovers, add)\n }\n const bound: Bound = { id: objectId, root, sync: options.syncTransform !== false, parts: new Map(), lastPos: null, lastQuat: null, piece: null, isSplit: false }\n if (options.onFrame) bound.onFrame = options.onFrame\n const hosts = new Map<Mesh, HostVis>()\n for (const pid of partIds) bound.parts.set(pid, this.makePartVis(objectId, pid, state?.parts.find((p) => p.id === pid)?.material ?? '', byPart.get(pid) ?? [], hosts))\n for (const [pid, meshes] of byPart) {\n if (!bound.parts.has(pid)) bound.parts.set(pid, this.makePartVis(objectId, pid, this.world.part(objectId, pid)?.material ?? '', meshes, hosts))\n }\n this.bounds.set(objectId, bound)\n for (const pv of bound.parts.values()) this.tagPart(pv, objectId)\n }\n\n /**\n * Label the meshes of a part so a host can go from a raycast hit to the world: `userData.destructionPart` (the part id) and\n * `userData.destructionObject` (the id of the world object that part belongs to now; a loose piece has an id of its own). Parts drawn by a range\n * of a merged mesh share that mesh with others and are left alone until they get a mesh of their own. Decals are marked `destructionDebris`.\n */\n private tagPart(pv: PartVis, objectId: string): void {\n for (const mv of pv.meshes) {\n if (mv.merged && !mv.loose) continue\n mv.mesh.traverse((c) => {\n if (!(c as Mesh).isMesh) return\n const ud = c.userData as Record<string, unknown>\n if (ud.destructionDebris) return\n if (partHintOf(ud.destructionPart)?.id !== pv.id) ud.destructionPart = pv.id\n ud.destructionObject = objectId\n })\n }\n }\n\n private makePartVis(home: string, id: string, material: string, meshes: Array<{ mesh: Mesh; range?: [number, number] }>, hosts: Map<Mesh, HostVis>): PartVis {\n return { id, home, material, meshes: meshes.map((m) => this.visuals.makeMeshVis(m.mesh, home, m.range, hosts)), charApplied: 0, glowApplied: 0, meltApplied: 0, gone: 'none' }\n }\n\n /** Match unlabelled meshes to the part whose shape contains the centre of the mesh's bounding box. */\n private matchByBox(objectId: string, root: Object3D, meshes: Mesh[], add: (pid: string, m: Mesh) => void): void {\n let specParts: PartSpec[] | undefined\n try {\n specParts = this.world.serialize?.().objects.find((o) => o.id === objectId)?.spec.parts\n } catch {\n specParts = undefined\n }\n if (!specParts) return\n const frame = specFrameInverse(this.THREE, root)\n const e = new this.THREE.Euler()\n const q = new this.THREE.Quaternion()\n for (const m of meshes) {\n this.box.setFromObject(m)\n if (this.box.isEmpty()) continue\n const c = this.box.getCenter(this.v1).applyMatrix4(frame)\n let best: PartSpec | null = null\n let bestVol = Infinity\n for (const p of specParts) {\n const l = this.v2.set(c.x - p.position[0], c.y - p.position[1], c.z - p.position[2])\n if (p.rotation) l.applyQuaternion(q.setFromEuler(e.set(p.rotation[0], p.rotation[1], p.rotation[2], 'XYZ')).invert())\n let inside = false\n let vol = 0\n const s = p.shape\n if (s.kind === 'box') {\n inside = Math.abs(l.x) <= s.size[0] / 2 && Math.abs(l.y) <= s.size[1] / 2 && Math.abs(l.z) <= s.size[2] / 2\n vol = s.size[0] * s.size[1] * s.size[2]\n } else if (s.kind === 'cylinder') {\n inside = Math.hypot(l.x, l.z) <= s.radius && Math.abs(l.y) <= s.height / 2\n vol = Math.PI * s.radius * s.radius * s.height\n } else {\n inside = l.length() <= s.radius\n vol = (4 / 3) * Math.PI * s.radius ** 3\n }\n if (inside && vol < bestVol) {\n best = p\n bestVol = vol\n }\n }\n if (best) add(best.id, m)\n }\n }\n\n unbind(objectId: string): void {\n this.staticDirty.add(objectId)\n const b = this.bounds.get(objectId)\n if (!b) return\n this.restore(objectId)\n this.pieceSys.remove(objectId)\n this.bounds.delete(objectId)\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Pieces\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n /** Half extents and centre of the box around some meshes, in the metric frame of `root` (its pose removed, its scale kept). */\n private measure(root: Object3D, meshes: MeshVis[]): { half: Vec3; center: THREE_NS.Vector3 } {\n const inv = specFrameInverse(this.THREE, root)\n const total = new this.THREE.Box3()\n const m4 = new this.THREE.Matrix4()\n const lb = new this.THREE.Box3()\n for (const mv of meshes) {\n const m = mv.mesh\n m.updateWorldMatrix(true, false)\n this.visuals.localBox(mv, lb)\n if (lb.isEmpty()) continue\n total.union(lb.clone().applyMatrix4(m4.multiplyMatrices(inv, m.matrixWorld)))\n }\n if (total.isEmpty()) return { half: [0.25, 0.25, 0.25], center: new this.THREE.Vector3() }\n const size = total.getSize(new this.THREE.Vector3())\n return { half: [Math.max(0.02, size.x / 2), Math.max(0.02, size.y / 2), Math.max(0.02, size.z / 2)], center: total.getCenter(new this.THREE.Vector3()) }\n }\n\n private meshesOf(b: Bound): MeshVis[] {\n const out: MeshVis[] = []\n for (const pv of b.parts.values()) if (pv.gone === 'none') for (const mv of pv.meshes) out.push(mv)\n return out\n }\n\n private massOf(objectId: string): number {\n const st = this.world.state(objectId)\n if (!st) return 5\n let m = 0\n for (const p of st.parts) if (p.status !== 'broken' && p.status !== 'melted' && p.status !== 'ashes') m += p.mass\n return m > 0 ? m : 5\n }\n\n makePiece(objectId: string, options: { mass?: number; velocity?: Vec3 } = {}): Piece {\n this.staticDirty.add(objectId)\n const b = this.bounds.get(objectId)\n if (!b) throw new Error(`game-destruction-three: object \"${objectId}\" is not bound`)\n if (b.root.parent && b.root.parent !== this.scene) this.scene.attach(b.root)\n const { half, center } = this.measure(b.root, this.meshesOf(b))\n const piece = this.pieceSys.create(objectId, b.root, half, center, options.mass ?? this.massOf(objectId), options.velocity)\n b.piece = piece\n return piece\n }\n\n pieces(): Piece[] {\n return [...this.pieceSys.list]\n }\n\n piece(objectId: string): Piece | null {\n return this.pieceSys.get(objectId)\n }\n\n impulse(objectId: string, impulse: Vec3, point?: Vec3): void {\n const p = this.pieceSys.get(objectId)\n if (p) this.pieceSys.impulse(p, impulse, point)\n }\n\n /**\n * What a piece moving from `from` to `to` runs into: the core of its box (its thinnest half each way, at most `SWEEP_CORE`) swept through the world, the piece itself left out,\n * so a crate thrown by a blast stops at the wall instead of passing through it. Null for a world that cannot sweep.\n */\n private sweepPiece(p: PieceBody, from: Vec3, to: Vec3): PieceSweepHit | null {\n if (typeof this.world.sweepBox !== 'function') return null\n const d: Vec3 = [to[0] - from[0], to[1] - from[1], to[2] - from[2]]\n const travel = Math.hypot(d[0], d[1], d[2])\n if (travel < 1e-4) return null\n const core = Math.min(SWEEP_CORE, ...p.halfExtents)\n const box = { min: [from[0] - core, from[1] - core, from[2] - core] as Vec3, max: [from[0] + core, from[1] + core, from[2] + core] as Vec3 }\n const hit = this.world.sweepBox(box, d, travel, { ignore: p.objectId, spacing: Math.max(0.05, core) })\n if (!hit) return null\n return { object: hit.object, part: hit.part, distance: hit.distance, point: hit.point, normal: hit.normal }\n }\n\n /** A piece thrown into a wall: the wall takes the blow of its weight where it met it, the piece takes it too, and each sounds as its material does. */\n private slam(p: PieceBody, hit: PieceSweepHit, speed: number): void {\n const energy = 0.5 * p.mass * speed * speed\n const direction: Vec3 = [-hit.normal[0], -hit.normal[1], -hit.normal[2]]\n this.landingSound(hit.object, hit.point, clamp(speed / 10, 0.2, 1))\n this.syncBound(p.objectId)\n try {\n this.world.hitPart(hit.object, hit.part, { type: 'blunt', point: hit.point, energy, radius: 0.1, direction, normal: hit.normal, source: p.objectId })\n this.world.hit(p.objectId, { type: 'blunt', point: hit.point, energy, radius: 0.08, direction: hit.normal, source: 'slam' })\n } catch {\n // either may have left the world\n }\n }\n\n private hardLanding(p: PieceBody, point: Vec3, speed: number): void {\n this.landingSound(p.objectId, point, clamp(speed / 10, 0.2, 1))\n // the piece just moved this frame: the world must know where it is before the hit is resolved against its parts\n this.syncBound(p.objectId)\n try {\n this.world.hit(p.objectId, { type: 'blunt', point, energy: 0.5 * p.mass * speed * speed, radius: 0.08, direction: [0, -1, 0], source: 'fall' })\n } catch {\n // the object may have been removed from the world\n }\n }\n\n /** The impact of the heaviest part of an object (a piece landing): its material and the blunt blow of the fall. */\n private landingSound(objectId: string, point: Vec3, volume: number): void {\n const st = this.world.state(objectId)\n let best = ''\n let mass = -1\n for (const p of st?.parts ?? []) {\n if (p.mass > mass) {\n mass = p.mass\n best = p.material\n }\n }\n this.impactSound(best, point, volume, 'blunt')\n }\n\n /** The impact on a material by a blow: the legacy family key (`impactKey`) with the more specific keys to try first (`impactSoundKeys`). */\n private impactSound(material: string, point: Vec3, volume: number, blow?: DamageType): void {\n const def = this.world.materials.get(material)\n this.sound(impactKey(def), point, volume, impactSoundKeys(material, def, blow))\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Update\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n update(dt: number): void {\n if (this.disposed) return\n dt = clamp(dt, 0, 0.1)\n this.time += dt\n if (!this.attached) this.drainQueue()\n this.checkBroken()\n for (const b of this.bounds.values()) b.onFrame?.(dt)\n // a settling object keeps moving between its (throttled) `settle` events\n for (const b of this.bounds.values()) if (b.soilNode && this.world.state(b.id)?.soil?.status === 'yielding') this.onSettle(b.id)\n this.updateActive(dt)\n this.updateLeaks(dt)\n this.updateTrickles(dt)\n this.pieceSys.update(dt)\n this.fragments.update(dt)\n this.ground.update(dt)\n this.ownVfx?.update(dt)\n this.syncTransforms()\n }\n\n deferredQueue(): DeferredQueue {\n return this.eventQueue\n }\n\n private drainQueue(): void {\n this.runBudgeted(performance.now() + this.eventBudgetMs, () => performance.now())\n }\n\n /** Applies the waiting events in order until the deadline, after the slices earlier events left; always at least one unit when something waits. Returns the units run. */\n private runBudgeted(deadline: number, clock: () => number): number {\n // events produced while applying (a hard landing calls `hit`) wait for the next frame\n const batch = this.queue.splice(0, this.queue.length)\n const outerClock = this.drainClock\n this.drainClock = clock\n this.sliceDeadline = deadline\n let ran = 0\n try {\n ran = this.runSlices(deadline)\n for (let i = 0; i < batch.length; i++) {\n if ((i > 0 || (ran > 0 && this.attached)) && clock() >= deadline) {\n this.queue.unshift(...batch.slice(i))\n return ran\n }\n try {\n this.apply(batch[i]!)\n } catch (err) {\n if (typeof console !== 'undefined') console.error('game-destruction-three: failed to apply', batch[i]!.type, err)\n }\n ran++\n }\n } finally {\n this.sliceDeadline = Infinity\n this.drainClock = outerClock\n }\n return ran\n }\n\n /** Runs the work left by earlier frames until the deadline; at least one piece per frame, so it always finishes. */\n private runSlices(deadline: number): number {\n let ran = 0\n for (; this.slices.length > 0 && (ran === 0 || this.drainClock() < deadline); ran++) {\n try {\n this.slices.shift()!()\n } catch (err) {\n if (typeof console !== 'undefined') console.error('game-destruction-three: failed to run deferred work', err)\n }\n }\n return ran\n }\n\n /**\n * The ground under an object settled or tilted: its parts are drawn under a node with the soil's offset (`ObjectState.soil.offset`), so the host's\n * root keeps the pose the host gave and the world keeps getting it from `syncTransform`.\n */\n private onSettle(objectId: string): void {\n const b = this.bounds.get(objectId)\n const soil = this.world.state(objectId)?.soil\n if (!b || !soil) return\n let node = b.soilNode\n if (!node) {\n node = new this.THREE.Group()\n node.name = 'destruction-soil'\n for (const c of [...b.root.children]) node.add(c)\n b.root.add(node)\n b.soilNode = node\n }\n const { position: p, rotation: q } = soil.offset\n node.position.set(p[0], p[1], p[2])\n node.quaternion.set(q[0], q[1], q[2], q[3])\n node.updateMatrixWorld(true)\n }\n\n private syncTransforms(): void {\n for (const b of this.bounds.values()) this.syncOne(b)\n }\n\n /** Push the current transform of one bound object to the world right now (used before a landing hit). */\n private syncBound(objectId: string): void {\n const b = this.bounds.get(objectId)\n if (b) this.syncOne(b)\n }\n\n private syncOne(b: Bound): void {\n if (!b.sync) return\n const p = this.v1\n const q = this.tmpQ\n b.root.updateWorldMatrix(true, false)\n b.root.matrixWorld.decompose(p, q, this.v2)\n const last = b.lastPos\n const lq = b.lastQuat\n const moved = !last || !lq || Math.abs(p.x - last[0]) + Math.abs(p.y - last[1]) + Math.abs(p.z - last[2]) > 1e-5 || Math.abs(q.x - lq[0]) + Math.abs(q.y - lq[1]) + Math.abs(q.z - lq[2]) + Math.abs(q.w - lq[3]) > 1e-6\n if (!moved) return\n b.lastPos = [p.x, p.y, p.z]\n b.lastQuat = [q.x, q.y, q.z, q.w]\n if (this.world.has(b.id)) this.world.setTransform(b.id, [p.x, p.y, p.z], [q.x, q.y, q.z, q.w])\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Events\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n /**\n * The highest top of a bound object that is not a piece under (x, z) a corner at height `y` can land on (at most `step` above it). The world boxes\n * of their drawn meshes are kept until an event or a moved root changes them; parts drawn inside a merged mesh and meshes wider than `STATIC_SPAN`\n * are left out (walls, floors, roofs: the terrain under them is the host's `groundAt`).\n */\n private staticTopAt(x: number, z: number, y: number, step: number): number {\n let top = -Infinity\n for (const a of this.staticNow().values()) {\n // the first six numbers are the box around all of the object's boxes\n if (a.length === 0 || x < a[0] || x > a[3] || z < a[2] || z > a[5]) continue\n for (let i = 6; i < a.length; i += 6) {\n if (x < a[i] || x > a[i + 3] || z < a[i + 2] || z > a[i + 5]) continue\n const t = a[i + 4]\n if (t > top && t <= y + step) top = t\n }\n }\n return top\n }\n\n /** The boxes of the fixed objects (per object: the box around them all, then each one), each object measured again when an event touched it (all of them every `STATIC_REFRESH` s). */\n private staticNow(): Map<string, number[]> {\n if (this.time - this.staticAt > STATIC_REFRESH) {\n this.staticAt = this.time\n if (this.staticRound.length === 0) this.staticRound = [...this.bounds.keys()].reverse()\n }\n if (!this.staticAll && this.staticDirty.size === 0 && this.staticRound.length === 0) return this.staticBoxes\n const box = new this.THREE.Box3()\n const measure = (b: Bound): void => {\n if (b.piece || this.pieceSys.get(b.id)) {\n this.staticBoxes.delete(b.id)\n return\n }\n const out: number[] = [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity]\n for (const mv of this.meshesOf(b)) {\n if (mv.host || mv.loose || !this.visuals.shown(mv)) continue\n this.visuals.worldBox(mv, box)\n if (box.isEmpty() || box.max.x - box.min.x > STATIC_SPAN || box.max.z - box.min.z > STATIC_SPAN) continue\n this.visuals.fittedBoxes(mv, out)\n for (let k = 0; k < 3; k++) {\n out[k] = Math.min(out[k], box.min.getComponent(k))\n out[k + 3] = Math.max(out[k + 3], box.max.getComponent(k))\n }\n }\n this.staticBoxes.set(b.id, out.length > 6 ? out : [])\n }\n const measureId = (id: string): void => {\n const b = this.bounds.get(id)\n if (b) measure(b)\n else this.staticBoxes.delete(id)\n }\n if (this.staticAll) {\n this.staticBoxes.clear()\n for (const b of this.bounds.values()) measure(b)\n this.staticRound = []\n } else {\n for (const id of this.staticDirty) measureId(id)\n const until = performance.now() + STATIC_REFRESH_SLICE_MS\n while (this.staticRound.length > 0) {\n measureId(this.staticRound.pop() as string)\n if (performance.now() >= until) break\n }\n }\n this.staticAll = false\n this.staticDirty.clear()\n return this.staticBoxes\n }\n\n /** The boxes of a piece's drawn meshes, measured once per frame. */\n private pieceBoxesOf(pc: PieceBody): number[] {\n const cached = this.pieceBoxes.get(pc)\n if (cached && cached.at === this.time) return cached.boxes\n const boxes: number[] = []\n const b = this.bounds.get(pc.objectId)\n if (b) {\n for (const mv of this.meshesOf(b)) {\n if (this.visuals.shown(mv)) this.visuals.fittedBoxes(mv, boxes)\n }\n }\n this.pieceBoxes.set(pc, { at: this.time, boxes })\n return boxes\n }\n\n solidsNear(x: number, z: number, radius: number): SolidBox[] {\n const found: SolidBox[] = []\n const scan = (a: number[], id: string, piece: Piece | null, from: number): void => {\n if (from > 0 && (a.length === 0 || x < a[0] - radius || x > a[3] + radius || z < a[2] - radius || z > a[5] + radius)) return\n for (let i = from; i < a.length; i += 6) {\n if (x < a[i] - radius || x > a[i + 3] + radius || z < a[i + 2] - radius || z > a[i + 5] + radius) continue\n found.push({ objectId: id, min: [a[i], a[i + 1], a[i + 2]], max: [a[i + 3], a[i + 4], a[i + 5]], piece })\n }\n }\n for (const [id, a] of this.staticNow()) scan(a, id, null, 6)\n const c = this.v1\n for (const pc of this.pieceSys.list) {\n if (pc.held) continue\n // only the pieces whose box can reach the point are measured\n this.pieceSys.centerOf(pc, c)\n const reach = Math.hypot(pc.halfExtents[0], pc.halfExtents[1], pc.halfExtents[2]) + radius\n if (Math.abs(c.x - x) > reach || Math.abs(c.z - z) > reach) continue\n scan(this.pieceBoxesOf(pc), pc.objectId, pc, 0)\n }\n this.fragments.solidsNear(x, z, radius, (home, min, max, loose) => found.push({ objectId: home, min, max, piece: null, loose }))\n return found\n }\n\n private apply(ev: DestructionEvent): void {\n this.staticDirty.add(ev.object)\n if (ev.type === 'fracture' || ev.type === 'detach' || ev.type === 'collapse' || ev.type === 'burnout' || ev.type === 'destroyed') this.broken.add(ev.object)\n switch (ev.type) {\n case 'damage':\n if (ev.damageType === 'heat' || ev.damageType === 'fire' || ev.damageType === 'explosive') this.activate(ev.object, ev.part)\n break\n case 'dent':\n this.onDent(ev)\n break\n case 'hole':\n this.onHole(ev)\n break\n case 'crack':\n this.onCrack(ev)\n break\n case 'ricochet': {\n const d = ev.direction\n this.vfx.burst('sparks', ev.point, d, 4 + Math.min(10, ev.energy / 150), 4)\n // the whine of a round off steel, the short crack off stone: by what the part it glanced off is made of\n const glanced = this.partVis(ev.object, ev.part)?.material ?? ''\n this.sound('ricochet', ev.point, 0.7, ricochetSoundKeys(glanced, this.world.materials.get(glanced)))\n break\n }\n case 'debris':\n this.vfx.burst(ev.kind, ev.point, ev.normal, ev.count, ev.speed > 0 ? ev.speed : DEFAULT_SPEED[ev.kind] ?? 1, this.debrisOptions(ev.kind, ev.object, ev.part, ev.material))\n break\n case 'fracture':\n this.onFracture(ev)\n break\n case 'detach':\n this.onDetach(ev)\n break\n case 'settle':\n this.onSettle(ev.object)\n break\n case 'collapse': {\n // a storey coming down raises the cloud of the collapse effect; a piece of furniture (a shelf and its books) only a puff\n const root = this.bounds.get(ev.object)?.root\n const furniture = !!root && kitOriginOf(root)?.kind === 'furniture'\n this.splitLoose(ev.object)\n if (!furniture || ev.mass >= COLLAPSE_CLOUD_KG) this.playEvent({ kind: 'collapse' }, this.rootPoint(ev.object))\n else this.vfx.burst('dust', this.rootPoint(ev.object), [0, 1, 0], clamp(Math.round(ev.mass / 4), 4, 24), 0.8)\n break\n }\n case 'disassemble_progress': {\n const k = `unscrew:${ev.joint}`\n if (this.time - (this.throttles.get(k) ?? -1) > 0.25) {\n this.throttles.set(k, this.time)\n this.sound('unscrew', this.rootPoint(ev.object), clamp(0.3 + ev.progress * 0.5, 0, 1))\n }\n break\n }\n case 'ignite':\n this.startFire(ev)\n this.activate(ev.object, ev.part)\n this.sound('ignite', ev.point, 0.7)\n this.sound('burn_loop', ev.point, 0.5, this.burning(ev.object, ev.part))\n break\n case 'primed':\n // a bullet or fire sets the part burning until its delay runs out; a blast nearby only waits for the explosion\n if (ev.trigger !== 'explosion') {\n this.vfx.fire({ point: ev.point, radius: PRIMED_FIRE_RADIUS, life: ev.delay })\n this.primedBurning.add(`${ev.object}|${ev.part}`)\n this.activate(ev.object, ev.part)\n // the vessel is venting until it bursts: the gas leak for as long as the delay, and the flame it feeds\n this.sound('primed', ev.point, 0.7, { seconds: ev.delay })\n this.sound('burn_loop', ev.point, 0.5, { fuel: 'gas' })\n }\n break\n case 'spall':\n this.onSpall(ev)\n break\n case 'stage':\n this.onStage(ev)\n break\n case 'chip':\n this.onChip(ev)\n break\n case 'expose':\n if (ev.bars.length > 0) this.cages.set(`${ev.object}|${ev.part}`, ev.bars, this.bounds.get(ev.object)?.root)\n else this.dropCage(ev.object, ev.part)\n if (ev.bars.length > 0) {\n const [a, b] = ev.bars[0] as [Vec3, Vec3]\n this.playEvent({ kind: 'expose' }, [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2])\n }\n break\n case 'extinguish': {\n const f = this.fires.get(`${ev.object}|${ev.part}`)\n const primed = this.primedBurning.delete(`${ev.object}|${ev.part}`)\n if (f) {\n this.stopFire(`${ev.object}|${ev.part}`)\n this.vfx.burst('steam', f.point, [0, 1, 0], 14, 1.2)\n }\n if (f || primed) this.sound('burn_end', f?.point ?? this.rootPoint(ev.object), 0.5, primed ? { fuel: 'gas' } : this.burning(ev.object, ev.part))\n this.activate(ev.object, ev.part)\n this.sound('extinguish', f?.point ?? this.rootPoint(ev.object), 0.6)\n break\n }\n case 'burnout': {\n this.stopFire(`${ev.object}|${ev.part}`)\n const primed = this.primedBurning.delete(`${ev.object}|${ev.part}`)\n this.sound('burn_end', ev.point, 0.5, primed ? { fuel: 'gas' } : this.burning(ev.object, ev.part))\n this.vfx.burst('ash', ev.point, [0, 1, 0], 16, 1)\n this.vfx.burst('smoke', ev.point, [0, 1, 0], 6, 0.8, { color: SMOKE_TONES.grey })\n const pv = this.partVis(ev.object, ev.part)\n if (pv) {\n const def = this.world.materials.get(pv.material)\n this.visuals.setChar(pv, 1, def?.visual?.charColor ?? 0x1a1410)\n }\n this.activate(ev.object, ev.part)\n break\n }\n case 'melt':\n this.activate(ev.object, ev.part)\n // one sizzle per melting object every 1.5 s, not one per part (a plastic bin has dozens)\n if (this.time - (this.throttles.get(`melt:${ev.object}`) ?? -9) > 1.5) {\n this.throttles.set(`melt:${ev.object}`, this.time)\n this.sound('melt_sizzle', this.rootPoint(ev.object), 0.4)\n }\n break\n case 'drip': {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n const def = this.world.materials.get(ev.material)\n const color = (pv && this.partColor(pv, def)) ?? fallbackColor(ev.material, def)\n let tag = this.homeTags.indexOf(ev.object) + 1\n if (tag === 0) tag = this.homeTags.push(ev.object)\n this.vfx.spawn('drips', ev.point, [(this.rng() - 0.5) * 0.1, -0.1, (this.rng() - 0.5) * 0.1], { color, tag, owner: this.owner })\n break\n }\n case 'leak': {\n const key = `${ev.object}|${ev.part}`\n const b = this.bounds.get(ev.object)\n let localPoint: Vec3 | undefined\n let localDirection: Vec3 | undefined\n if (b) {\n b.root.updateWorldMatrix(true, false)\n const inv = new this.THREE.Matrix4().copy(b.root.matrixWorld).invert()\n const lp = this.v1.set(ev.point[0], ev.point[1], ev.point[2]).applyMatrix4(inv)\n const ld = this.v2.set(ev.direction[0], ev.direction[1], ev.direction[2]).transformDirection(inv).normalize()\n localPoint = [lp.x, lp.y, lp.z]\n localDirection = [ld.x, ld.y, ld.z]\n }\n const same = this.leaks.find((l) => l.object === ev.object && l.part === ev.part && Math.hypot(l.point[0] - ev.point[0], l.point[1] - ev.point[1], l.point[2] - ev.point[2]) < 0.03)\n if (same) {\n same.rate = ev.rate\n same.direction = ev.direction\n if (localPoint) same.localPoint = localPoint\n if (localDirection) same.localDirection = localDirection\n } else {\n if (this.leaks.length >= 24) this.leaks.shift()\n this.leaks.push({\n object: ev.object,\n part: ev.part,\n fluid: ev.fluid,\n point: ev.point,\n direction: ev.direction,\n rate: ev.rate,\n pressurized: ev.pressurized,\n acc: 0,\n opened: this.world.part(ev.object, ev.part)?.holes.some((h) => h.through) ?? false,\n localPoint,\n localDirection,\n life: 0,\n })\n }\n void key\n break\n }\n case 'explode':\n // the vessel that vented into its flame bursts: the gas jet ends with it\n if (this.primedBurning.delete(`${ev.object}|${ev.part}`)) this.sound('burn_end', ev.point, 0.5, { fuel: 'gas' })\n this.onExplode(ev)\n break\n case 'destroyed':\n break\n }\n }\n\n private rootPoint(objectId: string): Vec3 {\n const b = this.bounds.get(objectId)\n return b ? [b.root.position.x, b.root.position.y, b.root.position.z] : [0, 0, 0]\n }\n\n private sound(key: string, point: Vec3, volume: number, detail?: SoundDetail): void {\n if (detail) this.o.onSound?.(key, point, volume, detail)\n else this.o.onSound?.(key, point, volume)\n }\n\n /** What a burning part is made of, for the fire's sound. */\n private burning(objectId: string, partId: string): SoundDetail | undefined {\n const material = this.partVis(objectId, partId)?.material || this.world.part(objectId, partId)?.material\n return material ? { material } : undefined\n }\n\n private partVis(objectId: string, partId: string): PartVis | null {\n return this.bounds.get(objectId)?.parts.get(partId) ?? null\n }\n\n private activate(objectId: string, partId: string): void {\n this.active.set(`${objectId}|${partId}`, { object: objectId, part: partId })\n }\n\n /** Current colour of the part's first mesh (char included), or null. */\n private partColor(pv: PartVis, def: MaterialDef | undefined): number | null {\n const mv = pv.meshes[0]\n if (!mv) return null\n const mat = materialsOf(mv.mesh.material)[0] as THREE_NS.MeshStandardMaterial | undefined\n const c = mat?.color\n if (c && (c as THREE_NS.Color).isColor) {\n const tint = this.visuals.vertexTint(mv)\n return tint ? c.clone().multiply(tint).getHex() : c.getHex()\n }\n return def ? fallbackColor(def.id, def) : null\n }\n\n private debrisOptions(kind: DebrisKind, objectId: string, partId: string, material?: string): { color?: number } | undefined {\n const pv = this.partVis(objectId, partId)\n const def = this.world.materials.get(material ?? pv?.material ?? '')\n if (kind === 'smoke') return { color: SMOKE_TONES[def?.thermal.smoke ?? 'grey'] }\n // crushed masonry is the colour of its inside (brick orange, plaster light, concrete grey), not of the paint over it\n if ((kind === 'dust' || kind === 'chips') && def?.visual?.innerColor !== undefined) return { color: def.visual.innerColor }\n if (kind === 'fibers' || kind === 'leaves') {\n if (def?.visual?.innerColor !== undefined) return { color: def.visual.innerColor }\n const c = pv ? this.visuals.baseColorHex(pv.meshes[0] ?? ({} as never)) : -1\n return c >= 0 ? { color: c } : undefined\n }\n if (kind === 'dust' || kind === 'chips') {\n const c = pv && pv.meshes[0] ? this.visuals.baseColorHex(pv.meshes[0]) : -1\n return c >= 0 && kind === 'chips' ? { color: c } : undefined\n }\n return undefined\n }\n\n /** Mesh of the part closest to a world point. */\n private nearestMesh(pv: PartVis, p: THREE_NS.Vector3): PartVis['meshes'][number] | null {\n let best: PartVis['meshes'][number] | null = null\n let bd = Infinity\n for (const mv of pv.meshes) {\n if (!this.visuals.shown(mv)) continue\n const d = this.visuals.worldBox(mv, this.box).distanceToPoint(p)\n if (d < bd) {\n bd = d\n best = mv\n }\n }\n return best\n }\n\n private worldDir(b: Bound, v: Vec3): THREE_NS.Vector3 {\n b.root.updateWorldMatrix(true, false)\n return new this.THREE.Vector3(v[0], v[1], v[2]).applyQuaternion(b.root.getWorldQuaternion(this.tmpQ)).normalize()\n }\n\n private onDent(ev: Ev<'dent'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n if (!b || !pv) return\n const def = this.world.materials.get(pv.material)\n const wp = new this.THREE.Vector3(ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2])\n const wn = this.worldDir(b, ev.dent.normal)\n const shown = pv.meshes.filter((mv) => this.visuals.shown(mv))\n const reach = shown.reduce((widest, mv) => Math.max(widest, this.visuals.dentReach(mv, wp, ev.dent)), ev.dent.radius)\n this.visuals.applyPartDent(shown, wp, wn, ev.dent, reach)\n if (def?.tags?.includes('metal')) this.vfx.burst('sparks', ev.worldPoint, [wn.x, wn.y, wn.z], 4 + Math.min(8, ev.dent.depth * 150), 3.2)\n this.impactSound(pv.material, ev.worldPoint, clamp(0.3 + ev.dent.depth * 12, 0.3, 1), ev.blow)\n }\n\n private onHole(ev: Ev<'hole'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n if (!b || !pv) return\n const def = this.world.materials.get(pv.material)\n const n = this.worldDir(b, ev.hole.normal)\n const draw = (point: Vec3, normal: THREE_NS.Vector3): void => {\n const wp = new this.THREE.Vector3(point[0], point[1], point[2])\n const mv = this.nearestMesh(pv, wp)\n if (!mv) return\n if (def?.visual?.transparent) {\n const seed = hashNumbers(ev.time, point[0], point[1], point[2])\n this.visuals.addCrack(mv, wp, normal, 7, Math.max(0.05, ev.hole.diameter * 5), 0xe8f4ff, seed)\n } else {\n // wood tears its fibres around the hole: a ragged rim of fresh wood under it\n const fresh = def?.penetrationClass === 'wood' ? def.visual?.innerColor : undefined\n if (fresh !== undefined) this.visuals.addSpall(mv, wp, normal, Math.max(0.006, ev.hole.diameter * WOOD_RIM), fresh)\n this.visuals.addHole(mv, wp, normal, ev.hole.diameter)\n }\n }\n draw(ev.worldPoint, n)\n if (ev.hole.through && ev.exitPoint) draw(ev.exitPoint, n.clone().negate())\n if (def?.tags?.includes('metal')) this.vfx.burst('sparks', ev.worldPoint, [n.x, n.y, n.z], 6, 3.5)\n if (ev.powder) {\n // what the part holds loose (flakes, flour) puffs out: a little back out of the entry, most out of the exit along the shot\n const puff = { color: ev.powder.color, size: 0.6, life: 1.6, alpha: 1.3 }\n this.vfx.burst('dust', ev.worldPoint, [n.x, n.y, n.z], this.low ? 5 : 10, 0.7, puff)\n if (ev.hole.through && ev.exitPoint) this.vfx.burst('dust', ev.exitPoint, [-n.x, -n.y, -n.z], this.low ? 10 : 20, 1.3, puff)\n }\n // the blow's own keys first (`impact_steel_ballistic`...), then the round's per-family key (`shot_metal`), which falls back to the plain impact\n this.sound(shotKey(def), ev.worldPoint, 0.6, impactSoundKeys(pv.material, def, ev.blow))\n }\n\n private onCrack(ev: Ev<'crack'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n if (!b || !pv) return\n const def = this.world.materials.get(pv.material)\n // only glass shows a crack as lines (the break runs inside a clear body); an opaque body shows its damage as chips, holes and dents, never lines drawn over it\n if (def?.visual?.transparent) {\n const wp = new this.THREE.Vector3(ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2])\n const mv = this.nearestMesh(pv, wp)\n const seed = hashNumbers(ev.time, ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2])\n if (mv) this.visuals.addCrack(mv, wp, this.worldDir(b, ev.crack.normal), ev.crack.rays, ev.crack.length, 0xe8f4ff, seed)\n }\n this.impactSound(pv.material, ev.worldPoint, 0.5, ev.blow)\n }\n\n /** Outward normal of the face of `mv` nearest to a world point: the thin axis of its world box (right for a wall; a sloped face is left to the vertex-range binding). */\n private faceNormal(mv: PartVis['meshes'][number], point: THREE_NS.Vector3): THREE_NS.Vector3 {\n const box = this.visuals.worldBox(mv, this.box)\n const size = box.getSize(this.v1)\n const axis = size.x <= size.y && size.x <= size.z ? 'x' : size.y <= size.z ? 'y' : 'z'\n const side = point[axis] >= (box.min[axis] + box.max[axis]) / 2 ? 1 : -1\n return new this.THREE.Vector3(axis === 'x' ? side : 0, axis === 'y' ? side : 0, axis === 'z' ? side : 0)\n }\n\n /** The material an impact effect is chosen by: the tags of the material (`metal`, `glass`, `wood`), else stone and the like are `concrete`. */\n private impactMaterial(def: MaterialDef | undefined): string {\n for (const tag of IMPACT_TAGS) if (def?.tags?.includes(tag)) return tag\n return 'concrete'\n }\n\n /**\n * Plays the effect the event map names for a destruction event (`data/event-effects.json` of `game-vfx`, or `RendererOptions.eventEffects`) at a point.\n * Answers whether one played, so the caller can leave out the burst it replaces.\n */\n private playEvent(event: GameEvent, point: Vec3): boolean {\n const id = effectForEvent(event, this.o.eventEffects ?? EVENT_EFFECTS_MAP)\n if (!id) return false\n return this.vfx.play(id, point, { seed: hashNumbers(point[0], point[1], point[2], this.time) }) !== null\n }\n\n /** A coat came off: a patch in the colour of the core under it, below the bullet holes and cracks. */\n private onSpall(ev: Ev<'spall'>): void {\n const pv = this.partVis(ev.object, ev.part)\n if (!pv) return\n const wp = new this.THREE.Vector3(ev.point[0], ev.point[1], ev.point[2])\n const mv = this.nearestMesh(pv, wp)\n if (!mv) return\n const def = this.world.materials.get(pv.material)\n const normal = this.faceNormal(mv, wp)\n const core = def?.visual?.innerColor\n // masonry crumbles in the colour of what is under the coat (brick orange, concrete grey); the generic impact would throw dark grey chips\n if (core !== undefined) this.vfx.burst('chips', ev.point, [normal.x, normal.y, normal.z], 5, 2.5, { color: core })\n else this.playEvent({ kind: 'spall', material: this.impactMaterial(def) }, ev.point)\n if (core !== undefined) this.trickleFrom(ev.point, [normal.x, normal.y, normal.z], core)\n // a drawing that shows the coat coming off itself (the house renderer cuts its plaster and draws the bricks under it) takes no flat patch\n if ((mv.mesh.userData.drawnSpalls as string[] | undefined)?.includes(ev.part)) return\n this.visuals.addSpall(mv, wp, normal, Math.sqrt(ev.area / Math.PI), core ?? fallbackColor(pv.material, def))\n }\n\n /** Grit and dust go on falling from where a blow broke a hard face (masonry, concrete) for `TRICKLE_SECONDS`, a pinch at a time and less and less. */\n private trickleFrom(point: Vec3, normal: Vec3, color: number | undefined): void {\n if (this.trickles.length >= TRICKLE_MAX) this.trickles.shift()\n const total = TRICKLE_SECONDS[0] + (TRICKLE_SECONDS[1] - TRICKLE_SECONDS[0]) * this.rng()\n this.trickles.push({ point: [point[0], point[1], point[2]], normal, color, left: total, total, next: TRICKLE_EVERY })\n }\n\n private updateTrickles(dt: number): void {\n for (let i = this.trickles.length - 1; i >= 0; i--) {\n const t = this.trickles[i]!\n t.left -= dt\n t.next -= dt\n if (t.left <= 0) {\n this.trickles.splice(i, 1)\n continue\n }\n if (t.next > 0) continue\n // falling off the face, slower as the loose grit runs out\n const share = t.left / t.total\n t.next = TRICKLE_EVERY / Math.max(share, 0.25)\n const out: Vec3 = [t.normal[0] * 0.2, -1, t.normal[2] * 0.2]\n const options = t.color !== undefined ? { color: t.color } : undefined\n this.vfx.burst('chips', t.point, out, this.low ? 1 : 2, 0.3, options)\n if (this.rng() < 0.5) this.vfx.burst('dust', t.point, out, 1, 0.2, options)\n }\n }\n\n /**\n * Stage 2 of a staged part: the unit-sized fragments come out and the part stays drawn (hiding it is what `fracture` does). The opening itself\n * (cutting the wall's faces) is not drawn yet: it needs the per-vertex binding of the house renderer.\n */\n private onStage(ev: Ev<'stage'>): void {\n const played = this.playEvent({ kind: 'stage', stage: ev.stage }, ev.opening?.center ?? this.rootPoint(ev.object))\n if (!ev.fragments || !ev.opening) return\n const pv = this.partVis(ev.object, ev.part)\n const def = pv ? this.world.materials.get(pv.material) : undefined\n const color = (pv ? this.partColor(pv, def) : null) ?? fallbackColor(pv?.material ?? '', def)\n const maxAlive = this.low ? Math.floor(this.maxFragments / 2) : this.maxFragments\n const step = this.low ? 2 : 1\n for (let i = 0; i < ev.fragments.length; i += step) {\n const fr = ev.fragments[i] as Fragment\n const fdef = this.world.materials.get(fr.material)\n this.fragments.spawn(fr, this.fragments.materialFor(fr.material, fdef === def || !fdef ? color : fallbackColor(fr.material, fdef), false), ev.object, maxAlive)\n }\n if (!played) this.vfx.burst('dust', ev.opening.center, [0, 1, 0], 14, 1.2, { color })\n this.impactSound(pv?.material ?? '', ev.opening.center, 0.8, ev.blow)\n }\n\n /**\n * A unit came out of a wall of units: the unit flies as a fragment with a puff of its dust, and the marks drawn on it (bullet holes, spalls, the impact\n * marks of the effects) go with it. The gap itself is the drawing's (the house renderer cuts the wall where the unit was); a part drawn as one box\n * keeps its box.\n */\n private onChip(ev: Ev<'chip'>): void {\n const pv = this.partVis(ev.object, ev.part)\n const def = pv ? this.world.materials.get(pv.material) : undefined\n const color = (pv ? this.partColor(pv, def) : null) ?? fallbackColor(pv?.material ?? '', def)\n const maxAlive = this.low ? Math.floor(this.maxFragments / 2) : this.maxFragments\n for (const fr of ev.fragments) {\n const fdef = this.world.materials.get(fr.material)\n // the inside of the material (fresh wood) when the piece came from it, else the part's colour\n const tone = fr.inner && fdef?.visual?.innerColor !== undefined ? fdef.visual.innerColor : fdef === def ? color : fallbackColor(fr.material, fdef)\n this.fragments.spawn(fr as Fragment, this.fragments.materialFor(fr.material, tone, false), ev.object, maxAlive)\n }\n // a unit knocked out of masonry or concrete leaves a broken edge that goes on crumbling\n if (def?.visual?.innerColor !== undefined || pv?.material === 'concrete' || pv?.material === 'brick') this.trickleFrom(ev.center, [0, 0, 0], color)\n // what a blow tore off a face leaves the hole it made where it is\n if (ev.torn) {\n this.impactSound(pv?.material ?? '', ev.center, 0.5, ev.blow)\n return\n }\n // the holes and spalls drawn on the unit leave with it (also those on the wall a beam is drawn inside), and on the ragged edge of plaster around it\n const T = this.THREE\n const center = new T.Vector3(ev.center[0], ev.center[1], ev.center[2])\n const half = new T.Vector3(ev.size[0] / 2 + CHIP_DECAL_EDGE, ev.size[1] / 2 + CHIP_DECAL_EDGE, ev.size[2] / 2 + CHIP_DECAL_EDGE)\n const rotation = new T.Quaternion(ev.rotation[0], ev.rotation[1], ev.rotation[2], ev.rotation[3])\n for (const part of this.bounds.get(ev.object)?.parts.values() ?? []) for (const mv of part.meshes) this.visuals.clearDecals(mv, center, half, rotation)\n this.vfx.peekWorkshop()?.decals.clearInside(ev.center, [half.x, half.y, half.z], ev.rotation)\n // a puff of the unit's own dust; not the bullet impact effect, which would leave its black mark on the hole the unit left\n this.vfx.burst('dust', ev.center, [0, 1, 0], ev.units ? Math.min(40, 8 + ev.units.length) : 8, ev.units ? 1.6 : 0.8, { color })\n this.impactSound(pv?.material ?? '', ev.center, 0.7, ev.blow)\n }\n\n private onFracture(ev: Ev<'fracture'>): void {\n const b = this.bounds.get(ev.object)\n const pv = b?.parts.get(ev.part)\n const matId = pv?.material || (ev.fragments[0]?.material ?? '')\n const def = this.world.materials.get(matId)\n let color = fallbackColor(matId, def)\n let opacity = 0.5\n const transparent = def?.visual?.transparent === true\n if (pv) {\n const c = this.partColor(pv, def)\n if (c !== null) color = c\n const m = pv.meshes[0] ? (materialsOf(pv.meshes[0].origMaterial)[0] as THREE_NS.Material | undefined) : undefined\n if (m && m.transparent) opacity = clamp(m.opacity, 0.2, 0.8)\n this.visuals.hide(pv, 'broken')\n }\n this.spawnFragments(ev, 0, { def, color, opacity, transparent })\n this.loosenIfFootless(ev.object)\n const up: Vec3 = [0, 1, 0]\n const sizeK = clamp(ev.fragments.length / 10, 0.5, 2)\n switch (ev.style) {\n case 'shatter':\n this.vfx.burst('shards', ev.point, up, 18 * sizeK, 3)\n break\n case 'crumble':\n this.vfx.burst('dust', ev.point, up, 16 * sizeK, 1.2, { color: pv ? (this.partColor(pv, def) ?? undefined) : undefined })\n this.vfx.burst('chips', ev.point, up, 6, 3)\n break\n case 'splinter':\n this.vfx.burst('splinters', ev.point, up, 14 * sizeK, 3)\n this.vfx.burst('dust', ev.point, up, 5, 0.8, { color: 0xb59a74 })\n break\n case 'tear':\n this.vfx.burst('fibers', ev.point, up, 12 * sizeK, 1.6, { color: def?.visual?.innerColor ?? color })\n break\n case 'snap':\n this.vfx.burst('chips', ev.point, up, 8 * sizeK, 3)\n break\n default:\n this.vfx.burst('sparks', ev.point, up, 10, 4)\n }\n this.sound(fractureKey(def, ev.style), ev.point, clamp(0.4 + ev.fragments.length * 0.03, 0.4, 1), breakSoundKeys(matId, def, ev.blow))\n }\n\n /** Spawns the fragments of a fracture from index `from`; what does not fit in this frame's budget is spawned by the next frames. */\n private spawnFragments(ev: Ev<'fracture'>, from: number, look: { def: MaterialDef | undefined; color: number; opacity: number; transparent: boolean }): void {\n const maxAlive = this.low ? Math.floor(this.maxFragments / 2) : this.maxFragments\n const step = this.low ? 2 : 1\n for (let i = from; i < ev.fragments.length; i += step) {\n if (i - from >= MIN_FRAGMENTS_PER_SLICE * step && this.drainClock() >= this.sliceDeadline) {\n this.slices.push(() => this.spawnFragments(ev, i, look))\n return\n }\n const fr = ev.fragments[i]\n const fdef = this.world.materials.get(fr.material)\n const tone = fr.inner && fdef?.visual?.innerColor !== undefined ? fdef.visual.innerColor : fdef === look.def || !fdef ? look.color : fallbackColor(fr.material, fdef)\n const mat = this.fragments.materialFor(fr.material, tone, look.transparent || fdef?.visual?.transparent === true, look.opacity)\n this.fragments.spawn(fr, mat, ev.object, maxAlive)\n }\n }\n\n private onDetach(ev: Ev<'detach'>): void {\n this.sound('detach', this.rootPoint(ev.object), 0.5)\n this.splitLoose(ev.object)\n }\n\n /**\n * The cage of a part gave way (`expose` with no bars): nothing holds its bars any more, so each comes down where it is, as steel debris that stays on the\n * ground with a body (`FragmentSystem.spawn` with `lasting`), not as bars left standing in the air.\n */\n private dropCage(objectId: string, partId: string): void {\n const bars = this.cages.take(`${objectId}|${partId}`)\n if (bars.length === 0) return\n const radius = this.cages.barRadius\n const density = this.world.materials.get('steel')?.density ?? STEEL_DENSITY\n const material = this.fragments.materialFor('steel', REBAR_COLOR, false)\n const rnd = createRng(hashString(`${objectId}|${partId}`))\n bars.forEach((bar, i) => {\n const fragment: Fragment = {\n id: `${partId}#bar${i}`, part: partId, material: 'steel', shape: 'chunk', center: bar.center, size: [2 * radius, bar.length, 2 * radius], rotation: bar.rotation,\n velocity: [(rnd() - 0.5) * 0.4, 0, (rnd() - 0.5) * 0.4], angularVelocity: [(rnd() - 0.5) * 1.5, (rnd() - 0.5) * 0.5, (rnd() - 0.5) * 1.5],\n mass: density * Math.PI * radius * radius * bar.length,\n }\n this.fragments.spawn(fragment, material, objectId, this.maxFragments, true)\n })\n }\n\n /** Turn every loose group of the object (a detach, a collapse) into a piece of its own. */\n private splitLoose(objectId: string): void {\n if (!this.autoSplit) return\n const b = this.bounds.get(objectId)\n if (!b) return\n const st = this.world.state(objectId)\n if (!st || st.groups.length < 2) return\n const loose = st.groups.length - 1\n for (let i = 0; i < loose; i++) {\n if (i > 0 && this.drainClock() >= this.sliceDeadline) {\n this.slices.push(() => {\n this.staticDirty.add(objectId)\n this.splitLoose(objectId)\n })\n return\n }\n // the loose groups are always read from index 1: each split renumbers the rest\n let newId: string\n try {\n newId = this.world.splitGroup(objectId, 1)\n } catch {\n break\n }\n this.adoptSplit(b, newId)\n }\n const old = b.piece\n if (old) {\n const { half, center } = this.measure(b.root, this.meshesOf(b))\n old.halfExtents = half\n this.pieceSys.setCenter(old, center)\n old.mass = Math.max(0.05, this.massOf(objectId))\n old.sleeping = false\n } else if (kitOriginOf(b.root)?.kind === 'furniture') {\n // furniture only stands on the floor: what stayed (a leg, two legs and a board) is loose too, and what cannot stand on its own topples\n const piece = this.makePiece(objectId)\n this.tipIfTopHeavy(b)\n // the host stops keeping the footprint it had where it stood: it is a body that moves now\n this.o.onLoosened?.(objectId, piece, 'apart')\n }\n }\n\n /** The renderer side of `splitGroup`: a new group holding the meshes of the new object, made a piece. */\n private adoptSplit(from: Bound, newId: string): void {\n const state = this.world.state(newId)\n const root = from.root\n root.updateWorldMatrix(true, false)\n const group = new this.THREE.Group()\n group.name = `destruction-piece-${newId}`\n root.getWorldPosition(group.position)\n root.getWorldQuaternion(group.quaternion)\n this.scene.add(group)\n group.updateMatrixWorld(true)\n const nb: Bound = { id: newId, root: group, sync: true, parts: new Map(), lastPos: null, lastQuat: null, piece: null, isSplit: true }\n for (const p of state?.parts ?? []) {\n const pv = from.parts.get(p.id)\n if (!pv) continue\n from.parts.delete(p.id)\n nb.parts.set(p.id, pv)\n // its bare bars go with it\n this.cages.move(`${from.id}|${p.id}`, `${newId}|${p.id}`, group)\n for (const mv of pv.meshes) {\n // a part drawn by a range of a merged mesh leaves its faces behind: it gets a mesh of its own\n if (mv.host && !mv.loose) this.visuals.extract(mv, group)\n else {\n group.attach(mv.mesh)\n showCollapsedRanges(mv.mesh)\n mv.moved = true\n }\n }\n }\n this.bounds.set(newId, nb)\n for (const pv of nb.parts.values()) this.tagPart(pv, newId)\n const meshes = this.meshesOf(nb)\n if (meshes.length === 0) return\n const { half, center } = this.measure(group, meshes)\n let vel: Vec3 = [0, 0, 0]\n let ang: Vec3 = [0, 0, 0]\n const op = from.piece\n if (op) {\n vel = [...op.velocity]\n ang = [...op.angularVelocity]\n // linear velocity at the loose piece's centre\n const c = this.pieceSys.centerOf(op, new this.THREE.Vector3())\n const nc = center.clone().applyQuaternion(group.quaternion).add(group.position)\n vel[0] += ang[1] * (nc.z - c.z) - ang[2] * (nc.y - c.y)\n vel[1] += ang[2] * (nc.x - c.x) - ang[0] * (nc.z - c.z)\n vel[2] += ang[0] * (nc.y - c.y) - ang[1] * (nc.x - c.x)\n }\n const piece = this.pieceSys.create(newId, group, half, center, this.massOf(newId), vel, ang)\n nb.piece = piece\n if (kitOriginOf(from.root)?.kind === 'furniture') this.tipIfTopHeavy(nb)\n this.o.onPiece?.(piece)\n }\n\n /**\n * What lost what it stood on falls (furniture, a stand, a crate, a car; not a structure): with every leg of a table broken the top is loose, and with the legs of one side\n * gone what is left topples. Feet are the meshes at the bottom of the object as it was whole; while the ones left still span the same floor (a cupboard with a broken door,\n * a table missing one leg) it stands. A piece that lost a part is the box of what is left, touching the ground by the corners of each part (`setContacts`).\n */\n private loosenIfFootless(objectId: string): void {\n const b = this.bounds.get(objectId)\n if (!b || !this.autoSplit) return\n const left = this.meshesOf(b).filter((mv) => this.visuals.shown(mv))\n if (left.length === 0) return\n // a house, a wall, the ground answer to their own load path: their pieces only take the box of what is left\n const structural = UNCHECKED_KINDS.has(this.kindOf(b))\n const body = b.piece ?? this.pieceSys.get(objectId)\n if (body) {\n // a piece is the box of what is left of it: the legs that broke off no longer hold it up\n const { half, center } = this.measure(b.root, left)\n body.halfExtents = half\n this.pieceSys.setCenter(body, center)\n body.mass = Math.max(0.05, this.massOf(objectId))\n if (!structural) this.setContacts(b, body, left)\n body.sleeping = false\n return\n }\n if (structural) return\n const boxOf = (mv: MeshVis): THREE_NS.Box3 => this.visuals.worldBox(mv, new this.THREE.Box3())\n const whole = [...b.parts.values()].flatMap((pv) => pv.meshes).map(boxOf).filter((one) => !one.isEmpty())\n // what hangs (a wall cabinet, a lamp) is held by what it hangs on: only what stood on something can lose its footing\n if (!this.standsOn(objectId, whole.map((one): [number, number, number, number, number, number] => [one.min.x, one.min.y, one.min.z, one.max.x, one.max.y, one.max.z]))) return\n const floor = Math.min(...whole.map((one) => one.min.y))\n const feetOf = (boxes: THREE_NS.Box3[]): THREE_NS.Box3 => boxes.filter((one) => one.min.y < floor + FEET_BAND).reduce((feet, one) => feet.union(one), new this.THREE.Box3())\n const was = feetOf(whole)\n const now = feetOf(left.map(boxOf).filter((one) => !one.isEmpty()))\n const same = !now.isEmpty() && now.min.x <= was.min.x + FEET_BAND && now.max.x >= was.max.x - FEET_BAND && now.min.z <= was.min.z + FEET_BAND && now.max.z >= was.max.z - FEET_BAND\n if (same) return\n if (!now.isEmpty()) {\n const box = left.map(boxOf).reduce((all, one) => all.union(one), new this.THREE.Box3())\n const centreX = (box.min.x + box.max.x) / 2\n const centreZ = (box.min.z + box.max.z) / 2\n const height = box.max.y - box.min.y\n const narrow = height >= TIP_MIN_HEIGHT && Math.min(now.max.x - now.min.x, now.max.z - now.min.z) < TIP_NARROW * height\n if (!narrow && centreX > now.min.x && centreX < now.max.x && centreZ > now.min.z && centreZ < now.max.z) return\n }\n const piece = this.makePiece(objectId)\n this.setContacts(b, b.piece ?? (piece as PieceBody), left)\n this.tipIfTopHeavy(b)\n // the host stops keeping the footprint it had where it stood: it is a body that moves now\n this.o.onLoosened?.(objectId, piece, 'apart')\n }\n\n shownBoxes(objectId: string, partId?: string): Array<[number, number, number, number, number, number]> {\n const b = this.bounds.get(objectId)\n if (!b) return []\n const box = new this.THREE.Box3()\n const out: Array<[number, number, number, number, number, number]> = []\n const pv = partId === undefined ? null : b.parts.get(partId)\n if (partId !== undefined && (!pv || pv.gone !== 'none')) return out\n for (const mv of pv ? pv.meshes : this.meshesOf(b)) {\n if (!this.visuals.shown(mv)) continue\n this.visuals.worldBox(mv, box)\n if (!box.isEmpty()) out.push([box.min.x, box.min.y, box.min.z, box.max.x, box.max.y, box.max.z])\n }\n return out\n }\n\n /**\n * What is left of each object broken since the last update stands on something, or falls: an object that is not a piece whose lowest drawn box has neither the ground, a\n * fixed top nor a piece within `BROKEN_GAP` under it is made a piece on the spot (see `onBrokenChecked`).\n */\n private checkBroken(): void {\n if (this.broken.size === 0) return\n const ids = [...this.broken]\n this.broken.clear()\n for (const id of ids) {\n const released = this.releaseIfFloating(id)\n this.o.onBrokenChecked?.(id, released)\n }\n }\n\n private releaseIfFloating(objectId: string): boolean {\n const b = this.bounds.get(objectId)\n if (!b || b.piece || this.pieceSys.get(objectId) || !this.autoSplit || UNCHECKED_KINDS.has(this.kindOf(b))) return false\n const boxes = this.shownBoxes(objectId)\n if (boxes.length === 0) return false\n // the object as it was whole (it has not moved: it is no piece): one that hung (a wall cabinet, a lamp) is held by what it hangs on, not checked here\n const whole = new this.THREE.Box3()\n const wholeBoxes: Array<[number, number, number, number, number, number]> = []\n for (const pv of b.parts.values()) {\n for (const mv of pv.meshes) {\n this.visuals.worldBox(mv, whole)\n if (!whole.isEmpty()) wholeBoxes.push([whole.min.x, whole.min.y, whole.min.z, whole.max.x, whole.max.y, whole.max.z])\n }\n }\n if (!this.standsOn(objectId, wholeBoxes) || this.standsOn(objectId, boxes)) return false\n const piece = this.makePiece(objectId)\n this.setContacts(b, b.piece ?? (piece as PieceBody), this.meshesOf(b).filter((mv) => this.visuals.shown(mv)))\n this.tipIfTopHeavy(b)\n this.o.onLoosened?.(objectId, piece, 'apart')\n return true\n }\n\n /** Whether the lowest of `boxes` (world boxes of the object `objectId`) has the ground, a fixed top or a piece within `BROKEN_GAP` under it. */\n private standsOn(objectId: string, boxes: ReadonlyArray<readonly [number, number, number, number, number, number]>): boolean {\n if (boxes.length === 0) return false\n const low = Math.min(...boxes.map((one) => one[1]))\n for (const [x0, y0, z0, x1, , z1] of boxes) {\n if (y0 > low + FEET_BAND) continue\n for (const [fx, fz] of BROKEN_SAMPLES) {\n const x = x0 + (x1 - x0) * fx\n const z = z0 + (z1 - z0) * fz\n const under = Math.max(this.groundAt(x, z), this.staticTopAtBut(objectId, x, z, y0, BROKEN_GAP), this.pieceSys.topAt(x, z, y0, BROKEN_GAP, objectId))\n if (under >= y0 - BROKEN_GAP) return true\n }\n }\n return false\n }\n\n /** The kind of kit piece a bound object is, by the mark on its root or the nearest one above it (a house binds a group inside its marked root); '' when unmarked. */\n private kindOf(b: Bound): string {\n for (let o: THREE_NS.Object3D | null = b.root; o; o = o.parent) {\n const kind = kitOriginOf(o)?.kind\n if (kind) return kind\n }\n return ''\n }\n\n /** `staticTopAt` without the boxes of `objectId` itself. */\n private staticTopAtBut(objectId: string, x: number, z: number, y: number, step: number): number {\n let top = -Infinity\n for (const [id, a] of this.staticNow()) {\n if (id === objectId || a.length === 0 || x < a[0] || x > a[3] || z < a[2] || z > a[5]) continue\n for (let i = 6; i < a.length; i += 6) {\n if (x < a[i] || x > a[i + 3] || z < a[i + 2] || z > a[i + 5]) continue\n const t = a[i + 4]\n if (t > top && t <= y + step) top = t\n }\n }\n return top\n }\n\n /**\n * The piece touches the ground by the corners of each part left of it, not by the box around them all: on one leg, or on the legs of one side, its centre of mass is off\n * what holds it and it goes over until the top meets the floor. Past `CONTACT_MESHES` meshes it keeps the corners of its box.\n */\n private setContacts(b: Bound, body: PieceBody, meshes: MeshVis[]): void {\n if (meshes.length > CONTACT_MESHES) {\n body.contacts = undefined\n return\n }\n const inv = specFrameInverse(this.THREE, b.root)\n const m4 = new this.THREE.Matrix4()\n const lb = new this.THREE.Box3()\n const [cx, cy, cz] = body.localCenter\n const points: Vec3[] = []\n for (const mv of meshes) {\n mv.mesh.updateWorldMatrix(true, false)\n this.visuals.localBox(mv, lb)\n if (lb.isEmpty()) continue\n lb.applyMatrix4(m4.multiplyMatrices(inv, mv.mesh.matrixWorld))\n for (let i = 0; i < 8; i++) points.push([(i & 1 ? lb.max.x : lb.min.x) - cx, (i & 2 ? lb.max.y : lb.min.y) - cy, (i & 4 ? lb.max.z : lb.min.z) - cz])\n }\n body.contacts = points.length > 0 ? points : undefined\n }\n\n /**\n * A piece of furniture standing on feet too close for its height (a board on two legs in a line, a lone leg) does not stay up: the box of a piece hides that its weight is up\n * high and its feet are thin, so it gets the start of the fall, across the line of its feet.\n */\n private tipIfTopHeavy(b: Bound): void {\n const piece = b.piece\n if (!piece) return\n const box = new this.THREE.Box3()\n const boxes = this.meshesOf(b).filter((mv) => this.visuals.shown(mv)).map((mv) => this.visuals.worldBox(mv, new this.THREE.Box3()))\n if (boxes.length === 0) return\n for (const one of boxes) box.union(one)\n const height = box.max.y - box.min.y\n const feet = new this.THREE.Box3()\n for (const one of boxes) if (one.min.y < box.min.y + FEET_BAND) feet.union(one)\n const spanX = feet.max.x - feet.min.x\n const spanZ = feet.max.z - feet.min.z\n if (height < TIP_MIN_HEIGHT || Math.min(spanX, spanZ) >= TIP_NARROW * height) return\n const across = spanX <= spanZ ? 0 : 2\n const lean = across === 0 ? box.min.x + box.max.x - feet.min.x - feet.max.x : box.min.z + box.max.z - feet.min.z - feet.max.z\n const away = lean < 0 ? -1 : 1\n // rotating about -z moves the top toward +x; rotating about +x moves it toward +z\n if (across === 0) this.pieceSys.tip(piece, 0, -away)\n else this.pieceSys.tip(piece, away, 0)\n }\n\n private onExplode(ev: Ev<'explode'>, options: ExplodeOptions = {}): void {\n const p = ev.point\n if (options.visual !== false) this.playExplosion(ev, options)\n this.vfx.push(p, ev.radius, 4)\n // shove pieces and fragments\n const c = this.v1\n const report = options.report\n const confinement = report?.find((r) => r.blast !== undefined)?.blast?.confinement ?? 1\n const energy = ev.energy * confinement\n // the energy that got to an object after what stood in the way: the world's shelter of this blast when it carries one, else the cover between the centre and the\n // object's centre (`blastReach`, always on: a wall, a car or a cupboard between them takes the push), as it stood when the part went off: the cupboard the wave\n // tears apart still met it, and the stove it throws was not in the way yet\n const wentOff = this.coverWhenWentOff.get(ev)\n const reachOf = (objectId: string, at: Vec3): number =>\n report?.find((r) => r.object === objectId)?.blast?.shelter ??\n wentOff?.get(objectId) ??\n this.world.blastReach?.(p, at, { ignore: ev.object ? [ev.object, objectId] : [objectId] }) ??\n 1\n const shove = (pc: PieceBody): void => {\n this.pieceSys.centerOf(pc, c)\n if (c.distanceTo(this.v2.set(p[0], p[1], p[2])) > ev.radius) return\n const hit = blastShove({ point: p, energy, radius: ev.radius, reach: reachOf(pc.objectId, [c.x, c.y, c.z]) }, { position: [c.x, c.y, c.z], mass: pc.mass }, this.o.blastShove)\n if (!hit) return\n const spread = pc.halfExtents[0]\n const momentum = hit.speed * pc.mass\n this.pieceSys.impulse(pc, [hit.direction[0] * momentum, hit.direction[1] * momentum, hit.direction[2] * momentum], [c.x + (this.rng() - 0.5) * spread, c.y + spread * 0.5, c.z + (this.rng() - 0.5) * spread])\n }\n for (const pc of [...this.pieceSys.list]) shove(pc)\n if (this.o.shoveable) this.loosen(p, ev.radius, energy, reachOf)\n this.fragments.blast(p, ev.radius, Math.min(20, Math.sqrt(energy) * 0.08))\n this.sound('explode', p, clamp(0.5 + ev.radius / 10, 0.5, 1), {\n radius: ev.radius,\n ...(ev.effect !== undefined ? { effect: ev.effect } : {}),\n ...(options.effect !== undefined ? { effect: options.effect } : {}),\n ...(report ? { confinement } : {}),\n })\n }\n\n /** The cover between a part of the world that goes off and the centre of each piece and each shoveable body within its radius, as the world stands at that moment. */\n private coverAround(ev: Ev<'explode'>): Map<string, number> {\n const cover = new Map<string, number>()\n const reach = this.world.blastReach\n if (!reach) return cover\n const point = new this.THREE.Vector3(ev.point[0], ev.point[1], ev.point[2])\n const centre = new this.THREE.Vector3()\n const read = (objectId: string): void => {\n if (centre.distanceTo(point) <= ev.radius) cover.set(objectId, reach.call(this.world, ev.point, [centre.x, centre.y, centre.z], { ignore: [ev.object, objectId] }))\n }\n for (const pc of this.pieceSys.list) {\n this.pieceSys.centerOf(pc, centre)\n read(pc.objectId)\n }\n const shoveable = this.o.shoveable\n if (!shoveable) return cover\n for (const b of this.bounds.values()) {\n if (b.piece || cover.has(b.id) || !shoveable(b.id) || !this.world.has(b.id)) continue\n centre.copy(this.measure(b.root, this.meshesOf(b)).center).applyQuaternion(b.root.quaternion).add(b.root.position)\n read(b.id)\n }\n return cover\n }\n\n /** The bound objects without a piece that the host lets a blast move (`shoveable`): the ones it reaches with enough speed become pieces and get the shove. */\n private loosen(point: Vec3, radius: number, energy: number, reachOf: (objectId: string, at: Vec3) => number): void {\n const shoveable = this.o.shoveable\n if (!shoveable) return\n for (const b of [...this.bounds.values()]) {\n if (b.piece || this.pieceSys.get(b.id) || !shoveable(b.id) || !this.world.has(b.id)) continue\n const { half, center } = this.measure(b.root, this.meshesOf(b))\n const world = center.clone().applyQuaternion(b.root.quaternion).add(b.root.position)\n const mass = this.massOf(b.id)\n if (world.distanceTo(this.v2.set(point[0], point[1], point[2])) > radius) continue\n const hit = blastShove({ point, energy, radius, reach: reachOf(b.id, [world.x, world.y, world.z]) }, { position: [world.x, world.y, world.z], mass }, this.o.blastShove)\n if (!hit) continue\n const piece = this.makePiece(b.id, { mass })\n const body = this.pieceSys.get(b.id)\n if (!body) continue\n this.o.onLoosened?.(b.id, piece, 'blast')\n const spread = half[0]\n const momentum = hit.speed * mass\n this.pieceSys.impulse(body, [hit.direction[0] * momentum, hit.direction[1] * momentum, hit.direction[2] * momentum], [world.x + (this.rng() - 0.5) * spread, world.y + spread * 0.5, world.z + (this.rng() - 0.5) * spread])\n }\n }\n\n private playExplosion(ev: Ev<'explode'>, options: ExplodeOptions): void {\n const named = options.effect ?? ev.effect\n const direction = options.direction\n const scale = clamp(ev.radius / GENERIC_REFERENCE_RADIUS, 0.2, 3)\n if (named !== undefined && this.vfx.explosion(named, ev.point, direction ? { direction } : {}) !== null) return\n this.vfx.explosion('generic', ev.point, { scale, ...(direction ? { direction } : {}) })\n }\n\n private startFire(ev: { object: string; part: string; point: Vec3 }): void {\n const key = `${ev.object}|${ev.part}`\n this.stopFire(key)\n this.fires.set(key, { object: ev.object, part: ev.part, point: ev.point, follow: { x: ev.point[0], y: ev.point[1], z: ev.point[2] } })\n }\n\n private stopFire(key: string): void {\n const fire = this.fires.get(key)\n if (!fire) return\n if (fire.handle !== undefined) this.vfx.stop(fire.handle)\n this.fires.delete(key)\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Fire, heat, char, melt, leaks\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n private updateActive(dt: number): void {\n this.scanTimer += dt\n if (this.scanTimer >= 0.4) {\n this.scanTimer = 0\n for (const b of this.bounds.values()) {\n for (const pv of b.parts.values()) {\n if (pv.gone !== 'none' && pv.gone !== 'broken') continue\n const ps = this.world.part(b.id, pv.id)\n if (!ps) continue\n const def = this.world.materials.get(pv.material)\n if (\n ps.burning ||\n (def?.visual?.glows && ps.temperature > GLOW_FROM_C) ||\n Math.abs(ps.char - pv.charApplied) > 0.01 ||\n Math.abs(ps.melt - pv.meltApplied) > 0.01 ||\n (pv.gone === 'none' && (ps.status === 'melted' || ps.status === 'ashes'))\n ) {\n this.activate(b.id, pv.id)\n }\n }\n }\n }\n for (const [key, a] of this.active) {\n const pv = this.partVis(a.object, a.part)\n const ps = pv ? this.world.part(a.object, a.part) : null\n if (!pv || !ps) {\n this.active.delete(key)\n continue\n }\n const def = this.world.materials.get(pv.material)\n if (pv.gone === 'none') {\n this.visuals.setChar(pv, ps.char, def?.visual?.charColor ?? 0x1a1410)\n if (def?.visual?.glows) this.visuals.setGlow(pv, ps.temperature)\n this.visuals.setMelt(pv, ps.melt)\n if (ps.status === 'melted') this.onGone(a.object, pv, 'melted', def)\n else if (ps.status === 'ashes') this.onGone(a.object, pv, 'ashes', def)\n }\n const fire = this.fires.get(key)\n if (fire) {\n if (ps.burning && ps.status !== 'broken' && ps.status !== 'ashes' && ps.status !== 'melted') this.emitFire(fire, pv, def)\n else this.stopFire(key)\n }\n const hot = def?.visual?.glows === true && ps.temperature > GLOW_FROM_C\n if (!ps.burning && !hot && Math.abs(ps.char - pv.charApplied) < 0.01 && Math.abs(ps.melt - pv.meltApplied) < 0.01) {\n if (def?.visual?.glows && pv.gone === 'none') this.visuals.setGlow(pv, 0)\n this.active.delete(key)\n }\n }\n }\n\n private onGone(objectId: string, pv: PartVis, reason: 'melted' | 'ashes', def: MaterialDef | undefined): void {\n const bb = new this.THREE.Box3()\n for (const mv of pv.meshes) bb.union(this.visuals.worldBox(mv, this.box))\n this.visuals.hide(pv, reason)\n if (bb.isEmpty()) return\n const c = bb.getCenter(new this.THREE.Vector3())\n const s = bb.getSize(new this.THREE.Vector3())\n const footprint = Math.sqrt(Math.max(s.x * s.z, 1e-4))\n if (reason === 'melted') {\n this.ground.add('puddle', c.x, c.z, clamp(footprint * 0.55, 0.05, 1), this.partColor(pv, def) ?? fallbackColor(pv.material, def), objectId)\n } else {\n this.ground.add('ash', c.x, c.z, clamp(footprint * 0.35, 0.04, 0.5), 0x1d1a18, objectId)\n this.vfx.burst('ash', [c.x, bb.max.y, c.z], [0, 1, 0], 10, 0.8)\n }\n }\n\n private emitFire(f: FireEmitter, pv: PartVis, def: MaterialDef | undefined): void {\n const bb = this.box\n bb.makeEmpty()\n const tmp = new this.THREE.Box3()\n for (const mv of pv.meshes) if (this.visuals.shown(mv)) bb.union(this.visuals.worldBox(mv, tmp))\n if (!bb.isEmpty()) {\n const c = bb.getCenter(this.v1)\n f.follow.x = c.x\n f.follow.y = bb.min.y\n f.follow.z = c.z\n }\n if (f.handle !== undefined) return\n const size = bb.isEmpty() ? this.v2.set(0.2, 0.2, 0.2) : bb.getSize(this.v2)\n const radius = clamp(Math.max(size.x, size.z) * 0.5, 0.12, 1.2)\n const smokeColor = SMOKE_TONES[def?.thermal.smoke ?? 'grey']\n f.handle = this.vfx.fire({ point: [f.follow.x, f.follow.y, f.follow.z], radius, life: FIRE_CEILING_SECONDS, follow: f.follow, ...(smokeColor !== undefined ? { smokeColor } : {}) })\n }\n\n private updateLeaks(dt: number): void {\n for (let i = this.leaks.length - 1; i >= 0; i--) {\n const l = this.leaks[i]\n const b = this.bounds.get(l.object)\n const ps = this.world.part(l.object, l.part)\n // a leak ends when the container is empty or the opening is closed (a valve shut, `seal`)\n if (!b || !ps || ps.liters === undefined || ps.liters <= 1e-4 || (l.opened && !ps.holes.some((h) => h.through))) {\n this.leaks.splice(i, 1)\n continue\n }\n l.life = (l.life ?? 0) + dt\n if (l.pressurized && l.life > 0.8) l.pressurized = false\n\n if (l.lastLiters !== undefined && Math.abs(ps.liters - l.lastLiters) < 1e-5) {\n l.idleSeconds = (l.idleSeconds ?? 0) + dt\n if (l.idleSeconds > 0.4) {\n this.leaks.splice(i, 1)\n continue\n }\n } else {\n l.idleSeconds = 0\n l.lastLiters = ps.liters\n }\n\n let pt = l.point\n let dir = l.direction\n if (l.localPoint && l.localDirection) {\n b.root.updateWorldMatrix(true, false)\n const wp = this.v1.set(l.localPoint[0], l.localPoint[1], l.localPoint[2]).applyMatrix4(b.root.matrixWorld)\n const wd = this.v2.set(l.localDirection[0], l.localDirection[1], l.localDirection[2]).transformDirection(b.root.matrixWorld).normalize()\n pt = [wp.x, wp.y, wp.z]\n dir = [wd.x, wd.y, wd.z]\n l.point = pt\n l.direction = dir\n }\n\n l.acc += clamp(20 + l.rate * 400, 15, 120) * dt\n const color = FLUID_COLORS[l.fluid] ?? 0xaaaaaa\n const dl = Math.hypot(dir[0], dir[1], dir[2]) || 1\n const sp = l.pressurized ? 2.5 + this.rng() * 1.5 : 0.3 + this.rng() * 0.3\n while (l.acc >= 1) {\n l.acc -= 1\n const vel: Vec3 = [(dir[0] / dl) * sp + (this.rng() - 0.5) * 0.25, (dir[1] / dl) * sp + (this.rng() - 0.5) * 0.25, (dir[2] / dl) * sp + (this.rng() - 0.5) * 0.25]\n if (l.fluid === 'gas') this.vfx.spawn('steam', pt, vel, { color, size: 0.5, alpha: 0.5 })\n else this.vfx.spawn('drips', pt, vel, { color, tag: this.rng() < 0.03 ? this.tagOf(l.object) : 0, owner: this.owner })\n }\n }\n }\n\n private tagOf(object: string): number {\n let tag = this.homeTags.indexOf(object) + 1\n if (tag === 0) tag = this.homeTags.push(object)\n return tag\n }\n\n // ----------------------------------------------------------------------------------------------------------------------------------\n // Emit, clear, restore, stats, dispose\n // ----------------------------------------------------------------------------------------------------------------------------------\n\n emit(kind: DebrisKind | 'fire' | 'flash' | 'foam', point: Vec3, normal: Vec3, count: number, speed?: number): void {\n this.vfx.burst(kind, point, normal, count, speed ?? DEFAULT_SPEED[kind] ?? 1, kind === 'smoke' ? { color: SMOKE_TONES.grey } : undefined)\n }\n\n explode(point: Vec3, energy: number, radius: number, options?: ExplodeOptions): void {\n this.onExplode({ type: 'explode', object: '', part: '', time: this.time, point, energy, radius }, options)\n }\n\n restore(objectId: string): void {\n const homes = new Set<string>([objectId])\n const self = this.bounds.get(objectId)\n if (self?.isSplit) for (const pv of self.parts.values()) homes.add(pv.home)\n for (const home of homes) this.restoreHome(home)\n for (const [key, a] of [...this.active]) if (homes.has(a.object)) this.active.delete(key)\n for (const [key, f] of [...this.fires]) if (homes.has(f.object)) this.stopFire(key)\n for (let i = this.leaks.length - 1; i >= 0; i--) if (homes.has(this.leaks[i].object)) this.leaks.splice(i, 1)\n for (const home of homes) {\n this.fragments.removeHome(home)\n this.ground.removeHome(home)\n this.cages.removeObject(home)\n }\n }\n\n private restoreHome(home: string): void {\n const homeBound = this.bounds.get(home)\n for (const b of [...this.bounds.values()]) {\n for (const [pid, pv] of [...b.parts]) {\n if (pv.home !== home) continue\n this.visuals.restorePart(pv)\n this.tagPart(pv, home)\n if (b !== homeBound && homeBound) {\n b.parts.delete(pid)\n homeBound.parts.set(pid, pv)\n }\n }\n if (b.isSplit && b.parts.size === 0) {\n this.scene.remove(b.root)\n this.pieceSys.remove(b.id)\n this.bounds.delete(b.id)\n // its box leaves now: the periodic round only walks the objects still bound\n this.staticDirty.add(b.id)\n }\n }\n }\n\n clear(): void {\n // what was bound is gone: the next read measures what is left, all of it\n this.staticAll = true\n this.queue.length = 0\n this.slices.length = 0\n this.active.clear()\n for (const key of [...this.fires.keys()]) this.stopFire(key)\n this.leaks.length = 0\n this.trickles.length = 0\n for (const id of [...this.bounds.keys()]) if (this.bounds.has(id)) this.restore(id)\n // anything left of a split object whose home is gone\n for (const b of [...this.bounds.values()]) {\n if (b.isSplit) {\n for (const pv of b.parts.values()) this.visuals.restorePart(pv)\n this.scene.remove(b.root)\n this.pieceSys.remove(b.id)\n this.bounds.delete(b.id)\n }\n }\n this.fragments.clear()\n this.ground.clear()\n this.cages.clear()\n this.primedBurning.clear()\n this.vfx.sprites().clear()\n this.ownVfx?.world.clear()\n }\n\n reset(): void {\n this.clear()\n this.rng = createRng(RNG_SEED)\n this.time = 0\n this.staticAt = 0\n this.staticRound = []\n this.staticAll = true\n this.throttles.clear()\n this.fragments.reset()\n this.pieceSys.reset()\n }\n\n wakeRegion(x: number, z: number, radius: number): void {\n this.fragments.wakeRegion(x, z, radius)\n this.pieceSys.wakeRegion(x, z, radius)\n }\n\n stats(): { fragments: number; particles: number; pieces: number; decals: number } {\n return { fragments: this.fragments.count, particles: this.vfx.sprites().live + this.ownedVfxParticles(), pieces: this.pieceSys.list.length, decals: this.visuals.decalCount + this.ground.count }\n }\n\n private ownedVfxParticles(): number {\n if (!this.ownVfx) return 0\n const { puffs, sparks, glows, chunks } = this.vfx.stats()\n return puffs + sparks + glows + chunks\n }\n\n // The last warm-up keeps its materials until the next one: a material that does not use lights keeps the program of the lights it was first drawn with, so each warm-up needs materials of its own.\n private warmProbes: { readonly group: THREE_NS.Group; readonly geometry: THREE_NS.BufferGeometry; readonly materials: THREE_NS.Material[] } | undefined\n\n warmUpProbes(): WarmUpProbes {\n this.releaseWarmProbes()\n const { kit } = this.visuals\n const T = this.THREE\n const geometry = new T.BufferGeometry()\n geometry.setAttribute('position', new T.BufferAttribute(new Float32Array(6), 3))\n const materials = [kit.discMaterial().clone(), kit.patchMaterial(0x808080).clone(), kit.lineMaterial(0x000000).clone()]\n const group = new T.Group()\n group.add(new T.Mesh(kit.discGeometry(), materials[0]), new T.Mesh(kit.discGeometry(), materials[1]), new T.LineSegments(geometry, materials[2] as THREE_NS.LineBasicMaterial))\n group.add(...this.fragments.warmMeshes())\n for (const probe of group.children) probe.frustumCulled = false\n this.warmProbes = { group, geometry, materials }\n return { group, dispose: () => {} }\n }\n\n private releaseWarmProbes(): void {\n if (!this.warmProbes) return\n this.warmProbes.geometry.dispose()\n for (const material of this.warmProbes.materials) material.dispose()\n this.warmProbes = undefined\n }\n\n rebarCount(): number {\n return this.cages.count\n }\n\n dispose(): void {\n this.releaseWarmProbes()\n if (this.disposed) return\n this.unsubscribe()\n this.clear()\n for (const id of [...this.bounds.keys()]) this.unbind(id)\n this.fragments.dispose()\n this.ground.dispose()\n this.cages.dispose()\n this.stopLanding()\n this.visuals.dispose()\n this.ownVfx?.dispose()\n this.disposed = true\n }\n}\n","import type * as THREE_NS from 'three'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { Fragment, SplitForm } from '@adatechnology/game-destruction'\n\nimport { pushFittedBoxes } from './fitted-boxes'\nimport { FRAGMENT_SHAPE_VARIANTS, buildBrokenBoardGeometry, buildLumpGeometry, buildSliverGeometry, buildVeneerGeometry } from './fragment-shapes'\nimport { clamp, createRng, hashString } from './math'\nimport type { LooseBody } from './types'\n\ninterface Live {\n mesh: THREE_NS.Mesh\n home: string\n vel: THREE_NS.Vector3\n ang: THREE_NS.Vector3\n half: THREE_NS.Vector3\n baseScale: THREE_NS.Vector3\n still: number\n asleep: boolean\n /** Seconds at rest. */\n rest: number\n /** 1 while alive; counts down to 0 while shrinking away. */\n fade: number\n dying: boolean\n /** Air drag per second: a loose sheet (a page) glides and flutters down instead of dropping. */\n air: number\n /** A big one (`isBig`): it stays where it lies, and what walks steps on it or kicks it. */\n body: LooseBody | null\n /** The `update` count when it was made. */\n born: number\n /** Seconds it stays at rest before it fades (0 = forever). */\n life: number\n}\n\n/** What a fragment's resting time can depend on: the fragment (its material, size, shape) and the id of the object it came from. */\nexport type FragmentLifeRule = (fragment: Fragment, objectId: string) => number\n\nexport interface FragmentSystemOptions {\n scene: THREE_NS.Scene\n groundAt: (x: number, z: number) => number\n gravity: number\n max: number\n /** Seconds a resting fragment stays before it fades (0 = forever), or a rule that gives it per fragment. */\n life: number | FragmentLifeRule\n /** How a material comes apart (`MaterialDef.splitForm`): MDF lumps and plywood veneer get shapes of their own. Default: none. */\n formOf?: (materialId: string) => SplitForm | undefined\n}\n\nconst BUILDERS: Record<Exclude<SharedShape, 'shard'>, (THREE: typeof THREE_NS, seed: number) => THREE_NS.BufferGeometry> = {\n sliver: buildSliverGeometry,\n lump: buildLumpGeometry,\n veneer: buildVeneerGeometry,\n board: buildBrokenBoardGeometry,\n}\n\n/** The shared shapes a fragment can take besides the box: glass shards, wood splinters, MDF lumps, plywood veneer and the torn stub of a broken board. */\ntype SharedShape = 'shard' | 'sliver' | 'lump' | 'veneer' | 'board'\n\n/** Thickest scrap that flies as a sheet (m), its air drag (1/s) and how hard it sways (m/s²). */\nconst SHEET_MAX = 0.004\nconst SHEET_AIR = 2.5\nconst SHEET_SWAY = 3\n/** A fragment at least this long (m) and this wide is a piece of the thing (half a board), not a splinter; a shard of glass never is. */\nconst BIG_LENGTH = 0.2\nconst BIG_WIDTH = 0.03\n/** The seed of the fragments' random stream (their spin and sway); `reset` takes it back here. */\nconst FRAGMENT_SEED = 0x51ed270b\n\n/** Fragments asleep whose ground is looked at again each update, in turn, and how far (m) over it one may lie before it falls: the table it lay on broke. */\nconst SUPPORT_CHECKS = 32\nconst SUPPORT_GAP = 0.02\n\n/** How many shard shapes there are; a fragment takes one by the hash of its id. */\nconst SHARD_SHAPES = 6\n\nconst isBig = (size: readonly number[]): boolean => {\n const [, middle, longest] = [...size].sort((a, b) => a - b)\n return longest >= BIG_LENGTH && middle >= BIG_WIDTH\n}\n\n/** Light physics for fracture debris: gravity, ground bounce and friction, spin damping, settling flat, sleep, shrink-away and removal. */\nexport class FragmentSystem {\n private readonly list: Live[] = []\n private readonly box: THREE_NS.BoxGeometry\n /** The mesh box of a fragment before its scale. */\n private readonly unitBox = { min: { x: -0.5, y: -0.5, z: -0.5 }, max: { x: 0.5, y: 0.5, z: 0.5 } }\n private shardGeos: THREE_NS.BufferGeometry[] = []\n private readonly shapeGeos = new Map<Exclude<SharedShape, 'shard'>, THREE_NS.BufferGeometry[]>()\n private readonly materials = new Map<string, THREE_NS.Material>()\n private readonly q: THREE_NS.Quaternion\n private readonly dq: THREE_NS.Quaternion\n private readonly m: THREE_NS.Matrix4\n private readonly v: THREE_NS.Vector3\n private readonly w: THREE_NS.Vector3\n private rng = createRng(FRAGMENT_SEED)\n /** Count of `update` calls: what makes the fragments of one burst tell apart from older ones. */\n private tick = 0\n private supportTurn = 0\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly o: FragmentSystemOptions,\n ) {\n this.box = new THREE.BoxGeometry(1, 1, 1)\n this.q = new THREE.Quaternion()\n this.dq = new THREE.Quaternion()\n this.m = new THREE.Matrix4()\n this.v = new THREE.Vector3()\n this.w = new THREE.Vector3()\n }\n\n get count(): number {\n return this.list.length\n }\n\n /** Meshes of every live fragment (tests and picking). */\n meshes(): THREE_NS.Mesh[] {\n return this.list.map((f) => f.mesh)\n }\n\n /** One shared material per source material id + colour (+ transparency). */\n materialFor(materialId: string, color: number, transparent: boolean, opacity = 0.5): THREE_NS.Material {\n const key = `${materialId}:${color}:${transparent ? 1 : 0}`\n let m = this.materials.get(key)\n if (!m) {\n m = transparent\n ? new this.THREE.MeshStandardMaterial({ color, roughness: 0.15, metalness: 0.1, transparent: true, opacity, side: this.THREE.DoubleSide, depthWrite: false })\n : new this.THREE.MeshLambertMaterial({ color })\n this.materials.set(key, m)\n }\n return m\n }\n\n private shardGeometry(seed: number): THREE_NS.BufferGeometry {\n const idx = seed % SHARD_SHAPES\n let g = this.shardGeos[idx]\n if (!g) {\n const r = createRng(1000 + idx)\n const n = 3 + Math.floor(r() * 3) // triangle, quad or pentagon, irregular\n const shape = new this.THREE.Shape()\n const pts: Array<[number, number]> = []\n for (let i = 0; i < n; i++) {\n const a = (i / n) * Math.PI * 2 + (r() - 0.5) * 0.7\n const rad = 0.35 + r() * 0.15\n pts.push([Math.cos(a) * rad, Math.sin(a) * rad])\n }\n shape.moveTo(pts[0][0], pts[0][1])\n for (let i = 1; i < n; i++) shape.lineTo(pts[i][0], pts[i][1])\n shape.closePath()\n g = new this.THREE.ExtrudeGeometry(shape, { depth: 1, bevelEnabled: false })\n g.translate(0, 0, -0.5)\n this.shardGeos[idx] = g\n }\n return g\n }\n\n private sharedGeometry(shape: Exclude<SharedShape, 'shard'>, seed: number): THREE_NS.BufferGeometry {\n const idx = seed % FRAGMENT_SHAPE_VARIANTS\n let variants = this.shapeGeos.get(shape)\n if (!variants) {\n variants = []\n this.shapeGeos.set(shape, variants)\n }\n let g = variants[idx]\n if (!g) {\n g = BUILDERS[shape](this.THREE, idx)\n variants[idx] = g\n }\n return g\n }\n\n /**\n * The geometry a fragment is drawn with: a splinter is a pointed, frayed sliver; MDF breaks in lumps, plywood peels in ragged veneer, the stub of a broken\n * board ends in torn strands at +x; the rest are boxes.\n */\n private geometryOf(f: Fragment): THREE_NS.BufferGeometry {\n const seed = hashString(f.id)\n if (f.shape === 'shard') return this.shardGeometry(seed)\n if (f.shape === 'splinter') return this.sharedGeometry('sliver', seed)\n const form = this.o.formOf?.(f.material)\n if (f.shape === 'chunk' && form === 'granules') return this.sharedGeometry('lump', seed)\n if (f.shape === 'scrap' && form === 'plies') return this.sharedGeometry('veneer', seed)\n if (f.shape === 'slab' && (form === 'slivers' || form === 'plies')) return this.sharedGeometry('board', seed)\n return this.box\n }\n\n private markGeometry: THREE_NS.CircleGeometry | null = null\n private markMaterial: THREE_NS.MeshBasicMaterial | null = null\n\n private markParts(): { geometry: THREE_NS.CircleGeometry; material: THREE_NS.MeshBasicMaterial } {\n this.markGeometry ??= new this.THREE.CircleGeometry(1, 10)\n this.markMaterial ??= new this.THREE.MeshBasicMaterial({ color: 0x0b0a09, depthWrite: false, polygonOffset: true, polygonOffsetFactor: -4, polygonOffsetUnits: -4 })\n return { geometry: this.markGeometry, material: this.markMaterial }\n }\n\n /**\n * Meshes, never put in a scene by this class, that draw every shared piece of a fragment once: the box, the six shards, the wood splinters, MDF lumps and plywood veneer, the bullet-hole disc, and the opaque and\n * glass materials. A host draws them at load so the first blast does not upload these buffers in the middle of a frame.\n */\n warmMeshes(): THREE_NS.Mesh[] {\n const opaque = this.materialFor('warm', 0x808080, false)\n const glass = this.materialFor('warm', 0x808080, true)\n const geometries = [this.box, ...Array.from({ length: SHARD_SHAPES }, (_, index) => this.shardGeometry(index))]\n const wood = (['sliver', 'lump', 'veneer', 'board'] as const).flatMap((shape) => Array.from({ length: FRAGMENT_SHAPE_VARIANTS }, (_, index) => this.sharedGeometry(shape, index)))\n const { geometry, material } = this.markParts()\n return [\n ...geometries.flatMap((shared) => [new this.THREE.Mesh(shared, opaque), new this.THREE.Mesh(shared, glass)]),\n ...wood.map((shared) => new this.THREE.Mesh(shared, opaque)),\n new this.THREE.Mesh(geometry, material),\n ]\n }\n\n /**\n * Bullet holes that stay on a fragment (`Fragment.marks`): dark discs that are children of its mesh, so they fall, spin and settle with it. The mesh is\n * a unit box scaled to the fragment, so each disc is scaled back; exact for a mark on a face, which is where a bullet hole is.\n */\n addMarks(mesh: THREE_NS.Mesh, f: Fragment): void {\n if (!f.marks?.length) return\n const { geometry, material } = this.markParts()\n const sc = mesh.scale\n for (const mark of f.marks) {\n const disc = new this.THREE.Mesh(geometry, material)\n const radius = Math.max(0.004, mark.diameter) * 0.6\n const n = this.v.set(mark.normal[0], mark.normal[1], mark.normal[2]).normalize()\n disc.position.set(mark.point[0] / sc.x + (n.x * 0.002) / sc.x, mark.point[1] / sc.y + (n.y * 0.002) / sc.y, mark.point[2] / sc.z + (n.z * 0.002) / sc.z)\n disc.quaternion.setFromUnitVectors(this.w.set(0, 0, 1), n)\n disc.scale.set(radius / sc.x, radius / sc.y, radius / sc.z)\n mesh.add(disc)\n }\n }\n\n /**\n * Create the mesh of a fragment and start its motion. `maxAllowed` is the live budget: over it the oldest fragment still showing fades out to make room, and a burst\n * bigger than the budget (every live fragment was made in this same frame) does not make the rest at all, so a blast never builds a thousand meshes only to fade them\n * out. Returns null when the fragment was not made.\n */\n /**\n * Throws `f` into the scene, within `maxAllowed` live fragments (the oldest small ones make room first). A `lasting` fragment (a steel bar) is debris that\n * stays: it has a body the player and the pieces run into, however thin it is, and it never fades.\n */\n spawn(f: Fragment, material: THREE_NS.Material, home: string, maxAllowed: number, lasting = false): THREE_NS.Mesh | null {\n if (this.list.length >= maxAllowed) {\n let alive = 0\n let oldest: Live | undefined\n let oldestSmall: Live | undefined\n for (const l of this.list) {\n if (l.dying) continue\n alive++\n oldest ??= l\n if (!l.body) oldestSmall ??= l\n }\n // the splinters go first; the big ones only when nothing else is left\n oldest = oldestSmall ?? oldest\n if (alive >= maxAllowed) {\n if (!oldest || oldest.born === this.tick) return null\n oldest.dying = true\n }\n }\n const geo = this.geometryOf(f)\n const mesh = new this.THREE.Mesh(geo, material)\n mesh.position.set(f.center[0], f.center[1], f.center[2])\n mesh.quaternion.set(f.rotation[0], f.rotation[1], f.rotation[2], f.rotation[3]).normalize()\n const sz = f.size\n const sc = new this.THREE.Vector3(Math.max(0.005, sz[0]), Math.max(0.005, sz[1]), Math.max(0.003, sz[2]))\n mesh.scale.copy(sc)\n mesh.castShadow = true\n // pure visual debris: a host that picks with a raycast can skip it\n mesh.userData.destructionDebris = true\n mesh.name = 'fragment'\n markKitOrigin(mesh, { owner: 'game-destruction-three', kind: 'fragment', id: f.material })\n this.o.scene.add(mesh)\n const live: Live = {\n mesh,\n home,\n vel: new this.THREE.Vector3(f.velocity[0], f.velocity[1], f.velocity[2]),\n ang: new this.THREE.Vector3(f.angularVelocity[0], f.angularVelocity[1], f.angularVelocity[2]),\n // shards are thin: the contact extent uses the real (small) thickness, the chunk uses half of each side\n half: sc.clone().multiplyScalar(0.5),\n baseScale: sc,\n still: 0,\n asleep: false,\n rest: 0,\n fade: 1,\n dying: false,\n air: f.shape === 'scrap' && sz[2] <= SHEET_MAX ? SHEET_AIR : 0,\n body: null,\n born: this.tick,\n life: lasting ? 0 : Math.max(0, typeof this.o.life === 'function' ? this.o.life(f, home) : this.o.life),\n }\n if (lasting || (f.shape !== 'shard' && isBig(f.size))) {\n live.body = {\n mass: f.mass,\n push: (x, z) => {\n live.vel.x = x\n live.vel.z = z\n live.vel.y = Math.max(live.vel.y, 0.3)\n this.rouse(live)\n },\n }\n }\n this.list.push(live)\n this.addMarks(mesh, f)\n return mesh\n }\n\n /** The boxes of the big fragments around (x, z). */\n solidsNear(x: number, z: number, radius: number, found: (home: string, min: [number, number, number], max: [number, number, number], body: LooseBody) => void): void {\n const boxes: number[] = []\n for (const f of this.list) {\n if (!f.body || f.dying) continue\n const reach = f.half.length() + radius\n if (Math.abs(f.mesh.position.x - x) > reach || Math.abs(f.mesh.position.z - z) > reach) continue\n f.mesh.updateMatrixWorld()\n boxes.length = 0\n pushFittedBoxes(this.unitBox, f.mesh.matrixWorld, boxes)\n for (let i = 0; i < boxes.length; i += 6) {\n if (x < boxes[i] - radius || x > boxes[i + 3] + radius || z < boxes[i + 2] - radius || z > boxes[i + 5] + radius) continue\n found(f.home, [boxes[i], boxes[i + 1], boxes[i + 2]], [boxes[i + 3], boxes[i + 4], boxes[i + 5]], f.body)\n }\n }\n }\n\n /** Add velocity to every fragment within `radius` of a point (blasts). */\n blast(point: [number, number, number], radius: number, speed: number): void {\n for (const f of this.list) {\n const d = this.v.copy(f.mesh.position).sub(this.w.set(point[0], point[1], point[2]))\n const dist = d.length()\n if (dist > radius || f.dying) continue\n const k = (1 - dist / radius) ** 2 * speed\n d.normalize().multiplyScalar(k)\n d.y += k * 0.4\n f.vel.add(d)\n f.ang.add(this.w.set(this.rng() - 0.5, this.rng() - 0.5, this.rng() - 0.5).multiplyScalar(k))\n this.rouse(f)\n }\n }\n\n /** A fragment that came to rest stops having its matrix recomputed on every frame; whatever moves it again calls this first. */\n private rouse(f: Live): void {\n f.asleep = false\n f.rest = 0\n f.mesh.matrixAutoUpdate = true\n }\n\n /** What lies inside the disc looks at the ground again: it was dug or heaped under it. */\n wakeRegion(x: number, z: number, radius: number): void {\n for (const f of this.list) {\n if (!f.asleep || Math.hypot(f.mesh.position.x - x, f.mesh.position.z - z) > radius) continue\n this.rouse(f)\n }\n }\n\n update(dt: number): void {\n this.tick++\n this.wakeUnsupported()\n const g = this.o.gravity\n for (let i = this.list.length - 1; i >= 0; i--) {\n const f = this.list[i]\n if (f.dying) {\n f.mesh.matrixAutoUpdate = true\n f.fade -= dt / 0.6\n if (f.fade <= 0) {\n this.o.scene.remove(f.mesh)\n this.list.splice(i, 1)\n continue\n }\n f.mesh.scale.copy(f.baseScale).multiplyScalar(f.fade)\n }\n if (f.asleep) {\n f.rest += dt\n if (f.life > 0 && f.rest > f.life && !f.body) {\n f.dying = true\n f.mesh.matrixAutoUpdate = true\n }\n continue\n }\n this.step(f, dt, g)\n }\n }\n\n /** A few fragments asleep each update (`SUPPORT_CHECKS`, in turn) look at the ground under them again: one left over air falls. */\n private wakeUnsupported(): void {\n const n = this.list.length\n for (let k = 0; k < Math.min(SUPPORT_CHECKS, n); k++) {\n this.supportTurn = (this.supportTurn + 1) % n\n const f = this.list[this.supportTurn]\n if (!f.asleep || f.dying) continue\n const e = this.m.makeRotationFromQuaternion(f.mesh.quaternion).elements\n const ext = Math.abs(e[1]) * f.half.x + Math.abs(e[5]) * f.half.y + Math.abs(e[9]) * f.half.z\n if (f.mesh.position.y - ext > this.o.groundAt(f.mesh.position.x, f.mesh.position.z) + SUPPORT_GAP) this.rouse(f)\n }\n }\n\n private step(f: Live, dt: number, g: number): void {\n const mesh = f.mesh\n f.vel.y -= g * dt\n mesh.position.addScaledVector(f.vel, dt)\n const w = f.ang.length()\n if (w > 1e-5) {\n this.dq.setFromAxisAngle(this.v.copy(f.ang).multiplyScalar(1 / w), w * dt)\n mesh.quaternion.premultiply(this.dq).normalize()\n }\n // ground contact: lowest point of the oriented box\n this.m.makeRotationFromQuaternion(mesh.quaternion)\n const e = this.m.elements\n const h = f.half\n const sc = f.dying ? f.fade : 1\n const ext = (Math.abs(e[1]) * h.x + Math.abs(e[5]) * h.y + Math.abs(e[9]) * h.z) * sc\n const gy = this.o.groundAt(mesh.position.x, mesh.position.z)\n let contact = false\n if (mesh.position.y - ext < gy) {\n contact = true\n mesh.position.y = gy + ext\n if (f.vel.y < -0.6) {\n f.vel.y = -f.vel.y * 0.25\n f.vel.x *= 0.7\n f.vel.z *= 0.7\n f.ang.multiplyScalar(0.55)\n // a hit on a corner makes it tumble a little\n f.ang.x += (this.rng() - 0.5) * 2\n f.ang.z += (this.rng() - 0.5) * 2\n } else {\n f.vel.y = 0\n const fr = Math.exp(-7 * dt)\n f.vel.x *= fr\n f.vel.z *= fr\n f.ang.multiplyScalar(Math.exp(-6 * dt))\n }\n } else {\n f.ang.multiplyScalar(Math.exp(-0.15 * dt))\n if (f.air > 0) this.flutter(f, dt)\n }\n if (contact && f.vel.lengthSq() < 4) this.settle(f, dt)\n const slow = f.vel.lengthSq() < 0.012 && f.ang.lengthSq() < 0.2\n if (contact && slow) {\n f.still += dt\n if (f.still > 0.4) {\n f.asleep = true\n f.mesh.updateMatrix()\n f.mesh.matrixAutoUpdate = false\n f.vel.set(0, 0, 0)\n f.ang.set(0, 0, 0)\n }\n } else {\n f.still = 0\n }\n }\n\n /** A sheet in the air: drag slows it to a slow fall, and it sways and turns over as it goes. */\n private flutter(f: Live, dt: number): void {\n f.vel.multiplyScalar(Math.exp(-f.air * dt))\n f.vel.x += (this.rng() - 0.5) * SHEET_SWAY * dt\n f.vel.z += (this.rng() - 0.5) * SHEET_SWAY * dt\n f.ang.x += (this.rng() - 0.5) * SHEET_SWAY * 4 * dt\n f.ang.z += (this.rng() - 0.5) * SHEET_SWAY * 4 * dt\n }\n\n /** Tip the fragment towards lying on its flattest face. */\n private settle(f: Live, dt: number): void {\n const mesh = f.mesh\n this.m.makeRotationFromQuaternion(mesh.quaternion)\n const e = this.m.elements\n const up = [e[1], e[5], e[9]] // world-y component of each local axis\n const half = [f.half.x, f.half.y, f.half.z]\n let small = 0\n for (let i = 1; i < 3; i++) if (half[i] < half[small]) small = i\n let axis = small\n // a broken board does not stand on its end\n if (Math.abs(up[small]) < 0.35 && !f.body) {\n axis = 0\n for (let i = 1; i < 3; i++) if (Math.abs(up[i]) > Math.abs(up[axis])) axis = i\n }\n const sign = up[axis] >= 0 ? 1 : -1\n this.v.set(e[axis * 4], e[axis * 4 + 1], e[axis * 4 + 2]).multiplyScalar(sign)\n this.w.set(0, 1, 0)\n this.dq.setFromUnitVectors(this.v, this.w)\n this.q.copy(this.dq).multiply(mesh.quaternion)\n mesh.quaternion.slerp(this.q, clamp(dt * 7, 0, 1))\n }\n\n /** Remove the fragments of one object (after `restore`). */\n removeHome(home: string): void {\n for (let i = this.list.length - 1; i >= 0; i--) {\n if (this.list[i].home === home) {\n this.o.scene.remove(this.list[i].mesh)\n this.list.splice(i, 1)\n }\n }\n }\n\n clear(): void {\n for (const f of this.list) this.o.scene.remove(f.mesh)\n this.list.length = 0\n }\n\n /** `clear`, the random stream back to its seed and the tick to 0: what comes next flies as on a new system. */\n reset(): void {\n this.clear()\n this.rng = createRng(FRAGMENT_SEED)\n this.tick = 0\n }\n\n dispose(): void {\n this.clear()\n this.box.dispose()\n this.markGeometry?.dispose()\n this.markMaterial?.dispose()\n for (const g of this.shardGeos) g?.dispose()\n this.shardGeos = []\n for (const variants of this.shapeGeos.values()) for (const g of variants) g?.dispose()\n this.shapeGeos.clear()\n for (const m of this.materials.values()) m.dispose()\n this.materials.clear()\n }\n}\n","import type * as THREE_NS from 'three'\n\n/** Slice length (m) of a turned mesh and the most slices of one mesh. */\nconst SLICE_LENGTH = 0.12\nconst MAX_SLICES = 12\n/** A mesh whose axis box is at most this many times its own volume counts as not turned. */\nconst SNUG_RATIO = 1.1\n\ntype Corner = { readonly x: number; readonly y: number; readonly z: number }\ntype Local = { readonly min: Corner; readonly max: Corner }\n\n/**\n * Appends world axis boxes (min x, y, z, max x, y, z) around the local box of a mesh: one when it lies square, else slices along its longest side. The axis box of a board\n * lying askew is a wide square that holds mostly air, and what walks would hit that air.\n */\nexport function pushFittedBoxes(local: Local, matrix: THREE_NS.Matrix4, out: number[]): void {\n const e = matrix.elements\n const sizes = [0, 1, 2].map((k) => (k === 0 ? local.max.x - local.min.x : k === 1 ? local.max.y - local.min.y : local.max.z - local.min.z))\n const lengths = [0, 1, 2].map((k) => sizes[k] * Math.hypot(e[k * 4], e[k * 4 + 1], e[k * 4 + 2]))\n const longest = lengths.indexOf(Math.max(...lengths))\n const whole = worldBoxOf(local, matrix, longest, 0, 1)\n const span = (whole[3] - whole[0]) * (whole[4] - whole[1]) * (whole[5] - whole[2])\n const volume = lengths[0] * lengths[1] * lengths[2]\n const slices = span <= volume * SNUG_RATIO ? 1 : Math.min(MAX_SLICES, Math.ceil(lengths[longest] / SLICE_LENGTH))\n if (slices <= 1) {\n out.push(...whole)\n return\n }\n for (let i = 0; i < slices; i++) out.push(...worldBoxOf(local, matrix, longest, i / slices, (i + 1) / slices))\n}\n\nfunction worldBoxOf(local: Local, matrix: THREE_NS.Matrix4, axis: number, from: number, to: number): number[] {\n const e = matrix.elements\n const low = [local.min.x, local.min.y, local.min.z]\n const high = [local.max.x, local.max.y, local.max.z]\n const start = low[axis]\n const size = high[axis] - start\n low[axis] = start + size * from\n high[axis] = start + size * to\n const box = [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity]\n for (const x of [low[0], high[0]]) for (const y of [low[1], high[1]]) for (const z of [low[2], high[2]]) {\n for (let k = 0; k < 3; k++) {\n const v = e[k] * x + e[k + 4] * y + e[k + 8] * z + e[k + 12]\n box[k] = Math.min(box[k], v)\n box[k + 3] = Math.max(box[k + 3], v)\n }\n }\n return box\n}\n","import type { Vec3 } from '@adatechnology/game-destruction'\n\n/** Small deterministic PRNG (mulberry32): returns a function giving numbers in [0, 1). */\nexport function createRng(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** Hash of a few numbers into an unsigned 32-bit seed. */\nexport function hashNumbers(...values: number[]): number {\n let h = 2166136261\n for (const v of values) {\n const n = Math.round(v * 1000) | 0\n h = Math.imul(h ^ n, 16777619)\n h ^= h >>> 13\n }\n return h >>> 0\n}\n\nexport function hashString(s: string): number {\n let h = 2166136261\n for (let i = 0; i < s.length; i++) h = Math.imul(h ^ s.charCodeAt(i), 16777619)\n return h >>> 0\n}\n\nexport const clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v)\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t\n\nexport function vec3Length(v: Vec3): number {\n return Math.hypot(v[0], v[1], v[2])\n}\n\nexport function normalize3(v: Vec3): Vec3 {\n const l = Math.hypot(v[0], v[1], v[2])\n return l > 1e-9 ? [v[0] / l, v[1] / l, v[2] / l] : [0, 1, 0]\n}\n\n/** `0xRRGGBB` -> `[r, g, b]` in 0..1. */\nexport function hexToRgb(hex: number): [number, number, number] {\n return [((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255]\n}\n\nexport function mixHex(a: number, b: number, t: number): number {\n const ar = (a >> 16) & 255\n const ag = (a >> 8) & 255\n const ab = a & 255\n const r = Math.round(ar + (((b >> 16) & 255) - ar) * t)\n const g = Math.round(ag + (((b >> 8) & 255) - ag) * t)\n const bl = Math.round(ab + ((b & 255) - ab) * t)\n return (r << 16) | (g << 8) | bl\n}\n","import type * as THREE_NS from 'three'\n\nimport { createRng } from './math'\n\n/** How many shapes of each kind there are; a fragment takes one by the hash of its id, so a burst shares a handful of buffers. */\nexport const FRAGMENT_SHAPE_VARIANTS = 6\n\n/** Cross-sections along a sliver (the last one is its point) and how much each corner may stray in or out (the torn fibres). */\nconst SLIVER_STATIONS = 6\nconst SLIVER_FRAY = 0.3\n\n/** Corners of a sliver's cross-section in the unit box: the four corners and a ridge on each wide face. */\nconst SLIVER_SECTION: ReadonlyArray<readonly [number, number]> = [[0.5, 0.5], [0, 0.5], [-0.5, 0.5], [-0.5, -0.5], [0, -0.5], [0.5, -0.5]]\n\n/** Width of the section along a sliver (0 at the broken end, 1 at the point): ragged and narrower at the break, full in the middle, tapering to the point. */\nconst sliverWidth = (t: number): number => (t < 0.25 ? 0.6 + 1.6 * t : t > 0.5 ? Math.max(0, (1 - t) / 0.5) ** 0.85 : 1)\n\nconst pushTriangle = (out: number[], a: readonly number[], b: readonly number[], c: readonly number[]): void => {\n out.push(a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2])\n}\n\nconst faceted = (THREE: typeof THREE_NS, positions: number[]): THREE_NS.BufferGeometry => {\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n geometry.computeVertexNormals()\n return geometry\n}\n\n/**\n * A splinter of wood in the unit box, long along x: a ragged broken end, a body whose corners stray in and out from section to section (the torn fibres\n * along its edges), bending a little, and a point at the other end that is off its axis. About 60 triangles, shared by every splinter of the variant.\n */\nexport function buildSliverGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(7000 + seed)\n const rings: number[][][] = []\n const bendY = (rnd() - 0.5) * 0.3\n const bendZ = (rnd() - 0.5) * 0.3\n for (let i = 0; i < SLIVER_STATIONS - 1; i++) {\n const t = i / (SLIVER_STATIONS - 1)\n const x = -0.5 + t + (i > 0 ? (rnd() - 0.5) * 0.08 : 0)\n const width = sliverWidth(t)\n const lift = Math.sin(t * Math.PI)\n rings.push(SLIVER_SECTION.map(([y, z]) => {\n const fray = 1 - SLIVER_FRAY + SLIVER_FRAY * 1.4 * rnd()\n return [x, Math.max(-0.5, Math.min(0.5, y * width * fray + bendY * lift)), Math.max(-0.5, Math.min(0.5, z * width * fray + bendZ * lift))]\n }))\n }\n const tip = [0.5, (rnd() - 0.5) * 0.5, (rnd() - 0.5) * 0.3]\n // the broken end is torn, not cut: its centre stands out or sinks in\n const torn = [-0.5 + rnd() * 0.12, (rnd() - 0.5) * 0.2, (rnd() - 0.5) * 0.2]\n const sides = SLIVER_SECTION.length\n const positions: number[] = []\n for (let k = 0; k < sides; k++) {\n const next = (k + 1) % sides\n pushTriangle(positions, torn, rings[0][next], rings[0][k])\n for (let i = 0; i < rings.length - 1; i++) {\n const a = rings[i][k], b = rings[i][next], c = rings[i + 1][next], d = rings[i + 1][k]\n pushTriangle(positions, a, b, c)\n pushTriangle(positions, a, c, d)\n }\n const last = rings[rings.length - 1]\n pushTriangle(positions, last[k], last[next], tip)\n }\n return faceted(THREE, positions)\n}\n\n/**\n * A crumbly lump of pressed fibre (MDF) in the unit box: an icosahedron whose corners are pushed in and out by where they are (so the faces stay\n * closed), squashed to fill the box. 20 triangles.\n */\nexport function buildLumpGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(8000 + seed)\n const base = new THREE.IcosahedronGeometry(0.5, 0)\n const source = base.getAttribute('position')\n const pushOf = new Map<string, number>()\n const positions: number[] = []\n for (let i = 0; i < source.count; i++) {\n const x = source.getX(i), y = source.getY(i), z = source.getZ(i)\n const key = `${x.toFixed(3)},${y.toFixed(3)},${z.toFixed(3)}`\n let push = pushOf.get(key)\n if (push === undefined) {\n push = 0.6 + 0.55 * rnd()\n pushOf.set(key, push)\n }\n positions.push(x * push, y * push, z * push)\n }\n base.dispose()\n const extent = [0, 0, 0]\n for (let i = 0; i < positions.length; i++) extent[i % 3] = Math.max(extent[i % 3], Math.abs(positions[i]))\n for (let i = 0; i < positions.length; i++) positions[i] *= 0.5 / Math.max(extent[i % 3], 1e-3)\n return faceted(THREE, positions)\n}\n\n/** Points along each long edge of a peeled sheet of veneer. */\nconst VENEER_EDGE = 11\n\n/**\n * A sheet of veneer peeled off plywood in the unit box (thin along z): long edges torn along the grain in fine teeth (now and then a deeper notch) and\n * the short ends broken across with a sliver standing out, extruded to its thickness.\n */\nexport function buildVeneerGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(9000 + seed)\n const shape = new THREE.Shape()\n const outline: Array<[number, number]> = []\n // the long edges tear along the grain in fine teeth; each short end breaks across with one long sliver of veneer standing out\n const edge = (y: number, inward: number): number => y - inward * (rnd() * 0.16 + (rnd() < 0.15 ? 0.12 : 0))\n for (let i = 0; i <= VENEER_EDGE; i++) outline.push([-0.5 + i / VENEER_EDGE, edge(0.5, 1)])\n outline.push([0.5 - rnd() * 0.12, 0.2 * rnd()], [0.5, -0.1 + 0.2 * rnd()], [0.5 - rnd() * 0.12, -0.25 * rnd()])\n for (let i = VENEER_EDGE; i >= 0; i--) outline.push([-0.5 + i / VENEER_EDGE, edge(-0.5, -1)])\n outline.push([-0.5 + rnd() * 0.12, -0.2 * rnd()], [-0.5, 0.1 * rnd()], [-0.5 + rnd() * 0.12, 0.25 * rnd()])\n shape.moveTo(outline[0][0], outline[0][1])\n for (let i = 1; i < outline.length; i++) shape.lineTo(outline[i][0], outline[i][1])\n shape.closePath()\n const geometry = new THREE.ExtrudeGeometry(shape, { depth: 1, bevelEnabled: false })\n geometry.translate(0, 0, -0.5)\n return geometry\n}\n\n/** Share of a broken board's length its torn end takes, and how many strands of fibre (at least, at most) the end splits into across its width. */\nconst TORN_END = 0.24\nconst TORN_STRANDS: readonly [number, number] = [4, 7]\n\n/** Pushes the two triangles of the quad a-b-c-d, wound so that it faces where (b - a) x (c - b) points. */\nconst pushQuad = (out: number[], quad: ReadonlyArray<readonly number[]>): void => {\n pushTriangle(out, quad[0], quad[1], quad[2])\n pushTriangle(out, quad[0], quad[2], quad[3])\n}\n\n/** Uneven cuts of [-0.5, 0.5] into `count` widths, each between a third and twice the mean. */\nconst unevenCuts = (count: number, rnd: () => number): number[] => {\n const shares = Array.from({ length: count }, () => 0.35 + 1.65 * rnd())\n const total = shares.reduce((sum, share) => sum + share, 0)\n const cuts = [-0.5]\n for (const share of shares) cuts.push(cuts[cuts.length - 1] + share / total)\n cuts[cuts.length - 1] = 0.5\n return cuts\n}\n\n/**\n * The stub of a wooden board broken across, in the unit box, long along x: the sound part of the board, and at its +x end the break, torn into strands\n * of fibre of uneven widths and lengths that bend a little and fray before they come to points, not a clean saw cut. 58 to 94 triangles.\n */\nexport function buildBrokenBoardGeometry(THREE: typeof THREE_NS, seed: number): THREE_NS.BufferGeometry {\n const rnd = createRng(10000 + seed)\n const end = 0.5 - TORN_END\n const positions: number[] = []\n const lo = -0.5, hi = 0.5\n // the sound part of the board: a box from the far end to where the break starts (its face at the break is closed by the strands)\n pushQuad(positions, [[lo, lo, hi], [end, lo, hi], [end, hi, hi], [lo, hi, hi]])\n pushQuad(positions, [[lo, hi, lo], [end, hi, lo], [end, lo, lo], [lo, lo, lo]])\n pushQuad(positions, [[lo, hi, hi], [end, hi, hi], [end, hi, lo], [lo, hi, lo]])\n pushQuad(positions, [[lo, lo, lo], [end, lo, lo], [end, lo, hi], [lo, lo, hi]])\n pushQuad(positions, [[lo, lo, lo], [lo, lo, hi], [lo, hi, hi], [lo, hi, lo]])\n const count = TORN_STRANDS[0] + Math.floor(rnd() * (TORN_STRANDS[1] - TORN_STRANDS[0] + 1))\n const cuts = unevenCuts(count, rnd)\n for (let k = 0; k < count; k++) {\n const y0 = cuts[k], y1 = cuts[k + 1]\n const length = TORN_END * (0.15 + 0.85 * rnd())\n // halfway out the strand has narrowed and strays a little sideways and up or down; then it comes to a point off its middle\n const midX = end + length * (0.35 + 0.3 * rnd())\n const narrow = 0.55 + 0.35 * rnd()\n const shiftY = (rnd() - 0.5) * (y1 - y0) * 0.6\n const shiftZ = (rnd() - 0.5) * 0.5\n const cy = (y0 + y1) / 2 + shiftY, hy = ((y1 - y0) / 2) * narrow, hz = 0.5 * (0.4 + 0.5 * rnd())\n const base = [[end, y0, lo], [end, y1, lo], [end, y1, hi], [end, y0, hi]]\n const clampZ = (z: number): number => Math.max(lo, Math.min(hi, z))\n const mid = [[midX, cy - hy, clampZ(shiftZ - hz)], [midX, cy + hy, clampZ(shiftZ - hz)], [midX, cy + hy, clampZ(shiftZ + hz)], [midX, cy - hy, clampZ(shiftZ + hz)]]\n const tip = [end + length, y0 + (y1 - y0) * rnd(), clampZ(shiftZ + (rnd() - 0.5) * 0.4)]\n for (let i = 0; i < 4; i++) {\n const next = (i + 1) % 4\n pushQuad(positions, [base[i], base[next], mid[next], mid[i]])\n pushTriangle(positions, mid[i], mid[next], tip)\n }\n }\n return faceted(THREE, positions)\n}\n","import type * as THREE_NS from 'three'\nimport { lerp } from './math'\n\ninterface Spot {\n mesh: THREE_NS.Mesh\n kind: 'puddle' | 'ash'\n home: string\n x: number\n z: number\n radius: number\n target: number\n}\n\nconst MAX_RADIUS = 1.2\n\n/** Flat discs on the ground: puddles of melted material and piles of ash. Nearby ones merge; the oldest go when the cap is reached. */\nexport class GroundSpots {\n private readonly spots: Spot[] = []\n private readonly geometry: THREE_NS.CircleGeometry\n private readonly materials = new Map<string, THREE_NS.MeshBasicMaterial>()\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly scene: THREE_NS.Scene,\n private readonly groundAt: (x: number, z: number) => number,\n private readonly cap: number,\n ) {\n this.geometry = new THREE.CircleGeometry(1, 20)\n this.geometry.rotateX(-Math.PI / 2)\n }\n\n get count(): number {\n return this.spots.length\n }\n\n private material(kind: 'puddle' | 'ash', color: number): THREE_NS.MeshBasicMaterial {\n const key = `${kind}:${color}`\n let m = this.materials.get(key)\n if (!m) {\n m = new this.THREE.MeshBasicMaterial({\n color,\n transparent: true,\n opacity: kind === 'puddle' ? 0.88 : 0.95,\n depthWrite: false,\n polygonOffset: true,\n polygonOffsetFactor: -2,\n polygonOffsetUnits: -2,\n })\n this.materials.set(key, m)\n }\n return m\n }\n\n /** Add (or grow) a spot at (x, z). `radius` is the radius this addition contributes. */\n add(kind: 'puddle' | 'ash', x: number, z: number, radius: number, color: number, home: string): void {\n for (const s of this.spots) {\n if (s.kind !== kind) continue\n const d = Math.hypot(s.x - x, s.z - z)\n if (d < Math.max(s.target, radius) * 0.9) {\n s.target = Math.min(MAX_RADIUS, Math.sqrt(s.target * s.target + radius * radius * 0.5))\n return\n }\n }\n while (this.spots.length >= this.cap) this.remove(this.spots[0])\n const mesh = new this.THREE.Mesh(this.geometry, this.material(kind, color))\n const y = this.groundAt(x, z) + 0.004 + (this.spots.length % 8) * 0.0004\n mesh.position.set(x, y, z)\n mesh.scale.setScalar(0.001)\n mesh.renderOrder = 1\n mesh.userData.destructionDebris = true\n this.scene.add(mesh)\n this.spots.push({ mesh, kind, home, x, z, radius: 0.001, target: Math.min(MAX_RADIUS, radius) })\n }\n\n private remove(s: Spot): void {\n const i = this.spots.indexOf(s)\n if (i >= 0) this.spots.splice(i, 1)\n this.scene.remove(s.mesh)\n }\n\n update(dt: number): void {\n const k = Math.min(1, dt * 3)\n for (const s of this.spots) {\n if (Math.abs(s.radius - s.target) < 1e-4) continue\n s.radius = lerp(s.radius, s.target, k)\n s.mesh.scale.setScalar(s.radius)\n }\n }\n\n /** Remove the spots made for one object (after its `restore`). */\n removeHome(home: string): void {\n for (const s of [...this.spots]) if (s.home === home) this.remove(s)\n }\n\n clear(): void {\n for (const s of [...this.spots]) this.remove(s)\n }\n\n dispose(): void {\n this.clear()\n this.geometry.dispose()\n for (const m of this.materials.values()) m.dispose()\n this.materials.clear()\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { Vec3 } from '@adatechnology/game-destruction'\nimport type { PieceBody, PieceFriction } from './internal'\nimport { clamp } from './math'\n\nexport interface PieceSystemOptions {\n groundAt: (x: number, z: number) => number\n /**\n * The highest top of what does not move (furniture, scenery) under `(x, z)` that a corner at height `y` can land on (at most `step` above it),\n * `-Infinity` when none. The ground and the other pieces are added by the system.\n */\n staticTopAt?: (x: number, z: number, y: number, step: number) => number\n gravity: number\n /** A piece hit the ground faster than 3 m/s (throttled per piece). */\n onHardLanding: (piece: PieceBody, point: Vec3, speed: number) => void\n /** Notified when a piece is about to be removed. */\n scene: THREE_NS.Scene\n /**\n * What a piece moving from `from` to `to` (its centre, world) runs into on the way: a wall, a car, a cupboard (`distance` along the way, the `normal` of what it met).\n * Without it a piece only meets the ground, the tops of fixed things and the other pieces.\n */\n sweep?: (piece: PieceBody, from: Vec3, to: Vec3) => PieceSweepHit | null\n /** A piece ran into something (`sweep`) faster than `SLAM_MIN_SPEED` m/s into it (throttled per piece): for the blow on both and the sound. */\n onSlam?: (piece: PieceBody, hit: PieceSweepHit, speed: number) => void\n}\n\n/** What a moving piece ran into (`PieceSystemOptions.sweep`). */\nexport interface PieceSweepHit {\n readonly object: string\n readonly part: string\n /** Metres along the way from the centre where the piece meets it. */\n readonly distance: number\n readonly point: Vec3\n readonly normal: Vec3\n}\n\n/** Slower than this (m/s) into a wall a piece only stops against it: no blow, no sound. */\nexport const SLAM_MIN_SPEED = 2\n/** Share of the speed into a wall a piece keeps, bouncing back. */\nconst SLAM_BOUNCE = 0.2\n/** Normals steeper than this (y) are a floor or a top: the support of the pieces answers those, not the sweep. */\nconst SLAM_FLOOR_NORMAL = 0.7\n\nconst SUB_DT = 1 / 120\n/** Coulomb friction of a piece when no material says otherwise: what holds it still (static) and what drags it while it slides (dynamic). */\nconst MU_STATIC = 0.7\nconst MU_DYNAMIC = 0.6\n/** Sliding faster than this (m/s) along the surface, a contact drags with the dynamic friction; slower, it holds with the static one. */\nconst SLIP_SPEED = 0.02\nconst SLEEP_AFTER = 0.5\n/**\n * A piece on the ground that neither moves farther than `CALM_DRIFT` (m) nor turns more than `CALM_TURN` (rad) in `CALM_SLEEP_AFTER` seconds sleeps, however\n * its speed flickers: a book propped on another, or trembling where its corners rest on two pieces, stays in place; a fall or a slide leaves the window sooner.\n */\nconst CALM_DRIFT = 0.01\nconst CALM_TURN = 0.05\nconst CALM_SLEEP_AFTER = 1.5\nconst HARD_LANDING = 3\n/** Contact tolerance in metres: corners this close to the ground count as touching, which keeps the contact set (and a resting box) stable. */\nconst SLOP = 0.002\n/** A resting support narrower than this fraction of the centre-of-mass height is a balancing act, not a rest: the piece topples. */\nconst NARROW = 0.3\n/** Angular acceleration (rad/s^2 per metre of height) that pushes a balancing piece off its edge, toward the side its centre of mass leans to. */\nconst TOPPLE = 3\n/** Angular acceleration (rad/s^2) of a piece that falls over (`tip`), beyond what the box of its bounds would allow, and the height of the centre of mass (m) at which it lies. */\nconst TIP_ACCELERATION = 30\nconst TIP_LYING = 0.25\nconst TIP_SECONDS = 3\n/** How far (m) above a corner a top may be and still catch it (on top of what the corner falls in one sub-step): higher is beside it, not under it. */\nconst STEP = 0.03\n/** Slots of the warm start: the 8 corners and the points along the 12 edges. */\nconst WARM_SLOTS = 8 + 12 * 7\n/** Passes of the contact solver over the points that touch the ground, each substep. */\nconst SOLVER_PASSES = 10\n/** Restitution of a piece against the side of a step of the ground. */\nconst SIDE_BOUNCE = 0.1\n/**\n * Points along each edge of the box, between its corners (fractions of the half edge), that also touch the ground when the support under the corners is not level\n * (the piece is over a step): the edge of a table under a box's bottom is a support between its corners. On level ground the corners are enough.\n */\nconst EDGE_POINTS = [-0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75]\n/** Sleeping pieces whose support is looked at again each update, in turn: what held one up may have broken, fallen over or been carried off. */\nconst SUPPORT_CHECKS = 16\n/** A sleeping piece none of whose lowest points has a support within this many metres under it wakes and falls. */\nconst SUPPORT_GAP = 0.02\n/** A piece moving faster than this (m/s) or turning faster than this (rad/s) wakes what lies asleep on it. */\nconst WAKE_ABOVE_SPEED = 0.05\nconst WAKE_ABOVE_SPIN = 0.1\n\n/** Box of a piece in the world: centre, rotation columns (`Matrix4.elements`) and half extents. */\ninterface Solid {\n body: PieceBody\n c: Vec3\n e: number[]\n half: Vec3\n /** Radius of the box around its centre: a point farther than it on the ground plane misses it. */\n r: number\n}\n\n/** The axis of the box whose face the last `boxTopAt` line left through (its top there): the face a point on that spot stands on. */\nlet topFace = 1\n\n/** Height where the vertical line through `(x, z)` leaves the top of a box, or -Infinity when it misses the box. */\nconst boxTopAt = (s: Solid, x: number, z: number): number => {\n const e = s.e\n const dx = x - s.c[0], dz = z - s.c[2]\n let t0 = -Infinity, t1 = Infinity\n for (let k = 0; k < 3; k++) {\n // the line is c + (dx, t, dz) with t the height over the centre; along axis k: p + t d\n const p = e[k * 4] * dx + e[k * 4 + 2] * dz\n const d = e[k * 4 + 1]\n const h = s.half[k]\n if (Math.abs(d) < 1e-9) {\n if (Math.abs(p) > h) return -Infinity\n continue\n }\n let a = (-h - p) / d, b = (h - p) / d\n if (a > b) [a, b] = [b, a]\n t0 = Math.max(t0, a)\n if (b < t1) {\n t1 = b\n topFace = k\n }\n if (t0 > t1) return -Infinity\n }\n return s.c[1] + t1\n}\n\nconst UP: Vec3 = [0, 1, 0]\n\n/** The outward normal of face `axis` of a box on its upper side: the surface of a tilted table top under a point. */\nconst faceNormal = (s: Solid, axis: number): Vec3 => {\n const e = s.e\n const sign = e[axis * 4 + 1] < 0 ? -1 : 1\n return [sign * e[axis * 4], sign * e[axis * 4 + 1], sign * e[axis * 4 + 2]]\n}\n\n/** The friction of two surfaces against each other: the geometric mean of each one's coefficients. */\nconst pairFriction = (a: PieceFriction | undefined, b: PieceFriction | null): PieceFriction => ({\n static: Math.sqrt((a?.static ?? MU_STATIC) * (b?.static ?? MU_STATIC)),\n dynamic: Math.sqrt((a?.dynamic ?? MU_DYNAMIC) * (b?.dynamic ?? MU_DYNAMIC)),\n})\n\n/**\n * Light rigid-body physics for loose pieces: gravity, the 8 corners of the local box against the ground with an impulse (restitution, friction,\n * angular response), damping, sleeping, and a gentle horizontal separation between pieces side by side. The ground a corner lands on is the\n * highest of the terrain, the top of any other piece under it and what the host reports as fixed (`staticTopAt`): a falling shelf lands on the books\n * below it, a tipping panel on the chair in front of it. Over a step (a table's edge) points along the box's edges touch too, so the edge holds the box between\n * its corners, and the side of a step of the ground is a wall: a corner that comes at it from the side stops there. The contacts are solved together, warm started.\n * Not a general solver: what lies under a corner holds it, what stands beside it does not.\n */\nexport class PieceSystem {\n readonly list: PieceBody[] = []\n private time = 0\n private readonly p: THREE_NS.Vector3\n private readonly q: THREE_NS.Quaternion\n private readonly dq: THREE_NS.Quaternion\n private readonly m: THREE_NS.Matrix4\n private readonly ax: THREE_NS.Vector3\n private solids: Solid[] = []\n private supportTurn = 0\n /** The surface normal and the friction of what the last `supportAt` found under the point (the ground and fixed tops are level: up, and no piece). */\n private supportNormal: Vec3 = UP\n private supportFriction: PieceFriction | null = null\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly o: PieceSystemOptions,\n ) {\n this.p = new THREE.Vector3()\n this.q = new THREE.Quaternion()\n this.dq = new THREE.Quaternion()\n this.m = new THREE.Matrix4()\n this.ax = new THREE.Vector3()\n }\n\n get(objectId: string): PieceBody | null {\n return this.list.find((b) => b.objectId === objectId) ?? null\n }\n\n /** Sets a piece falling over, about the world axes x and z (a unit axis): its feet are thinner than the box that stands for it, so the box alone would hold it up. */\n tip(body: PieceBody, x: number, z: number): void {\n body.tipping = { x, z, seconds: TIP_SECONDS }\n body.sleeping = false\n }\n\n create(objectId: string, root: THREE_NS.Object3D, halfExtents: Vec3, localCenter: THREE_NS.Vector3, mass: number, velocity?: Vec3, angular?: Vec3): PieceBody {\n const existing = this.get(objectId)\n if (existing) {\n existing.root = root\n existing.halfExtents = halfExtents\n existing.mass = mass\n this.setCenter(existing, localCenter)\n if (velocity) existing.velocity = [...velocity]\n existing.sleeping = false\n return existing\n }\n const body: PieceBody = {\n objectId,\n tipping: null,\n root,\n velocity: velocity ? [...velocity] : [0, 0, 0],\n angularVelocity: angular ? [...angular] : [0, 0, 0],\n halfExtents: [Math.max(0.01, halfExtents[0]), Math.max(0.01, halfExtents[1]), Math.max(0.01, halfExtents[2])],\n mass: Math.max(0.05, mass),\n sleeping: false,\n held: false,\n localCenter: [localCenter.x, localCenter.y, localCenter.z],\n centerV: localCenter.clone(),\n still: 0,\n calmAt: null,\n calm: 0,\n lastHit: -1,\n onGround: false,\n }\n this.list.push(body)\n return body\n }\n\n /** Move the centre of mass (after a part broke off). */\n setCenter(b: PieceBody, c: THREE_NS.Vector3): void {\n b.centerV.copy(c)\n b.localCenter = [c.x, c.y, c.z]\n }\n\n remove(objectId: string): void {\n const i = this.list.findIndex((b) => b.objectId === objectId)\n if (i >= 0) this.list.splice(i, 1)\n }\n\n clear(): void {\n this.list.length = 0\n }\n\n /** `clear` and the clock back to 0. */\n reset(): void {\n this.clear()\n this.time = 0\n }\n\n /** World position of the centre of mass. */\n centerOf(b: PieceBody, out: THREE_NS.Vector3): THREE_NS.Vector3 {\n return out.copy(b.centerV).applyQuaternion(b.root.quaternion).add(b.root.position)\n }\n\n impulse(b: PieceBody, impulse: Vec3, point?: Vec3): void {\n const inv = 1 / b.mass\n b.velocity[0] += impulse[0] * inv\n b.velocity[1] += impulse[1] * inv\n b.velocity[2] += impulse[2] * inv\n if (point) {\n const c = this.centerOf(b, this.p)\n const rx = point[0] - c.x\n const ry = point[1] - c.y\n const rz = point[2] - c.z\n // torque = r x J, angular velocity change = I^-1 torque\n const tx = ry * impulse[2] - rz * impulse[1]\n const ty = rz * impulse[0] - rx * impulse[2]\n const tz = rx * impulse[1] - ry * impulse[0]\n const w = this.mulInvInertia(b, tx, ty, tz)\n b.angularVelocity[0] += w[0]\n b.angularVelocity[1] += w[1]\n b.angularVelocity[2] += w[2]\n }\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n }\n\n /** I^-1 * (x, y, z) in world space for a box with the body's half extents and mass (needs `this.m` to hold the body's rotation). */\n private mulInvInertia(b: PieceBody, x: number, y: number, z: number): Vec3 {\n this.m.makeRotationFromQuaternion(b.root.quaternion)\n return this.mulInvInertiaWith(b, this.m.elements, x, y, z)\n }\n\n private mulInvInertiaWith(b: PieceBody, e: ArrayLike<number>, x: number, y: number, z: number): Vec3 {\n const [hx, hy, hz] = b.halfExtents\n const k = 3 / b.mass\n const ix = k / (hy * hy + hz * hz)\n const iy = k / (hx * hx + hz * hz)\n const iz = k / (hx * hx + hy * hy)\n // local = R^T v (columns of R are the local axes in world space)\n const lx = (e[0] * x + e[1] * y + e[2] * z) * ix\n const ly = (e[4] * x + e[5] * y + e[6] * z) * iy\n const lz = (e[8] * x + e[9] * y + e[10] * z) * iz\n return [e[0] * lx + e[4] * ly + e[8] * lz, e[1] * lx + e[5] * ly + e[9] * lz, e[2] * lx + e[6] * ly + e[10] * lz]\n }\n\n /** The points of the box that touch the ground, in its own frame: the 8 corners, then (with `edges`) `EDGE_POINTS` along each of its 12 edges; or the piece's own `contacts`. */\n private samples(b: PieceBody, edges: boolean): Vec3[] {\n if (b.contacts) return b.contacts\n const [hx, hy, hz] = b.halfExtents\n const out: Vec3[] = []\n for (let i = 0; i < 8; i++) out.push([i & 1 ? hx : -hx, i & 2 ? hy : -hy, i & 4 ? hz : -hz])\n if (!edges) return out\n const h = [hx, hy, hz]\n for (let axis = 0; axis < 3; axis++) {\n const a1 = (axis + 1) % 3\n const a2 = (axis + 2) % 3\n for (let k = 0; k < 4; k++) {\n for (const f of EDGE_POINTS) {\n const p: Vec3 = [0, 0, 0]\n p[axis] = f * h[axis]\n p[a1] = k & 1 ? h[a1] : -h[a1]\n p[a2] = k & 2 ? h[a2] : -h[a2]\n out.push(p)\n }\n }\n }\n return out\n }\n\n /**\n * An impulse along the unit normal `n` at `r` (from the centre of mass, world) that stops the point closing in along `n` (with `bounce`); `e` holds the body's rotation.\n */\n private contactImpulse(b: PieceBody, e: ArrayLike<number>, r: Vec3, n: Vec3, bounce: number): void {\n const v = b.velocity\n const w = b.angularVelocity\n const vn = (v[0] + w[1] * r[2] - w[2] * r[1]) * n[0] + (v[1] + w[2] * r[0] - w[0] * r[2]) * n[1] + (v[2] + w[0] * r[1] - w[1] * r[0]) * n[2]\n if (vn >= 0) return\n // I^-1 (r x n), then (I^-1 (r x n) x r) . n\n const a = this.mulInvInertiaWith(b, e, r[1] * n[2] - r[2] * n[1], r[2] * n[0] - r[0] * n[2], r[0] * n[1] - r[1] * n[0])\n const k = (a[1] * r[2] - a[2] * r[1]) * n[0] + (a[2] * r[0] - a[0] * r[2]) * n[1] + (a[0] * r[1] - a[1] * r[0]) * n[2]\n const j = (-(1 + bounce) * vn) / (1 / b.mass + k)\n for (let i = 0; i < 3; i++) {\n v[i] += (j * n[i]) / b.mass\n w[i] += a[i] * j\n }\n }\n\n /** What lies inside the disc looks at the ground again: it was dug or heaped under it. */\n wakeRegion(x: number, z: number, radius: number): void {\n for (const b of this.list) {\n if (!b.sleeping || b.held || Math.hypot(b.root.position.x - x, b.root.position.z - z) > radius) continue\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n }\n }\n\n update(dt: number): void {\n this.time += dt\n this.solids = this.list.map((body) => {\n const c = this.centerOf(body, new this.THREE.Vector3())\n const h = body.halfExtents\n return { body, c: [c.x, c.y, c.z] as Vec3, e: [...new this.THREE.Matrix4().makeRotationFromQuaternion(body.root.quaternion).elements], half: h, r: Math.hypot(h[0], h[1], h[2]) }\n })\n this.wakeUnsupported()\n for (const b of this.list) {\n if (b.held) {\n b.velocity = [0, 0, 0]\n b.angularVelocity = [0, 0, 0]\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n continue\n }\n if (b.sleeping) continue\n this.integrate(b, dt)\n if (b.sleeping) continue\n const v = b.velocity\n const w = b.angularVelocity\n if (Math.hypot(v[0], v[1], v[2]) > WAKE_ABOVE_SPEED || Math.hypot(w[0], w[1], w[2]) > WAKE_ABOVE_SPIN) this.wakeAbove(b)\n }\n this.separate(dt)\n }\n\n /** A few sleeping pieces each update (`SUPPORT_CHECKS`, in turn) look under them again: one whose table broke, or whose shelf fell over, falls. */\n private wakeUnsupported(): void {\n const n = this.list.length\n for (let k = 0; k < Math.min(SUPPORT_CHECKS, n); k++) {\n this.supportTurn = (this.supportTurn + 1) % n\n const b = this.list[this.supportTurn]\n if (!b.sleeping || b.held || this.supported(b, false) || this.supported(b, true)) continue\n b.sleeping = false\n b.still = 0\n b.calmAt = null\n }\n }\n\n /**\n * Whether a point of `b` (its corners, or with `edges` the points along its edges too) has the ground, a piece or a fixed top under it. Any point, not only the lowest:\n * a book propped on a fallen case rests by a corner high on it while its lowest one hangs beside it.\n */\n private supported(b: PieceBody, edges: boolean): boolean {\n const c = this.centerOf(b, this.p)\n const e = this.m.makeRotationFromQuaternion(b.root.quaternion).elements\n for (const [sx, sy, sz] of this.samples(b, edges)) {\n const y = c.y + e[1] * sx + e[5] * sy + e[9] * sz\n const x = c.x + e[0] * sx + e[4] * sy + e[8] * sz\n const z = c.z + e[2] * sx + e[6] * sy + e[10] * sz\n if (this.supportAt(b, x, y, z, STEP) >= y - SUPPORT_GAP) return true\n }\n return false\n }\n\n /** The highest top of a piece (other than `self`) under `(x, z)` that a point at height `y` stands on (at most `step` above it), -Infinity when none; the boxes of the last update. */\n topAt(x: number, z: number, y: number, step: number, self?: string): number {\n let top = -Infinity\n for (const s of this.solids) {\n if (s.body.objectId === self || s.body.held || Math.abs(x - s.c[0]) > s.r || Math.abs(z - s.c[2]) > s.r) continue\n const t = boxTopAt(s, x, z)\n if (t > top && t <= y + step) top = t\n }\n return top\n }\n\n /** What lay asleep on `b` (a box over its top) wakes at once when `b` moves: a can on a table that goes over goes with it. */\n private wakeAbove(b: PieceBody): void {\n const below = this.solids.find((s) => s.body === b)\n if (!below) return\n const top = below.c[1] + below.half[0] * Math.abs(below.e[1]) + below.half[1] * Math.abs(below.e[5]) + below.half[2] * Math.abs(below.e[9])\n for (const s of this.solids) {\n const o = s.body\n if (!o.sleeping || o.held || o === b) continue\n if (s.c[1] < below.c[1] || s.c[1] - s.r > top + STEP || Math.hypot(s.c[0] - below.c[0], s.c[2] - below.c[2]) > s.r + below.r) continue\n o.sleeping = false\n o.still = 0\n o.calmAt = null\n }\n }\n\n /** Where a corner of `self` at `(x, y, z)` lands: the ground, the top of another piece or of something fixed under it. */\n private supportAt(self: PieceBody, x: number, y: number, z: number, step: number): number {\n let top = this.o.groundAt(x, z)\n let on: Solid | null = null\n let face = 1\n for (const s of this.solids) {\n if (s.body === self || s.body.held || Math.abs(x - s.c[0]) > s.r || Math.abs(z - s.c[2]) > s.r) continue\n const t = boxTopAt(s, x, z)\n if (t > top && t <= y + step) {\n top = t\n on = s\n face = topFace\n }\n }\n const fixed = this.o.staticTopAt?.(x, z, y, step) ?? -Infinity\n if (fixed >= top) on = null\n this.supportNormal = on ? faceNormal(on, face) : UP\n this.supportFriction = on?.body.friction ?? null\n return Math.max(top, fixed)\n }\n\n /** Stops a piece that ran into something on its way from `start` to `pos` (`sweep`): moves it back to where it met it and takes the speed into it. */\n private sweepOn(b: PieceBody, start: Vec3, pos: Vec3): void {\n const travel = Math.hypot(pos[0] - start[0], pos[1] - start[1], pos[2] - start[2])\n if (travel < 1e-3) return\n const hit = this.o.sweep?.(b, start, pos)\n if (!hit || hit.normal[1] > SLAM_FLOOR_NORMAL) return\n const v = b.velocity\n const n = hit.normal\n const into = -(v[0] * n[0] + v[1] * n[1] + v[2] * n[2])\n if (into <= 0) return\n const k = Math.min(1, hit.distance / travel)\n for (let i = 0; i < 3; i++) {\n pos[i] = start[i] + (pos[i] - start[i]) * k\n v[i] += (1 + SLAM_BOUNCE) * into * n[i]\n }\n const w = b.angularVelocity\n w[0] *= 0.5\n w[1] *= 0.5\n w[2] *= 0.5\n if (into >= SLAM_MIN_SPEED && this.time - b.lastHit > 0.15) {\n b.lastHit = this.time\n this.o.onSlam?.(b, hit, into)\n }\n }\n\n private integrate(b: PieceBody, dt: number): void {\n const c = this.centerOf(b, this.p)\n const pos: Vec3 = [c.x, c.y, c.z]\n const start: Vec3 = [c.x, c.y, c.z]\n const q = this.q.copy(b.root.quaternion)\n const v = b.velocity\n const w = b.angularVelocity\n const invM = 1 / b.mass\n const steps = clamp(Math.ceil(dt / SUB_DT), 1, 8)\n const h = dt / steps\n let landing = 0\n let landPoint: Vec3 = [pos[0], pos[1], pos[2]]\n let contactedLast = false\n let touched = false\n let unstable = false\n\n // over a step of the ground (the corners find it at different heights: a table's edge under it) the points along the edges touch too\n const corners = this.samples(b, false)\n this.m.makeRotationFromQuaternion(q)\n let gLow = Infinity\n let gHigh = -Infinity\n for (const [sx, sy, sz] of corners) {\n const e0 = this.m.elements\n const y = pos[1] + e0[1] * sx + e0[5] * sy + e0[9] * sz\n const x = pos[0] + e0[0] * sx + e0[4] * sy + e0[8] * sz\n const z = pos[2] + e0[2] * sx + e0[6] * sy + e0[10] * sz\n // only the fixed ground counts here: other pieces touching it (a pile, things spawned together) keep the corners\n const g = Math.max(this.o.groundAt(x, z), this.o.staticTopAt?.(x, z, y, STEP) ?? -Infinity)\n gLow = Math.min(gLow, g)\n gHigh = Math.max(gHigh, g)\n }\n const local = gHigh - gLow > STEP ? this.samples(b, true) : corners\n const prev: Vec3[] = local.map(() => [0, 0, 0])\n\n for (let s = 0; s < steps; s++) {\n // where each point was before this substep: a point that comes at a higher ground from below it hit the side of the step\n this.m.makeRotationFromQuaternion(q)\n const e0 = this.m.elements\n for (let i = 0; i < local.length; i++) {\n const [sx, sy, sz] = local[i]\n prev[i][0] = pos[0] + e0[0] * sx + e0[4] * sy + e0[8] * sz\n prev[i][1] = pos[1] + e0[1] * sx + e0[5] * sy + e0[9] * sz\n prev[i][2] = pos[2] + e0[2] * sx + e0[6] * sy + e0[10] * sz\n }\n v[1] -= this.o.gravity * h\n pos[0] += v[0] * h\n pos[1] += v[1] * h\n pos[2] += v[2] * h\n const wl = Math.hypot(w[0], w[1], w[2])\n if (wl > 1e-6) {\n this.dq.setFromAxisAngle(this.ax.set(w[0] / wl, w[1] / wl, w[2] / wl), wl * h)\n q.premultiply(this.dq).normalize()\n }\n const damp = Math.exp(-0.15 * h)\n w[0] *= damp\n w[1] *= damp\n w[2] *= damp\n\n this.m.makeRotationFromQuaternion(q)\n const e = this.m.elements\n const rs: Vec3[] = []\n const ids: number[] = []\n // per contact: the normal of the surface under it and the friction of the two surfaces\n const ns: Vec3[] = []\n const mus: PieceFriction[] = []\n let maxPen = 0\n // the normal of the surface under the deepest point: the piece is pushed out along it (straight up on the floor, across a tilted top)\n let penNormal: Vec3 = UP\n const rise = STEP + Math.max(0, -v[1]) * h * 2\n // the side of a step of the ground: how far back the piece goes (metres along -dir) and the point that hit it\n let side: { back: number; dir: [number, number]; r: Vec3 } | null = null\n let lowest = Infinity\n for (let i = 0; i < local.length; i++) {\n const [sx, sy, sz] = local[i]\n const r: Vec3 = [e[0] * sx + e[4] * sy + e[8] * sz, e[1] * sx + e[5] * sy + e[9] * sz, e[2] * sx + e[6] * sy + e[10] * sz]\n const px = pos[0] + r[0]\n const pz = pos[2] + r[2]\n const cy = pos[1] + r[1]\n // the ground's own step (a table, a counter) that the point was more than a step below before this substep: it came at its side or is\n // under it, and does not stand on it (nor ratchets up onto it as the rest of the piece is lifted)\n const was = prev[i]\n const raw = this.o.groundAt(px, pz)\n if (raw > cy - SLOP && was[1] < raw - STEP) {\n // under a top it was already beneath (put under an overhang), or coming at its side: either way that top does not hold it\n if (this.o.groundAt(was[0], was[2]) >= raw - STEP) {\n // beneath it, the point stands on the floor the piece last stood on (the height field cannot see under a top)\n const floor = b.floor\n if (floor !== undefined && floor - cy > -SLOP && floor < raw - STEP) {\n rs.push(r)\n ids.push(i)\n ns.push(UP)\n mus.push(pairFriction(b.friction, null))\n maxPen = Math.max(maxPen, floor - cy)\n }\n continue\n }\n const dx = px - was[0]\n const dz = pz - was[2]\n const len = Math.hypot(dx, dz)\n if (len > 1e-6) {\n // where along its move the point met the side: the first place the ground is up at this top\n let lo = 0\n let hi = 1\n for (let it = 0; it < 6; it++) {\n const mid = (lo + hi) / 2\n if (this.o.groundAt(was[0] + dx * mid, was[2] + dz * mid) >= raw - STEP) hi = mid\n else lo = mid\n }\n const back = (1 - lo) * len + 0.001\n if (!side || back > side.back) side = { back, dir: [dx / len, dz / len], r }\n }\n continue\n }\n // the points along the edges are there for the step of the ground; on other pieces only the corners stand, as everywhere else\n this.supportNormal = UP\n this.supportFriction = null\n const gy = i < 8 || b.contacts ? this.supportAt(b, px, cy, pz, rise) : Math.max(raw, this.o.staticTopAt?.(px, pz, cy, rise) ?? -Infinity)\n const pen = gy - cy\n if (pen > -SLOP) {\n rs.push(r)\n ids.push(i)\n ns.push(this.supportNormal)\n mus.push(pairFriction(b.friction, this.supportFriction))\n if (pen > maxPen) {\n maxPen = pen\n penNormal = this.supportNormal\n }\n lowest = Math.min(lowest, gy)\n }\n }\n if (lowest < Infinity) b.floor = lowest\n if (side) {\n // the side of the step stops the piece: back out of it, and the point loses the speed it had into the side\n pos[0] -= side.dir[0] * side.back\n pos[2] -= side.dir[1] * side.back\n this.contactImpulse(b, e, side.r, [-side.dir[0], 0, -side.dir[1]], SIDE_BOUNCE)\n }\n contactedLast = rs.length > 0\n if (contactedLast) touched = true\n if (!contactedLast) continue\n // a point `maxPen` under a surface of normal n is `maxPen * n.y` inside it, along n\n const out = Math.max(0, maxPen - SLOP * 0.5) * penNormal[1]\n pos[0] += penNormal[0] * out\n pos[1] += penNormal[1] * out\n pos[2] += penNormal[2] * out\n let impact = 0\n for (const r of rs) impact = Math.max(impact, -(v[1] + w[2] * r[0] - w[0] * r[2]))\n const restitution = impact > 2 ? 0.25 : 0\n if (impact > landing) {\n landing = impact\n let sx = 0\n let sz = 0\n for (const r of rs) {\n sx += r[0]\n sz += r[2]\n }\n const lx = pos[0] + sx / rs.length\n const lz = pos[2] + sz / rs.length\n landPoint = [lx, pos[1] - Math.max(...rs.map((r) => -r[1])), lz]\n }\n // Contact impulses, solved together: each point keeps the impulse it has given so far (pushing only, never pulling) and the friction it has\n // given (within the paper's grip times that push), and every pass corrects them. Points spread unevenly under the box (a table's edge under\n // half of it) then share the weight as they should, instead of the first ones handled kicking the box into a spin.\n // the velocity of a point of the piece: v + w x r\n const pointV = (r: Vec3): Vec3 => [v[0] + w[1] * r[2] - w[2] * r[1], v[1] + w[2] * r[0] - w[0] * r[2], v[2] + w[0] * r[1] - w[1] * r[0]]\n const dot = (a: Vec3, c: Vec3): number => a[0] * c[0] + a[1] * c[1] + a[2] * c[2]\n const goal = rs.map((r, k) => {\n const vn = dot(pointV(r), ns[k])\n return vn < 0 ? -restitution * vn : 0\n })\n // a point that slides drags with the dynamic friction, one that holds with the static one (Coulomb)\n const slipping = rs.map((r, k) => {\n const pv = pointV(r)\n const vn = dot(pv, ns[k])\n return Math.hypot(pv[0] - vn * ns[k][0], pv[1] - vn * ns[k][1], pv[2] - vn * ns[k][2]) > SLIP_SPEED\n })\n // the step moved the piece at the speed it had before the contacts: what they took from it along the ground is taken from the move too, so\n // a push the floor's grip holds does not creep the piece along\n const vx0 = v[0]\n const vz0 = v[2]\n // warm start: each point starts from what it gave in the last substep (a resting box carries its weight from the first pass)\n if (!b.warm || b.warm.length !== WARM_SLOTS * 4) b.warm = new Float64Array(WARM_SLOTS * 4)\n const warm = b.warm\n const accN = ids.map((id) => (id < WARM_SLOTS ? warm[id * 4] : 0))\n const accT = ids.map((id): Vec3 => (id < WARM_SLOTS ? [warm[id * 4 + 1], warm[id * 4 + 2], warm[id * 4 + 3]] : [0, 0, 0]))\n /** Gives the piece the impulse `j` (world) at `r`. */\n const push = (r: Vec3, j: Vec3): void => {\n v[0] += j[0] * invM\n v[1] += j[1] * invM\n v[2] += j[2] * invM\n const dw = this.mulInvInertiaWith(b, e, r[1] * j[2] - r[2] * j[1], r[2] * j[0] - r[0] * j[2], r[0] * j[1] - r[1] * j[0])\n w[0] += dw[0]\n w[1] += dw[1]\n w[2] += dw[2]\n }\n /** The mass the piece shows to an impulse along the unit `d` at `r`: 1 / (1/m + (I^-1 (r x d) x r) . d). */\n const reach = (r: Vec3, d: Vec3): number => {\n const a = this.mulInvInertiaWith(b, e, r[1] * d[2] - r[2] * d[1], r[2] * d[0] - r[0] * d[2], r[0] * d[1] - r[1] * d[0])\n return invM + (a[1] * r[2] - a[2] * r[1]) * d[0] + (a[2] * r[0] - a[0] * r[2]) * d[1] + (a[0] * r[1] - a[1] * r[0]) * d[2]\n }\n for (let k = 0; k < rs.length; k++) {\n const n = ns[k]\n const t = accT[k]\n if (accN[k] !== 0 || t[0] !== 0 || t[1] !== 0 || t[2] !== 0) push(rs[k], [n[0] * accN[k] + t[0], n[1] * accN[k] + t[1], n[2] * accN[k] + t[2]])\n }\n for (let it = 0; it < SOLVER_PASSES; it++) {\n for (let k = 0; k < rs.length; k++) {\n const r = rs[k]\n const n = ns[k]\n // the push along the normal of the surface (a tilted top pushes across it, not straight up)\n const vn = dot(pointV(r), n)\n const total = Math.max(0, accN[k] + (goal[k] - vn) / reach(r, n))\n const j = total - accN[k]\n accN[k] = total\n if (j !== 0) push(r, [n[0] * j, n[1] * j, n[2] * j])\n // friction in the plane of the surface, up to the static or dynamic coefficient times the push the point gives\n const pv = pointV(r)\n const pn = dot(pv, n)\n const vt: Vec3 = [pv[0] - pn * n[0], pv[1] - pn * n[1], pv[2] - pn * n[2]]\n const speed = Math.hypot(vt[0], vt[1], vt[2])\n const f: Vec3 = [accT[k][0], accT[k][1], accT[k][2]]\n if (speed > 1e-6) {\n const d: Vec3 = [vt[0] / speed, vt[1] / speed, vt[2] / speed]\n const jt = speed / reach(r, d)\n f[0] -= d[0] * jt\n f[1] -= d[1] * jt\n f[2] -= d[2] * jt\n } else if (f[0] === 0 && f[1] === 0 && f[2] === 0) continue\n const most = (slipping[k] ? mus[k].dynamic : mus[k].static) * accN[k]\n const fl = Math.hypot(f[0], f[1], f[2])\n if (fl > most) {\n f[0] *= most / fl\n f[1] *= most / fl\n f[2] *= most / fl\n }\n const dj: Vec3 = [f[0] - accT[k][0], f[1] - accT[k][1], f[2] - accT[k][2]]\n accT[k] = f\n if (dj[0] !== 0 || dj[1] !== 0 || dj[2] !== 0) push(r, dj)\n }\n }\n pos[0] += (v[0] - vx0) * h\n pos[2] += (v[2] - vz0) * h\n warm.fill(0)\n for (let k = 0; k < rs.length; k++) {\n const id = ids[k]\n if (id >= WARM_SLOTS) continue\n warm[id * 4] = accN[k]\n warm[id * 4 + 1] = accT[k][0]\n warm[id * 4 + 2] = accT[k][1]\n warm[id * 4 + 3] = accT[k][2]\n }\n // Support check. The corner contacts above are relative to the centre of mass, so they already give a torque when the centre of mass is\n // outside the support. What they cannot do is end a balancing act: a tall thin piece on its edge (or a single corner) is in equilibrium\n // with the centre of mass above a very small support, so it must not rest there. It gets a gentle topple push toward the side it leans\n // to (or toward the wider side when it leans nowhere), and it may not sleep.\n let x0 = Infinity, x1 = -Infinity, z0 = Infinity, z1 = -Infinity, low = 0\n for (const r of rs) {\n x0 = Math.min(x0, r[0]); x1 = Math.max(x1, r[0])\n z0 = Math.min(z0, r[2]); z1 = Math.max(z1, r[2])\n low = Math.min(low, r[1])\n }\n const height = -low\n const wx = x1 - x0\n const wz = z1 - z0\n unstable = Math.min(wx, wz) < NARROW * height || x0 > 0 || x1 < 0 || z0 > 0 || z1 < 0\n if (b.tipping) {\n b.tipping.seconds -= h\n // lying is measured on the box as it is turned: a top corner held from above (a board it was joined to) says nothing of how it stands\n const [hx, hy, hz] = b.halfExtents\n const upHalf = Math.abs(e[1]) * hx + Math.abs(e[5]) * hy + Math.abs(e[9]) * hz\n if (upHalf < TIP_LYING || b.tipping.seconds <= 0) b.tipping = null\n else {\n w[0] += b.tipping.x * TIP_ACCELERATION * h\n w[2] += b.tipping.z * TIP_ACCELERATION * h\n unstable = true\n }\n }\n if (unstable) {\n // the support centre relative to the centre of mass: the piece falls away from it (toward +axis when it is centred)\n const dirX = x0 + x1 > 0 ? -1 : 1\n const dirZ = z0 + z1 > 0 ? -1 : 1\n const k = TOPPLE * Math.min(height, 1) * h\n // rotating about -z moves the top toward +x; rotating about +x moves it toward +z\n if (wx <= wz) w[2] -= dirX * k\n else w[0] += dirZ * k\n }\n // rolling / spinning resistance while touching the ground\n const rd = Math.exp((rs.length >= 3 ? -3 : -1.5) * h)\n w[0] *= rd\n w[1] *= rd\n w[2] *= rd\n const fd = Math.exp(-0.3 * h)\n v[0] *= fd\n v[2] *= fd\n }\n\n // what stands in the way (a wall, a car): the piece stops against it, bounces a little and both take the blow\n if (this.o.sweep && !b.held) this.sweepOn(b, start, pos)\n\n // write back\n b.root.quaternion.copy(q)\n const off = this.ax.copy(b.centerV).applyQuaternion(q)\n b.root.position.set(pos[0] - off.x, pos[1] - off.y, pos[2] - off.z)\n b.root.updateMatrixWorld(true)\n b.onGround = contactedLast\n\n if (landing > HARD_LANDING && this.time - b.lastHit > 0.15) {\n b.lastHit = this.time\n this.o.onHardLanding(b, landPoint, landing)\n }\n\n const still = touched && !unstable && Math.hypot(v[0], v[1], v[2]) < 0.12 && Math.hypot(w[0], w[1], w[2]) < 0.45\n if (still) b.still += dt\n else b.still = 0\n if (b.still >= SLEEP_AFTER || this.staysInPlace(b, touched && !b.tipping, pos, q, dt)) {\n b.sleeping = true\n b.calmAt = null\n v[0] = v[1] = v[2] = 0\n w[0] = w[1] = w[2] = 0\n }\n }\n\n /** Whether the piece has kept to the same spot on the ground for `CALM_SLEEP_AFTER` (see `CALM_DRIFT`). */\n private staysInPlace(b: PieceBody, touched: boolean, center: Vec3, q: THREE_NS.Quaternion, dt: number): boolean {\n const at = b.calmAt\n const turned = at ? 2 * Math.acos(Math.min(1, Math.abs(at.quaternion[0] * q.x + at.quaternion[1] * q.y + at.quaternion[2] * q.z + at.quaternion[3] * q.w))) : Infinity\n if (!touched || !at || Math.hypot(center[0] - at.center[0], center[1] - at.center[1], center[2] - at.center[2]) > CALM_DRIFT || turned > CALM_TURN) {\n b.calmAt = touched ? { center: [center[0], center[1], center[2]], quaternion: [q.x, q.y, q.z, q.w] } : null\n b.calm = 0\n return false\n }\n b.calm += dt\n return b.calm >= CALM_SLEEP_AFTER\n }\n\n /** Whether the centre `c` of `upper` is over the top of `lower`'s box (as it was at the start of the update). */\n private onTopOf(upper: PieceBody, lower: PieceBody, c: THREE_NS.Vector3): boolean {\n const s = this.solids.find((one) => one.body === lower)\n if (!s) return false\n const top = boxTopAt(s, c.x, c.z)\n return top > -Infinity && c.y >= top - 0.01\n }\n\n /** Half the height of the box of a piece as it is turned now. */\n private halfHeight(b: PieceBody): number {\n const e = this.m.makeRotationFromQuaternion(b.root.quaternion).elements\n return Math.abs(e[1]) * b.halfExtents[0] + Math.abs(e[5]) * b.halfExtents[1] + Math.abs(e[9]) * b.halfExtents[2]\n }\n\n /** Push overlapping pieces apart (horizontal bounding circles), gently, so they do not interpenetrate forever. */\n private separate(dt: number): void {\n const n = this.list.length\n if (n < 2) return\n const maxMove = 1.5 * dt\n const ca = new this.THREE.Vector3()\n const cb = new this.THREE.Vector3()\n for (let i = 0; i < n; i++) {\n const a = this.list[i]\n for (let j = i + 1; j < n; j++) {\n const b = this.list[j]\n const fixedA = a.held || a.sleeping\n const fixedB = b.held || b.sleeping\n if (fixedA && fixedB) continue\n const ra = Math.hypot(a.halfExtents[0], a.halfExtents[1], a.halfExtents[2])\n const rb = Math.hypot(b.halfExtents[0], b.halfExtents[1], b.halfExtents[2])\n this.centerOf(a, ca)\n this.centerOf(b, cb)\n if (Math.abs(ca.y - cb.y) > ra + rb) continue\n // one lies on the other (a book on a shelf): the corners hold them apart, a sideways push would slide it off\n if (Math.abs(ca.y - cb.y) >= (this.halfHeight(a) + this.halfHeight(b)) * 0.9) continue\n // or on a tilted top (a table going over): the one above is over the other's top, whatever their boxes' heights\n if (this.onTopOf(b, a, cb) || this.onTopOf(a, b, ca)) continue\n const rh = (Math.max(a.halfExtents[0], a.halfExtents[2]) + Math.max(b.halfExtents[0], b.halfExtents[2])) * 0.8\n let dx = cb.x - ca.x\n let dz = cb.z - ca.z\n let d = Math.hypot(dx, dz)\n if (d >= rh) continue\n if (d < 1e-5) {\n dx = 1\n dz = 0\n d = 1\n }\n const push = Math.min(maxMove, (rh - d) * 0.5)\n const wa = fixedA ? 0 : fixedB ? 1 : b.mass / (a.mass + b.mass)\n const wb = fixedB ? 0 : fixedA ? 1 : a.mass / (a.mass + b.mass)\n const ux = dx / (d || 1)\n const uz = dz / (d || 1)\n if (!fixedA) {\n a.root.position.x -= ux * push * 2 * wa\n a.root.position.z -= uz * push * 2 * wa\n }\n if (!fixedB) {\n b.root.position.x += ux * push * 2 * wb\n b.root.position.z += uz * push * 2 * wb\n }\n }\n }\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { Vec3 } from '@adatechnology/game-destruction'\n\n/** A bar of a cage, in world space. */\nexport interface RebarBar {\n readonly center: Vec3\n readonly rotation: [number, number, number, number]\n readonly length: number\n}\n\n/** Bare rebar of reinforced parts: one instanced cylinder mesh per part, replaced whenever the part exposes more (or less) of its cage. */\nexport class RebarCages {\n private readonly cages = new Map<string, THREE_NS.InstancedMesh>()\n private readonly geometry: THREE_NS.CylinderGeometry\n private readonly material: THREE_NS.MeshStandardMaterial\n private readonly up: THREE_NS.Vector3\n private readonly dir: THREE_NS.Vector3\n private readonly mid: THREE_NS.Vector3\n private readonly q: THREE_NS.Quaternion\n private readonly scale: THREE_NS.Vector3\n private readonly m: THREE_NS.Matrix4\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly scene: THREE_NS.Scene,\n private readonly radius = 0.004,\n ) {\n this.geometry = new THREE.CylinderGeometry(radius, radius, 1, 6)\n this.material = new THREE.MeshStandardMaterial({ color: 0x74665c, roughness: 0.55, metalness: 0.6 })\n this.up = new THREE.Vector3(0, 1, 0)\n this.dir = new THREE.Vector3()\n this.mid = new THREE.Vector3()\n this.q = new THREE.Quaternion()\n this.scale = new THREE.Vector3()\n this.m = new THREE.Matrix4()\n }\n\n /** Bars drawn now, over every part. */\n get count(): number {\n let n = 0\n for (const mesh of this.cages.values()) n += mesh.count\n return n\n }\n\n /** Meshes of the live cages (tests and picking). */\n meshes(): THREE_NS.InstancedMesh[] {\n return [...this.cages.values()]\n }\n\n /**\n * Draw `bars` (world space) as the cage of `key`; an empty list removes it. The cage is a child of `holder` (the drawing of the part's object, the scene\n * by default), so it goes where the part goes: a beam that comes down takes its bare bars with it.\n */\n set(key: string, bars: ReadonlyArray<readonly [Vec3, Vec3]>, holder?: THREE_NS.Object3D): void {\n this.remove(key)\n if (bars.length === 0) return\n const parent = holder ?? this.scene\n parent.updateWorldMatrix(true, false)\n const toParent = new this.THREE.Matrix4().copy(parent.matrixWorld).invert()\n const mesh = new this.THREE.InstancedMesh(this.geometry, this.material, bars.length)\n bars.forEach(([a, b], i) => {\n this.dir.set(b[0] - a[0], b[1] - a[1], b[2] - a[2])\n const length = this.dir.length()\n this.mid.set((a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2)\n this.q.setFromUnitVectors(this.up, length > 1e-9 ? this.dir.divideScalar(length) : this.up)\n this.m.compose(this.mid, this.q, this.scale.set(1, Math.max(length, 1e-4), 1)).premultiply(toParent)\n mesh.setMatrixAt(i, this.m)\n })\n mesh.instanceMatrix.needsUpdate = true\n mesh.castShadow = true\n mesh.name = 'rebar-cage'\n parent.add(mesh)\n this.cages.set(key, mesh)\n }\n\n /** The cage of `from` now belongs to `to` (a part that left its object for one of its own) and hangs from `holder`, where it is in the world now. */\n move(from: string, to: string, holder: THREE_NS.Object3D): void {\n const mesh = this.cages.get(from)\n if (!mesh) return\n this.cages.delete(from)\n this.remove(to)\n holder.attach(mesh)\n this.cages.set(to, mesh)\n }\n\n /** Takes the cage of `key` away and gives its bars, where they are in the world now: centre, turn (the bar along its y) and length. */\n take(key: string): RebarBar[] {\n const mesh = this.cages.get(key)\n if (!mesh) return []\n mesh.updateWorldMatrix(true, false)\n const bars: RebarBar[] = []\n for (let i = 0; i < mesh.count; i++) {\n mesh.getMatrixAt(i, this.m)\n this.m.premultiply(mesh.matrixWorld).decompose(this.mid, this.q, this.scale)\n bars.push({ center: [this.mid.x, this.mid.y, this.mid.z], rotation: [this.q.x, this.q.y, this.q.z, this.q.w], length: this.scale.y })\n }\n this.remove(key)\n return bars\n }\n\n /** Radius of the bars drawn, metres. */\n get barRadius(): number {\n return this.radius\n }\n\n remove(key: string): void {\n const mesh = this.cages.get(key)\n if (!mesh) return\n mesh.removeFromParent()\n mesh.dispose()\n this.cages.delete(key)\n }\n\n /** Remove the cages of every part of `object` (keys are `object|part`). */\n removeObject(object: string): void {\n for (const key of [...this.cages.keys()]) if (key.startsWith(`${object}|`)) this.remove(key)\n }\n\n clear(): void {\n for (const key of [...this.cages.keys()]) this.remove(key)\n }\n\n dispose(): void {\n this.clear()\n this.geometry.dispose()\n this.material.dispose()\n }\n}\n","import type * as THREE_NS from 'three'\nimport { guessMaterial, inferJoints, MATERIALS, partMass } from '@adatechnology/game-destruction'\nimport type { JointKind, JointSpec, MaterialId, PartSpec } from '@adatechnology/game-destruction'\nimport type { Mesh, Object3D, SpecFromObjectOptions, SpecFromObjectResult, ThreeNamespace } from './types'\n\ninterface Entry {\n key: string\n meshes: Mesh[]\n box: THREE_NS.Box3\n material: MaterialId\n explicitId: string | null\n fill?: number\n hollow: boolean\n /** `userData.destructionSkin`: a layer drawn on a part (a label, a coat), never a part of its own. */\n skin: boolean\n tags?: string[]\n /** `userData.destructionContains`: the fluid the part holds (a hole in it makes it leak). */\n contains?: { fluid: string; liters: number }\n /** `userData.destructionPowder`: the loose dry contents the part holds (`PartSpec.powder`). */\n powder?: { color: number }\n /** `userData.destructionThickness`: the real wall thickness in metres (a can is a tenth of a millimetre, far less than its box says). */\n thickness?: number\n /** Part id wished by the host (`userData.destructionPart`). */\n fixedId: boolean\n name: string\n /** `parent` / `kind` of an object-valued `destructionPart`: the part is attached to `parent` by a joint of that kind. */\n parent?: string\n jointKind?: JointKind\n}\n\n/** What `userData.destructionPart` says: a string (the part id) or an object `{ id, material?, parent?, kind? }`. */\nexport interface PartHint {\n id: string\n material?: string\n parent?: string\n kind?: string\n}\n\n/** Read `userData.destructionContains` (`{ fluid, liters }`); undefined when it holds nothing. */\nfunction containsOf(value: unknown): { fluid: string; liters: number } | undefined {\n if (!value || typeof value !== 'object') return undefined\n const v = value as Record<string, unknown>\n return typeof v.fluid === 'string' && typeof v.liters === 'number' && v.liters > 0 ? { fluid: v.fluid, liters: v.liters } : undefined\n}\n\n/** Read `userData.destructionPart` (string or object with an `id`); null when it names no part. */\nexport function partHintOf(value: unknown): PartHint | null {\n if (typeof value === 'string') return value ? { id: value } : null\n if (!value || typeof value !== 'object') return null\n const v = value as Record<string, unknown>\n if (typeof v.id !== 'string' || !v.id) return null\n const str = (x: unknown): string | undefined => (typeof x === 'string' && x ? x : undefined)\n return { id: v.id, material: str(v.material), parent: str(v.parent), kind: str(v.kind) }\n}\n\nconst METAL = /steel|iron|metal|alumin|copper|brass|bronze|tin|titan|chrome|zinc|lead/i\n\nfunction sanitizeId(name: string): string {\n let id = name\n .trim()\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '')\n if (id && /^[0-9]/.test(id)) id = `p_${id}`\n return id\n}\n\nfunction isMesh(o: Object3D): o is Mesh {\n return (o as Mesh).isMesh === true\n}\n\nfunction sizeOf(box: THREE_NS.Box3): [number, number, number] {\n return [box.max.x - box.min.x, box.max.y - box.min.y, box.max.z - box.min.z]\n}\n\n/** Inverse of the root's world pose without its scale: world space to the metric frame the spec and the world's `setTransform` use. */\nexport function specFrameInverse(THREE: ThreeNamespace, root: Object3D): THREE_NS.Matrix4 {\n root.updateMatrixWorld(true)\n const position = new THREE.Vector3()\n const quaternion = new THREE.Quaternion()\n root.matrixWorld.decompose(position, quaternion, new THREE.Vector3())\n return new THREE.Matrix4().compose(position, quaternion, new THREE.Vector3(1, 1, 1)).invert()\n}\n\n/**\n * Build a `DestructibleSpec` from a three.js object: one part per mesh (meshes sharing `userData.destructionPart` become one part), each an\n * axis-aligned box in metres in the root's frame (its position and rotation removed, its world scale kept; rotation omitted), with the material taken from `options.materialOf`, `userData.destructionMaterial`\n * or a guess from the names. Tiny meshes are merged into the part they overlap most; joints are inferred from touching parts.\n *\n * `userData.destructionContains` (`{ fluid, liters }`) makes the part a container: a hole through it leaks. `userData.destructionPowder` (`{ color }`) fills it with a dry powder or flakes that puff out of a hole. `root.userData.destructionMass` (kg) fixes the total mass, split between the parts in proportion to their volume, density and fill.\n * A mesh with `userData.destructionSkin` (a label, a coat) joins the part it overlaps most instead of becoming a part: it stays drawn and bound to that part (decals, dents) but never breaks off.\n * Meshes that are invisible or have `userData.destructionIgnore` (or sit under such an object) are skipped. The result also tells which meshes\n * became which part, ready to be passed to `bind`.\n */\nexport function specFromObject3D(THREE: ThreeNamespace, root: Object3D, options: SpecFromObjectOptions = {}): SpecFromObjectResult {\n const fallback = options.fallback ?? 'plastic'\n const minSize = options.minSize ?? 0.015\n const inv = specFrameInverse(THREE, root)\n\n // 1. collect meshes -> entries (grouped by an explicit part name)\n const entries: Entry[] = []\n const byKey = new Map<string, Entry>()\n const visit = (o: Object3D): void => {\n if (!o.visible || o.userData?.destructionIgnore) return\n if (isMesh(o) && o.geometry) {\n const geom = o.geometry\n if (!geom.boundingBox) geom.computeBoundingBox()\n if (geom.boundingBox && !geom.boundingBox.isEmpty()) {\n const box = geom.boundingBox.clone().applyMatrix4(new THREE.Matrix4().multiplyMatrices(inv, o.matrixWorld))\n const mats = Array.isArray(o.material) ? o.material : [o.material]\n const matName = mats[0]?.name ?? ''\n const ud = o.userData ?? {}\n const hint = partHintOf(ud.destructionPart)\n const material =\n options.materialOf?.(o) ??\n (typeof ud.destructionMaterial === 'string' ? (ud.destructionMaterial as string) : undefined) ??\n hint?.material ??\n guessMaterial(`${o.name} ${matName} ${typeof ud.material === 'string' ? ud.material : ''}`) ??\n fallback\n const explicit = hint?.id ?? null\n const hollow = ud.hollow === true || /hollow/i.test(o.name)\n const skin = ud.destructionSkin === true\n const fill = options.fillOf?.(o, material)\n const tags = Array.isArray(ud.destructionTags) ? (ud.destructionTags as string[]) : undefined\n const contains = containsOf(ud.destructionContains)\n const powder = typeof (ud.destructionPowder as { color?: unknown } | undefined)?.color === 'number' ? { color: (ud.destructionPowder as { color: number }).color } : undefined\n const thickness = typeof ud.destructionThickness === 'number' && ud.destructionThickness > 0 ? (ud.destructionThickness as number) : undefined\n const existing = explicit ? byKey.get(explicit) : undefined\n if (existing) {\n const before = sizeOf(existing.box)\n const bv = before[0] * before[1] * before[2]\n const ns = sizeOf(box)\n existing.box.union(box)\n existing.meshes.push(o)\n if (ns[0] * ns[1] * ns[2] > bv) existing.material = material\n existing.hollow = existing.hollow || hollow\n existing.skin = existing.skin && skin\n if (fill !== undefined) existing.fill = fill\n if (contains) existing.contains = contains\n if (powder) existing.powder = powder\n if (thickness !== undefined) existing.thickness = Math.min(existing.thickness ?? thickness, thickness)\n } else {\n const e: Entry = { key: explicit ?? `m${entries.length}`, meshes: [o], box, material, explicitId: explicit, fill, hollow, skin, tags, fixedId: !!explicit, ...(contains ? { contains } : {}), ...(powder ? { powder } : {}), ...(thickness !== undefined ? { thickness } : {}), name: o.name, parent: hint?.parent, jointKind: hint?.kind as JointKind | undefined }\n entries.push(e)\n if (explicit) byKey.set(explicit, e)\n }\n }\n }\n for (const c of o.children) visit(c)\n }\n visit(root)\n\n // 2. merge tiny meshes and skins into the touching part they overlap most\n const eps = 0.005\n const overlapVolume = (a: THREE_NS.Box3, b: THREE_NS.Box3): number => {\n const x = Math.min(a.max.x, b.max.x) - Math.max(a.min.x, b.min.x) + eps\n const y = Math.min(a.max.y, b.max.y) - Math.max(a.min.y, b.min.y) + eps\n const z = Math.min(a.max.z, b.max.z) - Math.max(a.min.z, b.min.z) + eps\n return x > 0 && y > 0 && z > 0 ? x * y * z : 0\n }\n const largest = (e: Entry) => Math.max(...sizeOf(e.box))\n const kept: Entry[] = []\n const tiny: Entry[] = []\n for (const e of entries) (e.skin || (!e.fixedId && largest(e) < minSize) ? tiny : kept).push(e)\n for (const t of tiny) {\n let best: Entry | null = null\n let bestV = 0\n for (const k of kept) {\n const v = overlapVolume(t.box, k.box)\n if (v > bestV) {\n bestV = v\n best = k\n }\n }\n if (!best) {\n // not touching anything: join the nearest part within a small distance\n let bd = 0.05\n for (const k of kept) {\n const d = k.box.distanceToPoint(t.box.getCenter(new THREE.Vector3()))\n if (d < bd) {\n bd = d\n best = k\n }\n }\n }\n if (best) {\n best.meshes.push(...t.meshes) // the box stays: a tiny mesh sits inside or on the surface of its part\n } else {\n kept.push(t) // isolated crumb: keep it as its own part\n }\n }\n\n // 3. ids, parts\n const used = new Set<string>()\n const parts: PartSpec[] = []\n const meshesOf: Record<string, Object3D[]> = {}\n let counter = 0\n for (const e of kept) {\n counter++\n let base = (e.explicitId ? sanitizeId(e.explicitId) : '') || sanitizeId(e.name) || `part_${counter}`\n let id = base\n for (let n = 2; used.has(id); n++) id = `${base}_${n}`\n used.add(id)\n base = id\n const size = sizeOf(e.box)\n const center = e.box.getCenter(new THREE.Vector3())\n const part: PartSpec = {\n id,\n material: e.material,\n shape: { kind: 'box', size: [Math.max(size[0], 0.002), Math.max(size[1], 0.002), Math.max(size[2], 0.002)] },\n position: [center.x, center.y, center.z],\n }\n const minSide = Math.min(...size)\n if (e.fill !== undefined) part.fill = e.fill\n else if (e.hollow) part.fill = 0.05\n if (e.thickness !== undefined) part.thickness = e.thickness\n else if (minSide < 0.01 && METAL.test(e.material)) {\n part.fill = e.fill ?? 1\n part.thickness = Math.max(minSide, 0.0005)\n }\n if (e.tags) part.tags = [...e.tags]\n if (e.contains) part.contains = { ...e.contains }\n if (e.powder) part.powder = { ...e.powder }\n const ao = options.anchorBelow ?? -1\n if (ao >= 0 && e.box.min.y <= ao) part.anchored = true\n parts.push(part)\n meshesOf[id] = e.meshes\n }\n\n const knownMass = root.userData?.destructionMass\n if (typeof knownMass === 'number' && knownMass > 0) {\n const shares = parts.map((p) => {\n const material = MATERIALS.find((m) => m.id === p.material)\n return material ? partMass(p, material) : 0\n })\n const total = shares.reduce((a, b) => a + b, 0)\n if (total > 0) parts.forEach((p, i) => (p.mass = (knownMass * shares[i]) / total))\n }\n\n const spec: SpecFromObjectResult['spec'] = { parts }\n if (options.name !== undefined) spec.name = options.name\n else if (root.name) spec.name = root.name\n if (options.tags) spec.tags = [...options.tags]\n spec.joints = options.joints === false ? [] : inferJoints(parts)\n // explicit attachments from `destructionPart: { parent, kind }` win over the inferred joint between the same two parts\n if (options.joints !== false) {\n const finalId = new Map<Entry, string>()\n kept.forEach((e, i) => finalId.set(e, parts[i].id))\n const idOf = new Map<string, string>()\n for (const e of kept) if (e.explicitId) idOf.set(e.explicitId, finalId.get(e)!)\n const joints: JointSpec[] = spec.joints\n for (const e of kept) {\n if (!e.parent) continue\n const id = finalId.get(e)!\n const parent = idOf.get(e.parent) ?? (used.has(sanitizeId(e.parent)) ? sanitizeId(e.parent) : null)\n if (!parent || parent === id) continue\n const at = joints.findIndex((j) => (j.a === parent && j.b === id) || (j.a === id && j.b === parent))\n const kind = e.jointKind ?? (at >= 0 ? joints[at].kind : 'resting')\n const joint: JointSpec = { id: `${parent}~${id}`, a: parent, b: id, kind }\n if (at >= 0) joints[at] = joint\n else joints.push(joint)\n }\n }\n return { spec, parts: meshesOf }\n}\n","import { mixHex } from './math'\n\n/** Blackbody-ish stops: [temperature °C, colour]. Luminance grows with the temperature. */\nconst STOPS: Array<[number, number]> = [\n [450, 0x000000],\n [500, 0x2a0400],\n [650, 0x8a1500],\n [800, 0xd84a08],\n [950, 0xff8c14],\n [1100, 0xffc23a],\n [1250, 0xffe8a0],\n [1400, 0xffffff],\n]\n\n/**\n * Glow colour of a hot surface as `0xRRGGBB`: black (no glow) below about 450 °C, dark red around 500, orange around 800, yellow around 1100 and\n * white from 1400 °C. Brightness never decreases as the temperature rises. Use it as an emissive colour.\n */\nexport function heatColor(temperatureC: number): number {\n if (!(temperatureC > STOPS[0][0])) return 0\n const last = STOPS[STOPS.length - 1]\n if (temperatureC >= last[0]) return last[1]\n for (let i = 1; i < STOPS.length; i++) {\n const [t1, c1] = STOPS[i]\n if (temperatureC <= t1) {\n const [t0, c0] = STOPS[i - 1]\n return mixHex(c0, c1, (temperatureC - t0) / (t1 - t0))\n }\n }\n return last[1]\n}\n","import type * as THREE_NS from 'three'\n\n/** A shell mesh with its vertex positions before and after a dent, both in its own local space. */\nexport type ShellSnapshot = {\n readonly mesh: THREE_NS.Mesh\n readonly before: ArrayLike<number>\n readonly after: ArrayLike<number>\n}\n\n/**\n * How far the surface of the shells moved where `worldPoint` (a vertex of a skin: a label, a coat) lies on it, as a world vector: the displacement of the\n * nearest shell triangle, interpolated by barycentric weights. A skin that takes it moves with the shell, whatever the two meshes' vertex grids are.\n * Returns the distance (world metres) from the point to that triangle, how high above the shell the skin lies.\n */\nexport function shellDisplacementAt(THREE: typeof THREE_NS, worldPoint: THREE_NS.Vector3, shells: readonly ShellSnapshot[], out: THREE_NS.Vector3): number {\n const triangle = new THREE.Triangle()\n const corners = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()] as const\n const local = new THREE.Vector3()\n const closest = new THREE.Vector3()\n const weights = new THREE.Vector3()\n const moved = new THREE.Vector3()\n let nearest = Infinity\n out.set(0, 0, 0)\n let nearestScale = 1\n for (const shell of shells) {\n shell.mesh.updateWorldMatrix(true, false)\n shell.mesh.worldToLocal(local.copy(worldPoint))\n const index = shell.mesh.geometry.index\n const triangles = index ? index.count / 3 : shell.before.length / 9\n for (let t = 0; t < triangles; t++) {\n const ids = [0, 1, 2].map((corner) => (index ? index.getX(t * 3 + corner) : t * 3 + corner))\n ids.forEach((id, corner) => corners[corner]!.set(shell.before[id * 3]!, shell.before[id * 3 + 1]!, shell.before[id * 3 + 2]!))\n triangle.set(corners[0], corners[1], corners[2])\n // a degenerate triangle (the tip of a lathe on its axis, the doubled rim of a can) has no surface to follow and no closest point (NaN must never win)\n if (triangle.getArea() <= 1e-14) continue\n triangle.closestPointToPoint(local, closest)\n const distance = closest.distanceToSquared(local)\n if (!(distance < nearest)) continue\n nearest = distance\n nearestScale = shell.mesh.matrixWorld.getMaxScaleOnAxis() || 1\n triangle.getBarycoord(closest, weights)\n moved.set(0, 0, 0)\n ids.forEach((id, corner) => {\n const weight = corner === 0 ? weights.x : corner === 1 ? weights.y : weights.z\n moved.x += weight * (shell.after[id * 3]! - shell.before[id * 3]!)\n moved.y += weight * (shell.after[id * 3 + 1]! - shell.before[id * 3 + 1]!)\n moved.z += weight * (shell.after[id * 3 + 2]! - shell.before[id * 3 + 2]!)\n })\n out.copy(moved).transformDirection(shell.mesh.matrixWorld)\n out.multiplyScalar(moved.length() * (shell.mesh.matrixWorld.getMaxScaleOnAxis() || 1))\n }\n }\n return Math.sqrt(nearest) * nearestScale\n}\n","import type * as THREE_NS from 'three'\nimport type { Dent } from '@adatechnology/game-destruction'\nimport { heatColor } from './heat'\nimport type { Decal, HostVis, MeshVis, PartVis } from './internal'\nimport { clamp, createRng, lerp } from './math'\nimport { shellDisplacementAt, type ShellSnapshot } from './skin-dent'\nimport { pushFittedBoxes } from './fitted-boxes'\n\ntype Mesh = THREE_NS.Mesh\n\nconst POS_ATTR = 'position'\n\nfunction positionAttr(geo: THREE_NS.BufferGeometry): THREE_NS.BufferAttribute | null {\n const a = geo.getAttribute(POS_ATTR) as THREE_NS.BufferAttribute | THREE_NS.InterleavedBufferAttribute | undefined\n return a && !(a as THREE_NS.InterleavedBufferAttribute).isInterleavedBufferAttribute ? (a as THREE_NS.BufferAttribute) : null\n}\n\nfunction materialsOf(m: THREE_NS.Material | THREE_NS.Material[]): THREE_NS.Material[] {\n return Array.isArray(m) ? m : [m]\n}\n\nfunction colorOf(m: THREE_NS.Material): THREE_NS.Color | null {\n const c = (m as THREE_NS.MeshStandardMaterial).color\n return c && (c as THREE_NS.Color).isColor ? c : null\n}\n\n/** Shared resources for decals (one geometry, a few materials) created lazily and disposed together. */\nexport class DecalKit {\n private disc: THREE_NS.CircleGeometry | null = null\n private discMat: THREE_NS.MeshBasicMaterial | null = null\n private lineMats = new Map<number, THREE_NS.LineBasicMaterial>()\n private patchMats = new Map<number, THREE_NS.MeshBasicMaterial>()\n constructor(private readonly THREE: typeof THREE_NS) {}\n\n discGeometry(): THREE_NS.CircleGeometry {\n return (this.disc ??= new this.THREE.CircleGeometry(1, 14))\n }\n\n discMaterial(): THREE_NS.MeshBasicMaterial {\n return (this.discMat ??= new this.THREE.MeshBasicMaterial({\n color: 0x050505,\n transparent: true,\n opacity: 0.92,\n depthWrite: false,\n polygonOffset: true,\n polygonOffsetFactor: -4,\n polygonOffsetUnits: -4,\n side: this.THREE.DoubleSide,\n }))\n }\n\n /** Opaque patch in the colour of what shows under a spalled coat. */\n patchMaterial(color: number): THREE_NS.MeshBasicMaterial {\n let m = this.patchMats.get(color)\n if (!m) {\n m = new this.THREE.MeshBasicMaterial({ color, depthWrite: false, polygonOffset: true, polygonOffsetFactor: -3, polygonOffsetUnits: -3 })\n this.patchMats.set(color, m)\n }\n return m\n }\n\n lineMaterial(color: number): THREE_NS.LineBasicMaterial {\n let m = this.lineMats.get(color)\n if (!m) {\n m = new this.THREE.LineBasicMaterial({ color, transparent: true, opacity: 0.9, depthWrite: false })\n this.lineMats.set(color, m)\n }\n return m\n }\n\n dispose(): void {\n this.disc?.dispose()\n this.discMat?.dispose()\n for (const m of this.lineMats.values()) m.dispose()\n for (const m of this.patchMats.values()) m.dispose()\n this.patchMats.clear()\n this.disc = null\n this.discMat = null\n this.lineMats.clear()\n }\n}\n\nconst tmpV = (THREE: typeof THREE_NS) => new THREE.Vector3()\n\n/**\n * The positions a host drew a range with before it took the range out of the merged mesh to draw it another way (the house renderer collapses the range of a\n * wall it draws with holes, `userData.collapsedRanges`, and keeps the first positions in `userData.plainPositions`): a part that leaves the mesh takes those,\n * or it would leave as a collapsed, invisible range that still carries its decals and is still shot at.\n */\nexport function plainPositions(mesh: THREE_NS.Mesh, v0: number, v1: number): Float32Array | null {\n const { collapsedRanges, plainPositions: plain } = mesh.userData as { collapsedRanges?: ReadonlyArray<readonly [number, number]>; plainPositions?: Float32Array }\n if (!plain || !collapsedRanges?.some(([a, b]) => a < v1 && b > v0)) return null\n return plain\n}\n\n/** A whole mesh that leaves with its part draws again the ranges its host collapsed (`plainPositions`): it is the part now, and the part is still there. */\nexport function showCollapsedRanges(mesh: THREE_NS.Mesh): void {\n const data = mesh.userData as { collapsedRanges?: Array<[number, number]>; plainPositions?: Float32Array }\n const plain = data.plainPositions\n const position = mesh.geometry?.getAttribute(POS_ATTR) as THREE_NS.BufferAttribute | undefined\n if (!plain || !data.collapsedRanges?.length || !position) return\n const array = position.array as Float32Array\n for (const [v0, v1] of data.collapsedRanges) array.set(plain.subarray(v0 * 3, v1 * 3), v0 * 3)\n data.collapsedRanges = []\n position.needsUpdate = true\n mesh.geometry.computeBoundingBox()\n mesh.geometry.computeBoundingSphere()\n}\n\n/** Mesh-level visual changes: copy-on-write geometry and materials, dents, decals, char, glow, melt, hiding, restoring. */\n/** A dent reaches at least this many vertices of a mesh: fewer and the mesh cannot show its curve (it would be invisible or a sharp spike). */\nconst MIN_DENT_VERTICES = 10\n/** The reach of a dent that had to widen is this many times the distance to the farthest of those vertices, so they all get a falloff above zero. */\nconst WIDEN_MARGIN = 1.1\n/** A skin follows its shell this share of the way in: the two meshes triangulate the dent differently, and a skin left a bit outside never lets the shell through. */\nconst SKIN_FOLLOW = 0.85\n/** And stays this many metres outside, so the thin gap of a label (a millimetre) survives the two meshes triangulating the rim differently. */\nconst SKIN_SLACK = 0.0005\n/** Extra slack per metre a skin lies above its shell: skins stacked on one another (a label and its band) keep their order while the dent bends them. */\nconst SKIN_LAYER_SLACK = 4\n/** And at least this many times the distance to the nearest vertex, so even the nearest one is pushed visibly. */\nconst NEAREST_MARGIN = 1.5\n/**\n * The first positions of a merged mesh: `userData._p0` when another drawing keeps them there (the house renderer, which collapses the ranges of what it\n * draws itself, `userData.collapsedRanges`), else those of the geometry it was bound with.\n */\nconst basePositions = (host: { mesh: Mesh; origGeometry: THREE_NS.BufferGeometry }): Float32Array | null => {\n const p0 = host.mesh.userData._p0 as Float32Array | undefined\n if (p0) return p0\n const op = positionAttr(host.origGeometry)\n return op ? (op.array as unknown as Float32Array) : null\n}\n\n/** Collapses in `arr` the ranges another drawing hides on the mesh (`userData.collapsedRanges`, each to its first vertex). */\nconst collapseForeign = (mesh: Mesh, arr: Float32Array): void => {\n for (const [v0, v1] of (mesh.userData.collapsedRanges as Array<[number, number]> | undefined) ?? []) {\n for (let k = v0 + 1; k < v1; k++) {\n arr[k * 3] = arr[v0 * 3]!\n arr[k * 3 + 1] = arr[v0 * 3 + 1]!\n arr[k * 3 + 2] = arr[v0 * 3 + 2]!\n }\n }\n}\n\n/** Metres along its normal a mark looks for the drawn face under it (`onFace`). */\nconst DECAL_SNAP = 0.03\n\nexport class Visuals {\n readonly kit: DecalKit\n private readonly a: THREE_NS.Vector3\n private readonly b: THREE_NS.Vector3\n private readonly m4: THREE_NS.Matrix4\n private readonly ray: THREE_NS.Raycaster\n private readonly box: THREE_NS.Box3\n private readonly t: THREE_NS.Vector3\n private readonly lbox: THREE_NS.Box3\n /** Total live decals across meshes (kept in sync by add/remove). */\n decalCount = 0\n\n constructor(\n private readonly THREE: typeof THREE_NS,\n private readonly lowQuality: boolean,\n private readonly decalCap: number,\n ) {\n this.kit = new DecalKit(THREE)\n this.a = tmpV(THREE)\n this.b = tmpV(THREE)\n this.m4 = new THREE.Matrix4()\n this.ray = new THREE.Raycaster()\n // batched meshes leave the camera layer (createStaticBatcher), not the world: rays still find them\n this.ray.layers.enableAll()\n this.box = new THREE.Box3()\n this.t = tmpV(THREE)\n this.lbox = new THREE.Box3()\n }\n\n /**\n * @param range vertex range `[v0, v1)` of a merged mesh this part is drawn by (see `MeshRange`); `hosts` caches the shared state per mesh for one `bind`.\n */\n makeMeshVis(mesh: Mesh, home: string, range?: [number, number], hosts?: Map<Mesh, HostVis>): MeshVis {\n let host: HostVis | null = null\n if (range) {\n host = hosts?.get(mesh) ?? null\n if (!host) {\n host = { mesh, origGeometry: mesh.geometry, origMaterial: mesh.material, ownGeo: false, work: null, ownMat: false, sharers: [] }\n hosts?.set(mesh, host)\n }\n }\n const mv: MeshVis = {\n mesh,\n home,\n origGeometry: mesh.geometry,\n origMaterial: mesh.material,\n origVisible: mesh.visible,\n origParent: mesh.parent,\n origPosition: mesh.position.clone(),\n origQuaternion: mesh.quaternion.clone(),\n origScale: mesh.scale.clone(),\n ownMat: false,\n ownGeo: false,\n work: null,\n baseColors: null,\n decals: [],\n meltApplied: 0,\n bottomY: 0,\n moved: false,\n host,\n range: range ? [range[0], range[1]] : null,\n merged: host && range ? { host, range: [range[0], range[1]] } : null,\n loose: false,\n collapsed: false,\n hidden: false,\n touched: false,\n charK: 0,\n charHex: 0,\n glowHex: 0,\n glowK: 0,\n }\n host?.sharers.push(mv)\n return mv\n }\n\n vertexCount(mv: MeshVis): number {\n if (mv.range) return mv.range[1] - mv.range[0]\n return mv.mesh.geometry.getAttribute(POS_ATTR)?.count ?? 0\n }\n\n /** Is the part drawn? (A ranged part shares its mesh, so `mesh.visible` says nothing about it.) */\n shown(mv: MeshVis): boolean {\n return mv.host ? !mv.hidden : mv.mesh.visible\n }\n\n /** Box of the part's vertices in the space of its mesh (the whole geometry for a plain mesh). */\n localBox(mv: MeshVis, out: THREE_NS.Box3): THREE_NS.Box3 {\n out.makeEmpty()\n if (!mv.host || !mv.range) {\n const geo = mv.mesh.geometry\n if (!geo.boundingBox) geo.computeBoundingBox()\n return geo.boundingBox ? out.copy(geo.boundingBox) : out\n }\n const arr = mv.host.work ?? (positionAttr(mv.mesh.geometry)?.array as unknown as ArrayLike<number> | undefined)\n if (!arr) return out\n for (let i = mv.range[0] * 3; i < mv.range[1] * 3; i += 3) out.expandByPoint(this.t.set(arr[i], arr[i + 1], arr[i + 2]))\n return out\n }\n\n /** Box of the part in world space. */\n /** Appends the boxes that follow the mesh in the world (`pushFittedBoxes`) to `out`. */\n fittedBoxes(mv: MeshVis, out: number[]): void {\n const box = new this.THREE.Box3()\n if (mv.host) this.localBox(mv, box)\n else {\n const geometry = mv.mesh.geometry\n if (!geometry.boundingBox) geometry.computeBoundingBox()\n if (geometry.boundingBox) box.copy(geometry.boundingBox)\n else box.makeEmpty()\n }\n if (box.isEmpty()) return\n mv.mesh.updateWorldMatrix(true, false)\n pushFittedBoxes(box, mv.mesh.matrixWorld, out)\n }\n\n worldBox(mv: MeshVis, out: THREE_NS.Box3): THREE_NS.Box3 {\n if (!mv.host) return out.setFromObject(mv.mesh)\n this.localBox(mv, out)\n mv.mesh.updateWorldMatrix(true, false)\n return out.isEmpty() ? out : out.applyMatrix4(mv.mesh.matrixWorld)\n }\n\n private readonly tints = new WeakMap<MeshVis, THREE_NS.Color | null>()\n\n /**\n * Average vertex colour of a mesh whose material uses `vertexColors` (computed once per mesh, from its original geometry), else null. Fragments\n * and debris of such a mesh multiply it by `material.color`; without it they come out white.\n */\n vertexTint(mv: MeshVis): THREE_NS.Color | null {\n if (this.tints.has(mv)) return this.tints.get(mv) ?? null\n let tint: THREE_NS.Color | null = null\n const used = materialsOf(mv.origMaterial).some((m) => (m as THREE_NS.MeshStandardMaterial).vertexColors === true)\n const attr = used ? (mv.origGeometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined) : undefined\n if (attr && attr.count > 0 && attr.itemSize >= 3) {\n // a ranged part averages its own vertices only\n const from = mv.merged ? mv.merged.range[0] : 0\n const to = mv.merged ? Math.min(attr.count, mv.merged.range[1]) : attr.count\n let r = 0, g = 0, b = 0\n for (let i = from; i < to; i++) {\n r += attr.getX(i)\n g += attr.getY(i)\n b += attr.getZ(i)\n }\n const n = Math.max(1, to - from)\n tint = new this.THREE.Color(r / n, g / n, b / n)\n }\n this.tints.set(mv, tint)\n return tint\n }\n\n /** Colour of the original material (before any char) times the vertex tint, `0xRRGGBB`, or -1. */\n baseColorHex(mv: MeshVis): number {\n const c = mv.baseColors?.[0] ?? colorOf(materialsOf(mv.origMaterial)[0])\n if (!c) return -1\n const tint = this.vertexTint(mv)\n return tint ? c.clone().multiply(tint).getHex() : c.getHex()\n }\n\n /** Is the original material transparent? */\n isTransparent(mv: MeshVis): boolean {\n return materialsOf(mv.origMaterial).some((m) => m.transparent && m.opacity < 1)\n }\n\n ownMaterial(mv: MeshVis): void {\n if (mv.ownMat) return\n mv.ownMat = true\n const src = materialsOf(mv.origMaterial)\n const cloned = src.map((m) => m.clone())\n mv.baseColors = src.map((m) => colorOf(m)?.clone() ?? new this.THREE.Color(0x888888))\n mv.mesh.material = Array.isArray(mv.origMaterial) ? cloned : cloned[0]\n }\n\n /** Clone the geometry (vertex edits); false when its positions cannot be edited. */\n ownGeometry(mv: MeshVis): boolean {\n if (mv.host) return this.ownHostGeometry(mv.host)\n if (mv.ownGeo) return true\n const pos = positionAttr(mv.mesh.geometry)\n if (!pos) return false\n mv.ownGeo = true\n const g = mv.mesh.geometry.clone()\n mv.mesh.geometry = g\n mv.work = new Float32Array((positionAttr(g) as THREE_NS.BufferAttribute).array as ArrayLike<number>)\n return true\n }\n\n private ownHostGeometry(host: HostVis): boolean {\n if (host.ownGeo) return true\n const pos = positionAttr(host.mesh.geometry)\n if (!pos) return false\n host.ownGeo = true\n const g = host.mesh.geometry.clone()\n host.mesh.geometry = g\n host.work = new Float32Array(basePositions(host) ?? ((positionAttr(g) as THREE_NS.BufferAttribute).array as ArrayLike<number>))\n return true\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Dents\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /**\n * Push the vertices of the mesh within `dent.radius` of `worldPoint` inwards along `worldNormal` by `depth * (1 - (d/r)^2)^2`.\n * Returns false when nothing was changed (too far, low quality on a heavy mesh, or no editable positions).\n */\n applyDent(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, dent: Dent, reachWorld = 0): boolean {\n const mesh = mv.mesh\n if (this.lowQuality && this.vertexCount(mv) > 20000) return false\n mesh.updateWorldMatrix(true, false)\n const s = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n const lp = mesh.worldToLocal(this.a.copy(worldPoint))\n const ln = this.b.copy(worldNormal).transformDirection(this.m4.copy(mesh.matrixWorld).invert()).normalize()\n const r = Math.max(dent.radius, reachWorld) / s\n const depth = dent.depth / s\n // quick reject: the point must be near the mesh bounds\n const geo = mesh.geometry\n let bb: THREE_NS.Box3 | null\n if (mv.host) bb = this.localBox(mv, this.lbox)\n else {\n if (!geo.boundingBox) geo.computeBoundingBox()\n bb = geo.boundingBox\n }\n if (bb && !bb.isEmpty() && bb.distanceToPoint(lp) > r) return false\n if (!this.ownGeometry(mv)) return false\n const work = (mv.host ? mv.host.work : mv.work) as Float32Array\n const pos = positionAttr(mesh.geometry) as THREE_NS.BufferAttribute\n const from = mv.range ? mv.range[0] * 3 : 0\n const to = mv.range ? mv.range[1] * 3 : work.length\n const reach = r\n const reach2 = reach * reach\n for (let i = from; i < to; i += 3) {\n const dx = work[i] - lp.x\n const dy = work[i + 1] - lp.y\n const dz = work[i + 2] - lp.z\n const d2 = dx * dx + dy * dy + dz * dz\n if (d2 >= reach2) continue\n const f = 1 - d2 / reach2\n const k = depth * f * f\n work[i] -= ln.x * k\n work[i + 1] -= ln.y * k\n work[i + 2] -= ln.z * k\n }\n mv.touched = true\n this.writePositions(mv, pos)\n return true\n }\n\n /**\n * World radius a dent needs on this mesh to reach `MIN_DENT_VERTICES` vertices (the dent's own radius when the mesh is fine enough). A part with several meshes\n * (a shell and its label) must dent them all with the largest of these, so the skin and the shell follow the same smooth surface and never cross.\n */\n dentReach(mv: MeshVis, worldPoint: THREE_NS.Vector3, dent: Dent): number {\n const mesh = mv.mesh\n mesh.updateWorldMatrix(true, false)\n const s = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n const lp = mesh.worldToLocal(this.a.copy(worldPoint))\n const source = (mv.host ? mv.host.work : mv.work) ?? ((positionAttr(mesh.geometry) as THREE_NS.BufferAttribute | undefined)?.array as ArrayLike<number> | undefined)\n if (!source) return dent.radius\n // a mesh the dent does not touch (the far cap of a can) must not widen it\n let bounds: THREE_NS.Box3 | null\n if (mv.host) bounds = this.localBox(mv, this.lbox)\n else {\n if (!mesh.geometry.boundingBox) mesh.geometry.computeBoundingBox()\n bounds = mesh.geometry.boundingBox\n }\n if (bounds && !bounds.isEmpty() && bounds.distanceToPoint(lp) > dent.radius / s) return dent.radius\n const from = mv.range ? mv.range[0] * 3 : 0\n const to = mv.range ? mv.range[1] * 3 : source.length\n const r2 = (dent.radius / s) ** 2\n const distances: number[] = []\n let inside = 0\n for (let i = from; i < to; i += 3) {\n const dx = source[i]! - lp.x\n const dy = source[i + 1]! - lp.y\n const dz = source[i + 2]! - lp.z\n const d2 = dx * dx + dy * dy + dz * dz\n if (d2 < r2) inside++\n distances.push(d2)\n }\n if (inside >= MIN_DENT_VERTICES || distances.length < MIN_DENT_VERTICES) return dent.radius\n distances.sort((x, y) => x - y)\n const nearest = Math.sqrt(distances[0]!)\n return Math.max(dent.radius, Math.sqrt(distances[MIN_DENT_VERTICES - 1]!) * s * WIDEN_MARGIN, nearest * s * NEAREST_MARGIN)\n }\n\n /**\n * Dent all the meshes of a part. The shells take the dent as `applyDent` gives it; a skin (label, coat: `userData.destructionSkin`) sits a hair above its shell\n * and moves with the shell's surface instead (see `shellDisplacementAt`), so the shell never shows through it whatever the two meshes' vertex grids are.\n */\n applyPartDent(meshes: readonly MeshVis[], worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, dent: Dent, reachWorld: number): void {\n const isSkin = (mv: MeshVis): boolean => mv.mesh.userData.destructionSkin === true && !mv.host\n const shells = meshes.filter((mv) => !isSkin(mv))\n const snapshots: ShellSnapshot[] = []\n for (const mv of shells) {\n const heavy = this.lowQuality && this.vertexCount(mv) > 20000\n const plain = !mv.host && !heavy && this.ownGeometry(mv) && mv.work\n const before = plain ? new Float32Array(mv.work as Float32Array) : null\n this.applyDent(mv, worldPoint, worldNormal, dent, reachWorld)\n if (before) snapshots.push({ mesh: mv.mesh, before, after: mv.work as Float32Array })\n }\n const displacement = this.t\n const vertex = this.a\n for (const mv of meshes) {\n if (!isSkin(mv)) continue\n if (snapshots.length === 0) {\n this.applyDent(mv, worldPoint, worldNormal, dent, reachWorld)\n continue\n }\n if (!this.ownGeometry(mv)) continue\n const work = mv.work as Float32Array\n const mesh = mv.mesh\n mesh.updateWorldMatrix(true, false)\n const toLocal = this.m4.copy(mesh.matrixWorld).invert()\n const scale = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n let touched = false\n for (let i = 0; i < work.length; i += 3) {\n vertex.set(work[i]!, work[i + 1]!, work[i + 2]!).applyMatrix4(mesh.matrixWorld)\n if (vertex.distanceTo(worldPoint) > reachWorld) continue\n const height = shellDisplacementAt(this.THREE, vertex, snapshots, displacement)\n const length = displacement.length()\n if (length === 0) continue\n // the shell's facets lie outside a dip (deeper than the shell, the skin would sink under it) and inside a rim (the smooth dent is shallower there): take the shallower of the two\n const falloff = 1 - (vertex.distanceTo(worldPoint) / reachWorld) ** 2\n const smooth = dent.depth * falloff * falloff\n const pull = Math.max(0, Math.min(length, smooth) * SKIN_FOLLOW - SKIN_SLACK - height * SKIN_LAYER_SLACK)\n displacement.transformDirection(toLocal).multiplyScalar(pull / scale)\n work[i] += displacement.x\n work[i + 1] += displacement.y\n work[i + 2] += displacement.z\n touched = true\n }\n if (touched) this.writePositions(mv, positionAttr(mesh.geometry) as THREE_NS.BufferAttribute)\n }\n }\n\n /** Copy `work` (dents) into the geometry, adding the melt sag when the mesh is melting. */\n private writePositions(mv: MeshVis, pos: THREE_NS.BufferAttribute): void {\n if (mv.host) {\n this.rebuildHost(mv.host)\n return\n }\n const work = mv.work as Float32Array\n const arr = pos.array as unknown as Float32Array\n const melt = mv.meltApplied\n if (melt <= 0 || (this.lowQuality && work.length / 3 > 20000)) {\n arr.set(work)\n } else {\n const geo = mv.mesh.geometry\n if (!geo.boundingBox) geo.computeBoundingBox()\n const bb = geo.boundingBox as THREE_NS.Box3\n const h = Math.max(1e-4, bb.max.y - bb.min.y)\n const minY = bb.min.y\n for (let i = 0, v = 0; i < work.length; i += 3, v++) {\n const n = ((Math.imul(v + 1, 2654435761) >>> 0) % 1000) / 1000\n const n2 = ((Math.imul(v + 7, 40503) >>> 0) % 1000) / 1000\n const lowness = 1 - (work[i + 1] - minY) / h // 1 at the bottom, 0 at the top\n const spread = 1 + 0.12 * melt * (0.4 + n2) * (0.3 + lowness)\n arr[i] = work[i] * spread\n arr[i + 2] = work[i + 2] * spread\n arr[i + 1] = Math.max(minY, work[i + 1] - n * melt * h * 0.08)\n }\n }\n pos.needsUpdate = true\n const geo = mv.mesh.geometry\n geo.computeVertexNormals()\n geo.boundingBox = null\n geo.boundingSphere = null\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Decals\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /**\n * The point on the drawn face of `mesh` under a world point, within `DECAL_SNAP` metres along the normal: the world's box of a part and the face\n * the renderer drew (a coat of plaster, a merged house mesh) can be a few millimetres apart, and a mark behind the drawn face does not show.\n */\n private onFace(mesh: Mesh, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3): THREE_NS.Vector3 {\n if (!(mesh as { isMesh?: boolean }).isMesh || !mesh.geometry?.attributes?.position) return worldPoint\n const n = worldNormal.clone().normalize()\n this.ray.set(worldPoint.clone().addScaledVector(n, DECAL_SNAP), n.clone().negate())\n this.ray.near = 0\n this.ray.far = 2 * DECAL_SNAP\n const hits: THREE_NS.Intersection[] = []\n mesh.raycast(this.ray, hits)\n // a wall the house cut where it was shot is drawn by a mesh of its own next to the merged one (`breach-shell` of the house renderer); where it is\n // cut (`userData.cutAt`), the mark goes on what shows through (`userData.behind`: the bricks)\n for (const c of mesh.parent?.children ?? []) {\n if (c === mesh || c.name !== 'breach-shell') continue\n c.raycast(this.ray, hits)\n const behind = (c.userData.behind as (() => THREE_NS.Object3D | null) | undefined)?.()\n if (behind) behind.raycast(this.ray, hits)\n }\n let best: THREE_NS.Intersection | null = null\n for (const h of hits) {\n if ((h.object.userData.cutAt as ((p: THREE_NS.Vector3) => boolean) | undefined)?.(h.point)) continue\n if (h.face && h.face.normal.clone().transformDirection(h.object.matrixWorld).dot(n) <= 0.3) continue\n if (!best || Math.abs(h.distance - DECAL_SNAP) < Math.abs(best.distance - DECAL_SNAP)) best = h\n }\n return best ? best.point : worldPoint\n }\n\n /** Decal pose in mesh space: position and a rotation taking +Z to the surface normal. */\n private decalPose(mesh: Mesh, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, lift: number): { s: number; pos: THREE_NS.Vector3; quat: THREE_NS.Quaternion } {\n mesh.updateWorldMatrix(true, false)\n const s = mesh.matrixWorld.getMaxScaleOnAxis() || 1\n const ln = worldNormal.clone().transformDirection(this.m4.copy(mesh.matrixWorld).invert()).normalize()\n const pos = mesh.worldToLocal(this.onFace(mesh, worldPoint, worldNormal).clone()).addScaledVector(ln, lift / s)\n const quat = new this.THREE.Quaternion().setFromUnitVectors(new this.THREE.Vector3(0, 0, 1), ln)\n return { s, pos, quat }\n }\n\n private addDecal(mv: MeshVis, decal: Decal): void {\n decal.obj.userData.destructionDebris = true\n mv.mesh.add(decal.obj)\n mv.decals.push(decal)\n this.decalCount++\n while (mv.decals.length > 48 || this.decalCount > this.decalCap) {\n const old = mv.decals.shift()\n if (!old) break\n this.disposeDecal(old)\n }\n }\n\n private disposeDecal(d: Decal): void {\n d.obj.parent?.remove(d.obj)\n d.geometry?.dispose()\n this.decalCount = Math.max(0, this.decalCount - 1)\n }\n\n /**\n * Takes away the decals of a mesh that sit inside a box (world `center`, `half` extents along the axes of the world `rotation`): the surface they\n * marked is gone (a unit came out of the wall with its bullet holes and spalls).\n */\n clearDecals(mv: MeshVis, center: THREE_NS.Vector3, half: THREE_NS.Vector3, rotation: THREE_NS.Quaternion): void {\n const inv = rotation.clone().invert()\n const p = new this.THREE.Vector3()\n for (let i = mv.decals.length - 1; i >= 0; i--) {\n const d = mv.decals[i]!\n d.obj.getWorldPosition(p).sub(center).applyQuaternion(inv)\n if (Math.abs(p.x) > half.x || Math.abs(p.y) > half.y || Math.abs(p.z) > half.z) continue\n this.disposeDecal(d)\n mv.decals.splice(i, 1)\n }\n }\n\n addHole(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, diameter: number): void {\n const { s, pos, quat } = this.decalPose(mv.mesh, worldPoint, worldNormal, 0.0025)\n const work = (mv.host ? mv.host.work : mv.work) as Float32Array | undefined\n if (work && mv.touched) {\n const ln = worldNormal.clone().transformDirection(this.m4.copy(mv.mesh.matrixWorld).invert()).normalize()\n let minDistSq = Infinity\n let nearestDisp = 0\n const from = mv.range ? mv.range[0] * 3 : 0\n const to = mv.range ? mv.range[1] * 3 : work.length\n for (let i = from; i < to; i += 3) {\n const dx = work[i]! - pos.x\n const dy = work[i + 1]! - pos.y\n const dz = work[i + 2]! - pos.z\n const d2 = dx * dx + dy * dy + dz * dz\n if (d2 < minDistSq) {\n minDistSq = d2\n nearestDisp = dx * ln.x + dy * ln.y + dz * ln.z\n }\n }\n if (minDistSq < (0.06 / s) ** 2 && nearestDisp < 0) {\n pos.addScaledVector(ln, nearestDisp)\n }\n }\n const disc = new this.THREE.Mesh(this.kit.discGeometry(), this.kit.discMaterial())\n disc.position.copy(pos)\n disc.quaternion.copy(quat)\n disc.scale.setScalar((Math.max(0.004, diameter) * 0.5 * 1.25) / s)\n disc.renderOrder = 2\n this.addDecal(mv, { obj: disc })\n }\n\n /** A patch where a surface coat came off, in the colour of the core under it; drawn under the bullet holes. */\n addSpall(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, radius: number, color: number): void {\n const { s, pos, quat } = this.decalPose(mv.mesh, worldPoint, worldNormal, 0.0015)\n const disc = new this.THREE.Mesh(this.kit.discGeometry(), this.kit.patchMaterial(color))\n disc.position.copy(pos)\n disc.quaternion.copy(quat)\n disc.scale.setScalar(Math.max(0.01, radius) / s)\n disc.renderOrder = 1\n this.addDecal(mv, { obj: disc })\n }\n\n /** A star of jagged lines: `rays` rays up to `length` metres, seeded so the same event always draws the same star. */\n addCrack(mv: MeshVis, worldPoint: THREE_NS.Vector3, worldNormal: THREE_NS.Vector3, rays: number, length: number, color: number, seed: number): void {\n const { s, pos, quat } = this.decalPose(mv.mesh, worldPoint, worldNormal, 0.002)\n const rnd = createRng(seed)\n const verts: number[] = []\n const n = clamp(Math.round(rays), 3, 16)\n const L = Math.max(0.02, length) / s\n for (let r = 0; r < n; r++) {\n let ang = (r / n) * Math.PI * 2 + (rnd() - 0.5) * 0.5\n let x = 0\n let y = 0\n const segs = 3\n const total = L * (0.6 + 0.4 * rnd())\n for (let k = 0; k < segs; k++) {\n const step = (total / segs) * (0.7 + 0.6 * rnd())\n ang += (rnd() - 0.5) * 0.45\n const nx = x + Math.cos(ang) * step\n const ny = y + Math.sin(ang) * step\n verts.push(x, y, 0, nx, ny, 0)\n if (k > 0 && rnd() < 0.5) {\n const ba = ang + (rnd() < 0.5 ? -1 : 1) * (0.5 + rnd() * 0.5)\n const bl = step * (0.6 + 0.6 * rnd())\n verts.push(nx, ny, 0, nx + Math.cos(ba) * bl, ny + Math.sin(ba) * bl, 0)\n }\n x = nx\n y = ny\n }\n }\n // a faint ring around the impact\n const ringR = L * 0.12\n for (let k = 0; k < 8; k++) {\n const a0 = (k / 8) * Math.PI * 2\n const a1 = ((k + 1) / 8) * Math.PI * 2\n if (rnd() < 0.75) verts.push(Math.cos(a0) * ringR, Math.sin(a0) * ringR, 0, Math.cos(a1) * ringR, Math.sin(a1) * ringR, 0)\n }\n const geo = new this.THREE.BufferGeometry()\n geo.setAttribute('position', new this.THREE.Float32BufferAttribute(verts, 3))\n const lines = new this.THREE.LineSegments(geo, this.kit.lineMaterial(color))\n lines.position.copy(pos)\n lines.quaternion.copy(quat)\n lines.renderOrder = 2\n this.addDecal(mv, { obj: lines, geometry: geo })\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Char and heat glow\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n setChar(pv: PartVis, char: number, charColor: number): void {\n if (Math.abs(char - pv.charApplied) < 0.004) return\n pv.charApplied = char\n const target = new this.THREE.Color(charColor)\n for (const mv of pv.meshes) {\n if (mv.host) {\n mv.charK = clamp(char, 0, 1)\n mv.charHex = charColor\n this.paint(mv)\n continue\n }\n this.ownMaterial(mv)\n const mats = materialsOf(mv.mesh.material)\n mats.forEach((m, i) => {\n const c = colorOf(m)\n const base = mv.baseColors?.[i]\n if (c && base) c.copy(base).lerp(target, clamp(char, 0, 1))\n })\n }\n }\n\n /** Emissive glow of a hot part. `temperature` below the glow threshold switches it off. */\n setGlow(pv: PartVis, temperatureC: number): void {\n const hex = heatColor(temperatureC)\n const key = hex === 0 ? 0 : Math.round(temperatureC / 5) * 5\n if (key === pv.glowApplied) return\n pv.glowApplied = key\n const intensity = hex === 0 ? 0 : clamp(0.35 + (temperatureC - 450) / 900, 0, 1.4)\n for (const mv of pv.meshes) {\n if (mv.host) {\n mv.glowHex = hex\n mv.glowK = intensity\n this.paint(mv)\n continue\n }\n this.ownMaterial(mv)\n for (const m of materialsOf(mv.mesh.material)) {\n const e = (m as THREE_NS.MeshStandardMaterial).emissive\n if (e && (e as THREE_NS.Color).isColor) {\n e.setHex(hex)\n ;(m as THREE_NS.MeshStandardMaterial).emissiveIntensity = intensity\n }\n }\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Melt\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /** Sag the part: shorter in Y (down to 25 %), a bit wider, vertices pushed down with noise, the bottom stays put. */\n setMelt(pv: PartVis, melt: number): void {\n const m = clamp(melt, 0, 1)\n if (Math.abs(m - pv.meltApplied) < 0.01) return\n pv.meltApplied = m\n for (const mv of pv.meshes) {\n const mesh = mv.mesh\n if (mv.host) {\n // a range of a shared mesh cannot scale the mesh: squash and widen its own vertices\n mv.meltApplied = m\n mv.touched = true\n if (!(this.lowQuality && this.vertexCount(mv) > 20000) && this.ownGeometry(mv)) this.rebuildHost(mv.host)\n continue\n }\n if (mv.meltApplied === 0 && m > 0) {\n mesh.updateWorldMatrix(true, false)\n mv.bottomY = this.box.setFromObject(mesh).min.y\n }\n mv.meltApplied = m\n mv.moved = true\n const sy = lerp(1, 0.25, m)\n const sxz = 1 + 0.18 * m\n mesh.scale.set(mv.origScale.x * sxz, mv.origScale.y * sy, mv.origScale.z * sxz)\n mesh.position.copy(mv.origPosition)\n mesh.updateWorldMatrix(true, false)\n const bottom = this.box.setFromObject(mesh).min.y\n const dy = mv.bottomY - bottom\n if (Math.abs(dy) > 1e-6 && mesh.parent) {\n mesh.parent.updateWorldMatrix(true, false)\n const inv = this.m4.copy(mesh.parent.matrixWorld).invert()\n this.a.set(0, dy, 0).applyMatrix4(inv)\n this.b.set(0, 0, 0).applyMatrix4(inv)\n mesh.position.copy(mv.origPosition).add(this.a.sub(this.b))\n }\n if (!(this.lowQuality && this.vertexCount(mv) > 20000) && this.ownGeometry(mv)) {\n this.writePositions(mv, positionAttr(mesh.geometry) as THREE_NS.BufferAttribute)\n }\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Visibility and restore\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n hide(pv: PartVis, reason: PartVis['gone']): void {\n pv.gone = reason\n for (const mv of pv.meshes) {\n if (!mv.host || mv.loose) {\n mv.mesh.visible = false\n mv.hidden = true\n continue\n }\n // a range of a shared mesh: collapse its vertices to a point and hide what was drawn on it\n mv.hidden = true\n for (const d of mv.decals) d.obj.visible = false\n this.collapse(mv)\n }\n }\n\n // ------------------------------------------------------------------------------------------------------------------------------------\n // Parts drawn by a vertex range of a merged mesh\n // ------------------------------------------------------------------------------------------------------------------------------------\n\n /** Collapse the part's vertices in the merged mesh to one point (its triangles become degenerate and vanish). */\n private collapse(mv: MeshVis): void {\n if (!mv.merged || !this.ownHostGeometry(mv.merged.host)) return\n mv.collapsed = true\n mv.touched = true\n this.rebuildHost(mv.merged.host)\n }\n\n /** Write `work` into the geometry again with the melt of ranged parts and the collapsed ranges applied. */\n private rebuildHost(host: HostVis): void {\n const geo = host.mesh.geometry\n const pos = positionAttr(geo)\n const work = host.work\n if (!pos || !work) return\n const arr = pos.array as unknown as Float32Array\n arr.set(work)\n collapseForeign(host.mesh, arr)\n for (const s of host.sharers) {\n if (s.merged && s.merged.host === host) {\n if (s.collapsed) this.collapseRange(arr, s.merged.range)\n else if (s.meltApplied > 0 && !s.loose) this.meltRange(arr, work, s.merged.range, s.meltApplied)\n } else if (s.host === host && s.range && s.meltApplied > 0) this.meltRange(arr, work, s.range, s.meltApplied)\n }\n pos.needsUpdate = true\n geo.computeVertexNormals()\n geo.boundingBox = null\n geo.boundingSphere = null\n }\n\n private collapseRange(arr: Float32Array, range: [number, number]): void {\n const x = arr[range[0] * 3]\n const y = arr[range[0] * 3 + 1]\n const z = arr[range[0] * 3 + 2]\n for (let i = range[0] * 3; i < range[1] * 3; i += 3) {\n arr[i] = x\n arr[i + 1] = y\n arr[i + 2] = z\n }\n }\n\n /** Melt of one range: shorter in Y (down to 25 %) with the bottom fixed, a bit wider around its centre, with the same noise as a whole mesh. */\n private meltRange(arr: Float32Array, work: Float32Array, range: [number, number], melt: number): void {\n let minY = Infinity\n let maxY = -Infinity\n let cx = 0\n let cz = 0\n const n = Math.max(1, range[1] - range[0])\n for (let i = range[0] * 3; i < range[1] * 3; i += 3) {\n minY = Math.min(minY, work[i + 1])\n maxY = Math.max(maxY, work[i + 1])\n cx += work[i]\n cz += work[i + 2]\n }\n cx /= n\n cz /= n\n const h = Math.max(1e-4, maxY - minY)\n const sy = lerp(1, 0.25, melt)\n const sxz = 1 + 0.18 * melt\n for (let i = range[0] * 3, v = 0; i < range[1] * 3; i += 3, v++) {\n const noise = ((Math.imul(v + 1, 2654435761) >>> 0) % 1000) / 1000\n arr[i] = cx + (work[i] - cx) * sxz\n arr[i + 2] = cz + (work[i + 2] - cz) * sxz\n arr[i + 1] = Math.max(minY, minY + (work[i + 1] - minY) * sy - noise * melt * h * 0.04)\n }\n }\n\n /** The colour attribute of the host's current geometry (created white when there is none) with vertex colours switched on in its material. */\n private ensureColors(host: HostVis): THREE_NS.BufferAttribute | null {\n if (!this.ownHostGeometry(host)) return null\n const geo = host.mesh.geometry\n let attr = geo.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n if (!attr) {\n const n = geo.getAttribute(POS_ATTR).count\n attr = new this.THREE.BufferAttribute(new Float32Array(n * 3).fill(1), 3)\n geo.setAttribute('color', attr)\n }\n if (!host.ownMat) {\n host.ownMat = true\n const src = materialsOf(host.mesh.material)\n const cloned = src.map((m) => m.clone())\n host.mesh.material = Array.isArray(host.mesh.material) ? cloned : cloned[0]\n }\n for (const m of materialsOf(host.mesh.material)) {\n if ((m as THREE_NS.MeshStandardMaterial).vertexColors !== true) {\n ;(m as THREE_NS.MeshStandardMaterial).vertexColors = true\n m.needsUpdate = true\n }\n }\n return attr\n }\n\n /** Colour of the part's vertices from the original colours, its char and its heat. Only the part's range is written. */\n private paint(mv: MeshVis): void {\n if (!mv.host || !mv.range || !mv.merged) return\n const idle = mv.charK <= 0 && mv.glowK <= 0\n if (idle && !mv.touched) return\n const attr = this.ensureColors(mv.host)\n if (!attr) return\n const size = attr.itemSize\n const arr = attr.array as unknown as Float32Array\n const orig = mv.merged.host.origGeometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n const oSize = orig?.itemSize ?? 3\n const oArr = orig?.array as unknown as ArrayLike<number> | undefined\n const shift = mv.merged.range[0] - mv.range[0]\n const ch = new this.THREE.Color(mv.charHex)\n const heat = new this.THREE.Color(mv.glowHex)\n const k = clamp(mv.charK, 0, 1)\n const gk = clamp(mv.glowK, 0, 1)\n const boost = 1 + Math.max(0, mv.glowK - 1)\n for (let i = mv.range[0]; i < mv.range[1]; i++) {\n const o = (i + shift) * oSize\n let r = oArr ? oArr[o] : 1\n let g = oArr ? oArr[o + 1] : 1\n let b = oArr ? oArr[o + 2] : 1\n if (k > 0) {\n r = lerp(r, ch.r, k)\n g = lerp(g, ch.g, k)\n b = lerp(b, ch.b, k)\n }\n if (gk > 0) {\n r = lerp(r, heat.r * boost, gk)\n g = lerp(g, heat.g * boost, gk)\n b = lerp(b, heat.b * boost, gk)\n }\n arr[i * size] = r\n arr[i * size + 1] = g\n arr[i * size + 2] = b\n }\n mv.touched = true\n attr.needsUpdate = true\n }\n\n /**\n * Move a ranged part to a mesh of its own: the faces whose vertices all lie in its range are copied (with the current dents and colours) into a\n * new mesh that takes the merged mesh's transform and material, then attached to `group`; the range is collapsed in the merged mesh. Decals\n * go with it.\n */\n extract(mv: MeshVis, group: THREE_NS.Object3D): void {\n if (!mv.host || !mv.range || !mv.merged || mv.loose) return\n const host = mv.host\n const [v0, v1] = mv.range\n const src = host.mesh.geometry\n const geo = new this.THREE.BufferGeometry()\n const count = v1 - v0\n for (const name of Object.keys(src.attributes)) {\n const a = src.getAttribute(name) as THREE_NS.BufferAttribute\n if ((a as unknown as { isInterleavedBufferAttribute?: boolean }).isInterleavedBufferAttribute) continue\n const size = a.itemSize\n const from = (name === POS_ATTR ? plainPositions(host.mesh, v0, v1) ?? host.work : null) ?? (a.array as unknown as Float32Array)\n const slice = (from as unknown as { slice(a: number, b: number): ArrayLike<number> }).slice(v0 * size, v1 * size)\n const Ctor = (a.array as unknown as { constructor: new (x: ArrayLike<number>) => ArrayLike<number> }).constructor\n geo.setAttribute(name, new this.THREE.BufferAttribute(new Ctor(slice) as never, size, a.normalized))\n }\n const index = src.getIndex()\n if (index) {\n const out: number[] = []\n for (let i = 0; i + 2 < index.count; i += 3) {\n const a = index.getX(i)\n const b = index.getX(i + 1)\n const c = index.getX(i + 2)\n if (a >= v0 && a < v1 && b >= v0 && b < v1 && c >= v0 && c < v1) out.push(a - v0, b - v0, c - v0)\n }\n geo.setIndex(count > 65535 ? new this.THREE.Uint32BufferAttribute(out, 1) : new this.THREE.Uint16BufferAttribute(out, 1))\n }\n const mats = materialsOf(host.mesh.material).map((m) => m.clone())\n const loose = new this.THREE.Mesh(geo, mats[0])\n loose.name = `${host.mesh.name || 'mesh'}:${v0}-${v1}`\n loose.castShadow = host.mesh.castShadow\n loose.receiveShadow = host.mesh.receiveShadow\n loose.renderOrder = host.mesh.renderOrder\n loose.frustumCulled = host.mesh.frustumCulled\n loose.layers.mask = host.mesh.layers.mask\n loose.position.copy(host.mesh.position)\n loose.quaternion.copy(host.mesh.quaternion)\n loose.scale.copy(host.mesh.scale)\n const parent = host.mesh.parent\n if (parent) parent.add(loose)\n loose.updateMatrixWorld(true)\n // the merged mesh loses the range; the decals and the part's state follow the new mesh\n this.collapse(mv)\n for (const d of mv.decals) {\n d.obj.visible = true\n loose.add(d.obj)\n }\n const lp = positionAttr(geo) as THREE_NS.BufferAttribute\n const lh: HostVis = {\n mesh: loose,\n origGeometry: geo,\n origMaterial: loose.material,\n ownGeo: true,\n work: new Float32Array(lp.array as ArrayLike<number>),\n ownMat: true,\n sharers: [mv],\n }\n mv.host = lh\n mv.range = [0, count]\n mv.mesh = loose\n mv.loose = true\n mv.moved = true\n group.attach(loose)\n for (const m of materialsOf(loose.material)) m.needsUpdate = true\n }\n\n private restoreRanged(mv: MeshVis): void {\n const merged = mv.merged as NonNullable<MeshVis['merged']>\n const host = merged.host\n for (const d of mv.decals) this.disposeDecal(d)\n mv.decals.length = 0\n if (mv.loose) {\n const loose = mv.mesh\n loose.parent?.remove(loose)\n loose.geometry.dispose()\n for (const m of materialsOf(loose.material)) m.dispose()\n mv.host = host\n mv.range = [merged.range[0], merged.range[1]]\n mv.mesh = host.mesh\n mv.loose = false\n mv.moved = false\n }\n mv.collapsed = false\n mv.hidden = false\n mv.meltApplied = 0\n mv.charK = 0\n mv.glowK = 0\n mv.touched = false\n if (!host.ownGeo) return\n // positions and colours of the range go back to the original ones\n const work = host.work as Float32Array\n const op = basePositions(host)\n const [v0, v1] = merged.range\n if (op) work.set(op.subarray(v0 * 3, v1 * 3), v0 * 3)\n const attr = host.mesh.geometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n if (attr) {\n const orig = host.origGeometry.getAttribute('color') as THREE_NS.BufferAttribute | undefined\n const size = attr.itemSize\n const a = attr.array as unknown as Float32Array\n for (let i = v0; i < v1; i++) {\n for (let c = 0; c < 3; c++) a[i * size + c] = orig ? orig.array[i * orig.itemSize + c] : 1\n }\n attr.needsUpdate = true\n }\n if (host.sharers.every((s) => !s.touched)) {\n host.mesh.geometry.dispose()\n host.mesh.geometry = host.origGeometry\n // the original geometry as it is now: its first positions, with what another drawing keeps collapsed\n const base = basePositions(host), back = positionAttr(host.origGeometry)\n if (base && back) {\n const arr = back.array as unknown as Float32Array\n arr.set(base)\n collapseForeign(host.mesh, arr)\n back.needsUpdate = true\n }\n host.work = null\n host.ownGeo = false\n if (host.ownMat) {\n for (const m of materialsOf(host.mesh.material)) m.dispose()\n host.mesh.material = host.origMaterial\n host.ownMat = false\n }\n } else this.rebuildHost(host)\n }\n\n /** Bring one mesh back to how it was when it was bound. */\n restoreMesh(mv: MeshVis): void {\n if (mv.merged) {\n this.restoreRanged(mv)\n return\n }\n const mesh = mv.mesh\n for (const d of mv.decals) this.disposeDecal(d)\n mv.decals.length = 0\n if (mv.ownGeo) {\n mesh.geometry.dispose()\n mesh.geometry = mv.origGeometry\n mv.ownGeo = false\n mv.work = null\n }\n if (mv.ownMat) {\n for (const m of materialsOf(mesh.material)) m.dispose()\n mesh.material = mv.origMaterial\n mv.ownMat = false\n mv.baseColors = null\n }\n mesh.visible = mv.origVisible\n if (mv.origParent && mesh.parent !== mv.origParent) {\n mv.origParent.add(mesh)\n mv.moved = true\n }\n if (mv.moved) {\n mesh.position.copy(mv.origPosition)\n mesh.quaternion.copy(mv.origQuaternion)\n mesh.scale.copy(mv.origScale)\n mv.moved = false\n }\n mv.meltApplied = 0\n }\n\n restorePart(pv: PartVis): void {\n for (const mv of pv.meshes) this.restoreMesh(mv)\n pv.charApplied = 0\n pv.glowApplied = 0\n pv.meltApplied = 0\n pv.gone = 'none'\n }\n\n dispose(): void {\n this.kit.dispose()\n }\n}\n","// The sounds of materials breaking, as recipes of @adatechnology/game-audio. The art scene's `sfx.*` (cena L1354-L1367) are ported literally: the same\n// filters, frequencies, lengths, volumes and reverb sends, and the same random numbers drawn in the same order, so a recipe leaves the trace of the team\n// code. The game's `boom` (jogo L68278) is here too, as the game's explosion.\nimport { DISTANCE_CURVES, sceneMany as many, sceneNoise as noise, sceneRecipe, sceneTone as tone } from '@adatechnology/game-audio'\nimport type { Layer, LoopRecipe, SoundBank, SoundRecipe } from '@adatechnology/game-audio'\n\nimport { BLAST_SOUNDS, FIRE_FUEL_LOOPS, FIRE_LOOP, FIRE_SOUNDS, GRENADE_PIN_PULL, SMOKE_HISS_LOOP } from './blast-fire'\n\nconst scene = (id: string, layers: readonly Layer[], line: string, vars?: SoundRecipe['vars'], group?: string): SoundRecipe =>\n sceneRecipe(id, layers, line, { ...(vars ? { vars } : {}), ...(group ? { group } : {}) })\n\nconst boomLayers = (big: boolean): Layer[] => [\n noise({ f: 1200, f2: 120, d: 1.8, vol: 2, wet: 1.2 }),\n tone({ f: 65, f2: 24, d: 1.0, vol: 1.8 }),\n noise({ type: 'highpass', f: 1500, d: 0.2, vol: 0.8 }),\n ...(big ? [noise({ f: 500, f2: 90, a: 0.2, d: 2.4, vol: 1.2, wet: 1, delay: 0.15 })] : []),\n ...many(8, () => tone({ f: [2600, 5600], d: 0.05, vol: 0.08, delay: [0.4, 1.6] })),\n]\n\n/** The art scene's destruction sounds, each with the team name in its `sources`. */\nexport const SCENE_SOUNDS: readonly SoundRecipe[] = [\n scene(\n 'glass_shatter',\n [noise({ type: 'highpass', f: 2800, d: 0.45, vol: 0.9, wet: 0.5 }), ...many(12, () => tone({ f: [3000, 7500], d: [0.06, 0.14], vol: 0.18, delay: [0, 0.55] }))],\n 'L1359 glass',\n ),\n scene(\n 'wood_hit',\n [noise({ type: 'bandpass', f: 850, q: 1, d: 0.25, vol: 0.9, wet: 0.3 }), tone({ f: 210, f2: 90, d: 0.1, vol: 0.6 }), noise({ type: 'highpass', f: 2000, d: 0.04, vol: 0.5 })],\n 'L1360 wood',\n ),\n // many parts coming loose at once share the `debris_knock` voices (game-audio voice-groups.json)\n scene('thunk', [noise({ type: 'bandpass', f: 700, q: 2, d: 0.07, vol: 0.4 })], 'L1361 thunk', undefined, 'debris_knock'),\n scene('ping', [tone({ f: [2600, 3500], f2: 1400, d: 0.14, vol: 0.18, wet: 0.3 })], 'L1362 ping'),\n scene('clang', [tone({ f: [520, 720], f2: 480, d: 0.5, vol: 0.35, wet: 0.4 }), tone({ f: 1370, f2: 1300, d: 0.3, vol: 0.15 }), noise({ type: 'highpass', f: 2000, d: 0.05, vol: 0.5 })], 'L1363 clang'),\n scene('chip', [noise({ type: 'bandpass', f: 1600, q: 1.2, d: 0.06, vol: 0.5 })], 'L1364 chip'),\n scene(\n 'crumble',\n [noise({ f: 900, f2: 200, d: 0.6, vol: 0.9, wet: 0.3 }), ...many(5, () => noise({ type: 'bandpass', f: [500, 1400], q: 2, d: 0.05, vol: 0.4, delay: [0.1, 0.5] }))],\n 'L1365 crumble',\n ),\n // `thud(x, z, v)`: `v` is the `scale` param (default 1)\n scene('thud', [tone({ f: 75, f2: 38, d: 0.22, vol: { param: 'scale', scale: 0.6 } }), noise({ f: 420, d: 0.16, vol: { param: 'scale', scale: 0.45 } })], 'L1358 thud', { scale: 1 }),\n // `hiss(x, z, d)`: `seconds` is the param `d` (default 1.2)\n // every melting part shares one `sizzle` voice\n scene('hiss', [noise({ type: 'highpass', f: 3500, a: 0.05, d: { param: 'seconds' }, vol: 0.35 })], 'L1366 hiss', { seconds: 1.2 }, 'sizzle'),\n scene('boom', boomLayers(false), 'L1367 boom'),\n scene('boom_big', boomLayers(true), 'L1367 boom (big)'),\n scene('burst', [noise({ f: 700, f2: 120, d: 0.7, vol: 1.4, wet: 0.5 }), noise({ type: 'highpass', f: 3000, a: 0.05, d: 1.2, vol: 0.4, delay: 0.1 })], 'L1357 burst'),\n scene('crack', [noise({ type: 'highpass', f: 1800, d: 0.05, vol: 0.8 }), tone({ f: 420, f2: 180, d: 0.06, vol: 0.4 })], 'L1354 crack'),\n]\n\n/** The game's explosion thump: a sine from 70 to 28 Hz over 1.2 s, `1.4 / (1 + d² × 0.002)` (jogo L68278). */\nexport const EXPLOSION_BOOM: SoundRecipe = {\n id: 'explosion_boom',\n bus: 'world',\n order: 'boom',\n duration: 1.6,\n tail: 0.1,\n layers: [\n {\n source: { kind: 'osc', wave: 'sine', frequency: { from: 70, to: 28, curve: 'exp', over: 1.2 } },\n envelope: [\n [0, 1, 'set'],\n ['1d', 0.001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: DISTANCE_CURVES.game_boom,\n sources: ['jogo:L68278-68285 boom'],\n}\n\n/**\n * The fire loop of the art scene (cena L1316): noise through a 1800 Hz bandpass (Q 0.6) into a gain that starts at 0. The page never raises it, so it is\n * silent there; here `createDestructionSound` raises it while something burns (the level is the kit's, in `fire`).\n */\nexport const BURN_LOOP: LoopRecipe = {\n id: 'burn_loop',\n bus: 'world',\n order: 'chain_loop',\n source: { kind: 'noise', loop: true },\n filters: { mode: 'serial', bank: [{ type: 'bandpass', frequency: { set: 1800 }, q: 0.6 }] },\n volume: 0,\n sources: ['cena:L1316 fire loop (silent in the page: its gain is never raised)', 'sdk: the level while burning'],\n}\n\nconst drag = (id: string, layers: readonly Layer[]): SoundRecipe => ({ ...sceneRecipe(id, layers, ''), sources: ['sdk: a base dragged on a floor, one grain per stretch'] })\n\n/** Something heavy dragged on a floor, by what its base is made of. */\nexport const DRAG_SOUNDS: readonly SoundRecipe[] = [\n drag('drag_wood', [noise({ type: 'bandpass', f: 380, q: 1.4, d: 0.28, vol: 0.5 }), noise({ type: 'bandpass', f: [900, 1300], q: 3, d: 0.08, vol: 0.14 })]),\n drag('drag_metal', [noise({ type: 'bandpass', f: 1500, q: 4, d: 0.26, vol: 0.32 }), tone({ f: [880, 1240], f2: 760, d: 0.18, vol: 0.05 })]),\n drag('drag_glass', [noise({ type: 'bandpass', f: 2600, q: 5, d: 0.2, vol: 0.22 })]),\n drag('drag_masonry', [noise({ type: 'bandpass', f: 260, q: 0.9, d: 0.3, vol: 0.62 }), ...many(3, () => noise({ type: 'bandpass', f: [600, 1200], q: 2, d: 0.04, vol: 0.14, delay: [0, 0.2] }))]),\n drag('drag_soft', [noise({ type: 'lowpass', f: 420, d: 0.28, vol: 0.3 })]),\n]\n\nconst leaf = (id: string, layers: readonly Layer[]): SoundRecipe => ({ ...sceneRecipe(id, layers, ''), sources: ['sdk: a door, lid or drawer worked by hand'] })\n\n/** A leaf worked by hand: the latch, the hinge as it turns (by what the leaf is made of), the leaf meeting its frame, a locked leaf shaken, a drawer on its runners. */\nexport const LEAF_SOUNDS: readonly SoundRecipe[] = [\n leaf('latch', [noise({ type: 'bandpass', f: 2400, q: 4, d: 0.03, vol: 0.35 }), tone({ f: 1900, f2: 1500, d: 0.025, vol: 0.06, delay: 0.035 })]),\n leaf('creak_wood', [tone({ f: [190, 240], f2: 310, d: 0.5, vol: 0.05 }), noise({ type: 'bandpass', f: 520, q: 6, a: 0.05, d: 0.45, vol: 0.12 })]),\n leaf('creak_metal', [tone({ f: [620, 760], f2: 900, d: 0.35, vol: 0.035 }), noise({ type: 'bandpass', f: 1400, q: 8, a: 0.04, d: 0.3, vol: 0.08 })]),\n leaf('shut_wood', [tone({ f: 120, f2: 60, d: 0.14, vol: 0.5 }), noise({ type: 'bandpass', f: 600, q: 1.2, d: 0.1, vol: 0.55, wet: 0.25 }), noise({ type: 'bandpass', f: 2400, q: 4, d: 0.03, vol: 0.25, delay: 0.02 })]),\n leaf('shut_metal', [tone({ f: 160, f2: 85, d: 0.18, vol: 0.55 }), noise({ type: 'bandpass', f: 900, q: 1.6, d: 0.12, vol: 0.45, wet: 0.3 }), tone({ f: 1250, f2: 1150, d: 0.12, vol: 0.06 })]),\n leaf('shut_soft', [tone({ f: 95, f2: 55, d: 0.12, vol: 0.35 }), noise({ type: 'lowpass', f: 500, d: 0.1, vol: 0.3 })]),\n leaf('rattle', many(5, () => noise({ type: 'bandpass', f: [1600, 2600], q: 3, d: 0.035, vol: 0.32, delay: [0, 0.45] }))),\n leaf('slide', [noise({ type: 'bandpass', f: 700, q: 2, a: 0.04, d: 0.35, vol: 0.22 }), noise({ type: 'bandpass', f: 2200, q: 5, d: 0.3, vol: 0.05 })]),\n // an item taken in the hand: the fingers on a hard surface and the sleeve moving, or a soft thing gathered up (the kit's recordings answer these ids)\n leaf('grab_hard', [noise({ type: 'bandpass', f: 1800, q: 3, d: 0.03, vol: 0.18 }), noise({ type: 'bandpass', f: 900, q: 1.2, a: 0.02, d: 0.14, vol: 0.08 })]),\n leaf('grab_soft', [noise({ type: 'lowpass', f: 1400, a: 0.02, d: 0.16, vol: 0.14 })]),\n]\n\nconst impact = (id: string, layers: readonly Layer[]): SoundRecipe => ({ ...sceneRecipe(id, layers, ''), sources: ['sdk: a blow on a material, by material and kind of blow (synthesised until the recorded samples arrive)'] })\n\n/**\n * A blow on a material, by what it is made of and what met it (`impactSoundKeys`): a bullet, a blunt blow (a punch, a kick, a fall), a blade. Each\n * is drawn from how the real thing sounds (checklist 5.3): a bullet rings steel and goes \"tchak\" on concrete with pebbles after it, a fist on steel is a\n * low \"bong\", a knife scrapes it; the ground is a dull \"tuf\", ceramic a dry \"tic\", plastic a hollow \"toc\", a sofa a \"fump\". Levels are matched so a\n * bullet on concrete is as loud as on wood.\n */\nexport const IMPACT_SOUNDS: readonly SoundRecipe[] = [\n // metal\n impact('metal_bullet', [noise({ type: 'highpass', f: 3000, d: 0.03, vol: 0.8 }), tone({ f: [2600, 3400], f2: 1800, d: 0.14, vol: 0.28, wet: 0.35 }), tone({ f: [520, 720], f2: 480, d: 0.35, vol: 0.22, wet: 0.35 })]),\n impact('metal_blunt', [noise({ type: 'bandpass', f: 800, q: 1, d: 0.05, vol: 0.5 }), tone({ f: [150, 210], f2: 120, d: 0.6, vol: 0.5, wet: 0.4 }), tone({ f: [420, 520], f2: 400, d: 0.4, vol: 0.12 })]),\n impact('metal_blade', [noise({ type: 'bandpass', f: [3500, 4500], q: 6, a: 0.01, d: 0.18, vol: 0.45 }), tone({ f: [2200, 2800], f2: 3000, d: 0.15, vol: 0.06 })]),\n impact('metal_thin', [noise({ type: 'highpass', f: 2500, d: 0.04, vol: 0.6 }), tone({ f: [900, 1300], f2: 700, d: 0.25, vol: 0.22, wet: 0.3 }), noise({ type: 'bandpass', f: 1200, q: 2, d: 0.08, vol: 0.3 })]),\n // wood (the bullet keeps the art scene's `wood_hit`)\n impact('wood_blunt', [tone({ f: [110, 150], f2: 70, d: 0.14, vol: 0.6 }), noise({ type: 'bandpass', f: 500, q: 1.2, d: 0.12, vol: 0.55, wet: 0.2 })]),\n impact('wood_blade', [noise({ type: 'bandpass', f: [1800, 2400], q: 2, a: 0.01, d: 0.12, vol: 0.5 }), ...many(3, () => noise({ type: 'bandpass', f: [2500, 4000], q: 3, d: 0.02, vol: 0.22, delay: [0.02, 0.1] }))]),\n impact('mdf_puff', [noise({ type: 'lowpass', f: 900, d: 0.08, vol: 1 }), tone({ f: [180, 230], f2: 110, d: 0.06, vol: 0.3 }), noise({ type: 'highpass', f: 3000, a: 0.01, d: 0.2, vol: 0.1 })]),\n // glass and ceramic\n impact('glass_bullet', [noise({ type: 'highpass', f: 4000, d: 0.05, vol: 0.7 }), tone({ f: [3200, 4200], f2: 2600, d: 0.2, vol: 0.14, wet: 0.3 }), ...many(4, () => tone({ f: [4000, 7000], d: 0.05, vol: 0.07, delay: [0.02, 0.2] }))]),\n impact('glass_blunt', [noise({ type: 'bandpass', f: 2200, q: 3, d: 0.05, vol: 0.8 }), tone({ f: [1400, 1800], f2: 1300, d: 0.2, vol: 0.16, wet: 0.3 })]),\n impact('glass_blade', [noise({ type: 'bandpass', f: 5000, q: 8, a: 0.02, d: 0.25, vol: 0.3 })]),\n impact('ceramic_hit', [noise({ type: 'bandpass', f: 3000, q: 2, d: 0.03, vol: 0.6 }), tone({ f: [1800, 2400], f2: 1600, d: 0.1, vol: 0.2 })]),\n impact('ceramic_bullet', [noise({ type: 'highpass', f: 2500, d: 0.06, vol: 0.85 }), ...many(5, () => tone({ f: [2500, 5000], d: 0.04, vol: 0.09, delay: [0, 0.15] }))]),\n // masonry and the ground\n impact('masonry_bullet', [noise({ type: 'bandpass', f: [1600, 2000], q: 1, d: 0.05, vol: 1.8 }), noise({ type: 'lowpass', f: 600, d: 0.12, vol: 0.9, wet: 0.2 }), ...many(4, () => noise({ type: 'bandpass', f: [2000, 4000], q: 3, d: 0.02, vol: 0.28, delay: [0.03, 0.3] }))]),\n impact('masonry_blunt', [tone({ f: [70, 95], f2: 45, d: 0.12, vol: 0.55 }), noise({ type: 'lowpass', f: 400, d: 0.1, vol: 0.5 })]),\n impact('masonry_blade', [noise({ type: 'bandpass', f: [2500, 3500], q: 4, a: 0.01, d: 0.15, vol: 0.4 })]),\n impact('plaster_puff', [noise({ type: 'lowpass', f: 900, d: 0.09, vol: 0.7 }), noise({ type: 'highpass', f: 3000, a: 0.01, d: 0.2, vol: 0.14 })]),\n impact('soil_bullet', [noise({ type: 'lowpass', f: 700, d: 0.08, vol: 2.2 }), ...many(3, () => noise({ type: 'bandpass', f: [1200, 2200], q: 2, d: 0.03, vol: 0.18, delay: [0.02, 0.2] }))]),\n impact('soil_blunt', [tone({ f: [55, 70], f2: 40, d: 0.1, vol: 0.45 }), noise({ type: 'lowpass', f: 300, d: 0.08, vol: 0.4 })]),\n impact('sand_hit', [noise({ type: 'bandpass', f: 3500, q: 0.8, a: 0.005, d: 0.15, vol: 0.45 }), noise({ type: 'lowpass', f: 500, d: 0.06, vol: 0.45 })]),\n impact('gravel_hit', [noise({ type: 'lowpass', f: 500, d: 0.06, vol: 0.45 }), ...many(6, () => noise({ type: 'bandpass', f: [1500, 3500], q: 3, d: 0.025, vol: 0.28, delay: [0, 0.18] }))]),\n // plastic, rubber, wax\n impact('plastic_hit', [noise({ type: 'bandpass', f: 1600, q: 3, d: 0.04, vol: 0.5 }), tone({ f: [380, 520], f2: 300, d: 0.08, vol: 0.32 })]),\n impact('plastic_bullet', [noise({ type: 'bandpass', f: 2500, q: 2, d: 0.03, vol: 1.3 }), tone({ f: [600, 800], f2: 450, d: 0.06, vol: 0.4 })]),\n impact('rubber_hit', [tone({ f: [90, 130], f2: 60, d: 0.1, vol: 0.45 }), noise({ type: 'lowpass', f: 350, d: 0.06, vol: 0.28 })]),\n impact('wax_hit', [noise({ type: 'lowpass', f: 800, d: 0.05, vol: 0.45 }), tone({ f: [240, 280], f2: 180, d: 0.05, vol: 0.22 })]),\n // soft things, paper, plants\n impact('soft_bullet', [noise({ type: 'lowpass', f: 450, a: 0.003, d: 0.1, vol: 1.8 }), noise({ type: 'bandpass', f: 900, q: 1, d: 0.05, vol: 0.5 })]),\n impact('fabric_rip', [noise({ type: 'bandpass', f: [2000, 2800], q: 1.5, a: 0.02, d: 0.25, vol: 0.4 }), ...many(4, () => noise({ type: 'bandpass', f: [3000, 5000], q: 4, d: 0.02, vol: 0.14, delay: [0, 0.22] }))]),\n impact('paper_hit', [noise({ type: 'bandpass', f: 2200, q: 1, d: 0.05, vol: 0.45 })]),\n impact('paper_tear', [noise({ type: 'highpass', f: 2500, a: 0.02, d: 0.3, vol: 0.15 })]),\n impact('leaf_rustle', many(6, () => noise({ type: 'bandpass', f: [2500, 6000], q: 2, d: 0.05, vol: 0.16, delay: [0, 0.3] }))),\n impact('branch_cut', [noise({ type: 'bandpass', f: 1500, q: 2, d: 0.04, vol: 0.55 }), tone({ f: [260, 340], f2: 150, d: 0.05, vol: 0.22 })]),\n impact('fruit_splat', [noise({ type: 'lowpass', f: 1200, d: 0.12, vol: 0.55 }), noise({ type: 'bandpass', f: 600, q: 0.7, d: 0.2, vol: 0.32 })]),\n // a round glancing off: steel whines down in pitch (\"piiuu\"), stone and concrete give a short crack with grit\n impact('ricochet_metal', [noise({ type: 'highpass', f: 3000, d: 0.02, vol: 0.6 }), tone({ f: [2800, 3600], f2: 900, d: 0.38, vol: 0.2, wet: 0.4 }), tone({ f: [5200, 6400], f2: 2000, d: 0.2, vol: 0.05 })]),\n impact('ricochet_stone', [noise({ type: 'bandpass', f: [2200, 2800], q: 2, d: 0.04, vol: 0.8 }), tone({ f: [1800, 2400], f2: 1200, d: 0.08, vol: 0.1 }), ...many(3, () => noise({ type: 'bandpass', f: [2500, 4500], q: 3, d: 0.015, vol: 0.2, delay: [0.02, 0.12] }))]),\n // breaks a material has of its own (the rest keep the art scene's shatter, crumble and splinter)\n impact('ceramic_break', [noise({ type: 'highpass', f: 1800, d: 0.3, vol: 0.85, wet: 0.4 }), ...many(8, () => tone({ f: [1800, 4500], d: [0.04, 0.1], vol: 0.15, delay: [0, 0.4] }))]),\n impact('tempered_burst', [noise({ type: 'highpass', f: 3500, d: 0.6, vol: 0.9, wet: 0.4 }), ...many(16, () => tone({ f: [4000, 8000], d: 0.04, vol: 0.08, delay: [0, 0.8] }))]),\n impact('plastic_crack', [noise({ type: 'bandpass', f: 1800, q: 2, d: 0.06, vol: 0.75 }), tone({ f: [450, 550], f2: 250, d: 0.05, vol: 0.22 })]),\n impact('mdf_crumble', [noise({ type: 'lowpass', f: 700, d: 0.25, vol: 0.75, wet: 0.2 }), ...many(4, () => noise({ type: 'lowpass', f: 500, d: 0.05, vol: 0.32, delay: [0.05, 0.3] }))]),\n]\n\nexport const DESTRUCTION_SOUND_BANK: SoundBank = { id: 'destruction_three', sounds: [...SCENE_SOUNDS, ...DRAG_SOUNDS, ...LEAF_SOUNDS, ...IMPACT_SOUNDS, EXPLOSION_BOOM, ...BLAST_SOUNDS, ...FIRE_SOUNDS, GRENADE_PIN_PULL], loops: [BURN_LOOP, FIRE_LOOP, ...FIRE_FUEL_LOOPS, SMOKE_HISS_LOOP] }\n","// Blasts and fire: the kit's synthesized sounds for each family of explosive (grenade, big charge, fuel, car, pipe bomb, rocket, flashbang, molotov),\n// the far and the indoor versions of a blast, and the fire (ignition, roar, crackle, gas leak, put out). Synthesized until recorded files reach the\n// SDK; each recipe is built so the loudest moment is the first few milliseconds (the crack of the blast lands on the frame of the event), the body\n// and the debris follow, and every frequency and timing is a range so no two plays sound alike.\nimport { sceneMany as many, sceneNoise as noise, sceneRecipe, sceneTone as tone } from '@adatechnology/game-audio'\nimport type { Falloff, FilterSpec, Layer, LoopRecipe, SoundRecipe } from '@adatechnology/game-audio'\n\n/** A blast near the listener: loud for tens of metres; lowpass cutoffs fall with distance. */\nexport const BLAST_FALLOFF: Falloff = { model: 'inverse_square', k: 0.0012, cutoffK: 0.006, minGain: 0.002 }\n/** A blast far away (past `BLAST_FAR_DISTANCE`): heard for hundreds of metres. */\nexport const BLAST_FAR_FALLOFF: Falloff = { model: 'inverse_square', k: 0.00008, scale: 0.3, minGain: 0.001 }\n/** Fire, ignition and crackles: a room-size sound. */\nexport const FIRE_FALLOFF: Falloff = { model: 'inverse_square', k: 0.01, cutoffK: 0.01, minGain: 0.005 }\n/** Metres from the listener past which a blast plays its far version. */\nexport const BLAST_FAR_DISTANCE = 60\n\n/** The explosion families, each with its own sound. */\nexport const BLAST_KINDS = ['grenade', 'big', 'fuel', 'car', 'pipe_bomb', 'rocket', 'flashbang', 'molotov'] as const\nexport type BlastKind = (typeof BLAST_KINDS)[number]\n\n/**\n * Which family each named explosion of `@adatechnology/game-vfx` (`explosions.json`, the `effect` of an explosive part) belongs to. Data: a game adds\n * or changes entries through `DestructionSoundOptions.blastKinds`. An explosion without a known effect is a grenade below `BIG_BLAST_RADIUS` and a big\n * charge above it.\n */\nexport const BLAST_KIND_OF: Readonly<Record<string, BlastKind>> = {\n m67: 'grenade',\n vog_25: 'grenade',\n m79_40mm: 'grenade',\n claymore: 'grenade',\n generic: 'grenade',\n c4: 'big',\n dynamite: 'big',\n fuel_station_tank: 'big',\n propane_p13: 'fuel',\n fuel_barrel: 'fuel',\n fuel_pump: 'fuel',\n car_fuel_tank: 'car',\n pipe_bomb: 'pipe_bomb',\n m72_66mm: 'rocket',\n at4_84mm: 'rocket',\n carl_gustaf_84mm: 'rocket',\n pg7v: 'rocket',\n flashbang: 'flashbang',\n molotov: 'molotov',\n}\n\n/** Blast radius (metres) from which an explosion with no known effect is a big charge. */\nexport const BIG_BLAST_RADIUS = 8\n\nconst blast = (id: string, layers: readonly Layer[], sources: readonly string[], falloff: Falloff = BLAST_FALLOFF): SoundRecipe => ({\n ...sceneRecipe(id, layers, ''),\n falloff,\n sources,\n})\n\n// the instant crack of the shock front: the loudest part, in the first milliseconds\nconst crack = (f: readonly [number, number], d: number, vol: number): Layer => noise({ type: 'highpass', f, a: 0.001, d, vol })\n// stones, wood and metal falling back after the blast, spread over `[from, to]` seconds\nconst debris = (count: number, from: number, to: number, vol: readonly [number, number]): Layer[] => [\n ...many(count, () => noise({ type: 'bandpass', f: [300, 1400], q: 2.5, d: [0.03, 0.09], vol, delay: [from, to] })),\n ...many(Math.ceil(count / 3), () => noise({ type: 'bandpass', f: [1800, 3600], q: 5, d: [0.02, 0.04], vol: [vol[0] * 0.6, vol[1] * 0.6] as const, delay: [from + 0.1, to] })),\n]\n// steel fragments whizzing and striking around the blast\nconst shrapnel = (count: number, to: number): Layer[] => many(count, () => noise({ type: 'bandpass', f: [2500, 6000], q: 6, d: [0.015, 0.045], vol: [0.08, 0.16], delay: [0.02, to] }))\n// glass panes breaking and their shards falling\nconst glass = (count: number, from: number): Layer[] => [\n noise({ type: 'highpass', f: [2600, 3000], d: 0.4, vol: 0.7, wet: 0.5, delay: from }),\n ...many(count, () => tone({ f: [3000, 7500], d: [0.05, 0.13], vol: 0.12, delay: [from, from + 0.7] })),\n]\n\n/** One sound per explosion family, the far and the indoor versions. */\nexport const BLAST_SOUNDS: readonly SoundRecipe[] = [\n blast(\n 'explosion_grenade',\n [\n crack([2300, 2700], 0.06, 2.4),\n noise({ f: [2500, 3000], f2: 160, d: 0.7, vol: 2, wet: 0.35 }),\n tone({ f: [80, 92], f2: 32, d: 0.5, vol: 1.6 }),\n noise({ type: 'bandpass', f: [620, 760], q: 0.8, d: 0.18, vol: 1.1 }),\n ...shrapnel(14, 0.7),\n ...debris(10, 0.35, 1.8, [0.1, 0.2]),\n ],\n ['sdk: frag grenade (M67, VOG-25, 40 mm): sharp crack, short body, fragments striking, a little debris'],\n ),\n blast(\n 'explosion_big',\n [\n crack([1900, 2300], 0.08, 2.4),\n noise({ f: [2200, 2600], f2: 90, d: 1.6, vol: 2.2, wet: 0.45 }),\n tone({ f: [52, 60], f2: 22, d: 1.6, vol: 1.9 }),\n noise({ f: [280, 330], f2: 60, a: 0.25, d: 2.8, vol: 0.8, wet: 0.6, delay: 0.05 }),\n ...debris(24, 0.5, 3.6, [0.12, 0.25]),\n ],\n ['sdk: big charge (C4, dynamite, a fuel station tank): crack, long deep roar, debris falling for 2 to 4 s'],\n ),\n blast(\n 'explosion_fuel',\n [\n noise({ type: 'highpass', f: [1700, 2000], a: 0.001, d: 0.05, vol: 1 }),\n tone({ f: [380, 450], f2: 300, d: 0.4, vol: 0.3 }),\n noise({ f: [1700, 2000], f2: 150, a: 0.03, d: 1.4, vol: 2.1, wet: 0.4 }),\n tone({ f: [48, 56], f2: 25, d: 1.2, vol: 1.7 }),\n noise({ type: 'bandpass', f: [450, 560], q: 0.6, a: 0.15, d: 2.2, vol: 0.85, wet: 0.5, delay: 0.1 }),\n ...debris(10, 0.5, 2.6, [0.08, 0.16]),\n ],\n ['sdk: a fuel vessel bursting (propane P13, fuel barrel, pump): the shell tearing, a fireball \"whoomp\" and its roar'],\n ),\n blast(\n 'explosion_car',\n [\n noise({ type: 'highpass', f: [1700, 2000], a: 0.001, d: 0.06, vol: 1.1 }),\n noise({ f: [1600, 1900], f2: 140, a: 0.03, d: 1.6, vol: 2.1, wet: 0.4 }),\n tone({ f: [44, 52], f2: 24, d: 1.4, vol: 1.8 }),\n noise({ type: 'bandpass', f: [420, 520], q: 0.6, a: 0.15, d: 2.6, vol: 0.9, wet: 0.5, delay: 0.1 }),\n ...glass(10, 0.04),\n tone({ f: [130, 150], f2: 85, d: 1.1, vol: 0.18, delay: [0.3, 0.5] }),\n ...debris(16, 0.6, 3.2, [0.1, 0.2]),\n ],\n ['sdk: a car going up: the fuel tank fireball, every window breaking, the body groaning, parts falling'],\n ),\n blast(\n 'explosion_pipe_bomb',\n [\n crack([2000, 2400], 0.07, 2.2),\n noise({ f: [2000, 2400], f2: 150, d: 0.8, vol: 1.9, wet: 0.35 }),\n tone({ f: [70, 82], f2: 30, d: 0.6, vol: 1.5 }),\n ...many(6, () => tone({ f: [1800, 3200], f2: 1200, d: [0.06, 0.12], vol: 0.06, delay: [0.05, 0.6] })),\n ...shrapnel(18, 0.9),\n ...debris(8, 0.4, 1.8, [0.08, 0.16]),\n ],\n ['sdk: pipe bomb: crack, body, the steel pipe flying apart in ringing pieces'],\n ),\n blast(\n 'explosion_rocket',\n [\n crack([2100, 2500], 0.08, 2.4),\n noise({ f: [2400, 2800], f2: 120, d: 1.1, vol: 2.1, wet: 0.4 }),\n tone({ f: [60, 70], f2: 26, d: 0.9, vol: 1.8 }),\n noise({ f: [350, 420], f2: 80, a: 0.08, d: 1.8, vol: 0.9, wet: 0.6, delay: 0.05 }),\n ...shrapnel(10, 0.8),\n ...debris(16, 0.4, 2.6, [0.1, 0.2]),\n ],\n ['sdk: rocket or anti-tank warhead (M72, AT4, RPG): hard crack, heavy body, debris'],\n ),\n blast(\n 'explosion_flashbang',\n [crack([1400, 1700], 0.12, 2.8), noise({ f: [1900, 2200], f2: 300, d: 0.35, vol: 1.3, wet: 0.3 }), tone({ f: [110, 130], f2: 60, d: 0.2, vol: 0.8 })],\n ['sdk: flashbang: a deafening crack with almost no body and no fragments'],\n ),\n blast(\n 'molotov_break_ignite',\n [\n ...glass(8, 0),\n noise({ f: [280, 340], f2: 2200, a: 0.12, d: 0.9, vol: 1.5, wet: 0.6, delay: 0.05 }),\n tone({ f: [85, 95], f2: 55, d: 0.4, vol: 0.5, delay: 0.08 }),\n ],\n ['sdk: molotov: the bottle breaking and the fuel catching with a \"fuuush\"'],\n FIRE_FALLOFF,\n ),\n blast(\n 'explosion_far',\n [\n noise({ f: [550, 650], f2: 80, a: 0.03, d: 2.5, vol: 2, wet: 1.4 }),\n tone({ f: [42, 48], f2: 25, d: 1.8, vol: 1.2 }),\n noise({ f: [350, 420], f2: 70, a: 0.1, d: 1.6, vol: 0.6, wet: 1.5, delay: [0.6, 1] }),\n ],\n ['sdk: any blast far away: no crack left, a dull thud and the echo rolling back'],\n BLAST_FAR_FALLOFF,\n ),\n blast(\n 'explosion_indoor_tail',\n [\n ...many(3, () => noise({ f: [650, 800], d: 0.12, vol: 0.5, delay: [0.04, 0.2] })),\n noise({ f: [850, 950], f2: 120, a: 0.05, d: 2.6, vol: 0.9, wet: 1.6, delay: 0.08 }),\n ],\n ['sdk: the room answering a blast inside it: slaps off the walls and a boomy tail'],\n ),\n]\n\n/** Fire: ignition, gas leaking from a vessel about to burst, a fire put out, and the crackles that ride on the fire loop. */\nexport const FIRE_SOUNDS: readonly SoundRecipe[] = [\n {\n ...blast(\n 'fire_ignite',\n [noise({ f: [230, 270], f2: 1500, a: 0.07, d: 0.5, vol: 1.6 }), tone({ f: [80, 90], f2: 55, d: 0.3, vol: 0.45 }), noise({ type: 'highpass', f: 3000, d: 0.3, vol: 0.1, delay: 0.1 })],\n ['sdk: fire catching, a soft \"fuuump\"'],\n FIRE_FALLOFF,\n ),\n group: 'fire_ignite',\n },\n {\n ...blast('gas_leak', [noise({ type: 'bandpass', f: [3200, 3800], q: 0.7, a: 0.08, d: { param: 'seconds' }, vol: 0.3 })], ['sdk: gas jetting from a punctured vessel'], FIRE_FALLOFF),\n vars: { seconds: 2 },\n },\n {\n ...blast(\n 'fire_extinguish',\n [noise({ type: 'highpass', f: [2300, 2700], a: 0.03, d: { param: 'seconds' }, vol: 0.3 }), noise({ type: 'bandpass', f: [800, 1000], q: 0.5, d: 0.5, vol: 0.25 })],\n ['sdk: water or foam on a fire: a steam puff and a sizzle'],\n FIRE_FALLOFF,\n ),\n vars: { seconds: 1.2 },\n },\n { ...blast('fire_crackle', [noise({ type: 'highpass', f: [1500, 3000], d: [0.01, 0.025], vol: [1.2, 2.2] })], ['sdk: a crackle of the fire'], FIRE_FALLOFF), group: 'fire_crackle' },\n { ...blast('fire_pop', [noise({ type: 'bandpass', f: [500, 1100], q: 1, d: [0.03, 0.06], vol: [3, 4.5] })], ['sdk: a log or a resin pocket popping'], FIRE_FALLOFF), group: 'fire_crackle' },\n]\n\n/** The roar of the fires: low, soft noise; `createDestructionSound` raises it with every part that burns and sprinkles crackles on it. */\nexport const FIRE_LOOP: LoopRecipe = {\n id: 'fire_loop',\n bus: 'world',\n order: 'chain_loop',\n source: { kind: 'noise', loop: true },\n filters: { mode: 'serial', bank: [{ type: 'lowpass', frequency: { set: 950 }, q: 0.5 }] },\n volume: 0,\n sources: ['sdk: the roar under the crackles of a fire'],\n}\n\n/** A smoke canister burning (an M18 and the like): a steady hiss of gas through the vents, bright and without crackles; the fallback of the recorded loop of the same id. */\nexport const SMOKE_HISS_LOOP: LoopRecipe = {\n id: 'smoke_grenade_hiss',\n bus: 'world',\n order: 'chain_loop',\n source: { kind: 'noise', loop: true },\n filters: { mode: 'serial', bank: [{ type: 'highpass', frequency: { set: 1400 }, q: 0.7 }, { type: 'lowpass', frequency: { set: 7000 }, q: 0.5 }] },\n volume: 0,\n sources: ['sdk: a smoke canister venting (the gas through its holes, steady for its whole burn)'],\n}\n\n/** The pin of a hand grenade pulled and the lever let go: two small metal clicks, heard only near. */\nexport const GRENADE_PIN_PULL: SoundRecipe = blast(\n 'grenade_pin_pull',\n [noise({ type: 'highpass', f: [3200, 4200], d: 0.025, vol: 0.5 }), noise({ type: 'bandpass', f: [2200, 2800], q: 2, d: 0.04, vol: 0.4, delay: 0.18 })],\n ['sdk: the ring pulled from the fuse, then the spoon flying off'],\n FIRE_FALLOFF,\n)\n\n/**\n * What is burning, for the sound: each fuel has its own roar (a gas jet, a fuel pool, wood, plastic) and its own share of crackles. The rules are the\n * same for all (the level grows with how much burns, fades with distance, never clips); only the timbre comes from the fuel.\n */\nexport const FIRE_FUELS = ['wood', 'fabric', 'plastic', 'gas', 'liquid'] as const\nexport type FireFuel = (typeof FIRE_FUELS)[number]\n\n/** The fuel of a burning material (`materials.json` of game-destruction). Data: a game adds its own materials through `DestructionSoundOptions.fuels`. */\nexport const FIRE_FUEL_OF: Readonly<Record<string, FireFuel>> = {\n wood_soft: 'wood',\n wood_hard: 'wood',\n plywood: 'wood',\n mdf: 'wood',\n green_wood: 'wood',\n foliage: 'wood',\n cactus: 'wood',\n paper: 'fabric',\n fabric: 'fabric',\n leather: 'fabric',\n foam: 'plastic',\n plastic: 'plastic',\n rubber: 'plastic',\n wax: 'plastic',\n}\n\n/** The loop each fuel plays. Fabric and paper share the wood roar until they have their own. */\nexport const FIRE_LOOP_OF: Readonly<Record<FireFuel, string>> = {\n wood: 'fire_loop',\n fabric: 'fire_loop',\n plastic: 'fire_loop_plastic',\n gas: 'fire_loop_gas',\n liquid: 'fire_loop_liquid',\n}\n\n/** How much each fuel crackles (0..1): wood snaps and pops, plastic now and then, a gas jet and a fuel pool not at all. */\nexport const FIRE_CRACKLE_OF: Readonly<Record<FireFuel, number>> = { wood: 1, fabric: 0.5, plastic: 0.35, gas: 0, liquid: 0 }\n\nconst roar = (id: string, bank: readonly FilterSpec[], source: string): LoopRecipe => ({\n id,\n bus: 'world',\n order: 'chain_loop',\n source: { kind: 'noise', loop: true },\n filters: { mode: 'serial', bank },\n volume: 0,\n sources: [source],\n})\n\n/** The synthesized roar of each fuel other than wood: the fallback of the recorded loops of the same id. */\nexport const FIRE_FUEL_LOOPS: readonly LoopRecipe[] = [\n // a gas jet: a steady, broad roar, brighter than wood and without crackles\n roar('fire_loop_gas', [{ type: 'highpass', frequency: { set: 220 }, q: 0.7 }, { type: 'lowpass', frequency: { set: 2400 }, q: 0.6 }], 'sdk: a gas jet burning (a vessel venting into the flame)'),\n // a fuel pool: a soft, low, rolling roar\n roar('fire_loop_liquid', [{ type: 'highpass', frequency: { set: 90 }, q: 0.7 }, { type: 'lowpass', frequency: { set: 650 }, q: 0.9 }], 'sdk: a pool of fuel burning'),\n // plastic and rubber: a thin sizzle over a low burn\n roar('fire_loop_plastic', [{ type: 'bandpass', frequency: { set: 1800 }, q: 0.6 }], 'sdk: plastic and rubber melting in the fire'),\n]\n\n/** The sound of a blast family. */\nexport const BLAST_SOUND_OF: Readonly<Record<BlastKind, string>> = {\n grenade: 'explosion_grenade',\n big: 'explosion_big',\n fuel: 'explosion_fuel',\n car: 'explosion_car',\n pipe_bomb: 'explosion_pipe_bomb',\n rocket: 'explosion_rocket',\n flashbang: 'explosion_flashbang',\n molotov: 'molotov_break_ignite',\n}\n","import type { Vec3 } from '@adatechnology/game-contracts'\nimport { FOLEY_BANK, GAME_SFX_BANK } from '@adatechnology/game-audio'\nimport type { AudioEngine, AudioLoopHandle } from '@adatechnology/game-audio'\n\nimport { BIG_BLAST_RADIUS, BLAST_FAR_DISTANCE, BLAST_KIND_OF, BLAST_SOUND_OF, FIRE_CRACKLE_OF, FIRE_FUEL_OF, FIRE_LOOP_OF } from './blast-fire'\nimport type { BlastKind, FireFuel } from './blast-fire'\nimport { DESTRUCTION_SOUND_BANK } from './recipes'\nimport type { SoundDetail } from '../types'\n\n/**\n * What a sound key plays: the recipe, its params, a scale on the volume the renderer gives, and (optionally) a louder recipe above a volume\n * (a big blast gets the long boom).\n */\nexport type SoundKeyRule = {\n readonly sound: string\n readonly params?: Readonly<Record<string, number>>\n readonly volumeScale?: number\n readonly above?: { readonly volume: number; readonly sound: string }\n /** A sound of this bank played when the engine does not know `sound` (a vehicle door without the vehicle bank registered shuts like metal). */\n readonly fallback?: string\n}\n\nexport type DestructionSoundStyle = 'art_scene' | 'game'\n\n/**\n * The keys of a blow on a material (`impactSoundKeys`, `breakSoundKeys`): `impact_<family>_<blow>`, `impact_<material>[_<blow>]`, `break_<...>`. The renderer\n * sends them before its legacy family key, so the first one with a rule plays; a game replaces any of them in `keys`.\n */\nexport const IMPACT_SOUND_KEYS: Readonly<Record<string, SoundKeyRule>> = {\n impact_metal_ballistic: { sound: 'metal_bullet' },\n impact_metal_blunt: { sound: 'metal_blunt' },\n impact_metal_slash: { sound: 'metal_blade' },\n impact_aluminium_ballistic: { sound: 'metal_thin' },\n impact_aluminium_blunt: { sound: 'metal_thin' },\n impact_copper_ballistic: { sound: 'metal_thin' },\n impact_copper_blunt: { sound: 'metal_thin' },\n impact_wood_ballistic: { sound: 'wood_hit' },\n impact_wood_blunt: { sound: 'wood_blunt' },\n impact_wood_slash: { sound: 'wood_blade' },\n impact_mdf_ballistic: { sound: 'mdf_puff' },\n impact_mdf_blunt: { sound: 'mdf_puff', volumeScale: 0.8 },\n impact_glass_ballistic: { sound: 'glass_bullet' },\n impact_glass_blunt: { sound: 'glass_blunt' },\n impact_glass_slash: { sound: 'glass_blade' },\n impact_ceramic: { sound: 'ceramic_hit' },\n impact_ceramic_ballistic: { sound: 'ceramic_bullet' },\n impact_masonry_ballistic: { sound: 'masonry_bullet' },\n impact_masonry_blunt: { sound: 'masonry_blunt' },\n impact_masonry_slash: { sound: 'masonry_blade' },\n impact_plaster: { sound: 'plaster_puff' },\n impact_soil: { sound: 'soil_blunt' },\n impact_soil_ballistic: { sound: 'soil_bullet' },\n impact_sand: { sound: 'sand_hit' },\n impact_gravel: { sound: 'gravel_hit' },\n impact_plastic: { sound: 'plastic_hit' },\n impact_plastic_ballistic: { sound: 'plastic_bullet' },\n impact_rubber: { sound: 'rubber_hit' },\n impact_wax: { sound: 'wax_hit' },\n impact_soft_ballistic: { sound: 'soft_bullet' },\n impact_soft_slash: { sound: 'fabric_rip' },\n impact_paper: { sound: 'paper_hit' },\n impact_paper_slash: { sound: 'paper_tear' },\n impact_plant: { sound: 'leaf_rustle' },\n impact_plant_slash: { sound: 'branch_cut' },\n impact_flesh_fruit: { sound: 'fruit_splat' },\n ricochet_metal: { sound: 'ricochet_metal' },\n ricochet_masonry: { sound: 'ricochet_stone' },\n ricochet_soil: { sound: 'ricochet_stone' },\n ricochet_ceramic: { sound: 'ricochet_stone' },\n break_ceramic: { sound: 'ceramic_break' },\n break_tempered_glass: { sound: 'tempered_burst' },\n break_plastic: { sound: 'plastic_crack' },\n break_mdf: { sound: 'mdf_crumble' },\n break_soft: { sound: 'fabric_rip' },\n break_paper: { sound: 'paper_tear' },\n break_plant: { sound: 'branch_cut' },\n}\n\n/**\n * Every sound a blow, ricochet or break on a material can play (`sound`, `above.sound` and `fallback` of each rule of `rules`): a game preloads them on\n * the first input, so even the first ricochet or impact plays the recording instead of the synthesized recipe while the file is still loading.\n */\nexport const impactSoundIds = (rules: Readonly<Record<string, SoundKeyRule>> = IMPACT_SOUND_KEYS): string[] => {\n const ids = new Set<string>()\n for (const rule of Object.values(rules)) {\n ids.add(rule.sound)\n if (rule.above) ids.add(rule.above.sound)\n if (rule.fallback) ids.add(rule.fallback)\n }\n return [...ids]\n}\n\n/**\n * The keys `createDestructionRenderer` sends to `onSound`, mapped to the sounds the teams delivered. The Cena de Arte has a sound for every material\n * (clang, wood, glass, crumble, thud...); the game has four classes (impact, glass, wood, explosion) and its own explosion thump. Which team sound answers\n * which key is the kit's choice (the teams call the sounds, not the renderer's keys), so it is data: `keys` replaces any entry.\n */\nexport const DESTRUCTION_SOUND_KEYS: Readonly<Record<DestructionSoundStyle, Readonly<Record<string, SoundKeyRule>>>> = {\n art_scene: {\n impact_metal: { sound: 'clang' },\n impact_wood: { sound: 'wood_hit' },\n impact_glass: { sound: 'ping' },\n impact_masonry: { sound: 'chip' },\n impact_soft: { sound: 'thud' },\n // a round strikes: the steel rings high, glass cracks, wood and masonry chip, a soft part takes a dull thunk\n shot_metal: { sound: 'ping' },\n shot_wood: { sound: 'chip' },\n shot_glass: { sound: 'crack' },\n shot_masonry: { sound: 'chip' },\n shot_soft: { sound: 'thunk' },\n drag_wood: { sound: 'drag_wood' },\n drag_metal: { sound: 'drag_metal' },\n drag_glass: { sound: 'drag_glass' },\n drag_masonry: { sound: 'drag_masonry' },\n drag_soft: { sound: 'drag_soft' },\n // a leaf worked by hand (doors, lids, drawers): the latch, the hinge turning, the leaf meeting the frame, a locked one shaken\n leaf_latch: { sound: 'latch' },\n leaf_creak_wood: { sound: 'creak_wood' },\n leaf_creak_metal: { sound: 'creak_metal' },\n leaf_shut_wood: { sound: 'shut_wood' },\n leaf_shut_metal: { sound: 'shut_metal' },\n leaf_shut_glass: { sound: 'shut_metal', volumeScale: 0.6 },\n leaf_shut_masonry: { sound: 'shut_wood' },\n leaf_shut_soft: { sound: 'shut_soft' },\n leaf_rattle: { sound: 'rattle' },\n leaf_slide: { sound: 'slide' },\n // the keys of the item clips (furniture and vehicle doors, hoods, trunks, drawers)\n door_latch: { sound: 'latch' },\n hood_latch: { sound: 'latch' },\n trunk_latch: { sound: 'latch' },\n door_open: { sound: 'latch' },\n door_shut: { sound: 'shut_metal' },\n hood_shut: { sound: 'shut_metal' },\n trunk_shut: { sound: 'shut_metal' },\n door_close: { sound: 'shut_wood', volumeScale: 0.7 },\n // a vehicle's leaves (the vehicle bank of game-vehicles-three): a car door shuts with a padded thump and a latch, not like a fridge\n vehicle_door_open: { sound: 'car_door_open', fallback: 'latch' },\n vehicle_door_shut: { sound: 'car_door_close', fallback: 'shut_metal' },\n vehicle_trunk_open: { sound: 'car_door_open', fallback: 'latch' },\n vehicle_trunk_shut: { sound: 'car_trunk_close', fallback: 'shut_metal' },\n vehicle_hood_open: { sound: 'car_door_open', fallback: 'latch' },\n vehicle_hood_shut: { sound: 'car_hood_close', fallback: 'shut_metal' },\n drawer_open: { sound: 'slide' },\n drawer_close: { sound: 'slide' },\n lid_open: { sound: 'latch' },\n lid_close: { sound: 'shut_soft' },\n flap_open: { sound: 'latch' },\n flap_close: { sound: 'shut_soft' },\n // an item taken in the hand, by what it is made of (game-audio's KIT_SAMPLE_ALIASES puts recordings on these ids)\n grab_metal: { sound: 'grab_hard' },\n grab_wood: { sound: 'grab_hard' },\n grab_glass: { sound: 'grab_hard', volumeScale: 0.7 },\n grab_masonry: { sound: 'grab_hard' },\n grab_soft: { sound: 'grab_soft' },\n shatter_glass: { sound: 'glass_shatter' },\n crumble: { sound: 'crumble' },\n splinter: { sound: 'crack' },\n ricochet: { sound: 'ping' },\n unscrew: { sound: 'chip' },\n detach: { sound: 'thunk' },\n ignite: { sound: 'fire_ignite' },\n primed: { sound: 'gas_leak' },\n extinguish: { sound: 'fire_extinguish' },\n melt_sizzle: { sound: 'hiss', params: { seconds: 0.6 } },\n // the blast family comes from the explosion's effect (`BLAST_KIND_OF`); this rule answers only an explosion the kit cannot place\n explode: { sound: 'explosion_grenade', above: { volume: 0.9, sound: 'explosion_big' } },\n ...IMPACT_SOUND_KEYS,\n },\n game: {\n impact_metal: { sound: 'sfx_impact' },\n impact_wood: { sound: 'sfx_wood' },\n impact_glass: { sound: 'sfx_glass' },\n impact_masonry: { sound: 'sfx_impact' },\n impact_soft: { sound: 'sfx_flesh' },\n shatter_glass: { sound: 'sfx_glass' },\n crumble: { sound: 'sfx_impact' },\n splinter: { sound: 'sfx_wood' },\n explode: { sound: 'explosion_boom' },\n },\n}\n\nexport type DestructionSoundOptions = {\n /** Which team answers the keys (default `art_scene`, the kit mix). `game` falls back to the art scene for the keys the game has no sound for. */\n readonly style?: DestructionSoundStyle\n /** Replaces or adds a key's rule; `null` silences it. A key without a rule that is the id of a registered sound (the foley bank's) plays that sound. */\n readonly keys?: Readonly<Record<string, SoundKeyRule | null>>\n /** The fire loop: the volume each burning part adds and the most it reaches (the page never raises it, so these are the kit's). */\n readonly fire?: { readonly perFire?: number; readonly max?: number }\n /** Burn loop on or off (default on). */\n readonly burnLoop?: boolean\n /** The loop of the wood fire (default `fire_loop`; `burn_loop` is the art scene's bright one). */\n readonly fireLoop?: string\n /** Adds to or changes `FIRE_FUEL_OF`: which fuel a burning material sounds like. */\n readonly fuels?: Readonly<Record<string, FireFuel>>\n /** Adds to or changes `FIRE_LOOP_OF`: the loop of each fuel. */\n readonly fireLoops?: Partial<Readonly<Record<FireFuel, string>>>\n /** The fuel of a fire whose material is not in the table (default `wood`). */\n readonly defaultFuel?: FireFuel\n /** Crackles per second over the fire loop: `base + perSqrtFire × √(parts burning)`, at most `max` (default 2, 3, 14). `false` turns them off. */\n readonly crackles?: false | { readonly base?: number; readonly perSqrtFire?: number; readonly max?: number; readonly volume?: number }\n /** Adds to or changes `BLAST_KIND_OF`: which family a named explosion (`effect`) sounds like. */\n readonly blastKinds?: Readonly<Record<string, BlastKind>>\n /** Metres past which a blast plays `explosion_far` instead of its own sound (default `BLAST_FAR_DISTANCE`). */\n readonly blastFarDistance?: number\n /** `confinement` of a blast (from its report) from which the indoor tail plays too (default 1.3). */\n readonly indoorConfinement?: number\n /** Seed of the crackle timing (default 1). */\n readonly seed?: number\n}\n\nexport type DestructionSound = {\n /** Pass to `createDestructionRenderer({ onSound })`. */\n readonly onSound: (key: string, point: Vec3, volume: number, detail?: SoundDetail) => void\n /** Moves the fire crackles on; call once per frame with the frame time in seconds. */\n update(dt: number): void\n /** The sound an explosion plays (`explode` with its detail), for a listener at the engine's listener position. */\n blastSound(point: Vec3, volume: number, detail?: SoundDetail): string\n /** The rule a key resolves to, if any; with `detail`, the rule `onSound` would play (the first of `detail.keys` that has one, else `key`'s). */\n rule(key: string, detail?: SoundDetail): SoundKeyRule | undefined\n /** Parts burning now. */\n readonly burning: () => number\n /** Parts burning now, by fuel. */\n readonly burningBy: () => Readonly<Partial<Record<FireFuel, number>>>\n /** Puts every fire sound out (the scene was cleared); the engine and the bank stay. */\n reset(): void\n dispose(): void\n}\n\nexport const DEFAULT_FIRE = { perFire: 0.08, max: 0.45 } as const\nexport const DEFAULT_CRACKLES = { base: 2, perSqrtFire: 3, max: 14, volume: 0.5 } as const\nexport const DEFAULT_INDOOR_CONFINEMENT = 1.3\n\n/**\n * Plays the renderer's sound keys on a game-audio engine: the bank is registered in the engine, a key becomes a positional sound at the point, and\n * `burn_loop` / `burn_end` (a part starts to burn, a part burns out or is put out) drive one fire loop whose volume follows how many parts burn, with\n * crackles at the burning points (`update`). An explosion plays the sound of its family (`BLAST_KIND_OF` by its effect), the far rumble past\n * `blastFarDistance` and the indoor tail when the blast was confined.\n */\nexport function createDestructionSound(engine: AudioEngine, options: DestructionSoundOptions = {}): DestructionSound {\n engine.register(DESTRUCTION_SOUND_BANK)\n engine.register(GAME_SFX_BANK)\n // the foley of the hand (doors, lids, drawers, items): its ids are keys of their own, played as they are\n engine.register(FOLEY_BANK)\n const fire = { ...DEFAULT_FIRE, ...options.fire }\n const crackles = options.crackles === false ? null : { ...DEFAULT_CRACKLES, ...options.crackles }\n const fireLoop = options.fireLoop ?? 'fire_loop'\n const kinds: Readonly<Record<string, BlastKind>> = { ...BLAST_KIND_OF, ...options.blastKinds }\n const farDistance = options.blastFarDistance ?? BLAST_FAR_DISTANCE\n const indoorFrom = options.indoorConfinement ?? DEFAULT_INDOOR_CONFINEMENT\n const rules: Record<string, SoundKeyRule | null | undefined> = { ...DESTRUCTION_SOUND_KEYS.art_scene, ...(options.style === 'game' ? DESTRUCTION_SOUND_KEYS.game : {}), ...options.keys }\n // a blast takes its family's sound unless the host chose the explode rule itself (a style or a key of its own)\n const blastByKind = options.style !== 'game' && !(options.keys && 'explode' in options.keys)\n const channel = engine.channel({ seed: options.seed ?? 1 })\n const fuelOf: Readonly<Record<string, FireFuel>> = { ...FIRE_FUEL_OF, ...options.fuels }\n const loopOf: Readonly<Record<FireFuel, string>> = { ...FIRE_LOOP_OF, ...(options.fireLoop ? { wood: fireLoop, fabric: fireLoop } : {}), ...options.fireLoops }\n const defaultFuel = options.defaultFuel ?? 'wood'\n // one loop per sound (fuels that share a loop share its level); a loop stops when nothing of its fuels burns\n const loops = new Map<string, AudioLoopHandle>()\n // where the fires are and what burns there: the crackles come from the points whose fuel crackles\n const fires: { readonly point: Vec3; readonly fuel: FireFuel }[] = []\n let nextCrackle = 0\n\n const fuelFor = (detail: SoundDetail | undefined): FireFuel => detail?.fuel ?? (detail?.material !== undefined ? fuelOf[detail.material] : undefined) ?? defaultFuel\n\n const setFire = (): void => {\n if (options.burnLoop === false) return\n const count = new Map<string, number>()\n for (const f of fires) {\n const id = loopOf[f.fuel]\n count.set(id, (count.get(id) ?? 0) + 1)\n }\n for (const [id, handle] of loops) {\n if (count.has(id)) continue\n handle.stop()\n loops.delete(id)\n }\n for (const [id, n] of count) {\n let handle = loops.get(id)\n if (!handle) {\n handle = engine.loop(id)\n loops.set(id, handle)\n }\n handle.set({ volume: Math.min(fire.max, fire.perFire * n) })\n }\n }\n\n // the nearest fire of that fuel goes out (any fuel when the end does not say)\n const forget = (point: Vec3, fuel: FireFuel | undefined): void => {\n let best = -1\n let bestD = Infinity\n fires.forEach((f, i) => {\n if (fuel !== undefined && f.fuel !== fuel) return\n const d = (f.point[0] - point[0]) ** 2 + (f.point[1] - point[1]) ** 2 + (f.point[2] - point[2]) ** 2\n if (d < bestD) {\n bestD = d\n best = i\n }\n })\n if (best < 0 && fuel !== undefined) forget(point, undefined)\n else if (best >= 0) fires.splice(best, 1)\n }\n\n const reset = (): void => {\n for (const handle of loops.values()) handle.stop()\n loops.clear()\n fires.length = 0\n }\n\n const blastSound = (point: Vec3, volume: number, detail?: SoundDetail): string => {\n const named = detail?.effect === undefined ? undefined : kinds[detail.effect]\n const kind = named ?? ((detail?.radius ?? 0) >= BIG_BLAST_RADIUS || volume >= 0.9 ? 'big' : 'grenade')\n const sound = BLAST_SOUND_OF[kind]\n const distance = engine.plan(sound, { position: point, seed: 1 })?.distance ?? 0\n // a molotov is a fire, not a blast: it never turns into the far rumble\n return kind !== 'molotov' && distance > farDistance ? 'explosion_far' : sound\n }\n\n return {\n onSound(key, point, volume, detail) {\n if (key === 'burn_loop') {\n fires.push({ point, fuel: fuelFor(detail) })\n setFire()\n return\n }\n if (key === 'burn_end') {\n forget(point, detail?.fuel ?? (detail?.material !== undefined ? fuelOf[detail.material] : undefined))\n setFire()\n return\n }\n if (key === 'explode' && blastByKind) {\n const sound = blastSound(point, volume, detail)\n engine.play(sound, { position: point, volume })\n if (sound !== 'explosion_far' && sound !== 'molotov_break_ignite' && (detail?.confinement ?? 1) >= indoorFrom) engine.play('explosion_indoor_tail', { position: point, volume })\n return\n }\n // the most specific key that has a rule (material and blow, material, family and blow, family), else the key itself (a `shot_` key with no rule\n // falls back to its `impact_` one); `null` on a specific key silences it\n let rule: SoundKeyRule | null | undefined\n for (const k of detail?.keys ?? []) {\n if (k in rules) {\n rule = rules[k]\n break\n }\n }\n if (rule === undefined) rule = key in rules ? rules[key] : rules[key.replace(/^shot_/, 'impact_')]\n if (rule === null) return\n if (!rule) {\n // a key with no rule that names a registered sound plays that sound (the foley ids: `door_wood_close`, `item_pickup_metal`...)\n if (engine.registry.sound(key)) engine.play(key, { position: point, volume })\n return\n }\n const wanted = rule.above && volume >= rule.above.volume ? rule.above.sound : rule.sound\n const sound = rule.fallback && !engine.registry.sound(wanted) ? rule.fallback : wanted\n const params = detail?.seconds === undefined ? rule.params : { ...rule.params, seconds: detail.seconds }\n engine.play(sound, { position: point, volume: volume * (rule.volumeScale ?? 1), ...(params ? { params } : {}) })\n },\n update(dt) {\n if (!crackles || fires.length === 0 || options.burnLoop === false) return\n // only the fuels that crackle count: a gas jet or a fuel pool roars without snapping\n const weight = fires.reduce((sum, f) => sum + FIRE_CRACKLE_OF[f.fuel], 0)\n if (weight <= 0) return\n nextCrackle -= dt\n // at most a few crackles per frame, even after a long one\n for (let i = 0; i < 4 && nextCrackle <= 0; i++) {\n const rate = Math.min(crackles.max, crackles.base * Math.min(1, weight) + crackles.perSqrtFire * Math.sqrt(weight))\n nextCrackle += (0.4 + channel.random() * 1.2) / rate\n let pick = channel.random() * weight\n const at = fires.find((f) => (pick -= FIRE_CRACKLE_OF[f.fuel]) <= 0) ?? (fires[fires.length - 1] as (typeof fires)[number])\n engine.play(channel.random() < 0.18 ? 'fire_pop' : 'fire_crackle', { position: at.point, volume: crackles.volume })\n }\n if (nextCrackle < 0) nextCrackle = 0\n },\n blastSound,\n rule(key, detail) {\n for (const k of detail?.keys ?? []) if (k in rules) return rules[k] ?? undefined\n return rules[key] ?? undefined\n },\n burning: () => fires.length,\n burningBy: () => {\n const by: Partial<Record<FireFuel, number>> = {}\n for (const f of fires) by[f.fuel] = (by[f.fuel] ?? 0) + 1\n return by\n },\n reset,\n dispose: reset,\n }\n}\n","// The recorded files of the blasts and the fire (`@adatechnology/game-audio/assets/sfx/explosoes-fogo`, field recordings): the numbers each sound id\n// needs on top of its files. Same ids as the synthesized recipes of `blast-fire.ts`, which stay as the fallback while the files load, when they fail,\n// and for every family that has no recording yet (fuel, pipe bomb, rocket, the indoor tail).\nimport { sampleBankFromManifest } from '@adatechnology/game-audio'\nimport type { SampleDefaults, SampleSound, SfxManifest, SoundBank } from '@adatechnology/game-audio'\nimport { BLAST_FALLOFF, BLAST_FAR_FALLOFF, FIRE_FALLOFF } from './blast-fire'\n\n/** The numbers of one recorded sound, plus whether it loops (the fire's roar). */\nexport type BlastFireSampleDefaults = SampleDefaults & { readonly loop?: boolean | { readonly crossfade?: number } }\n\nconst blast = (gain: number): BlastFireSampleDefaults => ({ bus: 'world', gain, falloff: BLAST_FALLOFF, cutoffK: 0.006, priority: 3 })\nconst fire = (gain: number, group?: string): BlastFireSampleDefaults => ({ bus: 'world', gain, falloff: FIRE_FALLOFF, cutoffK: 0.01, ...(group ? { group } : {}) })\n\n/**\n * The sounds of the blasts and the fire that have recorded takes, with their bus, level and distance curve (the recipes' own curves, so a file and its\n * fallback fade alike with distance). Data: a game passes its own table to `blastFireSampleBank`.\n */\nexport const BLAST_FIRE_SAMPLES: Readonly<Record<string, BlastFireSampleDefaults>> = {\n explosion_grenade: blast(1),\n explosion_big: blast(1),\n explosion_car: blast(1),\n explosion_flashbang: blast(1),\n molotov_break_ignite: blast(0.8),\n // the far takes are already muffled: no extra distance lowpass\n explosion_far: { bus: 'world', gain: 1, falloff: BLAST_FAR_FALLOFF, cutoffK: 0, priority: 2 },\n fire_ignite: fire(0.8, 'fire_ignite'),\n fire_crackle: fire(0.8, 'fire_crackle'),\n fire_pop: fire(0.6, 'fire_crackle'),\n fire_extinguish: fire(0.7),\n gas_leak: fire(0.5),\n // the roar: recorded fires chained with a crossfade (the level comes from `createDestructionSound`, by how much burns)\n fire_loop: { bus: 'world', gain: 4, loop: { crossfade: 1 } },\n // each fuel has its own roar: a gas jet (burners and torches), a pool of fuel, plastic and rubber sizzling under the flames\n fire_loop_gas: { bus: 'world', gain: 6, loop: { crossfade: 1 } },\n fire_loop_liquid: { bus: 'world', gain: 3.5, loop: { crossfade: 1 } },\n fire_loop_plastic: { bus: 'world', gain: 1, loop: { crossfade: 0.6 } },\n}\n\nexport type BlastFireSampleBankOptions = {\n /** Bank id (default 'destruction-samples'). */\n readonly id?: string\n /** Where the manifest's folder is served (`/sfx/`); default ''. */\n readonly baseUrl?: string\n /** Numbers per id (default `BLAST_FIRE_SAMPLES`). */\n readonly sounds?: Readonly<Record<string, BlastFireSampleDefaults>>\n}\n\n/**\n * A bank of the recorded blasts and fire from the kit's sound manifest. Register it with the engine next to `DESTRUCTION_SOUND_BANK`: each id plays\n * its files once loaded and its synthesized recipe until then.\n */\nexport function blastFireSampleBank(manifest: SfxManifest, options: BlastFireSampleBankOptions = {}): SoundBank {\n const sounds = options.sounds ?? BLAST_FIRE_SAMPLES\n const bank = sampleBankFromManifest(manifest, { id: options.id ?? 'destruction-samples', ...(options.baseUrl === undefined ? {} : { baseUrl: options.baseUrl }), sounds })\n const samples: SampleSound[] = (bank.samples ?? []).map((sample) => {\n const loop = sounds[sample.id]?.loop\n return loop === undefined ? sample : { ...sample, loop }\n })\n return { ...bank, samples }\n}\n"],"mappings":"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","names":["glass","scene","SUPPORT_CHECKS","SUPPORT_GAP","impact","c","scene","geo","noise","materialsOf","tone","fire","many","noise","sceneRecipe","tone","sceneRecipe","noise","tone","many","fire","sound","blast"]}