@adatechnology/game-destruction 0.4.1 → 0.5.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/README.md +32 -3
- package/dist/index.d.ts +72 -6
- package/dist/index.global.js +490 -22
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +490 -22
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/chain.ts","../src/math.ts","../src/fracture.ts","../src/data/materials.json","../src/data/material-hints.json","../src/materials.ts","../src/world.ts","../src/frame.ts","../src/size.ts","../src/locale.ts","../../game-contracts/src/impact.ts","../../game-contracts/src/spec.ts","../../game-contracts/src/weapons.ts","../../game-contracts/src/animation.ts","../../game-contracts/src/tool-animation.ts","../../game-contracts/src/bench.ts","../src/contracts.ts"],"sourcesContent":["export type * from './types'\nexport { createDestruction } from './world'\nexport { explosivePart, FIRE_PRIME_C } from './chain'\nexport type { ChainTrigger, ExplosivePartOptions, WorldExplosive } from './chain'\nexport { MATERIALS, JOINT_DEFAULTS, JOINT_BY_MATERIALS, inferJoints, guessMaterial, partVolume, partMass, partThickness, partCapacity, fragility } from './materials'\nexport { buildFrame } from './frame'\nexport type { FrameOptions } from './frame'\nexport { sizeStructure } from './size'\nexport { vec, quat, quatFromEuler, rotateVec, toLocal, toWorld } from './math'\nexport { resolveStrings, locales } from './locale'\nexport type { DestructionStrings, DestructionLocale } from './locale'\nexport { checkDestructible, checkHit, IMPACT_CONTRACT } from './contracts'\nexport type { DestructibleImpl, ImpactContract, CheckOptions } from './contracts'\n","import type { ChainDelay, ExplosionChain, PartSpec } from './types'\n\n/** What can set an explosive part off from outside, in the order a hit can carry it. */\nexport type ChainTrigger = 'shot' | 'fire' | 'explosion'\n\n/** Temperature in °C that primes a part with `chain.fire` when its `explodes.atC` is not set. */\nexport const FIRE_PRIME_C = 300\n\n/** Seconds from a trigger to the blast: a number is fixed, `[min, max]` is drawn from the world seed (one draw). */\nexport const drawChainDelay = (delay: ChainDelay, random: () => number): number => {\n if (typeof delay === 'number') return delay\n const [min, max] = delay\n return min + random() * (max - min)\n}\n\n/** The delay `spec` gives for `trigger`, or undefined when the part does not answer to it. */\nexport const chainDelayOf = (spec: PartSpec, trigger: ChainTrigger): ChainDelay | undefined => spec.explodes?.chain?.[trigger]\n\n/** Fraction of the hit points a shot must have taken off before it primes the part. */\nexport const shotDamageFractionOf = (spec: PartSpec): number => spec.explodes?.chain?.shotDamageFraction ?? 0\n\n/** The numbers of an explosive that sits in the world, as `game-weapons` gives them (`ExplosiveDef` fits). */\nexport interface WorldExplosive {\n readonly energy: number\n /** Metres within which the blast reaches other parts (and primes theirs). */\n readonly injuryRadius: number\n readonly chain?: ExplosionChain\n}\n\nexport interface ExplosivePartOptions {\n /** Temperature in °C at which fire primes (or sets off) the part; default `FIRE_PRIME_C` when the explosive answers to fire. */\n readonly atC?: number\n}\n\n/**\n * A part that explodes with the energy and reach of `explosive` and answers to what `explosive.chain` says: a bullet, fire or a blast\n * nearby primes it and it goes off after the delay. `part` is everything else about the part (shape, material, position, fluid inside).\n */\nexport const explosivePart = (explosive: WorldExplosive, part: Omit<PartSpec, 'explodes'>, options: ExplosivePartOptions = {}): PartSpec => ({\n ...part,\n explodes: {\n energy: explosive.energy,\n radius: explosive.injuryRadius,\n ...(options.atC !== undefined ? { atC: options.atC } : {}),\n ...(explosive.chain ? { chain: { ...explosive.chain } } : {}),\n },\n})\n","import type { PartShape, Quat, Vec3 } from './types'\n\nconst EPS = 1e-9\n\n/** Small vector helpers (arrays of three numbers). Pure functions; they allocate a new array. */\nexport const vec = {\n add: (a: Vec3, b: Vec3): Vec3 => [a[0] + b[0], a[1] + b[1], a[2] + b[2]],\n sub: (a: Vec3, b: Vec3): Vec3 => [a[0] - b[0], a[1] - b[1], a[2] - b[2]],\n scale: (a: Vec3, s: number): Vec3 => [a[0] * s, a[1] * s, a[2] * s],\n dot: (a: Vec3, b: Vec3): number => a[0] * b[0] + a[1] * b[1] + a[2] * b[2],\n cross: (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]],\n length: (a: Vec3): number => Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]),\n distance: (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]),\n normalize: (a: Vec3, fallback: Vec3 = [0, 1, 0]): Vec3 => {\n const l = Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])\n return l < EPS ? [fallback[0], fallback[1], fallback[2]] : [a[0] / l, a[1] / l, a[2] / l]\n },\n lerp: (a: Vec3, b: Vec3, t: number): Vec3 => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t],\n /** `a + b * s` */\n madd: (a: Vec3, b: Vec3, s: number): Vec3 => [a[0] + b[0] * s, a[1] + b[1] * s, a[2] + b[2] * s],\n}\n\nconst IDENTITY: Quat = [0, 0, 0, 1]\n\n/** Quaternion helpers (`[x, y, z, w]`). */\nexport const quat = {\n identity: (): Quat => [IDENTITY[0], IDENTITY[1], IDENTITY[2], IDENTITY[3]],\n /** Hamilton product `a * b` (apply `b` first, then `a`). */\n mul: (a: Quat, b: Quat): Quat => [\n a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1],\n a[3] * b[1] - a[0] * b[2] + a[1] * b[3] + a[2] * b[0],\n a[3] * b[2] + a[0] * b[1] - a[1] * b[0] + a[2] * b[3],\n a[3] * b[3] - a[0] * b[0] - a[1] * b[1] - a[2] * b[2],\n ],\n conjugate: (q: Quat): Quat => [-q[0], -q[1], -q[2], q[3]],\n normalize: (q: Quat): Quat => {\n const l = Math.hypot(q[0], q[1], q[2], q[3])\n return l < EPS ? [0, 0, 0, 1] : [q[0] / l, q[1] / l, q[2] / l, q[3] / l]\n },\n /** Rotation of `angle` radians around a unit `axis`. */\n fromAxisAngle: (axis: Vec3, angle: number): Quat => {\n const s = Math.sin(angle / 2)\n return [axis[0] * s, axis[1] * s, axis[2] * s, Math.cos(angle / 2)]\n },\n /** Rotation matrix, row-major 3x3. */\n toMatrix: (q: Quat): number[] => {\n const [x, y, z, w] = q\n const xx = x * x, yy = y * y, zz = z * z, xy = x * y, xz = x * z, yz = y * z, wx = w * x, wy = w * y, wz = w * z\n return [1 - 2 * (yy + zz), 2 * (xy - wz), 2 * (xz + wy), 2 * (xy + wz), 1 - 2 * (xx + zz), 2 * (yz - wx), 2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (xx + yy)]\n },\n /** Quaternion from three orthonormal columns (the images of the x, y and z axes). */\n fromColumns: (cx: Vec3, cy: Vec3, cz: Vec3): Quat => {\n const m00 = cx[0], m10 = cx[1], m20 = cx[2]\n const m01 = cy[0], m11 = cy[1], m21 = cy[2]\n const m02 = cz[0], m12 = cz[1], m22 = cz[2]\n const tr = m00 + m11 + m22\n let q: Quat\n if (tr > 0) {\n const s = Math.sqrt(tr + 1) * 2\n q = [(m21 - m12) / s, (m02 - m20) / s, (m10 - m01) / s, 0.25 * s]\n } else if (m00 > m11 && m00 > m22) {\n const s = Math.sqrt(1 + m00 - m11 - m22) * 2\n q = [0.25 * s, (m01 + m10) / s, (m02 + m20) / s, (m21 - m12) / s]\n } else if (m11 > m22) {\n const s = Math.sqrt(1 + m11 - m00 - m22) * 2\n q = [(m01 + m10) / s, 0.25 * s, (m12 + m21) / s, (m02 - m20) / s]\n } else {\n const s = Math.sqrt(1 + m22 - m00 - m11) * 2\n q = [(m02 + m20) / s, (m12 + m21) / s, 0.25 * s, (m10 - m01) / s]\n }\n return quat.normalize(q)\n },\n}\n\n/** Quaternion from Euler angles in radians, order XYZ (the three.js default). */\nexport const quatFromEuler = (x: number, y: number, z: number): Quat => {\n const c1 = Math.cos(x / 2), c2 = Math.cos(y / 2), c3 = Math.cos(z / 2)\n const s1 = Math.sin(x / 2), s2 = Math.sin(y / 2), s3 = Math.sin(z / 2)\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n}\n\n/** Rotate a vector by a quaternion. */\nexport const rotateVec = (q: Quat, v: Vec3): Vec3 => {\n const qx = q[0], qy = q[1], qz = q[2], qw = q[3]\n const tx = 2 * (qy * v[2] - qz * v[1])\n const ty = 2 * (qz * v[0] - qx * v[2])\n const tz = 2 * (qx * v[1] - qy * v[0])\n return [v[0] + qw * tx + (qy * tz - qz * ty), v[1] + qw * ty + (qz * tx - qx * tz), v[2] + qw * tz + (qx * ty - qy * tx)]\n}\n\n/** World point to the local space of a transform (`position`, `rotation`). */\nexport const toLocal = (position: Vec3, rotation: Quat, p: Vec3): Vec3 =>\n rotateVec([-rotation[0], -rotation[1], -rotation[2], rotation[3]], [p[0] - position[0], p[1] - position[1], p[2] - position[2]])\n\n/** Local point of a transform (`position`, `rotation`) to world space. */\nexport const toWorld = (position: Vec3, rotation: Quat, p: Vec3): Vec3 => {\n const r = rotateVec(rotation, p)\n return [r[0] + position[0], r[1] + position[1], r[2] + position[2]]\n}\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Shapes (part space: centred on the origin, cylinders along +Y)\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\n/** Dimensions of the bounding box of a shape, in the shape's own axes. */\nexport const shapeDims = (s: PartShape): Vec3 => {\n if (s.kind === 'box') return [s.size[0], s.size[1], s.size[2]]\n if (s.kind === 'cylinder') return [s.radius * 2, s.height, s.radius * 2]\n return [s.radius * 2, s.radius * 2, s.radius * 2]\n}\n\n/** Radius of the sphere that encloses the shape. */\nexport const shapeBound = (s: PartShape): number => {\n if (s.kind === 'box') return 0.5 * Math.hypot(s.size[0], s.size[1], s.size[2])\n if (s.kind === 'cylinder') return Math.hypot(s.radius, s.height / 2)\n return s.radius\n}\n\nexport const shapeArea = (s: PartShape): number => {\n if (s.kind === 'box') return 2 * (s.size[0] * s.size[1] + s.size[1] * s.size[2] + s.size[0] * s.size[2])\n if (s.kind === 'cylinder') return 2 * Math.PI * s.radius * s.height + 2 * Math.PI * s.radius * s.radius\n return 4 * Math.PI * s.radius * s.radius\n}\n\nexport interface ShapeRay {\n /** Entry distance along the ray (negative when the origin is inside). */\n t0: number\n /** Normal at the entry, outward. */\n n0: Vec3\n /** Exit distance. */\n t1: number\n /** Normal at the exit, outward. */\n n1: Vec3\n}\n\n/** Exact ray intersection with a shape in part space. `d` need not be normalised but must be non-zero. */\nexport const rayShape = (s: PartShape, o: Vec3, d: Vec3): ShapeRay | null => {\n if (s.kind === 'box') {\n let tmin = -Infinity, tmax = Infinity\n let a0 = 0, a1 = 0, s0 = 1, s1 = 1\n for (let i = 0; i < 3; i++) {\n const h = s.size[i] / 2\n if (Math.abs(d[i]) < EPS) {\n if (Math.abs(o[i]) > h) return null\n continue\n }\n let ta = (-h - o[i]) / d[i]\n let tb = (h - o[i]) / d[i]\n let sa = -1, sb = 1\n if (ta > tb) {\n const t = ta\n ta = tb\n tb = t\n sa = 1\n sb = -1\n }\n if (ta > tmin) {\n tmin = ta\n a0 = i\n s0 = sa\n }\n if (tb < tmax) {\n tmax = tb\n a1 = i\n s1 = sb\n }\n if (tmin > tmax) return null\n }\n if (tmax < 0 || !Number.isFinite(tmin) || !Number.isFinite(tmax)) return null\n const n0: Vec3 = [0, 0, 0]\n const n1: Vec3 = [0, 0, 0]\n n0[a0] = s0\n n1[a1] = s1\n return { t0: tmin, n0, t1: tmax, n1 }\n }\n if (s.kind === 'sphere') {\n const b = vec.dot(o, d)\n const a = vec.dot(d, d)\n const c = vec.dot(o, o) - s.radius * s.radius\n const disc = b * b - a * c\n if (disc < 0) return null\n const sq = Math.sqrt(disc)\n const t0 = (-b - sq) / a\n const t1 = (-b + sq) / a\n if (t1 < 0) return null\n const p0 = vec.madd(o, d, t0)\n const p1 = vec.madd(o, d, t1)\n return { t0, n0: vec.normalize(p0), t1, n1: vec.normalize(p1) }\n }\n // cylinder along Y: intersection of the infinite cylinder interval and the y slab\n const r = s.radius\n const hh = s.height / 2\n const a = d[0] * d[0] + d[2] * d[2]\n const c = o[0] * o[0] + o[2] * o[2] - r * r\n let tA = -Infinity, tB = Infinity\n if (a > EPS) {\n const b = o[0] * d[0] + o[2] * d[2]\n const disc = b * b - a * c\n if (disc < 0) return null\n const sq = Math.sqrt(disc)\n tA = (-b - sq) / a\n tB = (-b + sq) / a\n } else if (c > 0) return null\n let yA = -Infinity, yB = Infinity\n if (Math.abs(d[1]) > EPS) {\n yA = (-hh - o[1]) / d[1]\n yB = (hh - o[1]) / d[1]\n if (yA > yB) {\n const t = yA\n yA = yB\n yB = t\n }\n } else if (Math.abs(o[1]) > hh) return null\n const t0 = Math.max(tA, yA)\n const t1 = Math.min(tB, yB)\n if (t0 > t1 || t1 < 0 || !Number.isFinite(t0) || !Number.isFinite(t1)) return null\n const normalAt = (t: number, fromSide: boolean, sign: number): Vec3 => {\n if (fromSide) {\n const p = vec.madd(o, d, t)\n return vec.normalize([p[0], 0, p[2]], [1, 0, 0])\n }\n return [0, sign, 0]\n }\n const n0 = normalAt(t0, tA >= yA, d[1] > 0 ? -1 : 1)\n const n1 = normalAt(t1, tB <= yB, d[1] > 0 ? 1 : -1)\n return { t0, n0, t1, n1 }\n}\n\n/** Distance from a part-space point to the shape (0 inside). */\nexport const distanceToShape = (s: PartShape, p: Vec3): number => {\n if (s.kind === 'box') {\n const dx = Math.max(Math.abs(p[0]) - s.size[0] / 2, 0)\n const dy = Math.max(Math.abs(p[1]) - s.size[1] / 2, 0)\n const dz = Math.max(Math.abs(p[2]) - s.size[2] / 2, 0)\n return Math.hypot(dx, dy, dz)\n }\n if (s.kind === 'sphere') return Math.max(0, vec.length(p) - s.radius)\n const dr = Math.max(0, Math.hypot(p[0], p[2]) - s.radius)\n const dy = Math.max(0, Math.abs(p[1]) - s.height / 2)\n return Math.hypot(dr, dy)\n}\n\n/** Nearest point on the surface of a shape to a part-space point, with the outward normal. */\nexport const surfacePoint = (s: PartShape, p: Vec3): { point: Vec3; normal: Vec3 } => {\n if (s.kind === 'box') {\n const h: Vec3 = [s.size[0] / 2, s.size[1] / 2, s.size[2] / 2]\n const inside = Math.abs(p[0]) <= h[0] && Math.abs(p[1]) <= h[1] && Math.abs(p[2]) <= h[2]\n if (!inside) {\n const c: Vec3 = [Math.max(-h[0], Math.min(h[0], p[0])), Math.max(-h[1], Math.min(h[1], p[1])), Math.max(-h[2], Math.min(h[2], p[2]))]\n return { point: c, normal: vec.normalize(vec.sub(p, c)) }\n }\n let axis = 0\n let best = Infinity\n for (let i = 0; i < 3; i++) {\n const g = h[i] - Math.abs(p[i])\n if (g < best) {\n best = g\n axis = i\n }\n }\n const sign = p[axis] >= 0 ? 1 : -1\n const point: Vec3 = [p[0], p[1], p[2]]\n point[axis] = sign * h[axis]\n const normal: Vec3 = [0, 0, 0]\n normal[axis] = sign\n return { point, normal }\n }\n if (s.kind === 'sphere') {\n const n = vec.normalize(p)\n return { point: vec.scale(n, s.radius), normal: n }\n }\n const rho = Math.hypot(p[0], p[2])\n const hh = s.height / 2\n const inside = rho <= s.radius && Math.abs(p[1]) <= hh\n if (!inside) {\n const k = rho > s.radius ? s.radius / rho : 1\n const c: Vec3 = [p[0] * k, Math.max(-hh, Math.min(hh, p[1])), p[2] * k]\n return { point: c, normal: vec.normalize(vec.sub(p, c)) }\n }\n if (s.radius - rho < hh - Math.abs(p[1])) {\n const k = rho < EPS ? 0 : s.radius / rho\n const point: Vec3 = rho < EPS ? [s.radius, p[1], 0] : [p[0] * k, p[1], p[2] * k]\n return { point, normal: vec.normalize([point[0], 0, point[2]], [1, 0, 0]) }\n }\n const sign = p[1] >= 0 ? 1 : -1\n return { point: [p[0], sign * hh, p[2]], normal: [0, sign, 0] }\n}\n\n/** Axis-aligned bounds of a shape with a given centre and orientation. */\nexport const aabbOf = (s: PartShape, center: Vec3, q: Quat): { min: Vec3; max: Vec3 } => {\n let hx: number, hy: number, hz: number\n if (s.kind === 'sphere') {\n hx = hy = hz = s.radius\n } else {\n const m = quat.toMatrix(q)\n if (s.kind === 'box') {\n const a = s.size[0] / 2, b = s.size[1] / 2, c = s.size[2] / 2\n hx = Math.abs(m[0]) * a + Math.abs(m[1]) * b + Math.abs(m[2]) * c\n hy = Math.abs(m[3]) * a + Math.abs(m[4]) * b + Math.abs(m[5]) * c\n hz = Math.abs(m[6]) * a + Math.abs(m[7]) * b + Math.abs(m[8]) * c\n } else {\n const ax = [m[1], m[4], m[7]]\n const hh = s.height / 2\n const e = (i: number) => s.radius * Math.sqrt(Math.max(0, 1 - ax[i] * ax[i])) + hh * Math.abs(ax[i])\n hx = e(0)\n hy = e(1)\n hz = e(2)\n }\n }\n return { min: [center[0] - hx, center[1] - hy, center[2] - hz], max: [center[0] + hx, center[1] + hy, center[2] + hz] }\n}\n\n/** Seeded generator (mulberry32). The state is a single int32, so it round-trips through JSON. */\nexport interface Rng {\n next(): number\n state(): number\n set(state: number): void\n}\n\nexport const createRng = (seed: number): Rng => {\n let s = seed | 0\n return {\n next() {\n s = (s + 0x6d2b79f5) | 0\n let t = Math.imul(s ^ (s >>> 15), 1 | s)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n },\n state: () => s,\n set(v) {\n s = v | 0\n },\n }\n}\n","import { quat } from './math'\nimport type { Fragment, FractureStyle, Quat, Vec3 } from './types'\n\n/** A fragment in the part's local space (centre, size in the fragment's own axes, orientation relative to the part). */\nexport interface PlannedFragment {\n center: Vec3\n size: Vec3\n q: Quat\n shape: Fragment['shape']\n /** Share of the part's mass (unnormalised). */\n weight: number\n}\n\nexport interface PlanInput {\n style: FractureStyle\n /** Bounding box dimensions in part axes. */\n dims: Vec3\n thickness: number\n /** Index 0..2 of the grain axis, if any. */\n grain?: number\n /** Impact point in part space. */\n hit: Vec3\n fragmentSize: [number, number]\n maxFragments: number\n rnd: () => number\n}\n\ninterface Box {\n c: Vec3\n s: Vec3\n}\n\n/** Split a box into `count` pieces by cutting the largest piece along its longest allowed axis. */\nconst bsp = (root: Box, count: number, axes: number[], rnd: () => number): Box[] => {\n const pieces: Box[] = [root]\n const vol = (b: Box) => axes.reduce((v, a) => v * b.s[a], 1)\n while (pieces.length < count) {\n let bi = 0\n for (let i = 1; i < pieces.length; i++) if (vol(pieces[i]) > vol(pieces[bi])) bi = i\n const b = pieces[bi]\n let ax = axes[0]\n for (const a of axes) if (b.s[a] > b.s[ax]) ax = a\n if (b.s[ax] < 1e-4) break\n const r = 0.3 + 0.4 * rnd()\n const l1 = b.s[ax] * r\n const l2 = b.s[ax] - l1\n const c1: Vec3 = [b.c[0], b.c[1], b.c[2]]\n const c2: Vec3 = [b.c[0], b.c[1], b.c[2]]\n c1[ax] = b.c[ax] - b.s[ax] / 2 + l1 / 2\n c2[ax] = b.c[ax] + b.s[ax] / 2 - l2 / 2\n const s1: Vec3 = [b.s[0], b.s[1], b.s[2]]\n const s2: Vec3 = [b.s[0], b.s[1], b.s[2]]\n s1[ax] = l1\n s2[ax] = l2\n pieces[bi] = { c: c1, s: s1 }\n pieces.push({ c: c2, s: s2 })\n }\n return pieces\n}\n\nconst parity = (p: [number, number, number]): number => {\n let inv = 0\n for (let i = 0; i < 3; i++) for (let j = i + 1; j < 3; j++) if (p[i] > p[j]) inv++\n return inv % 2 === 0 ? 1 : -1\n}\n\n/** Orientation whose x, y, z axes are the part axes `ax`, `ay`, `az`, then rotated by `angle` around its own z. */\nconst frame = (ax: number, ay: number, az: number, angle = 0): Quat => {\n const e = (i: number): Vec3 => [i === 0 ? 1 : 0, i === 1 ? 1 : 0, i === 2 ? 1 : 0]\n const z = e(az)\n const sg = parity([ax, ay, az])\n const q = quat.fromColumns(e(ax), e(ay), [z[0] * sg, z[1] * sg, z[2] * sg])\n return angle === 0 ? q : quat.mul(q, quat.fromAxisAngle([0, 0, 1], angle))\n}\n\nconst clamp = (v: number, a: number, b: number) => Math.max(a, Math.min(b, v))\n\n/** Deterministic fragment layout for a failed part, in part space. */\nexport const planFragments = (inp: PlanInput): PlannedFragment[] => {\n const { style, dims, rnd, maxFragments } = inp\n const [fmin, fmax] = inp.fragmentSize\n const mean = (fmin + fmax) / 2\n const root: Box = { c: [0, 0, 0], s: [dims[0], dims[1], dims[2]] }\n const idq = quat.identity()\n const out: PlannedFragment[] = []\n const sorted = [0, 1, 2].sort((a, b) => dims[a] - dims[b])\n const t = sorted[0]\n const [u, v] = [sorted[1], sorted[2]].sort((a, b) => a - b)\n\n if (style === 'snap') {\n const n = Math.min(maxFragments, 2 + Math.floor(rnd() * 3))\n for (const b of bsp(root, n, [0, 1, 2], rnd)) out.push({ center: b.c, size: b.s, q: idq, shape: 'slab', weight: b.s[0] * b.s[1] * b.s[2] })\n return out\n }\n if (style === 'crumble' || style === 'none') {\n const n = clamp(Math.ceil((dims[0] * dims[1] * dims[2]) / (mean * mean * mean)), 4, maxFragments)\n for (const b of bsp(root, n, [0, 1, 2], rnd)) out.push({ center: b.c, size: b.s, q: idq, shape: 'chunk', weight: b.s[0] * b.s[1] * b.s[2] })\n return out\n }\n if (style === 'splinter') {\n const g = inp.grain ?? [0, 1, 2].sort((a, b) => dims[b] - dims[a])[0]\n const [a, b] = [0, 1, 2].filter((i) => i !== g)\n const w = Math.max(fmin * 1.5, 0.01)\n const c = clamp(Math.round((dims[a] * dims[b]) / (w * w)), 3, Math.max(3, Math.floor(maxFragments / 2)))\n const maxLen = fmax * 4\n const cells = bsp(root, c, [a, b], rnd)\n const pieces: Box[] = []\n for (const cell of cells) {\n let list = [cell]\n const extra = rnd() < 0.4 ? 1 : 0\n const k = Math.max(1, Math.ceil(dims[g] / maxLen)) + extra\n list = bsp(cell, k, [g], rnd)\n for (const p of list) pieces.push(p)\n }\n for (const p of pieces.slice(0, maxFragments)) {\n out.push({ center: p.c, size: [p.s[g], p.s[a], p.s[b]], q: frame(g, a, b), shape: 'splinter', weight: p.s[0] * p.s[1] * p.s[2] })\n }\n return out\n }\n if (style === 'tear') {\n const n = clamp(Math.round((dims[u] * dims[v]) / (mean * mean)), 3, maxFragments)\n const th = Math.min(inp.thickness, dims[t])\n for (const b of bsp(root, n, [u, v], rnd)) {\n out.push({ center: [b.c[0], b.c[1], b.c[2]], size: [b.s[u], b.s[v], th], q: frame(u, v, t), shape: 'scrap', weight: b.s[u] * b.s[v] })\n }\n return out\n }\n // shatter: thin shards radiating from the impact\n const th = Math.min(inp.thickness, dims[t])\n const Hu = dims[u] / 2, Hv = dims[v] / 2\n const hu = clamp(inp.hit[u], -Hu * 0.95, Hu * 0.95)\n const hv = clamp(inp.hit[v], -Hv * 0.95, Hv * 0.95)\n const R = Math.max(Math.hypot(Hu + Math.abs(hu), Hv + Math.abs(hv)), 0.02)\n const n = clamp(Math.round((dims[u] * dims[v]) / (mean * mean)), 6, maxFragments)\n const sectors = clamp(Math.round(Math.sqrt(n * 1.6)), 5, 10)\n const rings = Math.max(1, Math.ceil(n / sectors))\n const radii: number[] = []\n for (let k = 0; k <= rings; k++) radii.push(R * Math.pow(k / rings, 1.3))\n const cap = fmax * 1.5\n for (let j = 0; j < sectors && out.length < maxFragments; j++) {\n const theta = (j + (rnd() - 0.5) * 0.4) * ((Math.PI * 2) / sectors)\n for (let k = 0; k < rings && out.length < maxFragments; k++) {\n const rm = (radii[k] + radii[k + 1]) / 2\n const cu = hu + rm * Math.cos(theta)\n const cv = hv + rm * Math.sin(theta)\n if (Math.abs(cu) > Hu + 0.01 || Math.abs(cv) > Hv + 0.01) continue\n const radial = clamp(radii[k + 1] - radii[k], 0.01, cap)\n const tang = clamp(radii[k + 1] * ((Math.PI * 2) / sectors) * 0.9, 0.01, cap)\n const c: Vec3 = [0, 0, 0]\n c[u] = clamp(cu, -Hu * 0.98, Hu * 0.98)\n c[v] = clamp(cv, -Hv * 0.98, Hv * 0.98)\n c[t] = 0\n out.push({ center: c, size: [radial, tang, th], q: frame(u, v, t, theta), shape: 'shard', weight: radial * tang })\n }\n }\n if (out.length === 0) out.push({ center: [0, 0, 0], size: [dims[u], dims[v], th], q: frame(u, v, t), shape: 'shard', weight: 1 })\n return out\n}\n","[\n {\n \"id\": \"steel\",\n \"density\": 7850,\n \"hpPerKg\": 400,\n \"penetration\": 110,\n \"ductility\": 0.9,\n \"fracture\": \"none\",\n \"damageScale\": {\n \"slash\": 0.1,\n \"blunt\": 0.8\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"sparks\",\n \"ricochetDeg\": 20,\n \"thermal\": {\n \"meltC\": 1450,\n \"meltRate\": 0.05,\n \"conductivity\": 0.5,\n \"heatCapacity\": 3\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 2000000\n },\n {\n \"id\": \"cast_iron\",\n \"density\": 7200,\n \"hpPerKg\": 150,\n \"penetration\": 160,\n \"ductility\": 0.2,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.08,\n 0.3\n ],\n \"damageScale\": {\n \"slash\": 0.1,\n \"blunt\": 1.2\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"chips\",\n \"ricochetDeg\": 15,\n \"thermal\": {\n \"meltC\": 1200,\n \"meltRate\": 0.05,\n \"conductivity\": 0.45,\n \"heatCapacity\": 3\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 1500000\n },\n {\n \"id\": \"aluminium\",\n \"density\": 2700,\n \"hpPerKg\": 250,\n \"penetration\": 60,\n \"ductility\": 0.85,\n \"fracture\": \"none\",\n \"damageScale\": {\n \"slash\": 0.2\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"sparks\",\n \"ricochetDeg\": 15,\n \"thermal\": {\n \"meltC\": 660,\n \"meltRate\": 0.06,\n \"conductivity\": 0.8,\n \"heatCapacity\": 1.5\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 800000\n },\n {\n \"id\": \"copper\",\n \"density\": 8960,\n \"hpPerKg\": 300,\n \"penetration\": 70,\n \"ductility\": 0.95,\n \"fracture\": \"none\",\n \"damageScale\": {\n \"slash\": 0.2\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"sparks\",\n \"ricochetDeg\": 15,\n \"thermal\": {\n \"meltC\": 1085,\n \"meltRate\": 0.05,\n \"conductivity\": 1,\n \"heatCapacity\": 2.5\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 1000000\n },\n {\n \"id\": \"wood_soft\",\n \"density\": 500,\n \"hpPerKg\": 90,\n \"penetration\": 9,\n \"ductility\": 0.35,\n \"fracture\": \"splinter\",\n \"fragmentSize\": [\n 0.03,\n 0.15\n ],\n \"damageScale\": {\n \"blunt\": 1.2,\n \"slash\": 1.5\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"splinters\",\n \"thermal\": {\n \"ignitionC\": 300,\n \"flameC\": 800,\n \"fuelFraction\": 0.9,\n \"burnRate\": 0.012,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 100000\n },\n {\n \"id\": \"wood_hard\",\n \"density\": 750,\n \"hpPerKg\": 140,\n \"penetration\": 14,\n \"ductility\": 0.3,\n \"fracture\": \"splinter\",\n \"fragmentSize\": [\n 0.03,\n 0.2\n ],\n \"damageScale\": {\n \"slash\": 1.2\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"splinters\",\n \"thermal\": {\n \"ignitionC\": 330,\n \"flameC\": 800,\n \"fuelFraction\": 0.9,\n \"burnRate\": 0.01,\n \"conductivity\": 0.06,\n \"heatCapacity\": 1.4,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 150000\n },\n {\n \"id\": \"plywood\",\n \"density\": 600,\n \"hpPerKg\": 70,\n \"penetration\": 7,\n \"ductility\": 0.3,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.1,\n 0.4\n ],\n \"damageScale\": {\n \"slash\": 1.3\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"splinters\",\n \"thermal\": {\n \"ignitionC\": 300,\n \"flameC\": 800,\n \"fuelFraction\": 0.85,\n \"burnRate\": 0.013,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 60000\n },\n {\n \"id\": \"mdf\",\n \"density\": 750,\n \"hpPerKg\": 45,\n \"penetration\": 6,\n \"ductility\": 0.15,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.08,\n 0.35\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"ignitionC\": 290,\n \"flameC\": 750,\n \"fuelFraction\": 0.85,\n \"burnRate\": 0.014,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 30000\n },\n {\n \"id\": \"glass\",\n \"density\": 2500,\n \"hpPerKg\": 12,\n \"penetration\": 6,\n \"ductility\": 0.02,\n \"fracture\": \"shatter\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"blunt\": 1.5\n },\n \"hitDebris\": \"shards\",\n \"breakDebris\": \"shards\",\n \"ricochetDeg\": 8,\n \"thermal\": {\n \"meltC\": 1400,\n \"meltRate\": 0.03,\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5,\n \"thermalShockC\": 150\n },\n \"visual\": {\n \"glows\": true,\n \"transparent\": true\n },\n \"tags\": [\n \"glass\",\n \"brittle\"\n ],\n \"compressive\": 100000\n },\n {\n \"id\": \"tempered_glass\",\n \"density\": 2500,\n \"hpPerKg\": 30,\n \"penetration\": 9,\n \"ductility\": 0.02,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.006,\n 0.02\n ],\n \"hitDebris\": \"shards\",\n \"breakDebris\": \"shards\",\n \"ricochetDeg\": 8,\n \"thermal\": {\n \"meltC\": 1400,\n \"meltRate\": 0.03,\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5,\n \"thermalShockC\": 250\n },\n \"visual\": {\n \"glows\": true,\n \"transparent\": true\n },\n \"tags\": [\n \"glass\",\n \"brittle\"\n ],\n \"compressive\": 200000\n },\n {\n \"id\": \"ceramic\",\n \"density\": 2400,\n \"hpPerKg\": 25,\n \"penetration\": 12,\n \"ductility\": 0.02,\n \"fracture\": \"shatter\",\n \"fragmentSize\": [\n 0.03,\n 0.12\n ],\n \"damageScale\": {\n \"blunt\": 1.3\n },\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"shards\",\n \"thermal\": {\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5,\n \"thermalShockC\": 200\n },\n \"tags\": [\n \"ceramic\",\n \"brittle\"\n ],\n \"compressive\": 150000\n },\n {\n \"id\": \"concrete\",\n \"density\": 2300,\n \"hpPerKg\": 14,\n \"penetration\": 18,\n \"ductility\": 0.03,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"explosive\": 1.2\n },\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.15,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 444000\n },\n {\n \"id\": \"brick\",\n \"density\": 1900,\n \"hpPerKg\": 12,\n \"penetration\": 14,\n \"ductility\": 0.05,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.04,\n 0.12\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.15,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 40000\n },\n {\n \"id\": \"plaster\",\n \"density\": 850,\n \"hpPerKg\": 18,\n \"penetration\": 3,\n \"ductility\": 0.05,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.05,\n 0.3\n ],\n \"hitDebris\": \"dust\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 8000\n },\n {\n \"id\": \"stone\",\n \"density\": 2700,\n \"hpPerKg\": 25,\n \"penetration\": 25,\n \"ductility\": 0.03,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.06,\n 0.3\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.2,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 300000\n },\n {\n \"id\": \"plastic\",\n \"density\": 1100,\n \"hpPerKg\": 60,\n \"penetration\": 8,\n \"ductility\": 0.5,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.05,\n 0.3\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"chips\",\n \"thermal\": {\n \"ignitionC\": 400,\n \"flameC\": 700,\n \"fuelFraction\": 0.8,\n \"burnRate\": 0.02,\n \"meltC\": 200,\n \"meltRate\": 0.06,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1,\n \"smoke\": \"black\"\n },\n \"visual\": {\n \"charColor\": 855309\n },\n \"tags\": [\n \"plastic\",\n \"flammable\"\n ],\n \"compressive\": 40000\n },\n {\n \"id\": \"rubber\",\n \"density\": 1100,\n \"hpPerKg\": 80,\n \"penetration\": 12,\n \"ductility\": 0.9,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.05,\n 0.2\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 350,\n \"flameC\": 750,\n \"fuelFraction\": 0.6,\n \"burnRate\": 0.015,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"black\"\n },\n \"visual\": {\n \"charColor\": 855309\n },\n \"tags\": [\n \"rubber\",\n \"flammable\"\n ],\n \"compressive\": 20000\n },\n {\n \"id\": \"fabric\",\n \"density\": 400,\n \"hpPerKg\": 20,\n \"penetration\": 0.8,\n \"ductility\": 0.8,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"slash\": 4,\n \"ballistic\": 0.5\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 230,\n \"flameC\": 600,\n \"fuelFraction\": 1,\n \"burnRate\": 0.05,\n \"conductivity\": 0.03,\n \"heatCapacity\": 0.6,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"fabric\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 500\n },\n {\n \"id\": \"foam\",\n \"density\": 30,\n \"hpPerKg\": 15,\n \"penetration\": 0.5,\n \"ductility\": 0.7,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.03,\n 0.15\n ],\n \"damageScale\": {\n \"slash\": 2,\n \"ballistic\": 0.4\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 250,\n \"flameC\": 900,\n \"fuelFraction\": 0.95,\n \"burnRate\": 0.09,\n \"conductivity\": 0.02,\n \"heatCapacity\": 0.5,\n \"smoke\": \"black\"\n },\n \"visual\": {\n \"charColor\": 855309\n },\n \"tags\": [\n \"fabric\",\n \"flammable\"\n ],\n \"compressive\": 100\n },\n {\n \"id\": \"leather\",\n \"density\": 900,\n \"hpPerKg\": 50,\n \"penetration\": 4,\n \"ductility\": 0.8,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"slash\": 2\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 320,\n \"flameC\": 650,\n \"fuelFraction\": 0.7,\n \"burnRate\": 0.01,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"fabric\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 2000\n },\n {\n \"id\": \"paper\",\n \"density\": 700,\n \"hpPerKg\": 8,\n \"penetration\": 0.3,\n \"ductility\": 0.5,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.03,\n 0.15\n ],\n \"damageScale\": {\n \"slash\": 3\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 230,\n \"flameC\": 600,\n \"fuelFraction\": 1,\n \"burnRate\": 0.06,\n \"conductivity\": 0.03,\n \"heatCapacity\": 0.5,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"fabric\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 500\n },\n {\n \"id\": \"foliage\",\n \"density\": 150,\n \"hpPerKg\": 20,\n \"penetration\": 0.5,\n \"ductility\": 0.6,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.03,\n 0.1\n ],\n \"damageScale\": {\n \"slash\": 4\n },\n \"hitDebris\": \"leaves\",\n \"breakDebris\": \"leaves\",\n \"thermal\": {\n \"ignitionC\": 300,\n \"flameC\": 700,\n \"fuelFraction\": 0.8,\n \"burnRate\": 0.08,\n \"conductivity\": 0.03,\n \"heatCapacity\": 0.8,\n \"smoke\": \"white\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"plant\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 500\n },\n {\n \"id\": \"green_wood\",\n \"density\": 650,\n \"hpPerKg\": 5,\n \"penetration\": 10,\n \"ductility\": 0.5,\n \"fracture\": \"splinter\",\n \"fragmentSize\": [\n 0.03,\n 0.2\n ],\n \"damageScale\": {\n \"slash\": 1.3,\n \"ballistic\": 0.1\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"leaves\",\n \"thermal\": {\n \"ignitionC\": 400,\n \"flameC\": 700,\n \"fuelFraction\": 0.8,\n \"burnRate\": 0.006,\n \"conductivity\": 0.06,\n \"heatCapacity\": 2,\n \"smoke\": \"white\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"plant\",\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 60000\n },\n {\n \"id\": \"cactus\",\n \"density\": 900,\n \"hpPerKg\": 30,\n \"penetration\": 2,\n \"ductility\": 0.6,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.04,\n 0.15\n ],\n \"damageScale\": {\n \"slash\": 3\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 450,\n \"flameC\": 650,\n \"fuelFraction\": 0.3,\n \"burnRate\": 0.01,\n \"conductivity\": 0.05,\n \"heatCapacity\": 3,\n \"smoke\": \"white\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"plant\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 5000\n },\n {\n \"id\": \"flesh_fruit\",\n \"density\": 950,\n \"hpPerKg\": 15,\n \"penetration\": 1.5,\n \"ductility\": 0.7,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.02,\n 0.08\n ],\n \"damageScale\": {\n \"slash\": 2\n },\n \"hitDebris\": \"drips\",\n \"breakDebris\": \"drips\",\n \"thermal\": {\n \"conductivity\": 0.05,\n \"heatCapacity\": 3\n },\n \"tags\": [\n \"plant\",\n \"organic\"\n ],\n \"compressive\": 1000\n },\n {\n \"id\": \"wax\",\n \"density\": 900,\n \"hpPerKg\": 30,\n \"penetration\": 3,\n \"ductility\": 0.5,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.05,\n 0.2\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"chips\",\n \"thermal\": {\n \"ignitionC\": 230,\n \"flameC\": 700,\n \"fuelFraction\": 0.9,\n \"burnRate\": 0.02,\n \"meltC\": 60,\n \"meltRate\": 0.2,\n \"conductivity\": 0.05,\n \"heatCapacity\": 0.8,\n \"smoke\": \"grey\"\n },\n \"tags\": [\n \"wax\",\n \"flammable\"\n ],\n \"compressive\": 5000\n },\n {\n \"id\": \"soil\",\n \"density\": 1300,\n \"hpPerKg\": 3,\n \"penetration\": 5,\n \"ductility\": 0.3,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.03,\n 0.12\n ],\n \"hitDebris\": \"dust\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.1,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"soil\",\n \"masonry\"\n ],\n \"compressive\": 20000\n }\n]","{\n \"cast iron\": \"cast_iron\",\n \"cast_iron\": \"cast_iron\",\n \"castiron\": \"cast_iron\",\n \"metal\": \"steel\",\n \"steel\": \"steel\",\n \"iron\": \"steel\",\n \"chrome\": \"steel\",\n \"alumin\": \"aluminium\",\n \"alu_\": \"aluminium\",\n \"alu-\": \"aluminium\",\n \"alu \": \"aluminium\",\n \"copper\": \"copper\",\n \"brass\": \"copper\",\n \"bronze\": \"copper\",\n \"wood\": \"wood_soft\",\n \"timber\": \"wood_soft\",\n \"plank\": \"wood_soft\",\n \"lumber\": \"wood_soft\",\n \"pine\": \"wood_soft\",\n \"hardwood\": \"wood_hard\",\n \"oak\": \"wood_hard\",\n \"plywood\": \"plywood\",\n \"mdf\": \"mdf\",\n \"chipboard\": \"mdf\",\n \"glass\": \"glass\",\n \"window\": \"glass\",\n \"mirror\": \"glass\",\n \"tempered\": \"tempered_glass\",\n \"windshield\": \"tempered_glass\",\n \"fabric\": \"fabric\",\n \"cloth\": \"fabric\",\n \"cushion\": \"fabric\",\n \"sofa\": \"fabric\",\n \"curtain\": \"fabric\",\n \"carpet\": \"fabric\",\n \"textile\": \"fabric\",\n \"canvas\": \"fabric\",\n \"foam\": \"foam\",\n \"sponge\": \"foam\",\n \"mattress\": \"foam\",\n \"leather\": \"leather\",\n \"paper\": \"paper\",\n \"cardboard\": \"paper\",\n \"leaf\": \"foliage\",\n \"leaves\": \"foliage\",\n \"foliage\": \"foliage\",\n \"bush\": \"foliage\",\n \"grass\": \"foliage\",\n \"trunk\": \"green_wood\",\n \"branch\": \"green_wood\",\n \"twig\": \"green_wood\",\n \"cactus\": \"cactus\",\n \"fruit\": \"flesh_fruit\",\n \"apple\": \"flesh_fruit\",\n \"melon\": \"flesh_fruit\",\n \"wax\": \"wax\",\n \"candle\": \"wax\",\n \"concrete\": \"concrete\",\n \"cement\": \"concrete\",\n \"brick\": \"brick\",\n \"tile\": \"ceramic\",\n \"ceramic\": \"ceramic\",\n \"porcelain\": \"ceramic\",\n \"stone\": \"stone\",\n \"rock\": \"stone\",\n \"marble\": \"stone\",\n \"plaster\": \"plaster\",\n \"drywall\": \"plaster\",\n \"gypsum\": \"plaster\",\n \"plastic\": \"plastic\",\n \"pvc\": \"plastic\",\n \"acrylic\": \"plastic\",\n \"rubber\": \"rubber\",\n \"tire\": \"rubber\",\n \"tyre\": \"rubber\",\n \"soil\": \"soil\",\n \"dirt\": \"soil\",\n \"potting\": \"soil\",\n \"mud\": \"soil\"\n}","import materialsJson from './data/materials.json'\nimport hintsJson from './data/material-hints.json'\nimport { aabbOf, quatFromEuler, shapeDims } from './math'\nimport type { JointKind, JointSpec, MaterialDef, MaterialId, PartShape, PartSpec, ToolKind } from './types'\n\n/** Built-in materials (data in `src/data/materials.json`). Override or extend with the `materials` option of `createDestruction`. */\nexport const MATERIALS: MaterialDef[] = materialsJson as unknown as MaterialDef[]\n\n/** Default joint strength (joint hit points), tools that undo it and seconds of tool work. */\nexport const JOINT_DEFAULTS: Record<JointKind, { strength: number; tools: ToolKind[]; seconds: number }> = {\n screw: { strength: 80, tools: ['screwdriver'], seconds: 2.5 },\n bolt: { strength: 200, tools: ['wrench'], seconds: 4 },\n nail: { strength: 60, tools: ['pry_bar', 'hammer'], seconds: 2 },\n weld: { strength: 600, tools: ['cutting_torch', 'saw'], seconds: 8 },\n glue: { strength: 50, tools: ['pry_bar', 'knife'], seconds: 3 },\n hinge: { strength: 120, tools: ['screwdriver'], seconds: 3 },\n clip: { strength: 20, tools: ['hand'], seconds: 0.6 },\n tie: { strength: 15, tools: ['knife', 'hand'], seconds: 1 },\n mortar: { strength: 400, tools: ['hammer'], seconds: 6 },\n fused: { strength: 1000, tools: [], seconds: 0 },\n stem: { strength: 40, tools: ['knife', 'saw', 'hand'], seconds: 1.5 },\n rebar: { strength: 1500, tools: ['cutting_torch', 'saw'], seconds: 20 },\n resting: { strength: 30, tools: ['hand'], seconds: 1 },\n}\n\nconst has = (m: MaterialDef, tag: string) => !!m.tags && m.tags.includes(tag)\n\n/**\n * The joint kind that fits two materials: glass is glued (clipped to plastic), soft things are tied, plants share a stem, masonry gets mortar,\n * metal is welded, wood is screwed, plastic clips. `inferJoints` refines weld to bolt for thick metal and screw to nail for thin wood.\n */\nexport const JOINT_BY_MATERIALS = (a: MaterialDef, b: MaterialDef): JointKind => {\n const any = (tag: string) => has(a, tag) || has(b, tag)\n const both = (tag: string) => has(a, tag) && has(b, tag)\n if (any('glass')) return any('plastic') ? 'clip' : 'glue'\n if (any('fabric')) return 'tie'\n if (both('plant')) return 'stem'\n if (any('plant')) return 'tie'\n if (both('masonry')) return 'mortar'\n if (any('masonry') && any('metal')) return 'bolt'\n if (both('metal')) return 'weld'\n if (any('plastic')) return 'clip'\n if (any('rubber') || any('wax')) return 'glue'\n return 'screw'\n}\n\nconst MATERIAL_MAP: ReadonlyMap<MaterialId, MaterialDef> = new Map(MATERIALS.map((m) => [m.id, m]))\n\nconst HINTS = Object.entries(hintsJson as Record<string, string>).sort((x, y) => y[0].length - x[0].length)\n\n/** Guess a material id from a mesh or node name (case-insensitive substring; the longest keyword wins). */\nexport const guessMaterial = (name: string): MaterialId | undefined => {\n const n = name.toLowerCase()\n for (const [key, id] of HINTS) if (n.includes(key)) return id\n return undefined\n}\n\n/** Volume of a shape in m³. */\nexport const partVolume = (shape: PartShape): number => {\n if (shape.kind === 'box') return shape.size[0] * shape.size[1] * shape.size[2]\n if (shape.kind === 'cylinder') return Math.PI * shape.radius * shape.radius * shape.height\n return (4 / 3) * Math.PI * shape.radius ** 3\n}\n\n/** Mass of a part in kg: its `mass`, or density × volume × fill. */\nexport const partMass = (part: PartSpec, material: MaterialDef): number => part.mass ?? material.density * partVolume(part.shape) * (part.fill ?? 1)\n\n/** Wall thickness of a part in metres (see `PartSpec.thickness`). */\nexport const partThickness = (part: PartSpec): number => {\n const dims = shapeDims(part.shape)\n const min = Math.min(dims[0], dims[1], dims[2])\n return Math.max(1e-4, Math.min(part.thickness ?? min * (part.fill ?? 1), min))\n}\n\n/**\n * Joints for touching parts. Two parts touch when their axis-aligned bounds (after rotation), grown by `tolerance` metres, overlap. The kind comes\n * from `JOINT_BY_MATERIALS`; thick metal pairs (smallest dimension of both >= 2 cm) get a `bolt` instead of a `weld`, and thin wood pairs (either\n * under 2 cm) a `nail` instead of a `screw`.\n */\nexport const inferJoints = (parts: PartSpec[], tolerance = 0.01, materials: ReadonlyMap<string, MaterialDef> = MATERIAL_MAP): JointSpec[] => {\n const boxes = parts.map((p) => aabbOf(p.shape, p.position, quatFromEuler(...(p.rotation ?? [0, 0, 0]))))\n const out: JointSpec[] = []\n for (let i = 0; i < parts.length; i++) {\n for (let j = i + 1; j < parts.length; j++) {\n const a = boxes[i], b = boxes[j]\n let touch = true\n for (let k = 0; k < 3 && touch; k++) if (a.min[k] - tolerance > b.max[k] || b.min[k] - tolerance > a.max[k]) touch = false\n if (!touch) continue\n const ma = materials.get(parts[i].material)\n const mb = materials.get(parts[j].material)\n let kind: JointKind = ma && mb ? JOINT_BY_MATERIALS(ma, mb) : 'screw'\n const thin = Math.min(partThickness(parts[i]), partThickness(parts[j]))\n if (kind === 'weld' && thin >= 0.02) kind = 'bolt'\n if (kind === 'screw' && ma && mb && has(ma, 'wood') && has(mb, 'wood') && thin < 0.02) kind = 'nail'\n out.push({ id: `${parts[i].id}~${parts[j].id}`, a: parts[i].id, b: parts[j].id, kind })\n }\n }\n return out\n}\n\n/**\n * Load in kg a structural part carries before it fails: `structure.capacity`, else `material.compressive` (default 20 000 kg/m²) times the\n * section. The section is the product of the two smallest dimensions (thickness times longest dimension for slabs; thickness times horizontal length for walls); foundations get x10.\n */\nexport const partCapacity = (part: PartSpec, material: MaterialDef): number => {\n if (part.structure?.capacity !== undefined) return part.structure.capacity\n const d = shapeDims(part.shape).sort((a, b) => a - b)\n const role = part.structure?.role\n const sh = shapeDims(part.shape)\n const section = role === 'wall' || role === 'partition' ? Math.min(sh[0], sh[2]) * Math.max(sh[0], sh[2]) : role === 'slab' ? d[0] * d[2] : d[0] * d[1]\n return Math.max(1, section * (material.compressive ?? 20000) * (role === 'foundation' ? 10 : 1))\n}\n\n\n/**\n * Multiplier of blunt damage on brittle parts (ductility < 0.3): up to x4.7 for fully brittle materials (glass, ceramic, stone), times a thinness\n * term that follows bending stress (1 / thickness squared, x1 at 2 cm or more, at most x25). A 3 mm glass bottle breaks from a 1.5 m drop; a\n * concrete block (thick) is only ever x4.4.\n */\nexport const fragility = (ductility: number, thickness: number): number => {\n if (ductility >= 0.3) return 1\n return (1 + (4 * (0.3 - ductility)) / 0.3) * Math.min(25, Math.max(1, (0.02 / Math.max(thickness, 1e-4)) ** 2))\n}\n","import { chainDelayOf, drawChainDelay, FIRE_PRIME_C, shotDamageFractionOf } from './chain'\nimport type { ChainTrigger } from './chain'\nimport { planFragments } from './fracture'\nimport { JOINT_DEFAULTS, inferJoints, MATERIALS, partCapacity, partMass, partThickness, partVolume, fragility } from './materials'\nimport { aabbOf, createRng, distanceToShape, quat, quatFromEuler, rayShape, rotateVec, shapeArea, shapeBound, shapeDims, surfacePoint, toLocal, toWorld, vec } from './math'\nimport type { DestructibleImpl } from './contracts'\nimport type {\n AddOptions, Crack, DamageType, DebrisKind, DestructibleSpec, Dent, DestructionEvent, DestructionEventType, DestructionOptions, DestructionSnapshot,\n DestructionWorld, Fragment, Hit, HitResult, Hole, JointSpec, JointState, MaterialDef, MaterialId, ObjectRuntime, ObjectState, PartRuntime, PartSpec,\n PartState, Quat, RayHit, ToolKind, Vec3,\n} from './types'\n\n/** Hit points removed per joule (before the material's `damageScale`). */\nconst DMG_PER_J = 0.02\n/** Fraction of a blast's energy that reaches a part at distance 0. */\nconst BLAST_COUPLING = 0.1\nconst FLAMMABLE_FLUIDS = ['gas', 'fuel']\n\n/** A cut only goes through a slice of the part, so a part longer than `CUT_SLICE` costs no more to cut than a 1 m piece of the same section. */\nconst CUT_SLICE = 1\nconst cutFactorOf = (shape: PartSpec['shape']): number => clamp(Math.max(...shapeDims(shape)) / CUT_SLICE, 1, 50)\n\ninterface PartRT {\n spec: PartSpec\n mat: MaterialDef\n st: PartState\n q: Quat\n /** Current object-local position (the spec's, unless moved by `setPartPose`). */\n pos: Vec3\n mass0: number\n fuel0: number\n area: number\n thickness: number\n /** Slash damage multiplier: longest dimension / 1 m (1..50). */\n cutFactor: number\n dims: Vec3\n bound: number\n rt: PartRuntime\n /** Structural role other than `none`. */\n structural: boolean\n anchored: boolean\n cap: number\n}\n\ninterface JointRT {\n spec: Required<JointSpec>\n st: JointState\n ia: number\n ib: number\n bears: boolean | 'a_on_b' | 'b_on_a'\n /** Object-local position. */\n pos: Vec3\n step: number\n}\n\ninterface ObjRT {\n id: string\n spec: DestructibleSpec\n st: ObjectState\n parts: PartRT[]\n byId: Map<string, PartRT>\n idx: Map<string, number>\n joints: JointRT[]\n jointMap: Map<string, JointRT>\n byPart: Map<string, JointRT[]>\n /** Local bounding sphere. */\n bc: Vec3\n br: number\n active: boolean\n tmp: number[]\n hasStructure: boolean\n dirty: boolean\n maxStress: number\n collapsed: Set<string>\n /** Structural parts with no support path to an anchored part (they fall). */\n unsup: boolean[]\n anyAnchor: boolean\n /** Creation order of the object in this world: breaks ties between parts that go off at the same time. */\n order: number\n}\n\ninterface Carry {\n parts: Map<string, { st: PartState; rt: PartRuntime }>\n joints: Map<string, { st: JointState; step: number }>\n collapsed?: string[]\n}\n\ninterface Loc {\n p: PartRT\n point: Vec3\n normal: Vec3\n dir: Vec3\n pathLen: number\n}\n\ninterface ImplRT {\n impl: DestructibleImpl\n position: Vec3\n rotation: Quat\n /** Part pose overrides set by `setPartPose` (object-local). */\n poses: Map<string, { pos: Vec3; q: Quat }>\n}\n\ninterface Blast {\n point: Vec3\n energy: number\n radius: number\n source?: string\n}\n\nconst clamp = (v: number, a: number, b: number) => Math.max(a, Math.min(b, v))\nconst isLost = (p: PartRT) => p.st.status === 'broken' || p.st.status === 'melted' || p.st.status === 'ashes'\nconst clone = <T>(v: T): T => structuredClone(v)\n/**\n * Fraction of a structural part's hit points lost per second while its stress is above 1. A floor of 0.12 makes even a barely overloaded part\n * give way in about 8 s (a rate proportional to the excess alone never finishes: stress 1.02 would take two minutes), then it grows with the\n * excess and tops out at 0.6: stress 1.1 fails in ~4.5 s, 1.5 in ~1.9 s and anything above 1.7 in ~1.7 s. Deterministic: depends only on stress.\n */\nconst overloadRate = (stress: number) => Math.min(0.6, 0.12 + 0.8 * (stress - 1))\nconst updateBound = (o: ObjRT) => {\n if (!o.parts.length) return\n const c: Vec3 = [0, 0, 0]\n for (const p of o.parts) for (let k = 0; k < 3; k++) c[k] += p.pos[k] / o.parts.length\n let r = 0\n for (const p of o.parts) r = Math.max(r, vec.distance(c, p.pos) + p.bound)\n o.bc = c\n o.br = r\n}\nconst AXIS = { x: 0, y: 1, z: 2 } as const\n\nexport const createDestruction = (options: DestructionOptions = {}): DestructionWorld => {\n const materials = new Map<MaterialId, MaterialDef>()\n for (const m of MATERIALS) materials.set(m.id, m)\n for (const m of options.materials ?? []) materials.set(m.id, m)\n const ambient = options.ambientC ?? 20\n const maxFragments = options.maxFragments ?? 24\n const maxDents = options.maxDents ?? 24\n const maxHoles = options.maxHoles ?? 32\n const fireSpread = options.fireSpread ?? 0.6\n const rng = createRng(options.seed ?? 1)\n const rnd = () => rng.next()\n\n let time = 0\n let counter = 0\n const objects = new Map<string, ObjRT>()\n const listeners = new Map<string, Set<(e: DestructionEvent) => void>>()\n let cur: DestructionEvent[] = []\n const blasts: Blast[] = []\n /** Explosive parts that were primed and wait for their delay. */\n const primed = new Map<PartRT, ObjRT>()\n let orderCounter = 0\n const impls = new Map<string, ImplRT>()\n const taken = (id: string) => objects.has(id) || impls.has(id)\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Events\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const emit = (e: DestructionEvent) => {\n cur.push(e)\n options.onEvent?.(e)\n const all = listeners.get('*')\n if (all) for (const fn of [...all]) fn(e)\n const typed = listeners.get(e.type)\n if (typed) for (const fn of [...typed]) fn(e)\n }\n const base = (o: ObjRT, source?: string): { object: string; time: number; source?: string } =>\n source === undefined ? { object: o.id, time } : { object: o.id, time, source }\n\n const pendingCollapse = new Map<ObjRT, string | undefined>()\n let runDepth = 0\n\n /** Blasts queued by parts that exploded; each can prime or set off more parts. It ends: a part goes off once and is primed once, so the queue only grows by parts not yet lost. */\n const drainBlasts = () => {\n for (let blast = blasts.shift(); blast; blast = blasts.shift()) blastWorld(blast.point, blast.energy, blast.radius, blast.source)\n }\n\n const run = <T>(fn: () => T): { value: T; events: DestructionEvent[] } => {\n const prev = cur\n const mine: DestructionEvent[] = []\n cur = mine\n runDepth++\n try {\n const value = fn()\n drainBlasts()\n if (runDepth === 1) flushCollapse()\n return { value, events: mine }\n } finally {\n runDepth--\n cur = prev\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Building objects\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const nextId = () => {\n let id: string\n do id = `obj_${++counter}`\n while (taken(id))\n return id\n }\n\n const freshRuntime = (): PartRuntime => ({ meltEmitted: 0, dripT: 0, prevTemp: ambient, shockT: 0, jet: false })\n\n const resolveSpec = (spec: DestructibleSpec): DestructibleSpec => {\n const out = clone(spec)\n const joints = out.joints ?? inferJoints(out.parts, 0.01, materials)\n const structural = (id: string) => {\n const role = out.parts.find((p) => p.id === id)?.structure?.role\n return role !== undefined && role !== 'none'\n }\n out.joints = joints.map((j) => {\n const def = JOINT_DEFAULTS[j.kind]\n return {\n id: j.id ?? `${j.a}~${j.b}`, a: j.a, b: j.b, kind: j.kind, strength: j.strength ?? def.strength, tools: j.tools ?? [...def.tools], seconds: j.seconds ?? def.seconds,\n bears: j.bears ?? (structural(j.a) && structural(j.b)),\n }\n })\n return out\n }\n\n const build = (spec: DestructibleSpec, id: string, pos: Vec3, rot: Quat, carry?: Carry): ObjRT => {\n const st: ObjectState = { id, position: [pos[0], pos[1], pos[2]], rotation: [rot[0], rot[1], rot[2], rot[3]], parts: [], joints: [], groups: [], destroyed: false }\n if (spec.name !== undefined) st.name = spec.name\n const o: ObjRT = {\n id, spec, st, parts: [], byId: new Map(), idx: new Map(), joints: [], jointMap: new Map(), byPart: new Map(), bc: [0, 0, 0], br: 0, active: false, tmp: [], hasStructure: false, dirty: false, maxStress: 0, collapsed: new Set(carry?.collapsed ?? []), unsup: [], anyAnchor: false, order: ++orderCounter,\n }\n for (const ps of spec.parts) {\n if (o.byId.has(ps.id)) throw new Error(`duplicate part id \"${ps.id}\"`)\n const mat = materials.get(ps.material)\n if (!mat) throw new Error(`unknown material \"${ps.material}\" on part \"${ps.id}\"`)\n const mass0 = partMass(ps, mat)\n const maxHp = Math.max(1, ps.hp ?? mass0 * mat.hpPerKg)\n const fuel0 = mat.thermal.ignitionC !== undefined ? mass0 * (mat.thermal.fuelFraction ?? 0) : 0\n const c = carry?.parts.get(ps.id)\n const pst: PartState = c?.st ?? {\n id: ps.id, material: ps.material, status: 'intact', hp: maxHp, maxHp, mass: mass0, temperature: ambient, burning: false, fuel: fuel0, char: 0, melt: 0,\n dents: [], holes: [], cracks: [], group: 0,\n }\n if (!c && ps.contains) pst.liters = ps.contains.liters\n const p: PartRT = {\n spec: ps, mat, st: pst, q: quatFromEuler(...(ps.rotation ?? [0, 0, 0])), pos: [ps.position[0], ps.position[1], ps.position[2]], mass0, fuel0, area: shapeArea(ps.shape), thickness: partThickness(ps), cutFactor: cutFactorOf(ps.shape),\n dims: shapeDims(ps.shape), bound: shapeBound(ps.shape), rt: c?.rt ?? { ...freshRuntime(), prevTemp: pst.temperature },\n structural: !!ps.structure && ps.structure.role !== 'none', anchored: !!ps.anchored || ps.structure?.role === 'foundation', cap: ps.structure ? partCapacity(ps, mat) : 0,\n }\n if (p.structural) o.hasStructure = true\n if (p.rt.chainDue !== undefined && !isLost(p)) primed.set(p, o)\n o.idx.set(ps.id, o.parts.length)\n o.parts.push(p)\n o.byId.set(ps.id, p)\n o.st.parts.push(pst)\n o.byPart.set(ps.id, [])\n }\n for (const js of spec.joints ?? []) {\n const r = js as Required<JointSpec>\n const ia = o.idx.get(r.a), ib = o.idx.get(r.b)\n if (ia === undefined || ib === undefined) throw new Error(`joint \"${r.id}\" references an unknown part`)\n if (o.jointMap.has(r.id)) throw new Error(`duplicate joint id \"${r.id}\"`)\n const pa = o.parts[ia], pb = o.parts[ib]\n const A = aabbOf(pa.spec.shape, pa.spec.position, pa.q)\n const B = aabbOf(pb.spec.shape, pb.spec.position, pb.q)\n const pos: Vec3 = [0, 0, 0]\n for (let k = 0; k < 3; k++) pos[k] = (Math.max(A.min[k], B.min[k]) + Math.min(A.max[k], B.max[k])) / 2\n const bears: JointRT['bears'] = r.bears ?? (pa.structural && pb.structural)\n const c = carry?.joints.get(r.id)\n const jst: JointState = c?.st ?? { id: r.id, a: r.a, b: r.b, kind: r.kind, hp: r.strength, maxHp: r.strength, progress: 0, open: false }\n const j: JointRT = { spec: r, st: jst, ia, ib, bears, pos, step: c?.step ?? 0 }\n o.joints.push(j)\n o.jointMap.set(r.id, j)\n o.byPart.get(r.a)!.push(j)\n o.byPart.get(r.b)!.push(j)\n o.st.joints.push(jst)\n }\n // open joints whose parts are no longer both here (left behind by `splitGroup`) stay listed, inert, so callers still see them open\n for (const [jid, c] of carry?.joints ?? []) if (c.st.open && !o.jointMap.has(jid)) o.st.joints.push(c.st)\n updateBound(o)\n o.anyAnchor = o.parts.some((p) => p.anchored)\n o.unsup = o.parts.map(() => false)\n solveStructure(o)\n recomputeGroups(o)\n o.st.destroyed = o.parts.length > 0 && o.parts.every(isLost)\n o.active = o.maxStress > 0.8 || o.parts.some((p) => p.st.burning || p.st.temperature > ambient + 0.5 || (p.st.liters ?? 0) > 0)\n return o\n }\n\n const recomputeGroups = (o: ObjRT) => {\n const n = o.parts.length\n const parent = Array.from({ length: n }, (_, i) => i)\n const find = (i: number): number => {\n while (parent[i] !== i) {\n parent[i] = parent[parent[i]]\n i = parent[i]\n }\n return i\n }\n const union = (a: number, b: number) => {\n parent[find(a)] = find(b)\n }\n const live = (j: JointRT) => !j.st.open && !isLost(o.parts[j.ia]) && !isLost(o.parts[j.ib])\n if (o.unsup.some(Boolean)) {\n // parts that lost every support fall: cut them from the supported pieces; loose non-structural parts follow the part they hang on\n for (const j of o.joints) if (live(j) && !o.unsup[j.ia] && !o.unsup[j.ib]) union(j.ia, j.ib)\n const supported = new Set<number>()\n for (let i = 0; i < n; i++) if (!isLost(o.parts[i]) && !o.unsup[i] && (o.parts[i].structural || o.parts[i].anchored)) supported.add(find(i))\n for (const j of o.joints) {\n if (!live(j) || !(o.unsup[j.ia] || o.unsup[j.ib])) continue\n if (o.unsup[j.ia] && o.unsup[j.ib]) union(j.ia, j.ib)\n else {\n const u = o.unsup[j.ia] ? j.ia : j.ib\n const other = u === j.ia ? j.ib : j.ia\n if (!o.parts[other].structural && !supported.has(find(other))) union(u, other)\n }\n }\n } else for (const j of o.joints) if (live(j)) union(j.ia, j.ib)\n const comps = new Map<number, number[]>()\n for (let i = 0; i < n; i++) {\n if (isLost(o.parts[i])) continue\n const r = find(i)\n const l = comps.get(r)\n if (l) l.push(i)\n else comps.set(r, [i])\n }\n const list = [...comps.values()].map((ix) => ({\n ix,\n anchored: ix.some((i) => o.parts[i].anchored),\n mass: ix.reduce((s, i) => s + o.parts[i].st.mass, 0),\n }))\n list.sort((a, b) => (a.anchored === b.anchored ? (b.mass - a.mass) || (a.ix[0] - b.ix[0]) : a.anchored ? -1 : 1))\n o.st.groups = list.map((g) => g.ix.map((i) => o.parts[i].spec.id))\n for (const p of o.parts) if (isLost(p)) p.st.group = -1\n list.forEach((g, gi) => g.ix.forEach((i) => (o.parts[i].st.group = gi)))\n }\n\n /** Which part `r` rests on over joint `j` (index), or -1 when the joint does not let `r` rest on its other end. */\n const restsOn = (j: JointRT, r: number): number => {\n const b = j.bears\n if (!b) return -1\n if (b === true) return j.ia === r ? j.ib : j.ia\n if (b === 'a_on_b') return j.ia === r ? j.ib : -1\n return j.ib === r ? j.ia : -1\n }\n\n /** Distribute own mass plus carried load down the bearing graph to the anchored parts; mark parts without any support path. */\n const solveStructure = (o: ObjRT) => {\n o.maxStress = 0\n if (!o.hasStructure) return\n const parts = o.parts\n const n = parts.length\n const dist = new Array<number>(n).fill(-1)\n const queue: number[] = []\n const ok = (i: number) => parts[i].structural && !isLost(parts[i])\n const isPartition = (i: number) => parts[i].spec.structure?.role === 'partition'\n for (let i = 0; i < n; i++) if (ok(i) && parts[i].anchored) {\n dist[i] = 0\n queue.push(i)\n }\n for (let h = 0; h < queue.length; h++) {\n const s = queue[h]\n if (isPartition(s)) continue\n for (const j of o.byPart.get(parts[s].spec.id)!) {\n if (j.st.open || !j.bears) continue\n const r = j.ia === s ? j.ib : j.ia\n if (dist[r] >= 0 || !ok(r) || restsOn(j, r) !== s) continue\n dist[r] = dist[s] + 1\n queue.push(r)\n }\n }\n const incoming = new Array<number>(n).fill(0)\n for (let h = queue.length - 1; h >= 0; h--) {\n const i = queue[h]\n const total = parts[i].st.mass + incoming[i]\n parts[i].st.load = total\n const lower: number[] = []\n for (const j of o.byPart.get(parts[i].spec.id)!) {\n if (j.st.open || !j.bears) continue\n const k = restsOn(j, i)\n if (k >= 0 && dist[k] >= 0 && dist[k] < dist[i] && !isPartition(k)) lower.push(k)\n }\n for (const k of lower) incoming[k] += total / lower.length\n }\n for (let i = 0; i < n; i++) {\n const p = parts[i]\n o.unsup[i] = false\n if (!p.structural) continue\n if (dist[i] < 0 || isLost(p)) {\n p.st.load = p.st.mass\n p.st.stress = 0\n o.unsup[i] = o.anyAnchor && !isLost(p)\n continue\n }\n p.st.stress = p.st.load! / p.cap\n if (p.st.stress > o.maxStress) o.maxStress = p.st.stress\n }\n if (o.maxStress > 0.8) o.active = true\n }\n\n /**\n * Ask for a collapse report. It is not computed right away: a blow can break several parts in one go (a column and the roof's supports, or a\n * column whose joint opens just before the column itself fractures), so the groups are examined once, after every loss of the operation.\n */\n const collapseCheck = (o: ObjRT, src?: string) => {\n if (!o.hasStructure || !o.parts.some((p) => p.anchored)) return\n if (!pendingCollapse.has(o)) pendingCollapse.set(o, src)\n }\n\n /** Report the groups of remaining structural parts that lost every anchor (each part is reported once). */\n const flushCollapse = () => {\n for (const [o, src] of [...pendingCollapse]) {\n pendingCollapse.delete(o)\n if (!objects.has(o.id) || objects.get(o.id) !== o) continue\n for (const g of o.st.groups) {\n const ps = g.map((id) => o.byId.get(id)!).filter((p) => !isLost(p) && !o.collapsed.has(p.spec.id))\n if (ps.length === 0 || g.some((id) => o.byId.get(id)!.anchored) || !ps.some((p) => p.structural)) continue\n for (const p of ps) {\n o.collapsed.add(p.spec.id)\n p.st.status = 'collapsed'\n }\n emit({ ...base(o, src), type: 'collapse', parts: ps.map((p) => p.spec.id), mass: ps.reduce((sum, p) => sum + p.st.mass, 0) })\n }\n }\n }\n\n const getObj = (id: string): ObjRT => {\n const o = objects.get(id)\n if (!o) throw new Error(`unknown object \"${id}\"`)\n return o\n }\n const getPart = (o: ObjRT, id: string): PartRT => {\n const p = o.byId.get(id)\n if (!p) throw new Error(`unknown part \"${id}\" in object \"${o.id}\"`)\n return p\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Geometry in world space\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const partXf = (o: ObjRT, p: PartRT): { c: Vec3; q: Quat } => ({ c: toWorld(o.st.position, o.st.rotation, p.pos), q: quat.mul(o.st.rotation, p.q) })\n const objLocal = (o: ObjRT, w: Vec3) => toLocal(o.st.position, o.st.rotation, w)\n const objLocalDir = (o: ObjRT, w: Vec3) => rotateVec(quat.conjugate(o.st.rotation), w)\n const jointWorld = (o: ObjRT, j: JointRT) => toWorld(o.st.position, o.st.rotation, j.pos)\n const distToPart = (o: ObjRT, p: PartRT, w: Vec3) => {\n const { c, q } = partXf(o, p)\n return distanceToShape(p.spec.shape, toLocal(c, q, w))\n }\n const partWorldAabb = (o: ObjRT, p: PartRT) => {\n const { c, q } = partXf(o, p)\n return aabbOf(p.spec.shape, c, q)\n }\n\n interface PartRay { t0: number; t1: number; n: Vec3 }\n const rayPartRaw = (pos: Vec3, rot: Quat, spec: PartSpec, pq: Quat, origin: Vec3, d: Vec3, lp: Vec3 = spec.position): PartRay | null => {\n const c = toWorld(pos, rot, lp)\n const q = quat.mul(rot, pq)\n const qi = quat.conjugate(q)\n const r = rayShape(spec.shape, rotateVec(qi, vec.sub(origin, c)), rotateVec(qi, d))\n return r ? { t0: r.t0, t1: r.t1, n: rotateVec(q, r.n0) } : null\n }\n const rayPart = (o: ObjRT, p: PartRT, origin: Vec3, d: Vec3): PartRay | null => rayPartRaw(o.st.position, o.st.rotation, p.spec, p.q, origin, d, p.pos)\n\n const raySphereMiss = (origin: Vec3, d: Vec3, c: Vec3, r: number, maxDist: number): boolean => {\n const oc = vec.sub(origin, c)\n const b = vec.dot(oc, d)\n const cc = vec.dot(oc, oc) - r * r\n if (cc > 0 && b > 0) return true\n const disc = b * b - cc\n if (disc < 0) return true\n return -b - Math.sqrt(disc) > maxDist\n }\n\n const raycastInternal = (origin: Vec3, dir: Vec3, maxDist: number, ignore?: Set<string>): (RayHit & { pathLen: number }) | null => {\n const d = vec.normalize(dir)\n let best: (RayHit & { pathLen: number }) | null = null\n for (const o of objects.values()) {\n if (raySphereMiss(origin, d, toWorld(o.st.position, o.st.rotation, o.bc), o.br, best ? Math.min(maxDist, best.distance) : maxDist)) continue\n for (const p of o.parts) {\n if (isLost(p) || ignore?.has(`${o.id}\\0${p.spec.id}`)) continue\n const r = rayPart(o, p, origin, d)\n if (!r || r.t0 < 0 || r.t0 > maxDist) continue\n if (!best || r.t0 < best.distance) best = { object: o.id, part: p.spec.id, point: vec.madd(origin, d, r.t0), normal: r.n, distance: r.t0, pathLen: r.t1 - r.t0 }\n }\n }\n for (const im of impls.values()) {\n for (const ps of im.impl.describe().parts) {\n if (ignore?.has(`${im.impl.id}\\0${ps.id}`)) continue\n const ov = im.poses.get(ps.id)\n const r = rayPartRaw(im.position, im.rotation, ps, ov?.q ?? quatFromEuler(...(ps.rotation ?? [0, 0, 0])), origin, d, ov?.pos)\n if (!r || r.t0 < 0 || r.t0 > maxDist) continue\n if (!best || r.t0 < best.distance) best = { object: im.impl.id, part: ps.id, point: vec.madd(origin, d, r.t0), normal: r.n, distance: r.t0, pathLen: r.t1 - r.t0 }\n }\n }\n return best\n }\n\n // impl hosting\n const implHit = (im: ImplRT, hit: Hit): HitResult => {\n let h = hit\n if (hit.space === 'local') {\n h = { ...hit, space: 'world', point: toWorld(im.position, im.rotation, hit.point) }\n if (hit.direction) h.direction = rotateVec(im.rotation, hit.direction)\n }\n const start = cur.length\n for (const e of im.impl.hit(h) ?? []) emit(e.time === undefined ? { ...e, time } : e)\n const mine = cur.slice(start)\n const res: HitResult = { object: im.impl.id, damage: 0, penetrated: false, exitEnergy: 0, events: mine, point: hit.point }\n for (const e of mine) {\n if (e.type === 'damage') res.damage += e.amount\n if (e.type === 'hole' && e.hole.through) res.penetrated = true\n if (res.part === undefined && 'part' in e) res.part = (e as { part: string }).part\n }\n return res\n }\n\n const implJointPos = (im: ImplRT, a: string, b: string): Vec3 | null => {\n const parts = im.impl.describe().parts\n const pa = parts.find((p) => p.id === a), pb = parts.find((p) => p.id === b)\n if (!pa || !pb) return null\n const A = aabbOf(pa.shape, pa.position, quatFromEuler(...(pa.rotation ?? [0, 0, 0])))\n const B = aabbOf(pb.shape, pb.position, quatFromEuler(...(pb.rotation ?? [0, 0, 0])))\n const pos: Vec3 = [0, 0, 0]\n for (let k = 0; k < 3; k++) pos[k] = (Math.max(A.min[k], B.min[k]) + Math.min(A.max[k], B.max[k])) / 2\n return toWorld(im.position, im.rotation, pos)\n }\n\n /** Find the part a hit lands on: a short ray along `dir`, else the nearest part within `tol`. */\n const locate = (o: ObjRT, point: Vec3, dir: Vec3 | undefined, tol: number, only?: PartRT): Loc | null => {\n const cands = only ? [only] : o.parts\n if (dir && vec.length(dir) > 1e-9) {\n const d = vec.normalize(dir)\n const origin = vec.madd(point, d, -0.05)\n let best: Loc | null = null\n let bestT = Infinity\n let inside: Loc | null = null\n for (const p of cands) {\n if (isLost(p)) continue\n const r = rayPart(o, p, origin, d)\n if (!r) continue\n if (r.t0 >= 0 && r.t0 <= 0.15) {\n if (r.t0 < bestT) {\n bestT = r.t0\n best = { p, point: vec.madd(origin, d, r.t0), normal: r.n, dir: d, pathLen: Math.max(r.t1 - r.t0, 1e-4) }\n }\n } else if (r.t0 < 0 && r.t1 > 0 && !inside) {\n inside = { p, point, normal: vec.scale(d, -1), dir: d, pathLen: Math.max(r.t1 - 0.05, p.thickness) }\n }\n }\n if (best) return best\n if (inside) return inside\n }\n let np: PartRT | null = null\n let nd = Infinity\n for (const p of cands) {\n if (isLost(p)) continue\n const dd = distToPart(o, p, point)\n if (dd < nd) {\n nd = dd\n np = p\n }\n }\n if (!np || nd > tol) return null\n const { c, q } = partXf(o, np)\n const sp = surfacePoint(np.spec.shape, toLocal(c, q, point))\n const normal = rotateVec(q, sp.normal)\n return { p: np, point: toWorld(c, q, sp.point), normal, dir: dir && vec.length(dir) > 1e-9 ? vec.normalize(dir) : vec.scale(normal, -1), pathLen: np.thickness }\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Marks on parts\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const markDamaged = (p: PartRT) => {\n if (p.st.status === 'intact') p.st.status = 'damaged'\n }\n\n const addDent = (o: ObjRT, p: PartRT, wp: Vec3, wn: Vec3, radius: number, depth: number, src?: string) => {\n const dent: Dent = { point: objLocal(o, wp), normal: objLocalDir(o, wn), radius, depth }\n const arr = p.st.dents\n let ni = -1, nd = Infinity\n for (let i = 0; i < arr.length; i++) {\n const dd = vec.distance(arr[i].point, dent.point)\n if (dd < nd) {\n nd = dd\n ni = i\n }\n }\n if (ni >= 0 && (arr.length >= maxDents || nd < arr[ni].radius * 0.6)) {\n arr[ni].depth = Math.min(0.1, Math.max(arr[ni].depth, depth) + depth * 0.3)\n arr[ni].radius = Math.max(arr[ni].radius, radius)\n } else arr.push(dent)\n markDamaged(p)\n emit({ ...base(o, src), type: 'dent', part: p.spec.id, dent, worldPoint: wp })\n }\n\n const addHole = (o: ObjRT, p: PartRT, wp: Vec3, wn: Vec3, diameter: number, through: boolean, exit?: Vec3, src?: string) => {\n const hole: Hole = { point: objLocal(o, wp), normal: objLocalDir(o, wn), diameter, through }\n p.st.holes.push(hole)\n if (p.st.holes.length > maxHoles) p.st.holes.shift()\n markDamaged(p)\n emit({ ...base(o, src), type: 'hole', part: p.spec.id, hole, worldPoint: wp, ...(exit ? { exitPoint: exit } : {}) })\n return hole\n }\n\n const addCrack = (o: ObjRT, p: PartRT, wp: Vec3, wn: Vec3, length: number, src?: string) => {\n const crack: Crack = { point: objLocal(o, wp), normal: objLocalDir(o, wn), length: Math.min(length, Math.max(p.bound, 0.05)), rays: 5 + Math.floor(rnd() * 5) }\n p.st.cracks.push(crack)\n if (p.st.cracks.length > 16) p.st.cracks.shift()\n markDamaged(p)\n emit({ ...base(o, src), type: 'crack', part: p.spec.id, crack, worldPoint: wp })\n }\n\n const debris = (o: ObjRT, p: PartRT, kind: DebrisKind, point: Vec3, normal: Vec3, count: number, speed: number, src?: string) =>\n emit({ ...base(o, src), type: 'debris', part: p.spec.id, kind, point, normal, count, speed })\n\n const holeRate = (hole: Hole, pressurized: boolean) => (pressurized ? 0.5 : 0.1) * (hole.diameter / 0.009)\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Failure, joints\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const detachEvents = (o: ObjRT, opened: JointRT[], by: 'break' | 'tool' | 'part_lost', src?: string) => {\n for (const j of opened) emit({ ...base(o, src), type: 'detach', joint: j.spec.id, parts: [j.spec.a, j.spec.b], by, groups: o.st.groups.map((g) => [...g]) })\n }\n\n const checkDestroyed = (o: ObjRT, src?: string) => {\n if (!o.st.destroyed && o.parts.length > 0 && o.parts.every(isLost)) {\n o.st.destroyed = true\n emit({ ...base(o, src), type: 'destroyed' })\n }\n }\n\n const partLost = (o: ObjRT, p: PartRT, src?: string) => {\n const opened: JointRT[] = []\n for (const j of o.byPart.get(p.spec.id) ?? []) {\n if (j.st.open) continue\n j.st.open = true\n j.st.openedBy = 'part_lost'\n opened.push(j)\n }\n solveStructure(o)\n recomputeGroups(o)\n detachEvents(o, opened, 'part_lost', src)\n collapseCheck(o, src)\n checkDestroyed(o, src)\n }\n\n /**\n * Distance from a world point to the joint's contact region: the overlap box of the two parts' bounds (or, when they only nearly touch, the box\n * of the gap between them). Measuring to the joint centre would make a thick part untouchable: a blow on a trunk's surface is half the trunk's\n * width away from a joint that sits on its axis.\n */\n const jointReach = (o: ObjRT, j: JointRT, point: Vec3): number => {\n const A = partWorldAabb(o, o.parts[j.ia]), B = partWorldAabb(o, o.parts[j.ib])\n let d2 = 0\n for (let k = 0; k < 3; k++) {\n const lo = Math.min(Math.max(A.min[k], B.min[k]), Math.min(A.max[k], B.max[k]))\n const hi = Math.max(Math.max(A.min[k], B.min[k]), Math.min(A.max[k], B.max[k]))\n const d = point[k] < lo ? lo - point[k] : point[k] > hi ? point[k] - hi : 0\n d2 += d * d\n }\n return Math.sqrt(d2)\n }\n /** How far from the contact region a blow still counts: half the smallest dimension of the smaller part, at least 6 cm. */\n const jointReachLimit = (o: ObjRT, j: JointRT): number => {\n const pa = o.parts[j.ia], pb = o.parts[j.ib]\n const small = pa.dims[0] * pa.dims[1] * pa.dims[2] <= pb.dims[0] * pb.dims[1] * pb.dims[2] ? pa : pb\n return Math.max(0.06, 0.5 * Math.min(small.dims[0], small.dims[1], small.dims[2]))\n }\n\n const wearJoints = (o: ObjRT, p: PartRT, amount: number, near?: Vec3, radius = 0.06, src?: string, split = false) => {\n if (amount <= 0) return\n const mine = (o.byPart.get(p.spec.id) ?? []).filter((j) => !j.st.open)\n if (split && mine.length) amount /= mine.length\n for (const j of mine) {\n if (j.st.open) continue\n if (near && jointReach(o, j, near) > Math.max(radius, jointReachLimit(o, j))) continue\n j.st.hp -= amount\n if (j.st.hp <= 0) {\n j.st.hp = 0\n j.st.open = true\n j.st.openedBy = 'break'\n solveStructure(o)\n recomputeGroups(o)\n detachEvents(o, [j], 'break', src)\n collapseCheck(o, src)\n }\n }\n }\n\n /** Part hit points reached 0 (or it was forced to explode): fragments, debris, joints open. */\n const failPart = (o: ObjRT, p: PartRT, origin: Vec3 | null, dir: Vec3 | null, fragEnergy: number, cap: number, src?: string) => {\n if (isLost(p)) return\n const ex = p.spec.explodes\n const style = p.mat.fracture === 'none' ? 'snap' : p.mat.fracture\n const { c, q } = partXf(o, p)\n const hitW = origin ?? c\n const grain = p.spec.grain ? AXIS[p.spec.grain] : undefined\n const plan = planFragments({\n style, dims: p.dims, thickness: p.thickness, grain, hit: toLocal(c, q, hitW), fragmentSize: p.mat.fragmentSize ?? [0.04, 0.2], maxFragments, rnd,\n })\n const mass = p.st.mass\n const totW = plan.reduce((s, f) => s + f.weight, 0) || 1\n const energy = ex ? ex.energy * 0.2 : fragEnergy\n const speed = clamp(Math.sqrt((2 * energy) / Math.max(mass, 0.05)), 0.3, ex ? 40 : cap)\n const fragments: Fragment[] = plan.map((f, i) => {\n const cw = toWorld(c, q, f.center)\n const out = vec.normalize(vec.sub(cw, hitW), [0, 1, 0])\n const dv = dir ? vec.normalize(vec.madd(out, dir, 0.6)) : out\n const k = speed * (0.6 + 0.8 * rnd())\n return {\n id: `${p.spec.id}#${i}`, part: p.spec.id, material: p.spec.material, shape: f.shape, center: cw, size: f.size, rotation: quat.mul(q, f.q),\n velocity: [dv[0] * k, dv[1] * k + 0.5 * rnd(), dv[2] * k],\n angularVelocity: [(rnd() - 0.5) * 12, (rnd() - 0.5) * 12, (rnd() - 0.5) * 12],\n mass: (mass * f.weight) / totW,\n }\n })\n p.st.status = 'broken'\n p.st.hp = 0\n p.st.mass = 0\n p.st.burning = false\n p.rt.jet = false\n emit({ ...base(o, src), type: 'fracture', part: p.spec.id, style, fragments, point: hitW })\n debris(o, p, p.mat.breakDebris, c, [0, 1, 0], clamp(Math.round(Math.cbrt(partVolume(p.spec.shape)) * 30), 3, 20), 2, src)\n if (ex) {\n emit({ ...base(o, src), type: 'explode', part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius })\n blasts.push({ point: c, energy: ex.energy, radius: ex.radius, source: src })\n }\n partLost(o, p, src)\n }\n\n /**\n * Sets an explosive part off from outside (`explodes.chain`): it will explode after the delay of `trigger`, once. The delay is one draw\n * from the world seed, so the same inputs give the same order of blasts.\n */\n const prime = (o: ObjRT, p: PartRT, trigger: ChainTrigger, src?: string) => {\n const spec = chainDelayOf(p.spec, trigger)\n if (spec === undefined || isLost(p) || p.rt.chainDue !== undefined) return\n const delay = drawChainDelay(spec, rnd)\n p.rt.chainDue = time + delay\n primed.set(p, o)\n o.active = true\n emit({ ...base(o, src), type: 'primed', part: p.spec.id, point: partXf(o, p).c, trigger, delay })\n }\n\n const CHAIN_TRIGGER_OF: Partial<Record<DamageType, ChainTrigger>> = { ballistic: 'shot', explosive: 'explosion' }\n\n /** Remove hit points. Returns the amount actually removed. */\n const applyDamage = (o: ObjRT, p: PartRT, amount: number, type: DamageType, origin: Vec3 | null, dir: Vec3 | null, fragEnergy: number, cap: number, src?: string): number => {\n if (isLost(p) || amount <= 0) return 0\n const prev = p.st.hp\n p.st.hp -= amount\n markDamaged(p)\n const trigger = CHAIN_TRIGGER_OF[type]\n const chained = trigger !== undefined && chainDelayOf(p.spec, trigger) !== undefined\n // a bullet or a blast sets a chained part off after its delay instead of tearing it apart on the spot\n if (chained && p.st.hp <= 0 && p.rt.chainDue === undefined) p.st.hp = Math.min(prev, 1)\n if (p.st.hp <= 0 && p.mat.fracture === 'none' && !p.spec.explodes) p.st.hp = Math.min(prev, 1)\n const done = prev - p.st.hp\n if (done > 0) emit({ ...base(o, src), type: 'damage', part: p.spec.id, amount: done, hp: Math.max(0, p.st.hp), damageType: type })\n if (p.st.hp <= 0) failPart(o, p, origin, dir, fragEnergy, cap, src)\n else if (chained && (trigger === 'explosion' || 1 - p.st.hp / p.st.maxHp >= shotDamageFractionOf(p.spec))) prime(o, p, trigger, src)\n return done\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Hits\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n interface BallisticOut { penetrated: boolean; exitEnergy: number; exitPoint?: Vec3; damage: number }\n\n const ballistic = (o: ObjRT, p: PartRT, entry: Vec3, n: Vec3, d: Vec3, E: number, caliber: number, pathLen: number, src?: string): BallisticOut => {\n const mat = p.mat\n const sin = Math.min(1, Math.abs(vec.dot(d, n)))\n const angle = (Math.asin(sin) * 180) / Math.PI\n const effM = p.thickness / Math.max(sin, 0.3)\n const thr = mat.penetration * effM * 1000\n const penetrated = E > thr\n // a thin brittle shell that shatters (a pane, a bottle) is lost to one bullet that a thick block of the same glass shrugs off: the same\n // fragility factor that melee uses for blunt hits (1 for ductile materials and for shells 2 cm or thicker, up to x118 for 3 mm glass)\n const scale = (mat.damageScale?.ballistic ?? 1) * (mat.fracture === 'shatter' ? fragility(mat.ductility, p.thickness) : 1)\n const id = p.spec.id\n if (!penetrated && mat.ricochetDeg && angle < mat.ricochetDeg) {\n const r = vec.sub(d, vec.scale(n, 2 * vec.dot(d, n)))\n emit({ ...base(o, src), type: 'ricochet', part: id, point: entry, direction: vec.normalize(r), energy: E * 0.4 })\n debris(o, p, mat.hitDebris, entry, n, 3, 3, src)\n const dmg = applyDamage(o, p, E * DMG_PER_J * scale * 0.2, 'ballistic', entry, d, E * 0.1, 12, src)\n return { penetrated: false, exitEnergy: 0, damage: dmg }\n }\n const brittle = mat.ductility < 0.3\n const ratio = E / Math.max(thr, 1e-6)\n const crackLen = clamp(0.03 + ratio * 0.2, 0.03, 0.8)\n let exitPoint: Vec3 | undefined\n if (penetrated) {\n exitPoint = vec.madd(entry, d, Math.min(pathLen, effM))\n const hole = addHole(o, p, entry, n, (caliber / 1000) * (mat.ductility >= 0.3 ? 1 : 1.5), true, exitPoint, src)\n if (brittle && mat.fracture === 'shatter') addCrack(o, p, entry, n, crackLen, src)\n if (p.spec.contains && (p.st.liters ?? 0) > 0) {\n emit({\n ...base(o, src), type: 'leak', part: id, fluid: p.spec.contains.fluid, point: entry, direction: n, rate: holeRate(hole, !!p.spec.contains.pressurized),\n pressurized: !!p.spec.contains.pressurized,\n })\n }\n } else if (mat.ductility >= 0.5) {\n addDent(o, p, entry, n, Math.max((caliber * 3) / 1000, 0.012), clamp(Math.min(Math.max(p.thickness * 3, 0.003), ratio * 0.01), 0.001, 0.05), src)\n } else if (brittle) {\n addCrack(o, p, entry, n, crackLen, src)\n if (mat.fracture !== 'shatter') addHole(o, p, entry, n, caliber / 1000, false, undefined, src)\n } else addHole(o, p, entry, n, caliber / 1000, false, undefined, src)\n debris(o, p, mat.hitDebris, entry, n, clamp(Math.round(E / 60) + 2, 2, 14), clamp(Math.sqrt(E) / 6, 1, 8), src)\n // a bullet only wears the joints of the part it hits, by the energy the part absorbed (a through-and-through shot transfers little)\n wearJoints(o, p, (penetrated ? thr : E) * 0.02, undefined, 0, src, true)\n const dmg = applyDamage(o, p, E * DMG_PER_J * scale, 'ballistic', entry, d, E * 0.1, 12, src)\n return { penetrated, exitEnergy: penetrated ? E - thr : 0, exitPoint, damage: dmg }\n }\n\n const melee = (o: ObjRT, p: PartRT, kind: 'blunt' | 'slash', E: number, point: Vec3, n: Vec3, d: Vec3, contactR: number, src?: string): number => {\n const mat = p.mat\n const thrMm = mat.penetration * p.thickness * 1000\n // brittle thin shells (a bottle, a mug, a pane) break from a knock that a thick block shrugs off\n const fragile = kind === 'blunt' ? fragility(mat.ductility, p.thickness) : 1\n const Ec = E * fragile\n if (E > 0) {\n if (kind === 'blunt') {\n if (mat.ductility >= 0.5) addDent(o, p, point, n, Math.max(contactR, 0.015), clamp(E * 0.0001, 0.001, 0.06), src)\n else if (mat.ductility < 0.3) {\n if (Ec >= 5) addCrack(o, p, point, n, clamp(0.04 + Math.min(Ec, E * 6) * 0.0008, 0.04, 0.6), src)\n } else if (E >= thrMm * 0.2) addDent(o, p, point, n, Math.max(contactR, 0.015), clamp(E * 0.00006, 0.001, 0.04), src)\n } else if (mat.fracture === 'tear') {\n addHole(o, p, point, n, clamp(0.02 + E * 0.0005, 0.02, 0.3), true, undefined, src)\n } else if (mat.ductility >= 0.5) {\n addDent(o, p, point, n, Math.max(contactR, 0.01), clamp(E * 0.00004, 0.0005, 0.02), src)\n }\n debris(o, p, mat.hitDebris, point, n, clamp(Math.round(E / 25) + 1, 1, 10), clamp(Math.sqrt(E) / 8, 1, 6), src)\n }\n if (kind === 'blunt') wearJoints(o, p, E * 0.3, undefined, 0, src)\n else wearJoints(o, p, E * 0.3, point, 0.06, src)\n const scale = mat.damageScale?.[kind] ?? 1\n return applyDamage(o, p, Ec * DMG_PER_J * scale * (kind === 'slash' ? p.cutFactor : 1), kind, point, d, E * 0.1, 12, src)\n }\n\n const blastObject = (o: ObjRT, point: Vec3, energy: number, radius: number, src?: string): HitResult => {\n const start = cur.length\n const res: HitResult = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] }\n for (const p of o.parts) {\n if (isLost(p)) continue\n const { c, q } = partXf(o, p)\n const lp = toLocal(c, q, point)\n const dist = distanceToShape(p.spec.shape, lp)\n if (dist >= radius) continue\n const f = (1 - dist / radius) ** 2\n const Ein = energy * f * BLAST_COUPLING\n const sp = surfacePoint(p.spec.shape, lp)\n const wp = toWorld(c, q, sp.point)\n const wn = rotateVec(q, sp.normal)\n if (!res.part) {\n res.part = p.spec.id\n res.point = wp\n }\n const mat = p.mat\n if (Ein > 20) {\n if (mat.ductility >= 0.5) addDent(o, p, wp, wn, clamp(0.05 + Math.sqrt(Ein) * 0.002, 0.05, 0.4), clamp(0.004 + Ein * 0.00002, 0.004, 0.08), src)\n else if (mat.ductility < 0.3 && Ein > 60) addCrack(o, p, wp, wn, clamp(0.05 + Ein * 0.0005, 0.05, 1), src)\n debris(o, p, mat.hitDebris, wp, wn, clamp(Math.round(Ein / 80) + 1, 1, 12), clamp(Math.sqrt(Ein) / 4, 2, 15), src)\n }\n const th = mat.thermal\n if (th.ignitionC !== undefined && p.st.fuel > 0) {\n p.st.temperature += 300 * f\n o.active = true\n if (f >= 0.25 && !p.st.burning) {\n p.st.temperature = Math.max(p.st.temperature, th.ignitionC + 1)\n checkIgnite(o, p, src)\n }\n }\n wearJoints(o, p, Ein * 0.5, undefined, 0, src)\n res.damage += applyDamage(o, p, Ein * DMG_PER_J * (mat.damageScale?.explosive ?? 1), 'explosive', point, null, Ein * 0.3, 40, src)\n }\n res.events = cur.slice(start)\n return res\n }\n\n const blastWorld = (point: Vec3, energy: number, radius: number, src?: string): HitResult[] => {\n const out: HitResult[] = []\n for (const o of [...objects.values()]) {\n if (vec.distance(toWorld(o.st.position, o.st.rotation, o.bc), point) - o.br >= radius) continue\n const r = blastObject(o, point, energy, radius, src)\n if (r.part) out.push(r)\n }\n for (const im of [...impls.values()]) {\n const inRange = im.impl.describe().parts.some((ps) => {\n const ov = im.poses.get(ps.id)\n const c = toWorld(im.position, im.rotation, ov?.pos ?? ps.position)\n const q = quat.mul(im.rotation, ov?.q ?? quatFromEuler(...(ps.rotation ?? [0, 0, 0])))\n return distanceToShape(ps.shape, toLocal(c, q, point)) < radius\n })\n if (inRange) out.push(implHit(im, { type: 'explosive', point, energy, radius, ...(src !== undefined ? { source: src } : {}) }))\n }\n return out\n }\n\n const heatObject = (o: ObjRT, point: Vec3, T: number, radius: number, duration: number, src?: string): HitResult => {\n const start = cur.length\n const res: HitResult = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] }\n for (const p of o.parts) {\n if (isLost(p)) continue\n const dist = distToPart(o, p, point)\n if (dist >= radius) continue\n const f = clamp(1 - dist / radius, 0.25, 1)\n if (!res.part) {\n res.part = p.spec.id\n res.point = point\n }\n if (T > p.st.temperature) {\n const k = (0.8 * f) / (p.mat.thermal.heatCapacity ?? 1)\n p.st.temperature += (T - p.st.temperature) * (1 - Math.exp(-k * duration))\n }\n o.active = true\n checkIgnite(o, p, src)\n }\n res.events = cur.slice(start)\n return res\n }\n\n const doHit = (o: ObjRT, hit: Hit, only?: PartRT): HitResult => {\n let point = hit.point\n let dir = hit.direction\n if (hit.space === 'local') {\n point = toWorld(o.st.position, o.st.rotation, point)\n if (dir) dir = rotateVec(o.st.rotation, dir)\n }\n const src = hit.source\n const start = cur.length\n let res: HitResult = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] }\n const E = hit.energy ?? 0\n if (hit.type === 'ballistic') {\n const loc = locate(o, point, dir, 0.05, only)\n if (loc) {\n const out = ballistic(o, loc.p, loc.point, loc.normal, loc.dir, E, hit.caliber ?? 9, loc.pathLen, src)\n res = { ...res, part: loc.p.spec.id, point: loc.point, damage: out.damage, penetrated: out.penetrated, exitEnergy: out.exitEnergy }\n }\n } else if (hit.type === 'blunt' || hit.type === 'slash') {\n const radius = hit.radius ?? 0\n const loc = locate(o, point, dir, Math.max(0.05, radius), only)\n if (loc) {\n res.part = loc.p.spec.id\n res.point = loc.point\n res.damage += melee(o, loc.p, hit.type, E, loc.point, loc.normal, loc.dir, radius || 0.03, src)\n if (radius > 0.1 && !only) {\n for (const p of o.parts) {\n if (p === loc.p || isLost(p)) continue\n const dd = distToPart(o, p, point)\n if (dd >= radius) continue\n const { c, q } = partXf(o, p)\n const sp = surfacePoint(p.spec.shape, toLocal(c, q, point))\n res.damage += melee(o, p, hit.type, E * (1 - dd / radius) ** 2, toWorld(c, q, sp.point), rotateVec(q, sp.normal), loc.dir, radius, src)\n }\n }\n }\n } else if (hit.type === 'explosive') {\n res = blastObject(o, point, E, hit.radius ?? 2, src)\n } else {\n res = heatObject(o, point, hit.temperature ?? 800, hit.radius ?? 0.25, hit.duration ?? 1, src)\n }\n res.events = cur.slice(start)\n return res\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Fire, heat, melting, leaks\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const checkIgnite = (o: ObjRT, p: PartRT, src?: string) => {\n const th = p.mat.thermal\n if (isLost(p) || p.st.burning || th.ignitionC === undefined || p.st.fuel <= 0 || p.st.temperature < th.ignitionC) return\n p.st.burning = true\n p.st.temperature = Math.max(p.st.temperature, th.flameC ?? 800)\n o.active = true\n markDamaged(p)\n emit({ ...base(o, src), type: 'ignite', part: p.spec.id, point: partXf(o, p).c })\n }\n\n const syncMass = (p: PartRT) => {\n p.st.mass = Math.max(0, p.mass0 * (1 - p.st.melt) - (p.fuel0 - p.st.fuel))\n }\n\n const burnStep = (o: ObjRT, p: PartRT, dt: number) => {\n const th = p.mat.thermal\n const use = Math.min((th.burnRate ?? 0.01) * p.area * dt, p.st.fuel)\n p.st.fuel -= use\n syncMass(p)\n if (p.structural) o.dirty = true\n p.st.temperature = th.flameC ?? 800\n markDamaged(p)\n if (p.fuel0 > 0) {\n p.st.char = clamp(1 - p.st.fuel / p.fuel0, 0, 1)\n p.st.hp = Math.min(p.st.hp, Math.max(1, p.st.maxHp * (p.st.fuel / p.fuel0)))\n }\n if (p.st.fuel <= 1e-9) {\n p.st.fuel = 0\n p.st.burning = false\n p.st.char = 1\n const c = partXf(o, p).c\n if ((th.fuelFraction ?? 0) >= 0.8) {\n p.st.status = 'ashes'\n p.st.hp = 0\n p.st.mass = p.mass0 * (1 - (th.fuelFraction ?? 0))\n emit({ ...base(o), type: 'burnout', part: p.spec.id, point: c })\n debris(o, p, 'ash', c, [0, 1, 0], clamp(Math.round(Math.cbrt(partVolume(p.spec.shape)) * 30), 3, 20), 1)\n partLost(o, p)\n } else {\n emit({ ...base(o), type: 'burnout', part: p.spec.id, point: c })\n }\n }\n }\n\n const meltStep = (o: ObjRT, p: PartRT, dt: number) => {\n const th = p.mat.thermal\n if (th.meltC === undefined || p.st.temperature <= th.meltC) return\n const rate = (th.meltRate ?? 0.05) * ((p.st.temperature - th.meltC) / 100)\n p.st.melt = Math.min(1, p.st.melt + rate * dt)\n syncMass(p)\n if (p.structural) o.dirty = true\n markDamaged(p)\n p.rt.dripT += dt\n if (p.rt.dripT >= 0.25) {\n p.rt.dripT -= 0.25\n const b = partWorldAabb(o, p)\n const pt: Vec3 = [b.min[0] + (b.max[0] - b.min[0]) * (0.2 + 0.6 * rnd()), b.min[1], b.min[2] + (b.max[2] - b.min[2]) * (0.2 + 0.6 * rnd())]\n emit({ ...base(o), type: 'drip', part: p.spec.id, point: pt, material: p.mat.id })\n }\n if (p.st.melt - p.rt.meltEmitted >= 0.05 || p.st.melt >= 1) {\n p.rt.meltEmitted = p.st.melt\n emit({ ...base(o), type: 'melt', part: p.spec.id, melt: p.st.melt })\n }\n if (p.st.melt >= 1) {\n p.st.status = 'melted'\n p.st.hp = 0\n p.st.mass = 0\n p.st.burning = false\n p.rt.jet = false\n partLost(o, p)\n }\n }\n\n const stepObject = (o: ObjRT, dt: number, sources: Array<{ o: ObjRT; p: PartRT; flame: number }>) => {\n const parts = o.parts\n const T0 = o.tmp\n T0.length = parts.length\n for (let i = 0; i < parts.length; i++) T0[i] = parts[i].st.temperature\n let hot = false\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i]\n if (isLost(p)) continue\n const th = p.mat.thermal\n const hc = th.heatCapacity ?? 1\n const s = p.st\n if (p.rt.jet) {\n s.temperature = Math.max(s.temperature, 900)\n } else if (s.burning) {\n burnStep(o, p, dt)\n if (isLost(p)) continue\n }\n if (!s.burning && !p.rt.jet) {\n // conduction from hotter neighbours through closed joints, then cooling\n let dT = 0\n let maxN = s.temperature\n for (const j of o.byPart.get(p.spec.id)!) {\n if (j.st.open) continue\n const k = j.ia === i ? j.ib : j.ia\n if (isLost(parts[k]) || T0[k] <= T0[i]) continue\n const c = (th.conductivity + parts[k].mat.thermal.conductivity) / 2\n dT += (T0[k] - T0[i]) * (1 - Math.exp((-1.2 * c * dt) / hc))\n if (T0[k] > maxN) maxN = T0[k]\n }\n if (dT > 0) s.temperature = Math.min(s.temperature + dT, maxN)\n s.temperature += (ambient - s.temperature) * (1 - Math.exp(-dt / (20 * hc)))\n if (Math.abs(s.temperature - ambient) < 0.05) s.temperature = ambient\n }\n meltStep(o, p, dt)\n if (isLost(p)) continue\n checkIgnite(o, p)\n const ex = p.spec.explodes\n if (ex && chainDelayOf(p.spec, 'fire') !== undefined) {\n if (s.temperature >= (ex.atC ?? FIRE_PRIME_C)) prime(o, p, 'fire')\n } else if (ex && ex.atC !== undefined && s.temperature >= ex.atC) {\n failPart(o, p, null, null, 0, 40)\n continue\n }\n // leaks\n const cont = p.spec.contains\n if (cont && (s.liters ?? 0) > 0) {\n let rate = 0\n for (const h of s.holes) if (h.through) rate += holeRate(h, !!cont.pressurized)\n if (rate > 0) {\n s.liters = Math.max(0, (s.liters ?? 0) - rate * dt)\n hot = true\n if (FLAMMABLE_FLUIDS.includes(cont.fluid) && s.temperature >= 350 && !p.rt.jet) {\n if (ex && chainDelayOf(p.spec, 'fire') !== undefined) {\n prime(o, p, 'fire')\n continue\n }\n if (ex) {\n failPart(o, p, null, null, 0, 40)\n continue\n }\n p.rt.jet = true\n s.burning = true\n emit({ ...base(o), type: 'ignite', part: p.spec.id, point: partXf(o, p).c })\n }\n }\n }\n if (p.rt.jet && (s.liters ?? 0) <= 0) {\n p.rt.jet = false\n s.burning = false\n emit({ ...base(o), type: 'extinguish', part: p.spec.id })\n }\n // thermal shock\n const sc = th.thermalShockC\n if (sc !== undefined) {\n p.rt.shockT = Math.max(0, p.rt.shockT - dt)\n const rate = Math.abs(s.temperature - p.rt.prevTemp) / dt\n p.rt.prevTemp = s.temperature\n if (rate > sc && p.rt.shockT <= 0) {\n p.rt.shockT = 1\n const { c, q } = partXf(o, p)\n const lp: Vec3 = [(rnd() - 0.5) * p.dims[0], (rnd() - 0.5) * p.dims[1], (rnd() - 0.5) * p.dims[2]]\n const sp = surfacePoint(p.spec.shape, lp)\n addCrack(o, p, toWorld(c, q, sp.point), rotateVec(q, sp.normal), 0.1 + (rate / sc) * 0.1)\n applyDamage(o, p, p.st.maxHp * 0.25, 'heat', null, null, 5, 3)\n if (isLost(p)) continue\n }\n }\n if (s.burning || p.rt.jet) sources.push({ o, p, flame: p.rt.jet ? 900 : th.flameC ?? 800 })\n if (s.burning || p.rt.jet || s.temperature > ambient + 0.5) hot = true\n }\n if (o.hasStructure) {\n if (o.dirty) {\n o.dirty = false\n solveStructure(o)\n }\n for (const p of parts) {\n if (!p.structural || isLost(p)) continue\n const stress = p.st.stress ?? 0\n p.rt.stressT = Math.max(0, (p.rt.stressT ?? 0) - dt)\n if (stress > 1) {\n if (p.rt.stressT <= 0) {\n p.rt.stressT = 0.5\n emit({ ...base(o), type: 'stress', part: p.spec.id, stress, load: p.st.load ?? 0 })\n }\n applyDamage(o, p, overloadRate(stress) * p.st.maxHp * dt, 'blunt', null, null, 5, 3)\n } else if (stress > 0.8 && p.mat.ductility < 0.3 && p.rt.stressT <= 0 && p.st.cracks.length < 6) {\n p.rt.stressT = 0.5\n const { c, q } = partXf(o, p)\n const sp = surfacePoint(p.spec.shape, [(rnd() - 0.5) * p.dims[0], (rnd() - 0.5) * p.dims[1], (rnd() - 0.5) * p.dims[2]])\n addCrack(o, p, toWorld(c, q, sp.point), rotateVec(q, sp.normal), 0.1 + (stress - 0.8) * 0.5)\n }\n }\n if (o.maxStress > 0.8) hot = true\n }\n o.active = hot\n }\n\n const spread = (sources: Array<{ o: ObjRT; p: PartRT; flame: number }>, dt: number) => {\n for (const src of sources) {\n if (!src.p.st.burning && !src.p.rt.jet) continue\n const sc = toWorld(src.o.st.position, src.o.st.rotation, src.p.pos)\n const A = partWorldAabb(src.o, src.p)\n for (const o of objects.values()) {\n if (o === src.o) continue\n if (vec.distance(toWorld(o.st.position, o.st.rotation, o.bc), sc) > o.br + src.p.bound + fireSpread) continue\n for (const q of o.parts) {\n if (isLost(q) || q.st.burning) continue\n const B = partWorldAabb(o, q)\n const gap = Math.hypot(\n Math.max(0, A.min[0] - B.max[0], B.min[0] - A.max[0]),\n Math.max(0, A.min[1] - B.max[1], B.min[1] - A.max[1]),\n Math.max(0, A.min[2] - B.max[2], B.min[2] - A.max[2]),\n )\n if (gap >= fireSpread || src.flame <= q.st.temperature) continue\n const f = 1 - gap / fireSpread\n q.st.temperature += (src.flame - q.st.temperature) * (1 - Math.exp((-0.6 * f * dt) / (q.mat.thermal.heatCapacity ?? 1)))\n o.active = true\n }\n }\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // World API\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n /** The primed part that goes off first: earliest due time, then the older object, then the part listed first. */\n const nextPrimed = (until: number): { o: ObjRT; p: PartRT } | null => {\n let best: { o: ObjRT; p: PartRT } | null = null\n for (const [p, o] of primed) {\n if (objects.get(o.id) !== o || isLost(p)) {\n primed.delete(p)\n continue\n }\n const due = p.rt.chainDue as number\n if (due > until) continue\n if (!best) best = { o, p }\n else {\n const bestDue = best.p.rt.chainDue as number\n if (due < bestDue || (due === bestDue && (o.order < best.o.order || (o.order === best.o.order && (o.idx.get(p.spec.id) ?? 0) < (best.o.idx.get(best.p.spec.id) ?? 0))))) best = { o, p }\n }\n }\n return best\n }\n\n /**\n * Explodes the primed parts whose delay ran out by `until`, one at a time in order of time; each blast is resolved before the next part goes off,\n * so a part it primes counts its delay from that moment, not from the end of the frame.\n */\n const detonatePrimed = (until: number) => {\n const end = time\n for (let next = nextPrimed(until); next; next = nextPrimed(until)) {\n primed.delete(next.p)\n time = Math.max(0, Math.min(end, next.p.rt.chainDue as number))\n next.p.rt.chainDue = undefined\n failPart(next.o, next.p, null, null, 0, 40)\n drainBlasts()\n }\n time = end\n }\n\n /** Collapse events are produced after the whole operation: make sure the result of the operation carries them. */\n const withCollapses = (r: { value: HitResult[]; events: DestructionEvent[] }): HitResult[] => {\n const last = r.value[r.value.length - 1]\n if (!last) return r.value\n for (const e of r.events) if (e.type === 'collapse' && !r.value.some((h) => h.events.includes(e))) last.events.push(e)\n return r.value\n }\n\n const whole = (fn: () => HitResult): HitResult => {\n const r = run(fn)\n r.value.events = r.events\n return r.value\n }\n\n const world: DestructionWorld = {\n materials,\n get time() {\n return time\n },\n add(spec, opts: AddOptions = {}) {\n const id = opts.id ?? nextId()\n if (taken(id)) throw new Error(`object \"${id}\" already exists`)\n objects.set(id, build(resolveSpec(spec), id, opts.position ?? [0, 0, 0], opts.rotation ?? [0, 0, 0, 1]))\n return id\n },\n register(impl, opts: AddOptions = {}) {\n const id = opts.id ?? impl.id\n if (taken(id)) throw new Error(`object \"${id}\" already exists`)\n impls.set(id, { impl, position: opts.position ?? [0, 0, 0], rotation: opts.rotation ?? [0, 0, 0, 1], poses: new Map() })\n return id\n },\n setPartPose(objectId, partId, position, rotation) {\n const q = quatFromEuler(...(rotation ?? [0, 0, 0]))\n const im = impls.get(objectId)\n if (im) {\n im.impl.setPartPose?.(partId, position, rotation)\n im.poses.set(partId, { pos: [position[0], position[1], position[2]], q })\n return\n }\n const o = getObj(objectId)\n const p = getPart(o, partId)\n p.pos = [position[0], position[1], position[2]]\n p.q = q\n updateBound(o)\n },\n remove(id) {\n objects.delete(id)\n impls.delete(id)\n },\n has: (id) => taken(id),\n ids: () => [...objects.keys(), ...impls.keys()],\n setTransform(id, position, rotation) {\n const im = impls.get(id)\n if (im) {\n im.position = [position[0], position[1], position[2]]\n im.rotation = [rotation[0], rotation[1], rotation[2], rotation[3]]\n return\n }\n const o = getObj(id)\n o.st.position = [position[0], position[1], position[2]]\n o.st.rotation = [rotation[0], rotation[1], rotation[2], rotation[3]]\n },\n splitGroup(id, group, newId) {\n if (impls.has(id)) throw new Error(`object \"${id}\" is a registered DestructibleImpl and cannot be split; its module owns its pieces`)\n const o = getObj(id)\n if (o.st.groups.length < 2) return id\n const names = o.st.groups[group]\n if (!names) throw new Error(`object \"${id}\" has no group ${group}`)\n const moved = new Set(names)\n const nid = newId ?? nextId()\n if (objects.has(nid)) throw new Error(`object \"${nid}\" already exists`)\n // an open joint between the two objects stays with the original\n const carryFor = (keep: (pid: string) => boolean, keepOpen: (a: string, b: string) => boolean = () => false): Carry => ({\n parts: new Map(o.parts.filter((p) => keep(p.spec.id)).map((p) => [p.spec.id, { st: p.st, rt: p.rt }])),\n joints: new Map([\n ...o.joints.filter((j) => (keep(j.spec.a) && keep(j.spec.b)) || (j.st.open && keepOpen(j.spec.a, j.spec.b))).map((j): [string, { st: JointState; step: number }] => [j.spec.id, { st: j.st, step: j.step }]),\n ...o.st.joints.filter((st) => st.open && !o.jointMap.has(st.id) && keepOpen(st.a, st.b)).map((st): [string, { st: JointState; step: number }] => [st.id, { st, step: 0 }]),\n ]),\n collapsed: [...o.collapsed].filter(keep),\n })\n const sub = (keep: (pid: string) => boolean): DestructibleSpec => {\n const s: DestructibleSpec = { parts: o.spec.parts.filter((p) => keep(p.id)), joints: (o.spec.joints ?? []).filter((j) => keep(j.a) && keep(j.b)) }\n if (o.spec.name !== undefined) s.name = o.spec.name\n if (o.spec.tags) s.tags = [...o.spec.tags]\n return clone(s)\n }\n const inNew = (pid: string) => moved.has(pid)\n const inOld = (pid: string) => !moved.has(pid)\n const pos = o.st.position, rot = o.st.rotation\n const fresh = build(sub(inNew), nid, pos, rot, carryFor(inNew, (a, b) => inNew(a) && inNew(b)))\n const rest = build(sub(inOld), id, pos, rot, carryFor(inOld, (a, b) => !(inNew(a) && inNew(b))))\n objects.set(id, rest)\n objects.set(nid, fresh)\n return nid\n },\n hit(objectId, h) {\n const im = impls.get(objectId)\n if (im) return whole(() => implHit(im, h))\n const o = getObj(objectId)\n return whole(() => doHit(o, h))\n },\n hitPart(objectId, partId, h) {\n const im = impls.get(objectId)\n if (im) return whole(() => implHit(im, h))\n const o = getObj(objectId)\n const p = getPart(o, partId)\n return whole(() => doHit(o, h, p))\n },\n explode(point, energy, radius, source) {\n return withCollapses(run(() => blastWorld(point, energy, radius, source)))\n },\n raycast(origin, direction, maxDistance = Infinity) {\n const r = raycastInternal(origin, direction, maxDistance)\n return r ? { object: r.object, part: r.part, point: r.point, normal: r.normal, distance: r.distance } : null\n },\n shoot(origin, direction, energy, caliber, source) {\n return withCollapses(run(() => {\n const results: HitResult[] = []\n const d = vec.normalize(direction)\n const ignore = new Set<string>()\n let org = origin\n let E = energy\n for (let i = 0; i < 4 && E > 0; i++) {\n const rh = raycastInternal(org, d, Infinity, ignore)\n if (!rh) break\n const im = impls.get(rh.object)\n if (im) {\n const r = implHit(im, { type: 'ballistic', point: rh.point, direction: d, energy: E, caliber, ...(source !== undefined ? { source } : {}) })\n r.part = rh.part\n r.point = rh.point\n r.exitEnergy = r.penetrated ? E * 0.5 : 0\n results.push(r)\n ignore.add(`${im.impl.id}\\0${rh.part}`)\n if (!r.penetrated) break\n org = vec.madd(rh.point, d, Math.min(rh.pathLen, 0.05) + 0.001)\n E = r.exitEnergy\n continue\n }\n const o = getObj(rh.object)\n const p = getPart(o, rh.part)\n const start = cur.length\n const out = ballistic(o, p, rh.point, rh.normal, d, E, caliber, rh.pathLen, source)\n results.push({ object: o.id, part: p.spec.id, point: rh.point, damage: out.damage, penetrated: out.penetrated, exitEnergy: out.exitEnergy, events: cur.slice(start) })\n ignore.add(`${o.id}\\0${p.spec.id}`)\n if (!out.penetrated || !out.exitPoint) break\n org = vec.madd(out.exitPoint, d, 0.001)\n E = out.exitEnergy\n }\n return results\n }))\n },\n disassemble(objectId, jointId, tool: ToolKind, dt) {\n const im = impls.get(objectId)\n if (im) return im.impl.disassemble ? im.impl.disassemble(jointId, tool, dt) : -1\n const o = getObj(objectId)\n const j = o.jointMap.get(jointId)\n if (!j || !j.spec.tools.includes(tool)) return -1\n if (j.st.open) return 1\n return run(() => {\n j.st.progress = Math.min(1, j.st.progress + (j.spec.seconds > 0 ? dt / j.spec.seconds : 1))\n if (j.st.progress >= 1 - 1e-9) j.st.progress = 1\n const step = Math.floor(j.st.progress * 10 + 1e-9)\n if (step > j.step || j.st.progress >= 1) {\n j.step = step\n emit({ ...base(o), type: 'disassemble_progress', joint: j.spec.id, tool, progress: j.st.progress })\n }\n if (j.st.progress >= 1) {\n j.st.open = true\n j.st.openedBy = 'tool'\n solveStructure(o)\n recomputeGroups(o)\n detachEvents(o, [j], 'tool')\n collapseCheck(o)\n }\n return j.st.progress\n }).value\n },\n workableJoints(objectId, tool) {\n const im = impls.get(objectId)\n if (im) {\n const spec = im.impl.describe()\n return im.impl.state().joints.filter((js) => {\n const j = (spec.joints ?? []).find((x) => (x.id ?? `${x.a}~${x.b}`) === js.id)\n return !js.open && !!j && (j.tools ?? JOINT_DEFAULTS[j.kind].tools).includes(tool)\n })\n }\n return getObj(objectId).joints.filter((j) => !j.st.open && j.spec.tools.includes(tool)).map((j) => j.st)\n },\n nearestJoint(objectId, point, maxDistance = 0.3, tool) {\n const im = impls.get(objectId)\n // Candidates: closed joints with their world position and whether `tool` can undo them.\n const cands: { st: JointState; d: number; ok: boolean }[] = []\n if (im) {\n const spec = im.impl.describe()\n for (const js of im.impl.state().joints) {\n if (js.open) continue\n const pos = implJointPos(im, js.a, js.b)\n const j = (spec.joints ?? []).find((x) => (x.id ?? `${x.a}~${x.b}`) === js.id)\n cands.push({ st: js, d: pos ? vec.distance(pos, point) : Infinity, ok: !!j && (j.tools ?? JOINT_DEFAULTS[j.kind].tools).includes(tool as ToolKind) })\n }\n } else {\n const o = getObj(objectId)\n for (const j of o.joints) {\n if (j.st.open) continue\n cands.push({ st: j.st, d: vec.distance(jointWorld(o, j), point), ok: tool ? j.spec.tools.includes(tool) : true })\n }\n }\n const pick = (only: boolean): JointState | null => {\n let best: JointState | null = null\n let bd = maxDistance\n for (const c of cands) {\n if (only && !c.ok) continue\n if (c.d <= bd) {\n bd = c.d\n best = c.st\n }\n }\n return best\n }\n return (tool ? pick(true) : null) ?? pick(false)\n },\n extinguish(objectId, partId, coolC = 200) {\n const im = impls.get(objectId)\n if (im) {\n run(() => im.impl.extinguish?.(partId))\n return\n }\n const o = getObj(objectId)\n run(() => {\n for (const p of partId ? [getPart(o, partId)] : o.parts) {\n if (isLost(p)) continue\n if (p.st.burning) {\n p.st.burning = false\n p.rt.jet = false\n emit({ ...base(o), type: 'extinguish', part: p.spec.id })\n }\n p.st.temperature = Math.max(ambient, p.st.temperature - coolC)\n }\n o.active = true\n })\n },\n setLiters(objectId, partId, liters) {\n if (impls.has(objectId)) return\n const p = getPart(getObj(objectId), partId)\n if (!p.spec.contains) return\n p.st.liters = clamp(liters, 0, p.spec.contains.liters)\n getObj(objectId).active = true\n },\n update(dt) {\n if (!(dt > 0)) return []\n return run(() => {\n time += dt\n const sources: Array<{ o: ObjRT; p: PartRT; flame: number }> = []\n for (const o of [...objects.values()]) if (o.active) stepObject(o, dt, sources)\n if (sources.length) spread(sources, dt)\n detonatePrimed(time)\n for (const im of [...impls.values()]) {\n if (!im.impl.update) continue\n for (const e of im.impl.update(dt) ?? []) emit(e.time === undefined ? { ...e, time } : e)\n }\n }).events\n },\n state: (id) => objects.get(id)?.st ?? impls.get(id)?.impl.state() ?? null,\n snapshot: (id) => {\n const st = objects.get(id)?.st ?? impls.get(id)?.impl.state()\n return st ? clone(st) : null\n },\n part: (id, partId) => objects.get(id)?.byId.get(partId)?.st ?? impls.get(id)?.impl.state().parts.find((p) => p.id === partId) ?? null,\n reset(id) {\n const im = impls.get(id)\n if (im) {\n im.impl.reset?.()\n return\n }\n const o = getObj(id)\n objects.set(id, build(o.spec, id, o.st.position, o.st.rotation))\n },\n on(type: DestructionEventType | '*', fn) {\n let set = listeners.get(type)\n if (!set) listeners.set(type, (set = new Set()))\n set.add(fn)\n return () => {\n set!.delete(fn)\n }\n },\n serialize(): DestructionSnapshot {\n return {\n version: 1,\n time,\n rng: rng.state(),\n counter,\n objects: [...objects.values()].map((o) => {\n const runtime: ObjectRuntime = { parts: {}, joints: {}, collapsed: [...o.collapsed] }\n for (const p of o.parts) runtime.parts[p.spec.id] = { ...p.rt }\n for (const j of o.joints) runtime.joints[j.spec.id] = j.step\n return { id: o.id, spec: clone(o.spec), state: clone(o.st), runtime }\n }),\n ...(impls.size\n ? { impls: [...impls.values()].map((im) => ({ id: im.impl.id, position: [...im.position] as Vec3, rotation: [...im.rotation] as Quat, data: im.impl.serialize?.() })) }\n : {}),\n }\n },\n load(snap) {\n if (snap.version !== 1) throw new Error(`unsupported snapshot version ${String(snap.version)}`)\n objects.clear()\n time = snap.time\n rng.set(snap.rng)\n counter = snap.counter ?? 0\n for (const e of snap.objects) {\n const state = clone(e.state)\n const carry: Carry = {\n parts: new Map(\n state.parts.map((st) => [st.id, { st, rt: e.runtime?.parts[st.id] ? { ...e.runtime.parts[st.id] } : { ...freshRuntime(), prevTemp: st.temperature } }]),\n ),\n joints: new Map(state.joints.map((st) => [st.id, { st, step: e.runtime?.joints[st.id] ?? 0 }])),\n collapsed: e.runtime?.collapsed,\n }\n objects.set(e.id, build(clone(e.spec), e.id, state.position, state.rotation, carry))\n }\n for (const e of snap.impls ?? []) {\n const im = impls.get(e.id)\n if (!im) continue\n im.position = [e.position[0], e.position[1], e.position[2]]\n im.rotation = [e.rotation[0], e.rotation[1], e.rotation[2], e.rotation[3]]\n if (e.data !== undefined) im.impl.load?.(e.data)\n }\n },\n }\n return world\n}\n","import type { DestructibleSpec, JointSpec, MaterialId, PartSpec } from './types'\n\nexport interface FrameOptions {\n /** Total length along x between the outer column centres, metres (default 8). */\n spanX?: number\n /** Total length along z (default 8). */\n spanZ?: number\n /** Columns along x (at least 2, default 3). */\n columnsX?: number\n /** Columns along z (at least 2, default 3). */\n columnsZ?: number\n /** Height of one floor from slab top to the underside of the next slab, metres (default 3). */\n height?: number\n /** Number of floors (default 1). */\n floors?: number\n /** Brick walls on every perimeter bay of every floor; the first bay of the ground floor on the -z side gets a door opening (default false). */\n walls?: boolean\n /** A thin roof slab resting on the top beams (default true); without it the top floor is open. */\n roof?: boolean\n columnSize?: number\n beamHeight?: number\n slabThickness?: number\n wallThickness?: number\n doorWidth?: number\n doorHeight?: number\n /** Material of foundations, columns, beams, slabs and roof (default `concrete`). */\n material?: MaterialId\n wallMaterial?: MaterialId\n /** Override the load capacity of every column, kg (see `PartState.load`). */\n columnCapacity?: number\n}\n\n/**\n * A parametric test structure: a grid of columns on foundations, beams between the column tops, one slab per floor (the last one a roof), and\n * optional brick walls with a door. Joints are explicit and directional: columns rest on foundations (or on the slab below) with `rebar`, beams on\n * columns, slabs on beams, the roof rests on the top beams, walls hang on their columns with `mortar`. Part ids: `foundation_i_j`, `column_f_i_j`,\n * `beam_x_f_i_j`, `beam_z_f_i_j`, `slab_f`, `roof`, `wall_*`, `door`. Ground is y = 0 (the top of the foundations).\n */\nexport const buildFrame = (o: FrameOptions = {}): DestructibleSpec => {\n const spanX = o.spanX ?? 8, spanZ = o.spanZ ?? 8\n const nx = Math.max(2, o.columnsX ?? 3), nz = Math.max(2, o.columnsZ ?? 3)\n const H = o.height ?? 3, floors = Math.max(1, o.floors ?? 1)\n const cs = o.columnSize ?? 0.3, bh = o.beamHeight ?? 0.3, bw = 0.2, T = o.slabThickness ?? 0.2, wt = o.wallThickness ?? 0.2\n const dw = o.doorWidth ?? 1, dh = o.doorHeight ?? 2.1\n const mat = o.material ?? 'concrete', wmat = o.wallMaterial ?? 'brick'\n const roof = o.roof ?? true\n const xs = Array.from({ length: nx }, (_, i) => -spanX / 2 + (i * spanX) / (nx - 1))\n const zs = Array.from({ length: nz }, (_, j) => -spanZ / 2 + (j * spanZ) / (nz - 1))\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n const on = (a: string, b: string, kind: JointSpec['kind']) => joints.push({ id: `${a}~${b}`, a, b, kind, bears: 'a_on_b' })\n\n for (let i = 0; i < nx; i++) {\n for (let j = 0; j < nz; j++) {\n parts.push({\n id: `foundation_${i}_${j}`, material: mat, shape: { kind: 'box', size: [cs * 2.2, 0.3, cs * 2.2] }, position: [xs[i], -0.15, zs[j]],\n structure: { role: 'foundation' }, anchored: true,\n })\n }\n }\n for (let f = 0; f < floors; f++) {\n const yb = f * (H + T)\n const top = yb + H\n const last = f === floors - 1\n const slabId = last && roof ? 'roof' : `slab_${f}`\n for (let i = 0; i < nx; i++) {\n for (let j = 0; j < nz; j++) {\n const id = `column_${f}_${i}_${j}`\n parts.push({\n id, material: mat, shape: { kind: 'box', size: [cs, H, cs] }, position: [xs[i], yb + H / 2, zs[j]],\n structure: o.columnCapacity === undefined ? { role: 'column' } : { role: 'column', capacity: o.columnCapacity },\n })\n on(id, f === 0 ? `foundation_${i}_${j}` : `slab_${f - 1}`, 'rebar')\n }\n }\n const beams: string[] = []\n const beam = (id: string, size: [number, number, number], pos: [number, number, number], c1: string, c2: string) => {\n parts.push({ id, material: mat, shape: { kind: 'box', size }, position: pos, structure: { role: 'beam' } })\n on(id, c1, 'rebar')\n on(id, c2, 'rebar')\n beams.push(id)\n }\n for (let j = 0; j < nz; j++) {\n for (let i = 0; i < nx - 1; i++) {\n beam(`beam_x_${f}_${i}_${j}`, [xs[i + 1] - xs[i] - cs, bh, bw], [(xs[i] + xs[i + 1]) / 2, top - bh / 2, zs[j]], `column_${f}_${i}_${j}`, `column_${f}_${i + 1}_${j}`)\n }\n }\n for (let i = 0; i < nx; i++) {\n for (let j = 0; j < nz - 1; j++) {\n beam(`beam_z_${f}_${i}_${j}`, [bw, bh, zs[j + 1] - zs[j] - cs], [xs[i], top - bh / 2, (zs[j] + zs[j + 1]) / 2], `column_${f}_${i}_${j}`, `column_${f}_${i}_${j + 1}`)\n }\n }\n const thick = last && roof ? T * 0.75 : T\n parts.push({\n id: slabId, material: mat, shape: { kind: 'box', size: [spanX + cs + 0.2, thick, spanZ + cs + 0.2] }, position: [0, top + thick / 2, 0],\n structure: { role: last && roof ? 'roof' : 'slab' },\n })\n for (const b of beams) on(slabId, b, last && roof ? 'resting' : 'rebar')\n\n if (o.walls) {\n const wh = H - bh\n const wy = yb + wh / 2\n const wall = (id: string, size: [number, number, number], pos: [number, number, number], supports: string[]) => {\n parts.push({ id, material: wmat, shape: { kind: 'box', size }, position: pos, structure: { role: 'wall' } })\n for (const s of supports) on(id, s, 'mortar')\n }\n for (const j of [0, nz - 1]) {\n for (let i = 0; i < nx - 1; i++) {\n const c1 = `column_${f}_${i}_${j}`, c2 = `column_${f}_${i + 1}_${j}`\n const avail = xs[i + 1] - xs[i] - cs\n if (f === 0 && j === 0 && i === 0 && avail > dw + 0.4) {\n const side = (avail - dw) / 2\n const lx = xs[i] + cs / 2 + side / 2, rx = xs[i + 1] - cs / 2 - side / 2\n wall(`wall_door_left`, [side, wh, wt], [lx, wy, zs[j]], [c1])\n wall(`wall_door_right`, [side, wh, wt], [rx, wy, zs[j]], [c2])\n const lh = wh - dh\n wall(`wall_door_lintel`, [dw, lh, wt], [xs[i] + cs / 2 + side + dw / 2, yb + dh + lh / 2, zs[j]], ['wall_door_left', 'wall_door_right'])\n parts.push({ id: 'door', material: 'wood_hard', shape: { kind: 'box', size: [dw - 0.04, dh, 0.05] }, position: [xs[i] + cs / 2 + side + dw / 2, yb + dh / 2, zs[j]], tags: ['door'] })\n joints.push({ id: 'door~wall_door_left', a: 'door', b: 'wall_door_left', kind: 'hinge', bears: false })\n } else wall(`wall_x_${f}_${i}_${j}`, [avail, wh, wt], [(xs[i] + xs[i + 1]) / 2, wy, zs[j]], [c1, c2])\n }\n }\n for (const i of [0, nx - 1]) {\n for (let j = 0; j < nz - 1; j++) {\n wall(`wall_z_${f}_${i}_${j}`, [wt, wh, zs[j + 1] - zs[j] - cs], [xs[i], wy, (zs[j] + zs[j + 1]) / 2], [`column_${f}_${i}_${j}`, `column_${f}_${i}_${j + 1}`])\n }\n }\n }\n }\n return { name: 'frame', parts, joints, tags: ['structure'] }\n}\n","import { createDestruction } from './world'\nimport type { DestructibleSpec, SizeStructureOptions } from './types'\n\n/**\n * Sizes the load capacity of a structure the way an engineer would, from the loads the world itself computes. The intact spec goes through the\n * same load solver `createDestruction` uses, and each structural part (`structure.role` other than `none`) gets `structure.capacity = load / safety`,\n * so its at-rest stress is exactly `safety`. With `redundancy` set, every `column` is also removed in turn and the capacity of the parts that\n * would carry more is raised so they stay at or below `redundancy`. Parts without `structure`, with role `none`, or with no support path to an\n * anchored part are left as they are. The spec is not modified; a copy is returned.\n */\nexport const sizeStructure = (spec: DestructibleSpec, options: SizeStructureOptions = {}): DestructibleSpec => {\n const safety = options.safety ?? 0.65\n const redundancy = options.redundancy\n const loads = (s: DestructibleSpec): Map<string, { load: number; stress: number }> => {\n const w = createDestruction(options.materials ? { materials: options.materials } : {})\n const id = w.add(s)\n return new Map(w.state(id)!.parts.map((p) => [p.id, { load: p.load ?? 0, stress: p.stress ?? 0 }]))\n }\n const out = structuredClone(spec)\n const base = loads(out)\n const need = new Map<string, number>()\n for (const p of out.parts) {\n if (!p.structure || p.structure.role === 'none') continue\n const b = base.get(p.id)\n if (!b || b.stress <= 0) continue\n need.set(p.id, b.load / safety)\n }\n if (redundancy !== undefined) {\n for (const col of out.parts) {\n if (col.structure?.role !== 'column') continue\n const reduced: DestructibleSpec = {\n ...out,\n parts: out.parts.filter((p) => p.id !== col.id),\n joints: (out.joints ?? []).filter((j) => j.a !== col.id && j.b !== col.id),\n }\n // joints are inferred when the spec has none; removing a part then removes its joints with it\n if (!out.joints) delete reduced.joints\n const l = loads(reduced)\n for (const [id, n] of need) {\n const r = l.get(id)\n if (r && r.stress > 0) need.set(id, Math.max(n, r.load / redundancy))\n }\n }\n }\n for (const p of out.parts) {\n const n = need.get(p.id)\n if (n !== undefined) p.structure = { ...p.structure!, capacity: n }\n }\n return out\n}\n","import type { DamageType, DestructionEventType, FractureStyle, JointKind, PartStatus, StructureRole, ToolKind } from './types'\n\n/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type DestructionLocale = 'en' | 'pt-BR'\n\nexport interface DestructionStrings {\n /** Display name per material id (see `MATERIALS`). Unknown ids are not listed. */\n materialNames: Record<string, string>\n partStatus: Record<PartStatus, string>\n jointKinds: Record<JointKind, string>\n toolKinds: Record<ToolKind, string>\n damageTypes: Record<DamageType, string>\n /** Short label per event type, for logs and kill-feed style text. */\n eventLabels: Record<DestructionEventType, string>\n fractureStyles: Record<FractureStyle, string>\n structureRoles: Record<StructureRole, string>\n}\n\nexport const locales: Record<DestructionLocale, DestructionStrings> = {\n en: {\n materialNames: {\n steel: 'steel', cast_iron: 'cast iron', aluminium: 'aluminium', copper: 'copper', wood_soft: 'softwood', wood_hard: 'hardwood', plywood: 'plywood',\n mdf: 'MDF', glass: 'glass', tempered_glass: 'tempered glass', ceramic: 'ceramic', concrete: 'concrete', brick: 'brick', plaster: 'plaster',\n stone: 'stone', plastic: 'plastic', rubber: 'rubber', fabric: 'fabric', foam: 'foam', leather: 'leather', paper: 'paper', foliage: 'foliage',\n green_wood: 'green wood', cactus: 'cactus', flesh_fruit: 'fruit', wax: 'wax', soil: 'soil',\n },\n partStatus: { intact: 'intact', damaged: 'damaged', collapsed: 'collapsed', broken: 'broken', melted: 'melted', ashes: 'ashes' },\n jointKinds: {\n screw: 'screw', bolt: 'nut and bolt', nail: 'nail', weld: 'weld', glue: 'glue', hinge: 'hinge', clip: 'clip', tie: 'tie', mortar: 'mortar',\n fused: 'fused', stem: 'stem', rebar: 'rebar', resting: 'resting',\n },\n toolKinds: {\n hand: 'hand', screwdriver: 'screwdriver', wrench: 'wrench', pry_bar: 'pry bar', saw: 'saw', cutting_torch: 'cutting torch', knife: 'knife', hammer: 'hammer',\n },\n damageTypes: { ballistic: 'ballistic', blunt: 'blunt', slash: 'slash', explosive: 'explosive', fire: 'fire', heat: 'heat' },\n eventLabels: {\n damage: 'damage', dent: 'dent', hole: 'hole', crack: 'crack', ricochet: 'ricochet', debris: 'debris', fracture: 'broke', detach: 'came loose',\n disassemble_progress: 'taking apart', ignite: 'caught fire', extinguish: 'put out', burnout: 'burned to ash', melt: 'melting', drip: 'dripping',\n leak: 'leak', explode: 'exploded', primed: 'about to explode', stress: 'overload', collapse: 'collapsed', destroyed: 'destroyed',\n },\n fractureStyles: { shatter: 'shatter', crumble: 'crumble', splinter: 'splinter', tear: 'tear', snap: 'snap', none: 'none' },\n structureRoles: { foundation: 'foundation', column: 'column', beam: 'beam', slab: 'slab', wall: 'wall', partition: 'partition', roof: 'roof', stair: 'stairs', none: 'none' },\n },\n 'pt-BR': {\n materialNames: {\n steel: 'aço', cast_iron: 'ferro fundido', aluminium: 'alumínio', copper: 'cobre', wood_soft: 'madeira macia', wood_hard: 'madeira de lei',\n plywood: 'compensado', mdf: 'MDF', glass: 'vidro', tempered_glass: 'vidro temperado', ceramic: 'cerâmica', concrete: 'concreto', brick: 'tijolo',\n plaster: 'gesso', stone: 'pedra', plastic: 'plástico', rubber: 'borracha', fabric: 'tecido', foam: 'espuma', leather: 'couro', paper: 'papel',\n foliage: 'folhagem', green_wood: 'madeira verde', cactus: 'cacto', flesh_fruit: 'fruta', wax: 'cera', soil: 'terra',\n },\n partStatus: { intact: 'intacto', damaged: 'danificado', collapsed: 'desabado', broken: 'quebrado', melted: 'derretido', ashes: 'cinzas' },\n jointKinds: {\n screw: 'parafuso', bolt: 'porca e parafuso', nail: 'prego', weld: 'solda', glue: 'cola', hinge: 'dobradiça', clip: 'encaixe', tie: 'amarração',\n mortar: 'argamassa', fused: 'fundido', stem: 'caule', rebar: 'vergalhão', resting: 'apoiado',\n },\n toolKinds: {\n hand: 'mão', screwdriver: 'chave de fenda', wrench: 'chave inglesa', pry_bar: 'pé de cabra', saw: 'serra', cutting_torch: 'maçarico', knife: 'faca', hammer: 'martelo',\n },\n damageTypes: { ballistic: 'tiro', blunt: 'impacto', slash: 'corte', explosive: 'explosão', fire: 'fogo', heat: 'calor' },\n eventLabels: {\n damage: 'dano', dent: 'amassado', hole: 'furo', crack: 'trinca', ricochet: 'ricochete', debris: 'estilhaços', fracture: 'quebrou', detach: 'soltou',\n disassemble_progress: 'desmontando', ignite: 'pegou fogo', extinguish: 'apagou', burnout: 'virou cinza', melt: 'derretendo', drip: 'pingando',\n leak: 'vazamento', explode: 'explodiu', primed: 'prestes a explodir', stress: 'sobrecarga', collapse: 'desabou', destroyed: 'destruído',\n },\n fractureStyles: { shatter: 'estilhaçar', crumble: 'esfarelar', splinter: 'lascar', tear: 'rasgar', snap: 'partir', none: 'nenhuma' },\n structureRoles: { foundation: 'fundação', column: 'pilar', beam: 'viga', slab: 'laje', wall: 'parede', partition: 'divisória', roof: 'telhado', stair: 'escada', none: 'nenhum' },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined): DestructionStrings => locales[(locale as DestructionLocale) ?? 'en'] ?? locales.en\n","import type { DamageType, DestructibleSpec, DestructionEvent, Hit, JointSpec, ObjectState, ToolKind, Vec3 } from './destruction'\n\n/**\n * What a game module implements for an object whose behaviour it owns (a vehicle with its own panel deformation, a creature, a machine). The\n * world (`DestructionWorld.register`) hosts it next to its own objects: raycast, shoot, explode, hit, disassemble, extinguish, update, state,\n * reset and `on` all route to it.\n *\n * Space: the impl receives hits in WORLD space and returns events in WORLD space (it owns its transform; the transform given to `register` or\n * `setTransform` is only used by the world for raycasts and blast range). Every event must carry `object === id` and name parts listed by\n * `describe()`.\n */\nexport interface DestructibleImpl {\n readonly id: string\n readonly name?: string\n /** Parts, joints and structure in the impl's local space, for raycast, inspector and log. Called often: keep it cheap. */\n describe(): DestructibleSpec\n /** Apply one hit (see `IMPACT_CONTRACT` for the fields per type) and return the events it caused. */\n hit(hit: Hit): DestructionEvent[]\n /** Advance fire, melting, collapse and other timed behaviour. */\n update?(dt: number): DestructionEvent[]\n state(): ObjectState\n reset?(): void\n /** Same contract as `DestructionWorld.disassemble`: progress 0..1, or -1 when the tool cannot undo the joint. */\n disassemble?(jointId: string, tool: ToolKind, dt: number): number\n extinguish?(partId?: string): void\n /** Optional: an animation moved a part; `position` / `rotation` (Euler XYZ, radians) are object-local. Keep raycast and hit shapes in sync. */\n setPartPose?(partId: string, position: Vec3, rotation?: Vec3): void\n /** Plain JSON of the impl's own state, stored in `DestructionSnapshot.impls`. */\n serialize?(): unknown\n load?(data: unknown): void\n}\n\n/** The fields a weapon or hazard must put in a `Hit`, per damage type. THE impact contract. */\nexport interface ImpactContract {\n required: string[]\n optional: string[]\n note: string\n}\n\nexport const IMPACT_CONTRACT: Record<DamageType, ImpactContract> = {\n ballistic: { required: ['type', 'point', 'direction', 'energy', 'caliber'], optional: ['space', 'source'], note: 'bullets and pellets: joules and diameter in millimetres' },\n blunt: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'contact radius in metres (default 3 cm)' },\n slash: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'axes, knives, machetes' },\n explosive: { required: ['type', 'point', 'energy', 'radius'], optional: ['space', 'source'], note: 'point is the centre of the blast, radius the range in metres' },\n fire: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'flame temperature in °C; duration in seconds (call every frame with `dt`)' },\n heat: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'heat without flame (cutting torch, hot plate)' },\n}\n\n/** Problems with a hit according to the impact contract (empty when it is valid). */\nexport const checkHit = (hit: Hit): string[] => {\n const c = IMPACT_CONTRACT[hit.type]\n if (!c) return [`unknown damage type \"${String(hit.type)}\"`]\n const out: string[] = []\n for (const f of c.required) {\n const v = (hit as unknown as Record<string, unknown>)[f]\n if (v === undefined || (Array.isArray(v) ? v.some((n) => !Number.isFinite(n)) : typeof v === 'number' && !Number.isFinite(v))) out.push(`${hit.type} hit needs \"${f}\"`)\n }\n return out\n}\n\nexport interface CheckOptions {\n /**\n * Ids of every material the impl may use (the contracts package does not know the materials of your world: pass the ids of\n * `world.materials`, or the built-in plus your own). When omitted, the material check is skipped.\n */\n materials?: Iterable<string>\n}\n\nconst finiteJson = (v: unknown, path: string, out: string[]) => {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) out.push(`${path} is not a finite number`)\n } else if (Array.isArray(v)) v.forEach((x, i) => finiteJson(x, `${path}[${i}]`, out))\n else if (v && typeof v === 'object') for (const [k, x] of Object.entries(v)) finiteJson(x, `${path}.${k}`, out)\n else if (typeof v === 'function' || typeof v === 'symbol' || typeof v === 'bigint') out.push(`${path} is not JSON`)\n}\n\n/**\n * Contract checker for the test room (it needs no world): `describe()` is valid, a 500 J ballistic hit at a part centre returns well-formed events of this impl, `state()`\n * matches `describe()`, hit points never go negative, `update(0.016)` returns an array and every event is JSON-serializable. It hits the impl\n * (and calls `reset()` afterwards when there is one).\n */\nexport const checkDestructible = (impl: DestructibleImpl, options: CheckOptions = {}): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const known = options.materials ? new Set(options.materials) : null\n let spec: DestructibleSpec | undefined\n try {\n spec = impl.describe()\n } catch (e) {\n return { ok: false, problems: [`describe() threw: ${String(e)}`] }\n }\n if (!spec || !Array.isArray(spec.parts) || spec.parts.length === 0) return { ok: false, problems: ['describe() must return at least one part'] }\n const ids = new Set<string>()\n for (const p of spec.parts) {\n if (ids.has(p.id)) problems.push(`duplicate part id \"${p.id}\"`)\n ids.add(p.id)\n if (known && !known.has(p.material)) problems.push(`part \"${p.id}\" has unknown material \"${p.material}\"`)\n if (!p.shape || !['box', 'cylinder', 'sphere'].includes(p.shape.kind)) problems.push(`part \"${p.id}\" has no valid shape`)\n if (!Array.isArray(p.position) || p.position.length !== 3) problems.push(`part \"${p.id}\" has no position`)\n }\n const jointIds = new Set<string>()\n for (const j of (spec.joints ?? []) as JointSpec[]) {\n if (!ids.has(j.a) || !ids.has(j.b)) problems.push(`joint \"${j.id ?? `${j.a}~${j.b}`}\" references an unknown part`)\n const jid = j.id ?? `${j.a}~${j.b}`\n if (jointIds.has(jid)) problems.push(`duplicate joint id \"${jid}\"`)\n jointIds.add(jid)\n }\n const checkState = (label: string) => {\n let st: ObjectState\n try {\n st = impl.state()\n } catch (e) {\n problems.push(`state() threw ${label}: ${String(e)}`)\n return\n }\n const sids = st.parts.map((p) => p.id).sort().join(',')\n if (sids !== [...ids].sort().join(',')) problems.push(`state() part ids do not match describe() ${label}`)\n for (const p of st.parts) if (!(p.hp >= 0)) problems.push(`part \"${p.id}\" has negative or invalid hp ${label}`)\n }\n const checkEvents = (events: unknown, label: string) => {\n if (!Array.isArray(events)) {\n problems.push(`${label} must return an array`)\n return\n }\n const evs = events as DestructionEvent[]\n evs.forEach((e, i) => {\n if (e.object !== impl.id) problems.push(`${label} event ${i} (${e.type}) has object \"${String(e.object)}\", expected \"${impl.id}\"`)\n const part = (e as { part?: string }).part\n if (part !== undefined && !ids.has(part)) problems.push(`${label} event ${i} (${e.type}) names unknown part \"${part}\"`)\n })\n const bad: string[] = []\n finiteJson(evs, 'events', bad)\n problems.push(...bad.map((b) => `${label}: ${b}`))\n try {\n const s = JSON.stringify(evs)\n if (JSON.stringify(JSON.parse(s)) !== s) problems.push(`${label} events do not survive a JSON round trip`)\n } catch (e) {\n problems.push(`${label} events are not JSON-serializable: ${String(e)}`)\n }\n }\n checkState('before the hit')\n const target = spec.parts[0]\n try {\n const hit: Hit = { type: 'ballistic', point: [target.position[0], target.position[1], target.position[2]], direction: [0, 0, -1], energy: 500, caliber: 9 }\n checkEvents(impl.hit(hit), 'hit()')\n } catch (e) {\n problems.push(`hit() threw: ${String(e)}`)\n }\n checkState('after the hit')\n if (impl.update) {\n try {\n checkEvents(impl.update(0.016), 'update()')\n } catch (e) {\n problems.push(`update() threw: ${String(e)}`)\n }\n checkState('after update')\n }\n try {\n impl.reset?.()\n } catch (e) {\n problems.push(`reset() threw: ${String(e)}`)\n }\n return { ok: problems.length === 0, problems }\n}\n","import type { DestructibleSpec } from './destruction'\n\nexport interface CheckSpecOptions {\n /** Known material ids. When given, every part's material must be one of them. */\n materials?: Iterable<string>\n}\n\nexport interface SpecReport {\n /** False when there is at least one problem (warnings do not count). */\n ok: boolean\n problems: string[]\n /** Things that are legal but probably wrong, e.g. structural parts that cannot reach an anchored part. */\n warnings: string[]\n}\n\nconst STRUCTURE_ROLES = ['foundation', 'column', 'beam', 'slab', 'wall', 'partition', 'roof', 'stair', 'none']\nconst BEARS = [true, false, 'a_on_b', 'b_on_a']\n\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\nconst positive = (n: unknown): boolean => finite(n) && n > 0\nconst vec3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every(finite)\nconst nonNegative = (n: unknown): boolean => n === undefined || (finite(n) && n >= 0)\n\n/**\n * Static checks on a `DestructibleSpec` (no world needed), for items that give a `spec` instead of an `impl`: unique part ids, known materials\n * (when `options.materials` is given), joints that reference existing, different parts, finite positive sizes, non-negative mass / hp / capacity,\n * valid structure roles and `bears` directions. A structural part with no path of joints to an anchored part is a warning, not a problem: it\n * is allowed, it just falls.\n */\nexport const checkSpec = (spec: DestructibleSpec, options: CheckSpecOptions = {}): SpecReport => {\n const problems: string[] = []\n const warnings: string[] = []\n const materials = options.materials ? new Set(options.materials) : null\n const parts = Array.isArray(spec?.parts) ? spec.parts : []\n if (!Array.isArray(spec?.parts) || parts.length === 0) problems.push('the spec needs at least one part')\n const ids = new Set<string>()\n for (const p of parts) {\n const id = String(p?.id ?? '')\n const label = `part \"${id}\"`\n if (id === '') problems.push('a part has no id')\n else if (ids.has(id)) problems.push(`duplicate part id \"${id}\"`)\n ids.add(id)\n if (materials && !materials.has(p?.material)) problems.push(`${label} has unknown material \"${String(p?.material)}\"`)\n else if (typeof p?.material !== 'string' || p.material === '') problems.push(`${label} needs a material`)\n const s = p?.shape\n if (s?.kind === 'box') {\n if (!Array.isArray(s.size) || s.size.length !== 3 || !s.size.every(positive)) problems.push(`${label} box size must be three finite positive numbers`)\n } else if (s?.kind === 'cylinder') {\n if (!positive(s.radius) || !positive(s.height)) problems.push(`${label} cylinder radius and height must be finite and positive`)\n } else if (s?.kind === 'sphere') {\n if (!positive(s.radius)) problems.push(`${label} sphere radius must be finite and positive`)\n } else problems.push(`${label} has an unknown shape`)\n if (!vec3(p?.position)) problems.push(`${label} needs a finite position [x, y, z]`)\n if (p?.rotation !== undefined && !vec3(p.rotation)) problems.push(`${label} has an invalid rotation`)\n for (const f of ['mass', 'hp', 'thickness'] as const) if (!nonNegative(p?.[f])) problems.push(`${label} ${f} must be a finite number >= 0`)\n if (p?.fill !== undefined && !(finite(p.fill) && p.fill >= 0 && p.fill <= 1)) problems.push(`${label} fill must be between 0 and 1`)\n if (p?.structure) {\n if (!STRUCTURE_ROLES.includes(p.structure.role)) problems.push(`${label} has an invalid structure role \"${String(p.structure.role)}\"`)\n if (!nonNegative(p.structure.capacity)) problems.push(`${label} structure capacity must be a finite number >= 0`)\n }\n if (p?.contains && !nonNegative(p.contains.liters)) problems.push(`${label} contains.liters must be a finite number >= 0`)\n }\n\n const jointIds = new Set<string>()\n const edges: Array<[string, string]> = []\n for (const j of spec?.joints ?? []) {\n const id = j.id ?? `${j.a}~${j.b}`\n const label = `joint \"${id}\"`\n if (jointIds.has(id)) problems.push(`duplicate joint id \"${id}\"`)\n jointIds.add(id)\n if (!ids.has(j.a)) problems.push(`${label} references unknown part \"${String(j.a)}\"`)\n if (!ids.has(j.b)) problems.push(`${label} references unknown part \"${String(j.b)}\"`)\n if (j.a === j.b) problems.push(`${label} joins part \"${String(j.a)}\" to itself`)\n if (j.bears !== undefined && !BEARS.includes(j.bears)) problems.push(`${label} has an invalid bears \"${String(j.bears)}\"`)\n if (!nonNegative(j.strength)) problems.push(`${label} strength must be a finite number >= 0`)\n if (!nonNegative(j.seconds)) problems.push(`${label} seconds must be a finite number >= 0`)\n if (j.bears !== false && ids.has(j.a) && ids.has(j.b) && j.a !== j.b) edges.push([j.a, j.b])\n }\n\n // structural parts must reach an anchored part over the joints (only when the spec lists its joints: otherwise they are inferred later)\n const structural = parts.filter((p) => p?.structure && p.structure.role !== 'none')\n if (structural.length && spec.joints) {\n const anchored = parts.filter((p) => p.anchored || p.structure?.role === 'foundation').map((p) => p.id)\n const adj = new Map<string, string[]>()\n for (const [a, b] of edges) {\n adj.set(a, [...(adj.get(a) ?? []), b])\n adj.set(b, [...(adj.get(b) ?? []), a])\n }\n const seen = new Set(anchored)\n const queue = [...anchored]\n while (queue.length) {\n for (const n of adj.get(queue.pop()!) ?? []) {\n if (seen.has(n)) continue\n seen.add(n)\n queue.push(n)\n }\n }\n const lost = structural.filter((p) => !seen.has(p.id)).map((p) => p.id)\n if (lost.length) warnings.push(`structural part(s) ${lost.map((i) => `\"${i}\"`).join(', ')} cannot reach an anchored part, so they will fall`)\n }\n return { ok: problems.length === 0, problems, warnings }\n}\n","import type { Hit, Vec3 } from './destruction'\n\n/**\n * A ballistic shot (one per pellet) as a weapon module produces it. Plain data: any damage model can consume it (`shotToHit` makes the `Hit`).\n */\nexport interface Shot {\n origin: Vec3\n /** Unit vector. */\n direction: Vec3\n /** Muzzle energy in joules. */\n energy: number\n /** Bullet diameter in millimetres. */\n caliber: number\n /** snake_case calibre id, e.g. `9x19`. */\n caliberId: string\n /** Muzzle speed in m/s. */\n speed: number\n /** Energy at a distance in metres, with the calibre's drag. */\n energyAt(distance: number): number\n pellet: number\n /** snake_case weapon id. */\n weapon: string\n source?: string\n}\n\n/** One use of a non-firearm (melee swing, flame tick, heat tick, throw, tool tick, extinguisher tick). */\nexport type Use =\n | { kind: 'melee'; damage: 'blunt' | 'slash'; energy: number; radius: number; reach: number; origin: Vec3; direction: Vec3 }\n | { kind: 'flame'; temperature: number; radius: number; range: number; cone: boolean; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'heat'; temperature: number; radius: number; range: number; duration: number; origin: Vec3; direction: Vec3 }\n | {\n kind: 'throw'\n energy: number\n radius: number\n fuse: number\n velocity: Vec3\n origin: Vec3\n fire?: { temperature: number; radius: number; seconds: number }\n /** Explosive id (`m67`, `molotov`, `pg7v`...): the host looks the numbers up in the arsenal. Absent on a plain thrown object. */\n explosive?: string\n /** What sets it off: `timer` after `fuse` seconds, `impact` on the first hit once armed. */\n trigger?: 'timer' | 'impact'\n /** Metres the projectile must fly before an impact sets it off; closer, it hits without exploding (rocket launchers). */\n armDistance?: number\n /** Radius in metres of the wounding area (`radius` is the lethal one). */\n injuryRadius?: number\n /** Seconds the blast stuns whoever is inside the injury radius (flashbang). */\n stunSeconds?: number\n /** Seconds the thrower held it after pulling the pin: `fuse` is what was left of the full fuse when it left the hand. */\n cooked?: number\n /** Went off in the thrower's hand (held past the fuse): no velocity, `fuse` is 0 and the blast is at `origin`. */\n inHand?: boolean\n }\n /** An explosive set down where the trigger is pulled (mine, C4, charge): it waits for its trigger instead of flying. */\n | {\n kind: 'place'\n explosive: string\n /** `wire`: something trips it; `remote`: the player fires it; `timer`: after `fuse` seconds. */\n triggers: readonly ('timer' | 'wire' | 'remote')[]\n energy: number\n /** Lethal radius in metres. */\n radius: number\n injuryRadius: number\n /** Cone the blast goes through, in front of `direction` (mine); absent for a blast in every direction. */\n cone?: { halfAngleDeg: number; length: number }\n /** The wire a `wire` charge stretches from where it is set down: metres out, degrees from its facing (counter-clockwise from above) and metres above it. */\n tripwire?: { length: number; angleDeg: number; height: number }\n fuse?: number\n origin: Vec3\n direction: Vec3\n }\n /** The blast behind a rocket launcher: dangerous inside `radius` metres, in the cone around `direction` (pointing away from the target). */\n | { kind: 'backblast'; radius: number; halfAngleDeg: number; origin: Vec3; direction: Vec3 }\n | { kind: 'tool'; tool: string; reach: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'extinguish'; range: number; coolC: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'hand'; reach: number; origin: Vec3; direction: Vec3 }\n\n/**\n * The `Hit` a ballistic shot makes at `point` (world space): the energy is what is left of the shot at that distance from its origin\n * (`shot.energyAt`), the direction and calibre come from the shot. `normal` (the surface normal at the point, when the caller knows it) does not\n * change the hit; it is accepted so that callers can pass what their raycast returned and so that a stricter implementation could use it.\n */\nexport const shotToHit = (shot: Shot, point: Vec3, normal?: Vec3): Hit => {\n void normal\n const dx = point[0] - shot.origin[0]\n const dy = point[1] - shot.origin[1]\n const dz = point[2] - shot.origin[2]\n const distance = Math.hypot(dx, dy, dz)\n return {\n type: 'ballistic',\n point: [point[0], point[1], point[2]],\n direction: [shot.direction[0], shot.direction[1], shot.direction[2]],\n energy: shot.energyAt(distance),\n caliber: shot.caliber,\n source: shot.source ?? shot.weapon,\n }\n}\n","import type { Vec3 } from './destruction'\n\n/** Pose of one part (or of the whole item) at a key: position offset in metres and Euler XYZ rotation in radians, both relative to the rest pose. */\nexport interface AnimationPose {\n position?: Vec3\n rotation?: Vec3\n}\n\nexport interface AnimationKey {\n /** Seconds from the start of the clip. */\n t: number\n /** Pose of the item's root. */\n position?: Vec3\n rotation?: Vec3\n /** Poses of named parts: the key is a destruction part id (a pistol `reload` moves `mag`; a car door `open` rotates `door_l`). */\n parts?: Record<string, AnimationPose>\n}\n\nexport interface AnimationEventSpec {\n /** Seconds from the start of the clip. */\n t: number\n /** snake_case type the host maps (`sound`, `eject_casing`, `door_latch`...). */\n type: string\n data?: Record<string, unknown>\n}\n\n/** A use animation a module brings with its item. Poses between keys are interpolated by the player (the test room does it linearly). */\nexport interface AnimationClipSpec {\n /** snake_case: `reload`, `open`, `drink`... Unique within the item. */\n id: string\n /** Seconds. */\n duration: number\n keys: AnimationKey[]\n events?: AnimationEventSpec[]\n}\n\n/** What an item exposes when it brings its own animations. */\nexport interface ItemAnimationContract {\n animations: AnimationClipSpec[]\n}\n\nconst finite3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every((n) => typeof n === 'number' && Number.isFinite(n))\n\n/**\n * Problems with a clip (empty when it is valid): a snake_case id, a positive finite duration, at least one key, key and event times inside\n * `[0, duration]` and not going backwards, finite vectors, every named part one of `partIds`, event types that are non-empty strings and\n * JSON-serializable event data.\n */\nexport const checkAnimation = (clip: AnimationClipSpec, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const parts = new Set(partIds)\n const id = String(clip?.id ?? '')\n if (!/^[a-z][a-z0-9_]*$/.test(id)) problems.push(`clip id \"${id}\" must be snake_case`)\n const label = `clip \"${id}\"`\n if (!(typeof clip?.duration === 'number' && Number.isFinite(clip.duration) && clip.duration > 0)) problems.push(`${label} needs a positive finite duration`)\n const dur = typeof clip?.duration === 'number' && clip.duration > 0 ? clip.duration : Infinity\n if (!Array.isArray(clip?.keys) || clip.keys.length === 0) {\n problems.push(`${label} needs at least one key`)\n return { ok: false, problems }\n }\n let prev = -Infinity\n clip.keys.forEach((k, i) => {\n if (!(typeof k.t === 'number' && Number.isFinite(k.t)) || k.t < 0 || k.t > dur + 1e-9) problems.push(`${label} key ${i} has t=${String(k.t)} outside 0..${dur}`)\n else if (k.t < prev) problems.push(`${label} key ${i} goes back in time (${k.t} < ${prev})`)\n else prev = k.t\n for (const f of ['position', 'rotation'] as const) if (k[f] !== undefined && !finite3(k[f])) problems.push(`${label} key ${i} has an invalid ${f}`)\n for (const [pid, pose] of Object.entries(k.parts ?? {})) {\n if (!parts.has(pid)) problems.push(`${label} key ${i} moves unknown part \"${pid}\"`)\n for (const f of ['position', 'rotation'] as const) if (pose?.[f] !== undefined && !finite3(pose[f])) problems.push(`${label} key ${i} part \"${pid}\" has an invalid ${f}`)\n }\n })\n let prevEv = -Infinity\n ;(clip.events ?? []).forEach((e, i) => {\n if (!(typeof e.t === 'number' && Number.isFinite(e.t)) || e.t < 0 || e.t > dur + 1e-9) problems.push(`${label} event ${i} has t=${String(e.t)} outside 0..${dur}`)\n else if (e.t < prevEv) problems.push(`${label} event ${i} goes back in time`)\n else prevEv = e.t\n if (typeof e.type !== 'string' || e.type === '') problems.push(`${label} event ${i} needs a type`)\n try {\n JSON.stringify(e.data ?? {})\n } catch {\n problems.push(`${label} event ${i} data is not JSON`)\n }\n })\n return { ok: problems.length === 0, problems }\n}\n","import type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from './animation'\nimport { checkAnimation } from './animation'\nimport type { HostEvent } from './module'\n\n/** Clips a tool can bring, one per move of its cycle. A tool brings the ones it has; a missing clip is simply not played. */\nexport const TOOL_CLIP = {\n DRAW: 'draw',\n SHOT: 'shot',\n MISFIRE: 'misfire',\n EMPTY: 'empty',\n CYCLE: 'cycle',\n RELOAD: 'reload',\n FEED: 'feed',\n FAULT: 'fault',\n CLEAR: 'clear',\n SAFETY_ON: 'safety_on',\n SAFETY_OFF: 'safety_off',\n MODE: 'mode',\n /** A throwable with the pin out, held until it is thrown. */\n COOK: 'cook',\n /** The stock folds, unfolds, slides in or out (variants `fold`, `unfold`, `collapse`, `extend`). */\n STOCK: 'stock',\n /** A light or a laser is switched (variants `on`, `off`). */\n TOGGLE: 'toggle',\n} as const\nexport type ToolClipId = (typeof TOOL_CLIP)[keyof typeof TOOL_CLIP]\n\n/** What a renderer does when a rule event arrives. `variant` picks `<clip>_<variant>` when the tool has it, else `<clip>`. */\nexport type ToolAnimationStep =\n | { readonly type: 'play'; readonly clip: ToolClipId; readonly variant?: string; readonly duration?: number; readonly repeat?: number }\n /** Move the clip that is playing to the marker (a clip event `stage` with `data.stage`) the rule just reached. */\n | { readonly type: 'sync'; readonly stage: string }\n /** The rule says the phase is over: the clip jumps to its end if it is still running. */\n | { readonly type: 'finish'; readonly clip: ToolClipId }\n\nconst stockVariant = (event: Extract<HostEvent, { type: 'stock' }>): string => {\n const isFolding = event.kind === undefined ? false : event.kind.includes('fold')\n if (event.state === 'collapsed') return isFolding ? 'fold' : 'collapse'\n return isFolding ? 'unfold' : 'extend'\n}\n\n/** The move a host event asks of the tool in hand, or null when it has no motion. */\nexport const toolAnimationStep = (event: HostEvent): ToolAnimationStep | null => {\n switch (event.type) {\n case 'tool':\n return { type: 'play', clip: TOOL_CLIP.DRAW, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'shot':\n return { type: 'play', clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) }\n case 'misfire':\n return { type: 'play', clip: TOOL_CLIP.MISFIRE }\n case 'empty':\n return { type: 'play', clip: TOOL_CLIP.EMPTY }\n case 'mode':\n return { type: 'play', clip: TOOL_CLIP.MODE, variant: event.mode }\n case 'fault':\n return { type: 'play', clip: TOOL_CLIP.FAULT, variant: event.fault }\n case 'clear':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CLEAR }\n return { type: 'play', clip: TOOL_CLIP.CLEAR, variant: event.fault, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'safety':\n return { type: 'play', clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF }\n case 'cycle':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CYCLE }\n return { type: 'play', clip: TOOL_CLIP.CYCLE, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'reload':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.RELOAD }\n return { type: 'play', clip: TOOL_CLIP.RELOAD, ...(event.kind === undefined ? {} : { variant: event.kind }), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'stage':\n return { type: 'sync', stage: event.stage }\n case 'feed':\n return { type: 'play', clip: TOOL_CLIP.FEED }\n case 'cook':\n if (event.phase === 'start') return { type: 'play', clip: TOOL_CLIP.COOK, duration: event.fuse }\n return { type: 'finish', clip: TOOL_CLIP.COOK }\n case 'stock':\n return { type: 'play', clip: TOOL_CLIP.STOCK, variant: stockVariant(event), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'toggle':\n return { type: 'play', clip: TOOL_CLIP.TOGGLE, variant: event.on ? 'on' : 'off' }\n default:\n return null\n }\n}\n\n/** Where a renderer puts the poses: every part of the tool by id (the ids the clips move), and the whole tool. Poses are offsets from rest. */\nexport interface ToolRig {\n setPartPose(partId: string, pose: AnimationPose): void\n setRootPose?(pose: AnimationPose): void\n}\n\n/** Clips by id, with the variants as `<clip>_<variant>`. */\nexport type ToolClipSet = Readonly<Record<string, AnimationClipSpec>>\n\n/** A renderer's tool animator: feed it the host events and the frame time. */\nexport interface ToolAnimator {\n handle(event: HostEvent): void\n update(dt: number): void\n /** Ids of the clips playing now. */\n readonly playing: readonly string[]\n dispose(): void\n}\n\nexport const STAGE_EVENT = 'stage'\n\n/** The clip with its times (keys and events) scaled so that it lasts `duration` seconds. */\nexport const scaleClip = (clip: AnimationClipSpec, duration: number): AnimationClipSpec => {\n const factor = clip.duration > 0 ? duration / clip.duration : 1\n return {\n ...clip,\n duration,\n keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),\n ...(clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}),\n }\n}\n\nconst ZERO: [number, number, number] = [0, 0, 0]\nconst mix = (from: readonly number[], to: readonly number[], fraction: number): [number, number, number] => [\n (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,\n (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,\n (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction,\n]\n\n/** Pose of the whole tool (`partId` undefined) or of one part at `time`, linear between keys; a key that does not name it means rest. */\nexport const sampleClip = (clip: AnimationClipSpec, partId: string | undefined, time: number): { position: [number, number, number]; rotation: [number, number, number] } => {\n const points = clip.keys.map((key) => {\n const pose = partId === undefined ? key : key.parts?.[partId]\n return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO }\n })\n const first = points[0]\n if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO })\n const last = points[points.length - 1]\n if (!last) return { position: ZERO, rotation: ZERO }\n if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) }\n const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)))\n const from = points[index]\n const to = points[index + 1]\n if (!from || !to) return { position: ZERO, rotation: ZERO }\n const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0\n return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) }\n}\n\n/** Problems with a clip set (empty when valid): each key is the clip id (or `<clip>_<variant>`), every clip passes `checkAnimation`, and a `stage` event names its stage. */\nexport const checkToolClips = (clips: ToolClipSet, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const parts = [...partIds]\n const problems: string[] = []\n for (const [key, clip] of Object.entries(clips)) {\n if (clip.id !== key) problems.push(`clip \"${key}\" has the id \"${clip.id}\"`)\n if (!(clip.duration > 0)) problems.push(`clip \"${key}\" has no duration`)\n problems.push(...checkAnimation(clip, parts).problems)\n for (const event of clip.events ?? []) if (event.type === STAGE_EVENT && typeof event.data?.stage !== 'string') problems.push(`clip \"${key}\" has a stage event without data.stage`)\n }\n return { ok: problems.length === 0, problems }\n}\n\ninterface Instance {\n readonly name: string\n readonly clip: AnimationClipSpec\n time: number\n delay: number\n fired: number\n}\n\nexport interface ToolClipPlayerOptions {\n clips: ToolClipSet\n rig: ToolRig\n /** Called for each clip event as its time passes (`eject_casing`, `drop_magazine`, `stage`...). */\n onEvent?(event: AnimationEventSpec, clip: string): void\n /** Seconds between the rounds of a `repeat` (a burst): default 0.1. */\n repeatInterval?(): number\n}\n\n/** The default player of a tool's clips: runs the steps of `toolAnimationStep` against a rig, scaled to the duration the rule gives. */\nexport interface ToolClipPlayer {\n apply(step: ToolAnimationStep): void\n update(dt: number): void\n readonly playing: readonly string[]\n}\n\nexport const createToolClipPlayer = (options: ToolClipPlayerOptions): ToolClipPlayer => {\n const { clips, rig, onEvent } = options\n let instances: Instance[] = []\n\n const find = (clip: string, variant?: string): { name: string; clip: AnimationClipSpec } | undefined => {\n const name = variant !== undefined && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip\n const found = clips[name]\n return found ? { name, clip: found } : undefined\n }\n\n const render = (instance: Instance): void => {\n const time = Math.min(instance.time, instance.clip.duration)\n const root = sampleClip(instance.clip, undefined, time)\n if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root)\n const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})))\n for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time))\n }\n\n const fireEvents = (instance: Instance, upTo: number): void => {\n const events = instance.clip.events ?? []\n while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {\n const event = events[instance.fired]\n instance.fired += 1\n if (event) onEvent?.(event, instance.name)\n }\n }\n\n return {\n apply(step) {\n if (step.type === 'sync') {\n for (const instance of instances) {\n const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage)\n if (marker && instance.time < marker.t) instance.time = marker.t\n }\n return\n }\n if (step.type === 'finish') {\n for (const instance of instances) {\n if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue\n fireEvents(instance, instance.clip.duration)\n instance.time = instance.clip.duration\n }\n return\n }\n const found = find(step.clip, step.variant)\n if (!found) return\n const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip\n const interval = options.repeatInterval?.() ?? 0.1\n instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0)\n for (let round = 0; round < (step.repeat ?? 1); round++) {\n instances.push({ name: found.name, clip, time: 0, delay: round * interval, fired: 0 })\n }\n },\n update(dt) {\n for (const instance of instances) {\n const carried = instance.delay > 0 ? dt - instance.delay : dt\n if (instance.delay > 0) {\n instance.delay = Math.max(0, instance.delay - dt)\n if (instance.delay > 0) continue\n }\n instance.time += carried\n fireEvents(instance, instance.time)\n render(instance)\n }\n instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration)\n },\n get playing() {\n return instances.map((instance) => instance.name)\n },\n }\n}\n","import type { Vec3 } from './destruction'\n\n/**\n * The bench of a module: controls, layers and counters it declares as data. The host keeps the values, draws them in a generic way and hands\n * every change back through `ModuleHost.bench`. Nothing here is specific to a kind of module.\n */\nexport type ControlValue = number | boolean | string\n\nexport interface ChoiceOption {\n readonly id: string\n readonly name: string\n}\n\ninterface ControlBase {\n /** snake_case, unique across the module's controls, layers and metrics. */\n readonly id: string\n /** Display name, already translated for the locale the host asked for. */\n readonly name: string\n readonly hint?: string\n readonly hidden?: boolean\n}\n\nexport interface NumberControl extends ControlBase {\n readonly kind: 'number'\n readonly min: number\n readonly max: number\n readonly step?: number\n readonly unit?: string\n readonly default: number\n}\n\nexport interface BooleanControl extends ControlBase {\n readonly kind: 'boolean'\n readonly default: boolean\n}\n\nexport interface ChoiceControl extends ControlBase {\n readonly kind: 'choice'\n readonly options: readonly ChoiceOption[]\n readonly default: string\n}\n\n/** A button: no value, only the press. */\nexport interface ActionControl extends ControlBase {\n readonly kind: 'action'\n}\n\nexport type ModuleControl = NumberControl | BooleanControl | ChoiceControl | ActionControl\n\n/** Something of the module the viewer turns on or off (smoke, flash, casings). */\nexport interface ModuleLayer {\n readonly id: string\n readonly name: string\n /** On unless `false`. */\n readonly default?: boolean\n}\n\n/** Pulled: the room calls read only when it samples (~4 Hz, or on TestRoom.metrics()). */\nexport interface ModuleMetric {\n readonly id: string\n readonly name: string\n readonly unit?: string\n /** Budget: the host shows a bar and warns past it. */\n readonly max?: number\n readonly digits?: number\n read(): number | string\n}\n\nexport type BenchChange =\n | { readonly kind: 'control'; readonly id: string; readonly value: ControlValue }\n | { readonly kind: 'layer'; readonly id: string; readonly on: boolean }\n | { readonly kind: 'action'; readonly id: string }\n\nexport interface ControlPatch {\n readonly hidden?: boolean\n readonly disabled?: boolean\n readonly options?: readonly ChoiceOption[]\n readonly value?: ControlValue\n}\n\n/** What the host lends a module that declares a bench: the current values and the changes. */\nexport interface ModuleBench {\n value(id: string): ControlValue | undefined\n layer(id: string): boolean\n /** Right after attach returns, the host sends one change per control (not actions) and per layer, in declaration order. */\n onChange(listener: (change: BenchChange) => void): () => void\n /** `value` sets without emitting (no echo loops); `options` falls back to the first option if the value is no longer offered. */\n patch(id: string, patch: ControlPatch): void\n /** Move the host camera (a near / middle / far choice). */\n look(eye: Vec3, target: Vec3): void\n}\n\nexport interface BenchReport {\n readonly ok: boolean\n readonly problems: readonly string[]\n}\n\nexport interface BenchDeclaration {\n readonly controls?: readonly ModuleControl[]\n readonly layers?: readonly ModuleLayer[]\n readonly metrics?: readonly ModuleMetric[]\n}\n\nconst SNAKE_CASE = /^[a-z][a-z0-9_]*$/\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\n\nfunction checkControl(control: ModuleControl, problems: string[]): void {\n const label = `control \"${control.id}\"`\n if (control.kind === 'number') {\n if (!finite(control.min) || !finite(control.max) || control.min >= control.max) problems.push(`${label} needs min < max`)\n if (control.step !== undefined && !(finite(control.step) && control.step > 0)) problems.push(`${label} needs a step > 0`)\n if (!finite(control.default) || control.default < control.min || control.default > control.max) problems.push(`${label} default ${String(control.default)} is outside ${control.min}..${control.max}`)\n return\n }\n if (control.kind !== 'choice') return\n if (control.options.length === 0) {\n problems.push(`${label} needs at least one option`)\n return\n }\n const seen = new Set<string>()\n for (const option of control.options) {\n if (seen.has(option.id)) problems.push(`${label} repeats option \"${option.id}\"`)\n seen.add(option.id)\n }\n if (!seen.has(control.default)) problems.push(`${label} default \"${control.default}\" is not among its options`)\n}\n\n/** snake_case ids unique across controls, layers and metrics; min < max; step > 0; default in range; options non-empty, unique, default among them; metric max > 0. */\nexport function checkBench(declared: BenchDeclaration): BenchReport {\n const problems: string[] = []\n const ids = new Set<string>()\n const claim = (kind: string, id: string): void => {\n if (!SNAKE_CASE.test(id)) problems.push(`${kind} id \"${id}\" must be snake_case`)\n if (ids.has(id)) problems.push(`duplicate id \"${id}\" across controls, layers and metrics`)\n ids.add(id)\n }\n for (const control of declared.controls ?? []) {\n claim('control', control.id)\n checkControl(control, problems)\n }\n for (const layer of declared.layers ?? []) claim('layer', layer.id)\n for (const metric of declared.metrics ?? []) {\n claim('metric', metric.id)\n if (metric.max !== undefined && !(finite(metric.max) && metric.max > 0)) problems.push(`metric \"${metric.id}\" needs a max > 0`)\n }\n return { ok: problems.length === 0, problems }\n}\n","import { checkDestructible as check } from '@adatechnology/game-contracts'\nimport type { CheckOptions as ContractCheckOptions, DestructibleImpl } from '@adatechnology/game-contracts'\nimport { MATERIALS } from './materials'\n\n// The contract itself lives in @adatechnology/game-contracts (a module depends only on that); re-exported here so that no import breaks.\nexport { IMPACT_CONTRACT, checkHit } from '@adatechnology/game-contracts'\nexport type { DestructibleImpl, ImpactContract } from '@adatechnology/game-contracts'\n\nexport interface CheckOptions {\n /** Ids of custom materials the impl uses besides the built-in `MATERIALS`. */\n materials?: string[]\n}\n\n/**\n * `checkDestructible` of `@adatechnology/game-contracts`, with the built-in `MATERIALS` (plus `options.materials`) as the known material ids.\n * It hits the impl (and calls `reset()` afterwards when there is one).\n */\nexport const checkDestructible = (impl: DestructibleImpl, options: CheckOptions = {}): { ok: boolean; problems: string[] } => {\n const contractOptions: ContractCheckOptions = { materials: [...MATERIALS.map((m) => m.id), ...(options.materials ?? [])] }\n return check(impl, contractOptions)\n}\n"],"mappings":"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","names":["checkDestructible","n0","n1","a","c","t0","t1","dy","inside","sign","n","a","b","th","clamp","pos","dmg","checkDestructible"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/chain.ts","../src/math.ts","../src/fracture.ts","../src/breach.ts","../src/layers.ts","../src/rebar.ts","../src/data/materials.json","../src/data/material-hints.json","../src/materials.ts","../src/world.ts","../src/data/assemblies.json","../src/assemblies.ts","../src/frame.ts","../src/size.ts","../src/locale.ts","../../game-contracts/src/impact.ts","../../game-contracts/src/body.ts","../../game-contracts/src/spec.ts","../../game-contracts/src/weapons.ts","../../game-contracts/src/animation.ts","../../game-contracts/src/tool-animation.ts","../../game-contracts/src/registry.ts","../../game-contracts/src/bench.ts","../src/contracts.ts"],"sourcesContent":["export type * from './types'\nexport { createDestruction } from './world'\nexport { explosivePart, FIRE_PRIME_C } from './chain'\nexport type { ChainTrigger, ExplosivePartOptions, WorldExplosive } from './chain'\nexport { MATERIALS, JOINT_DEFAULTS, JOINT_BY_MATERIALS, inferJoints, guessMaterial, partVolume, partMass, partThickness, partCapacity, fragility } from './materials'\nexport { ASSEMBLIES, registerAssembly, getAssembly, assemblyPart, assemblyDepth } from './assemblies'\nexport type { AssemblyDef, AssemblyPartOptions } from './assemblies'\nexport { buildFrame } from './frame'\nexport type { FrameOptions } from './frame'\nexport { sizeStructure } from './size'\nexport { vec, quat, quatFromEuler, rotateVec, toLocal, toWorld } from './math'\nexport { resolveStrings, locales } from './locale'\nexport type { DestructionStrings, DestructionLocale } from './locale'\nexport { checkDestructible, checkHit, IMPACT_CONTRACT } from './contracts'\nexport type { DestructibleImpl, ImpactContract, CheckOptions } from './contracts'\n","import type { ChainDelay, ExplosionChain, PartSpec } from './types'\n\n/** What can set an explosive part off from outside, in the order a hit can carry it. */\nexport type ChainTrigger = 'shot' | 'fire' | 'explosion'\n\n/** Temperature in °C that primes a part with `chain.fire` when its `explodes.atC` is not set. */\nexport const FIRE_PRIME_C = 300\n\n/** Seconds from a trigger to the blast: a number is fixed, `[min, max]` is drawn from the world seed (one draw). */\nexport const drawChainDelay = (delay: ChainDelay, random: () => number): number => {\n if (typeof delay === 'number') return delay\n const [min, max] = delay\n return min + random() * (max - min)\n}\n\n/** The delay `spec` gives for `trigger`, or undefined when the part does not answer to it. */\nexport const chainDelayOf = (spec: PartSpec, trigger: ChainTrigger): ChainDelay | undefined => spec.explodes?.chain?.[trigger]\n\n/** Fraction of the hit points a shot must have taken off before it primes the part. */\nexport const shotDamageFractionOf = (spec: PartSpec): number => spec.explodes?.chain?.shotDamageFraction ?? 0\n\n/** The numbers of an explosive that sits in the world, as `game-weapons` gives them (`ExplosiveDef` fits). */\nexport interface WorldExplosive {\n readonly energy: number\n /** Metres within which the blast reaches other parts (and primes theirs). */\n readonly injuryRadius: number\n readonly chain?: ExplosionChain\n}\n\nexport interface ExplosivePartOptions {\n /** Temperature in °C at which fire primes (or sets off) the part; default `FIRE_PRIME_C` when the explosive answers to fire. */\n readonly atC?: number\n}\n\n/**\n * A part that explodes with the energy and reach of `explosive` and answers to what `explosive.chain` says: a bullet, fire or a blast\n * nearby primes it and it goes off after the delay. `part` is everything else about the part (shape, material, position, fluid inside).\n */\nexport const explosivePart = (explosive: WorldExplosive, part: Omit<PartSpec, 'explodes'>, options: ExplosivePartOptions = {}): PartSpec => ({\n ...part,\n explodes: {\n energy: explosive.energy,\n radius: explosive.injuryRadius,\n ...(options.atC !== undefined ? { atC: options.atC } : {}),\n ...(explosive.chain ? { chain: { ...explosive.chain } } : {}),\n },\n})\n","import type { PartShape, Quat, Vec3 } from './types'\n\nconst EPS = 1e-9\n\n/** Small vector helpers (arrays of three numbers). Pure functions; they allocate a new array. */\nexport const vec = {\n add: (a: Vec3, b: Vec3): Vec3 => [a[0] + b[0], a[1] + b[1], a[2] + b[2]],\n sub: (a: Vec3, b: Vec3): Vec3 => [a[0] - b[0], a[1] - b[1], a[2] - b[2]],\n scale: (a: Vec3, s: number): Vec3 => [a[0] * s, a[1] * s, a[2] * s],\n dot: (a: Vec3, b: Vec3): number => a[0] * b[0] + a[1] * b[1] + a[2] * b[2],\n cross: (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]],\n length: (a: Vec3): number => Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]),\n distance: (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]),\n normalize: (a: Vec3, fallback: Vec3 = [0, 1, 0]): Vec3 => {\n const l = Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])\n return l < EPS ? [fallback[0], fallback[1], fallback[2]] : [a[0] / l, a[1] / l, a[2] / l]\n },\n lerp: (a: Vec3, b: Vec3, t: number): Vec3 => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t],\n /** `a + b * s` */\n madd: (a: Vec3, b: Vec3, s: number): Vec3 => [a[0] + b[0] * s, a[1] + b[1] * s, a[2] + b[2] * s],\n}\n\nconst IDENTITY: Quat = [0, 0, 0, 1]\n\n/** Quaternion helpers (`[x, y, z, w]`). */\nexport const quat = {\n identity: (): Quat => [IDENTITY[0], IDENTITY[1], IDENTITY[2], IDENTITY[3]],\n /** Hamilton product `a * b` (apply `b` first, then `a`). */\n mul: (a: Quat, b: Quat): Quat => [\n a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1],\n a[3] * b[1] - a[0] * b[2] + a[1] * b[3] + a[2] * b[0],\n a[3] * b[2] + a[0] * b[1] - a[1] * b[0] + a[2] * b[3],\n a[3] * b[3] - a[0] * b[0] - a[1] * b[1] - a[2] * b[2],\n ],\n conjugate: (q: Quat): Quat => [-q[0], -q[1], -q[2], q[3]],\n normalize: (q: Quat): Quat => {\n const l = Math.hypot(q[0], q[1], q[2], q[3])\n return l < EPS ? [0, 0, 0, 1] : [q[0] / l, q[1] / l, q[2] / l, q[3] / l]\n },\n /** Rotation of `angle` radians around a unit `axis`. */\n fromAxisAngle: (axis: Vec3, angle: number): Quat => {\n const s = Math.sin(angle / 2)\n return [axis[0] * s, axis[1] * s, axis[2] * s, Math.cos(angle / 2)]\n },\n /** Rotation matrix, row-major 3x3. */\n toMatrix: (q: Quat): number[] => {\n const [x, y, z, w] = q\n const xx = x * x, yy = y * y, zz = z * z, xy = x * y, xz = x * z, yz = y * z, wx = w * x, wy = w * y, wz = w * z\n return [1 - 2 * (yy + zz), 2 * (xy - wz), 2 * (xz + wy), 2 * (xy + wz), 1 - 2 * (xx + zz), 2 * (yz - wx), 2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (xx + yy)]\n },\n /** Quaternion from three orthonormal columns (the images of the x, y and z axes). */\n fromColumns: (cx: Vec3, cy: Vec3, cz: Vec3): Quat => {\n const m00 = cx[0], m10 = cx[1], m20 = cx[2]\n const m01 = cy[0], m11 = cy[1], m21 = cy[2]\n const m02 = cz[0], m12 = cz[1], m22 = cz[2]\n const tr = m00 + m11 + m22\n let q: Quat\n if (tr > 0) {\n const s = Math.sqrt(tr + 1) * 2\n q = [(m21 - m12) / s, (m02 - m20) / s, (m10 - m01) / s, 0.25 * s]\n } else if (m00 > m11 && m00 > m22) {\n const s = Math.sqrt(1 + m00 - m11 - m22) * 2\n q = [0.25 * s, (m01 + m10) / s, (m02 + m20) / s, (m21 - m12) / s]\n } else if (m11 > m22) {\n const s = Math.sqrt(1 + m11 - m00 - m22) * 2\n q = [(m01 + m10) / s, 0.25 * s, (m12 + m21) / s, (m02 - m20) / s]\n } else {\n const s = Math.sqrt(1 + m22 - m00 - m11) * 2\n q = [(m02 + m20) / s, (m12 + m21) / s, 0.25 * s, (m10 - m01) / s]\n }\n return quat.normalize(q)\n },\n}\n\n/** Quaternion from Euler angles in radians, order XYZ (the three.js default). */\nexport const quatFromEuler = (x: number, y: number, z: number): Quat => {\n const c1 = Math.cos(x / 2), c2 = Math.cos(y / 2), c3 = Math.cos(z / 2)\n const s1 = Math.sin(x / 2), s2 = Math.sin(y / 2), s3 = Math.sin(z / 2)\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n}\n\n/** Rotate a vector by a quaternion. */\nexport const rotateVec = (q: Quat, v: Vec3): Vec3 => {\n const qx = q[0], qy = q[1], qz = q[2], qw = q[3]\n const tx = 2 * (qy * v[2] - qz * v[1])\n const ty = 2 * (qz * v[0] - qx * v[2])\n const tz = 2 * (qx * v[1] - qy * v[0])\n return [v[0] + qw * tx + (qy * tz - qz * ty), v[1] + qw * ty + (qz * tx - qx * tz), v[2] + qw * tz + (qx * ty - qy * tx)]\n}\n\n/** World point to the local space of a transform (`position`, `rotation`). */\nexport const toLocal = (position: Vec3, rotation: Quat, p: Vec3): Vec3 =>\n rotateVec([-rotation[0], -rotation[1], -rotation[2], rotation[3]], [p[0] - position[0], p[1] - position[1], p[2] - position[2]])\n\n/** Local point of a transform (`position`, `rotation`) to world space. */\nexport const toWorld = (position: Vec3, rotation: Quat, p: Vec3): Vec3 => {\n const r = rotateVec(rotation, p)\n return [r[0] + position[0], r[1] + position[1], r[2] + position[2]]\n}\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Shapes (part space: centred on the origin, cylinders along +Y)\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\n/** Dimensions of the bounding box of a shape, in the shape's own axes. */\nexport const shapeDims = (s: PartShape): Vec3 => {\n if (s.kind === 'box') return [s.size[0], s.size[1], s.size[2]]\n if (s.kind === 'cylinder') return [s.radius * 2, s.height, s.radius * 2]\n return [s.radius * 2, s.radius * 2, s.radius * 2]\n}\n\n/** Radius of the sphere that encloses the shape. */\nexport const shapeBound = (s: PartShape): number => {\n if (s.kind === 'box') return 0.5 * Math.hypot(s.size[0], s.size[1], s.size[2])\n if (s.kind === 'cylinder') return Math.hypot(s.radius, s.height / 2)\n return s.radius\n}\n\nexport const shapeArea = (s: PartShape): number => {\n if (s.kind === 'box') return 2 * (s.size[0] * s.size[1] + s.size[1] * s.size[2] + s.size[0] * s.size[2])\n if (s.kind === 'cylinder') return 2 * Math.PI * s.radius * s.height + 2 * Math.PI * s.radius * s.radius\n return 4 * Math.PI * s.radius * s.radius\n}\n\nexport interface ShapeRay {\n /** Entry distance along the ray (negative when the origin is inside). */\n t0: number\n /** Normal at the entry, outward. */\n n0: Vec3\n /** Exit distance. */\n t1: number\n /** Normal at the exit, outward. */\n n1: Vec3\n}\n\n/** Exact ray intersection with a shape in part space. `d` need not be normalised but must be non-zero. */\nexport const rayShape = (s: PartShape, o: Vec3, d: Vec3): ShapeRay | null => {\n if (s.kind === 'box') {\n let tmin = -Infinity, tmax = Infinity\n let a0 = 0, a1 = 0, s0 = 1, s1 = 1\n for (let i = 0; i < 3; i++) {\n const h = s.size[i] / 2\n if (Math.abs(d[i]) < EPS) {\n if (Math.abs(o[i]) > h) return null\n continue\n }\n let ta = (-h - o[i]) / d[i]\n let tb = (h - o[i]) / d[i]\n let sa = -1, sb = 1\n if (ta > tb) {\n const t = ta\n ta = tb\n tb = t\n sa = 1\n sb = -1\n }\n if (ta > tmin) {\n tmin = ta\n a0 = i\n s0 = sa\n }\n if (tb < tmax) {\n tmax = tb\n a1 = i\n s1 = sb\n }\n if (tmin > tmax) return null\n }\n if (tmax < 0 || !Number.isFinite(tmin) || !Number.isFinite(tmax)) return null\n const n0: Vec3 = [0, 0, 0]\n const n1: Vec3 = [0, 0, 0]\n n0[a0] = s0\n n1[a1] = s1\n return { t0: tmin, n0, t1: tmax, n1 }\n }\n if (s.kind === 'sphere') {\n const b = vec.dot(o, d)\n const a = vec.dot(d, d)\n const c = vec.dot(o, o) - s.radius * s.radius\n const disc = b * b - a * c\n if (disc < 0) return null\n const sq = Math.sqrt(disc)\n const t0 = (-b - sq) / a\n const t1 = (-b + sq) / a\n if (t1 < 0) return null\n const p0 = vec.madd(o, d, t0)\n const p1 = vec.madd(o, d, t1)\n return { t0, n0: vec.normalize(p0), t1, n1: vec.normalize(p1) }\n }\n // cylinder along Y: intersection of the infinite cylinder interval and the y slab\n const r = s.radius\n const hh = s.height / 2\n const a = d[0] * d[0] + d[2] * d[2]\n const c = o[0] * o[0] + o[2] * o[2] - r * r\n let tA = -Infinity, tB = Infinity\n if (a > EPS) {\n const b = o[0] * d[0] + o[2] * d[2]\n const disc = b * b - a * c\n if (disc < 0) return null\n const sq = Math.sqrt(disc)\n tA = (-b - sq) / a\n tB = (-b + sq) / a\n } else if (c > 0) return null\n let yA = -Infinity, yB = Infinity\n if (Math.abs(d[1]) > EPS) {\n yA = (-hh - o[1]) / d[1]\n yB = (hh - o[1]) / d[1]\n if (yA > yB) {\n const t = yA\n yA = yB\n yB = t\n }\n } else if (Math.abs(o[1]) > hh) return null\n const t0 = Math.max(tA, yA)\n const t1 = Math.min(tB, yB)\n if (t0 > t1 || t1 < 0 || !Number.isFinite(t0) || !Number.isFinite(t1)) return null\n const normalAt = (t: number, fromSide: boolean, sign: number): Vec3 => {\n if (fromSide) {\n const p = vec.madd(o, d, t)\n return vec.normalize([p[0], 0, p[2]], [1, 0, 0])\n }\n return [0, sign, 0]\n }\n const n0 = normalAt(t0, tA >= yA, d[1] > 0 ? -1 : 1)\n const n1 = normalAt(t1, tB <= yB, d[1] > 0 ? 1 : -1)\n return { t0, n0, t1, n1 }\n}\n\n/** Distance from a part-space point to the shape (0 inside). */\nexport const distanceToShape = (s: PartShape, p: Vec3): number => {\n if (s.kind === 'box') {\n const dx = Math.max(Math.abs(p[0]) - s.size[0] / 2, 0)\n const dy = Math.max(Math.abs(p[1]) - s.size[1] / 2, 0)\n const dz = Math.max(Math.abs(p[2]) - s.size[2] / 2, 0)\n return Math.hypot(dx, dy, dz)\n }\n if (s.kind === 'sphere') return Math.max(0, vec.length(p) - s.radius)\n const dr = Math.max(0, Math.hypot(p[0], p[2]) - s.radius)\n const dy = Math.max(0, Math.abs(p[1]) - s.height / 2)\n return Math.hypot(dr, dy)\n}\n\n/** Nearest point on the surface of a shape to a part-space point, with the outward normal. */\nexport const surfacePoint = (s: PartShape, p: Vec3): { point: Vec3; normal: Vec3 } => {\n if (s.kind === 'box') {\n const h: Vec3 = [s.size[0] / 2, s.size[1] / 2, s.size[2] / 2]\n const inside = Math.abs(p[0]) <= h[0] && Math.abs(p[1]) <= h[1] && Math.abs(p[2]) <= h[2]\n if (!inside) {\n const c: Vec3 = [Math.max(-h[0], Math.min(h[0], p[0])), Math.max(-h[1], Math.min(h[1], p[1])), Math.max(-h[2], Math.min(h[2], p[2]))]\n return { point: c, normal: vec.normalize(vec.sub(p, c)) }\n }\n let axis = 0\n let best = Infinity\n for (let i = 0; i < 3; i++) {\n const g = h[i] - Math.abs(p[i])\n if (g < best) {\n best = g\n axis = i\n }\n }\n const sign = p[axis] >= 0 ? 1 : -1\n const point: Vec3 = [p[0], p[1], p[2]]\n point[axis] = sign * h[axis]\n const normal: Vec3 = [0, 0, 0]\n normal[axis] = sign\n return { point, normal }\n }\n if (s.kind === 'sphere') {\n const n = vec.normalize(p)\n return { point: vec.scale(n, s.radius), normal: n }\n }\n const rho = Math.hypot(p[0], p[2])\n const hh = s.height / 2\n const inside = rho <= s.radius && Math.abs(p[1]) <= hh\n if (!inside) {\n const k = rho > s.radius ? s.radius / rho : 1\n const c: Vec3 = [p[0] * k, Math.max(-hh, Math.min(hh, p[1])), p[2] * k]\n return { point: c, normal: vec.normalize(vec.sub(p, c)) }\n }\n if (s.radius - rho < hh - Math.abs(p[1])) {\n const k = rho < EPS ? 0 : s.radius / rho\n const point: Vec3 = rho < EPS ? [s.radius, p[1], 0] : [p[0] * k, p[1], p[2] * k]\n return { point, normal: vec.normalize([point[0], 0, point[2]], [1, 0, 0]) }\n }\n const sign = p[1] >= 0 ? 1 : -1\n return { point: [p[0], sign * hh, p[2]], normal: [0, sign, 0] }\n}\n\n/** Axis-aligned bounds of a shape with a given centre and orientation. */\nexport const aabbOf = (s: PartShape, center: Vec3, q: Quat): { min: Vec3; max: Vec3 } => {\n let hx: number, hy: number, hz: number\n if (s.kind === 'sphere') {\n hx = hy = hz = s.radius\n } else {\n const m = quat.toMatrix(q)\n if (s.kind === 'box') {\n const a = s.size[0] / 2, b = s.size[1] / 2, c = s.size[2] / 2\n hx = Math.abs(m[0]) * a + Math.abs(m[1]) * b + Math.abs(m[2]) * c\n hy = Math.abs(m[3]) * a + Math.abs(m[4]) * b + Math.abs(m[5]) * c\n hz = Math.abs(m[6]) * a + Math.abs(m[7]) * b + Math.abs(m[8]) * c\n } else {\n const ax = [m[1], m[4], m[7]]\n const hh = s.height / 2\n const e = (i: number) => s.radius * Math.sqrt(Math.max(0, 1 - ax[i] * ax[i])) + hh * Math.abs(ax[i])\n hx = e(0)\n hy = e(1)\n hz = e(2)\n }\n }\n return { min: [center[0] - hx, center[1] - hy, center[2] - hz], max: [center[0] + hx, center[1] + hy, center[2] + hz] }\n}\n\n/** Seeded generator (mulberry32). The state is a single int32, so it round-trips through JSON. */\nexport interface Rng {\n next(): number\n state(): number\n set(state: number): void\n}\n\nexport const createRng = (seed: number): Rng => {\n let s = seed | 0\n return {\n next() {\n s = (s + 0x6d2b79f5) | 0\n let t = Math.imul(s ^ (s >>> 15), 1 | s)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n },\n state: () => s,\n set(v) {\n s = v | 0\n },\n }\n}\n","import { quat } from './math'\nimport type { Fragment, FractureStyle, Quat, Vec3 } from './types'\n\n/** A fragment in the part's local space (centre, size in the fragment's own axes, orientation relative to the part). */\nexport interface PlannedFragment {\n center: Vec3\n size: Vec3\n q: Quat\n shape: Fragment['shape']\n /** Share of the part's mass (unnormalised). */\n weight: number\n}\n\nexport interface PlanInput {\n style: FractureStyle\n /** Bounding box dimensions in part axes. */\n dims: Vec3\n thickness: number\n /** Index 0..2 of the grain axis, if any. */\n grain?: number\n /** Impact point in part space. */\n hit: Vec3\n fragmentSize: [number, number]\n maxFragments: number\n rnd: () => number\n}\n\ninterface Box {\n c: Vec3\n s: Vec3\n}\n\n/** Split a box into `count` pieces by cutting the largest piece along its longest allowed axis. */\nconst bsp = (root: Box, count: number, axes: number[], rnd: () => number): Box[] => {\n const pieces: Box[] = [root]\n const vol = (b: Box) => axes.reduce((v, a) => v * b.s[a], 1)\n while (pieces.length < count) {\n let bi = 0\n for (let i = 1; i < pieces.length; i++) if (vol(pieces[i]) > vol(pieces[bi])) bi = i\n const b = pieces[bi]\n let ax = axes[0]\n for (const a of axes) if (b.s[a] > b.s[ax]) ax = a\n if (b.s[ax] < 1e-4) break\n const r = 0.3 + 0.4 * rnd()\n const l1 = b.s[ax] * r\n const l2 = b.s[ax] - l1\n const c1: Vec3 = [b.c[0], b.c[1], b.c[2]]\n const c2: Vec3 = [b.c[0], b.c[1], b.c[2]]\n c1[ax] = b.c[ax] - b.s[ax] / 2 + l1 / 2\n c2[ax] = b.c[ax] + b.s[ax] / 2 - l2 / 2\n const s1: Vec3 = [b.s[0], b.s[1], b.s[2]]\n const s2: Vec3 = [b.s[0], b.s[1], b.s[2]]\n s1[ax] = l1\n s2[ax] = l2\n pieces[bi] = { c: c1, s: s1 }\n pieces.push({ c: c2, s: s2 })\n }\n return pieces\n}\n\nconst parity = (p: [number, number, number]): number => {\n let inv = 0\n for (let i = 0; i < 3; i++) for (let j = i + 1; j < 3; j++) if (p[i] > p[j]) inv++\n return inv % 2 === 0 ? 1 : -1\n}\n\n/** Orientation whose x, y, z axes are the part axes `ax`, `ay`, `az`, then rotated by `angle` around its own z. */\nconst frame = (ax: number, ay: number, az: number, angle = 0): Quat => {\n const e = (i: number): Vec3 => [i === 0 ? 1 : 0, i === 1 ? 1 : 0, i === 2 ? 1 : 0]\n const z = e(az)\n const sg = parity([ax, ay, az])\n const q = quat.fromColumns(e(ax), e(ay), [z[0] * sg, z[1] * sg, z[2] * sg])\n return angle === 0 ? q : quat.mul(q, quat.fromAxisAngle([0, 0, 1], angle))\n}\n\nconst clamp = (v: number, a: number, b: number) => Math.max(a, Math.min(b, v))\n\n/** Deterministic fragment layout for a failed part, in part space. */\nexport const planFragments = (inp: PlanInput): PlannedFragment[] => {\n const { style, dims, rnd, maxFragments } = inp\n const [fmin, fmax] = inp.fragmentSize\n const mean = (fmin + fmax) / 2\n const root: Box = { c: [0, 0, 0], s: [dims[0], dims[1], dims[2]] }\n const idq = quat.identity()\n const out: PlannedFragment[] = []\n const sorted = [0, 1, 2].sort((a, b) => dims[a] - dims[b])\n const t = sorted[0]\n const [u, v] = [sorted[1], sorted[2]].sort((a, b) => a - b)\n\n if (style === 'snap') {\n const n = Math.min(maxFragments, 2 + Math.floor(rnd() * 3))\n for (const b of bsp(root, n, [0, 1, 2], rnd)) out.push({ center: b.c, size: b.s, q: idq, shape: 'slab', weight: b.s[0] * b.s[1] * b.s[2] })\n return out\n }\n if (style === 'crumble' || style === 'none') {\n const n = clamp(Math.ceil((dims[0] * dims[1] * dims[2]) / (mean * mean * mean)), 4, maxFragments)\n for (const b of bsp(root, n, [0, 1, 2], rnd)) out.push({ center: b.c, size: b.s, q: idq, shape: 'chunk', weight: b.s[0] * b.s[1] * b.s[2] })\n return out\n }\n if (style === 'splinter') {\n const g = inp.grain ?? [0, 1, 2].sort((a, b) => dims[b] - dims[a])[0]\n const [a, b] = [0, 1, 2].filter((i) => i !== g)\n const w = Math.max(fmin * 1.5, 0.01)\n const c = clamp(Math.round((dims[a] * dims[b]) / (w * w)), 3, Math.max(3, Math.floor(maxFragments / 2)))\n const maxLen = fmax * 4\n const cells = bsp(root, c, [a, b], rnd)\n const pieces: Box[] = []\n for (const cell of cells) {\n let list = [cell]\n const extra = rnd() < 0.4 ? 1 : 0\n const k = Math.max(1, Math.ceil(dims[g] / maxLen)) + extra\n list = bsp(cell, k, [g], rnd)\n for (const p of list) pieces.push(p)\n }\n for (const p of pieces.slice(0, maxFragments)) {\n out.push({ center: p.c, size: [p.s[g], p.s[a], p.s[b]], q: frame(g, a, b), shape: 'splinter', weight: p.s[0] * p.s[1] * p.s[2] })\n }\n return out\n }\n if (style === 'tear') {\n const n = clamp(Math.round((dims[u] * dims[v]) / (mean * mean)), 3, maxFragments)\n const th = Math.min(inp.thickness, dims[t])\n for (const b of bsp(root, n, [u, v], rnd)) {\n out.push({ center: [b.c[0], b.c[1], b.c[2]], size: [b.s[u], b.s[v], th], q: frame(u, v, t), shape: 'scrap', weight: b.s[u] * b.s[v] })\n }\n return out\n }\n // shatter: thin shards radiating from the impact\n const th = Math.min(inp.thickness, dims[t])\n const Hu = dims[u] / 2, Hv = dims[v] / 2\n const hu = clamp(inp.hit[u], -Hu * 0.95, Hu * 0.95)\n const hv = clamp(inp.hit[v], -Hv * 0.95, Hv * 0.95)\n const R = Math.max(Math.hypot(Hu + Math.abs(hu), Hv + Math.abs(hv)), 0.02)\n const n = clamp(Math.round((dims[u] * dims[v]) / (mean * mean)), 6, maxFragments)\n const sectors = clamp(Math.round(Math.sqrt(n * 1.6)), 5, 10)\n const rings = Math.max(1, Math.ceil(n / sectors))\n const radii: number[] = []\n for (let k = 0; k <= rings; k++) radii.push(R * Math.pow(k / rings, 1.3))\n const cap = fmax * 1.5\n for (let j = 0; j < sectors && out.length < maxFragments; j++) {\n const theta = (j + (rnd() - 0.5) * 0.4) * ((Math.PI * 2) / sectors)\n for (let k = 0; k < rings && out.length < maxFragments; k++) {\n const rm = (radii[k] + radii[k + 1]) / 2\n const cu = hu + rm * Math.cos(theta)\n const cv = hv + rm * Math.sin(theta)\n if (Math.abs(cu) > Hu + 0.01 || Math.abs(cv) > Hv + 0.01) continue\n const radial = clamp(radii[k + 1] - radii[k], 0.01, cap)\n const tang = clamp(radii[k + 1] * ((Math.PI * 2) / sectors) * 0.9, 0.01, cap)\n const c: Vec3 = [0, 0, 0]\n c[u] = clamp(cu, -Hu * 0.98, Hu * 0.98)\n c[v] = clamp(cv, -Hv * 0.98, Hv * 0.98)\n c[t] = 0\n out.push({ center: c, size: [radial, tang, th], q: frame(u, v, t, theta), shape: 'shard', weight: radial * tang })\n }\n }\n if (out.length === 0) out.push({ center: [0, 0, 0], size: [dims[u], dims[v], th], q: frame(u, v, t), shape: 'shard', weight: 1 })\n return out\n}\n","import { quat, rotateVec } from './math'\nimport type { FragmentMark, PartUnits, Quat, Vec3 } from './types'\n\n/** One masonry unit (or panel) cut out of a wall, in the part's own axes. */\nexport interface UnitCell {\n center: Vec3\n size: Vec3\n}\n\n/** The two axes a wall spreads along: height is local y unless the part is thin along y (a slab), then x and z. */\nexport const planeAxes = (thin: number): [number, number] => (thin === 1 ? [0, 2] : [thin === 0 ? 2 : 0, 1])\n\n/**\n * Every unit of the wall laid in `bond`: rows along the plane's second axis, running bond shifts odd rows by half a unit, edge units are cut to\n * the wall. More than `cap` units are merged into bigger ones (the same bond) so a whole wall stays a drawable number of fragments.\n */\nexport const unitGrid = (dims: Vec3, thin: number, units: Pick<PartUnits, 'size' | 'bond'>, cap: number): UnitCell[] => {\n const [u, v] = planeAxes(thin)\n let unitU = Math.min(units.size[0], dims[u]), unitV = Math.min(units.size[1], dims[v])\n const rowsFor = (h: number): number => Math.ceil(dims[v] / h - 1e-9)\n const colsFor = (w: number): number => Math.ceil(dims[u] / w - 1e-9) + (units.bond === 'running' ? 1 : 0)\n const merge = Math.ceil(Math.sqrt((rowsFor(unitV) * colsFor(unitU)) / cap))\n if (merge > 1) {\n unitU = Math.min(unitU * merge, dims[u])\n unitV = Math.min(unitV * merge, dims[v])\n }\n const cells: UnitCell[] = []\n for (let row = 0; row < rowsFor(unitV); row++) {\n const v0 = -dims[v] / 2 + row * unitV, v1 = Math.min(v0 + unitV, dims[v] / 2)\n const shift = units.bond === 'running' && row % 2 === 1 ? unitU / 2 : 0\n for (let col = 0; col < colsFor(unitU); col++) {\n const u0 = Math.max(-dims[u] / 2 + col * unitU - shift, -dims[u] / 2), u1 = Math.min(-dims[u] / 2 + (col + 1) * unitU - shift, dims[u] / 2)\n if (u1 - u0 < 0.01) continue\n const center: Vec3 = [0, 0, 0], size: Vec3 = [0, 0, 0]\n center[u] = (u0 + u1) / 2\n center[v] = (v0 + v1) / 2\n size[u] = u1 - u0\n size[v] = v1 - v0\n size[thin] = dims[thin]\n cells.push({ center, size })\n }\n }\n return cells\n}\n\nconst planeDistance = (cell: UnitCell, thin: number, point: Vec3): number => {\n const [u, v] = planeAxes(thin)\n const du = cell.center[u] - point[u], dv = cell.center[v] - point[v]\n return Math.sqrt(du * du + dv * dv)\n}\n\n/** Units whose centre is within `radius` of `point` (part-local) in the wall plane; at least the nearest one. */\nexport const cellsWithin = (cells: readonly UnitCell[], thin: number, point: Vec3, radius: number): UnitCell[] => {\n const inside = cells.filter((c) => planeDistance(c, thin, point) <= radius)\n if (inside.length > 0 || cells.length === 0) return inside\n return [cells.reduce((best, c) => (planeDistance(c, thin, point) < planeDistance(best, thin, point) ? c : best))]\n}\n\nexport const cellsOutside = (cells: readonly UnitCell[], thin: number, point: Vec3, radius: number): UnitCell[] => cells.filter((c) => planeDistance(c, thin, point) > radius)\n\n/** A hole in the part's own axes. */\nexport interface LocalHole {\n point: Vec3\n normal: Vec3\n diameter: number\n}\n\nexport const MAX_MARKS_PER_FRAGMENT = 12\n\n/** The holes that fall inside a fragment box (`rotation` is the fragment's orientation in the part), in the fragment's own axes. */\nexport const marksInBox = (center: Vec3, size: Vec3, rotation: Quat | undefined, holes: readonly LocalHole[]): FragmentMark[] => {\n const inverse = rotation ? quat.conjugate(rotation) : undefined\n const marks: FragmentMark[] = []\n for (const hole of holes) {\n const offset: Vec3 = [hole.point[0] - center[0], hole.point[1] - center[1], hole.point[2] - center[2]]\n const point = inverse ? rotateVec(inverse, offset) : offset\n const inside = point.every((value, k) => Math.abs(value) <= size[k]! / 2 + hole.diameter / 2)\n if (!inside) continue\n marks.push({ point, normal: inverse ? rotateVec(inverse, hole.normal) : hole.normal, diameter: hole.diameter })\n if (marks.length >= MAX_MARKS_PER_FRAGMENT) break\n }\n return marks\n}\n","import type { MaterialDef, SurfaceLayer, Vec3 } from './types'\n\n/** A surface layer with its material resolved; `energy` is what a bullet spends crossing one face's worth of it, in joules. */\nexport interface LayerRT {\n index: number\n def: SurfaceLayer\n mat: MaterialDef\n energy: number\n}\n\n/** `[layer, face (+1 or -1), x, y, z, radius]`: a patch of a layer that came off, in object-local space. Saved with the part. */\nexport type Spall = readonly [number, number, number, number, number, number]\n\nexport const MAX_SPALLS = 64\n\n/** Index of the smallest dimension (the first one on a tie): the axis a wall is thin along. */\nexport const thinAxisOf = (dims: Vec3): number => (dims[0] <= dims[1] && dims[0] <= dims[2] ? 0 : dims[1] <= dims[2] ? 1 : 2)\n\nexport const resolveLayer = (def: SurfaceLayer, index: number, mat: MaterialDef): LayerRT => ({ index, def, mat, energy: mat.penetration * def.thickness * 1000 })\n\nconst onFace = (layer: LayerRT, face: number): boolean => layer.def.faces === 'both' || layer.def.faces === (face > 0 ? '+' : '-')\n\nconst isSpalled = (spalls: readonly Spall[] | undefined, layer: number, face: number, point: Vec3): boolean => {\n for (const s of spalls ?? []) {\n if (s[0] !== layer || s[1] !== face) continue\n const dx = s[2] - point[0], dy = s[3] - point[1], dz = s[4] - point[2]\n if (dx * dx + dy * dy + dz * dz <= s[5] * s[5]) return true\n }\n return false\n}\n\n/** The outermost layer still on `face` at `point` (layers are listed outermost first). */\nexport const outerLayer = (layers: readonly LayerRT[], spalls: readonly Spall[] | undefined, face: number, point: Vec3): LayerRT | undefined =>\n layers.find((l) => onFace(l, face) && !isSpalled(spalls, l.index, face, point))\n\n/** Joules a bullet spends crossing every layer still on `face` at `point`. */\nexport const layersEnergy = (layers: readonly LayerRT[], spalls: readonly Spall[] | undefined, face: number, point: Vec3): number => {\n let sum = 0\n for (const l of layers) if (onFace(l, face) && !isSpalled(spalls, l.index, face, point)) sum += l.energy\n return sum\n}\n\n/** Metres of layer a ray crosses on one face (full thickness, before obliquity). */\nexport const layersThickness = (layers: readonly LayerRT[], face: number): number => {\n let sum = 0\n for (const l of layers) if (onFace(l, face)) sum += l.def.thickness\n return sum\n}\n","import type { Vec3 } from './types'\n\n/** A bar as two end points. */\nexport type Bar = [Vec3, Vec3]\n\nconst COVER = 0.03\nconst MAX_BARS_PER_DIRECTION = 24\nconst MAX_MEMBER_BARS_PER_SIDE = 6\nconst STEEL_DENSITY = 7850\n\n/** Positions centred on 0 with exact `spacing`, as many as fit inside `length - 2 * cover` (at least two, at most `cap`). */\nconst spread = (length: number, cover: number, spacing: number, cap: number): number[] => {\n const room = Math.max(0, length - 2 * cover)\n const count = Math.min(cap, Math.max(2, Math.floor(room / spacing) + 1))\n const step = count > 1 && room / (count - 1) < spacing ? room / (count - 1) : spacing\n return Array.from({ length: count }, (_, i) => (i - (count - 1) / 2) * step)\n}\n\nconst bar = (axis: number, along: number, fixed: Array<[number, number]>): Bar => {\n const a: Vec3 = [0, 0, 0], b: Vec3 = [0, 0, 0]\n for (const [index, value] of fixed) {\n a[index] = value\n b[index] = value\n }\n a[axis] = -along\n b[axis] = along\n return [a, b]\n}\n\n/** Long members (columns, beams): two smaller dimensions close to each other and a much longer third one. */\nconst isMember = (dims: Vec3): boolean => {\n const [a = 0, b = 0, c = 0] = [...dims].sort((x, y) => x - y)\n return b / a < 3 && c / b >= 3\n}\n\n/**\n * Rebar of a box in the part's own axes. Plates (walls, slabs) get a grid along each of the two large axes at mid thickness; long members get\n * bars along their length at the perimeter of the section. `thin` is the axis the part is thinnest along.\n */\nexport const rebarBars = (dims: Vec3, thin: number, spacing: number): Bar[] => {\n const out: Bar[] = []\n if (isMember(dims)) {\n const long = dims.indexOf(Math.max(...dims))\n const [u = 0, v = 0] = [0, 1, 2].filter((i) => i !== long)\n const us = spread(dims[u], COVER, spacing, MAX_MEMBER_BARS_PER_SIDE)\n const vs = spread(dims[v], COVER, spacing, MAX_MEMBER_BARS_PER_SIDE)\n us.forEach((x, i) => vs.forEach((y, j) => {\n if (i === 0 || j === 0 || i === us.length - 1 || j === vs.length - 1) out.push(bar(long, dims[long] / 2 - 0.02, [[u, x], [v, y]]))\n }))\n return out\n }\n const [u = 0, v = 0] = [0, 1, 2].filter((i) => i !== thin)\n for (const y of spread(dims[v], COVER, spacing, MAX_BARS_PER_DIRECTION)) out.push(bar(u, dims[u] / 2 - 0.02, [[v, y], [thin, 0]]))\n for (const x of spread(dims[u], COVER, spacing, MAX_BARS_PER_DIRECTION)) out.push(bar(v, dims[v] / 2 - 0.02, [[u, x], [thin, 0]]))\n return out\n}\n\n/** The part of each bar that lies within `radius` of `center` in the plane of axes `u` and `v` (bars that miss the disc are dropped). */\nexport const clipBarsToDisc = (bars: readonly Bar[], u: number, v: number, center: [number, number], radius: number): Bar[] => {\n const out: Bar[] = []\n for (const [a, b] of bars) {\n const axis = a[u] !== b[u] ? u : v\n const other = axis === u ? v : u\n const off = a[other] - center[other === u ? 0 : 1]\n if (Math.abs(off) >= radius) continue\n const half = Math.sqrt(radius * radius - off * off)\n const mid = center[axis === u ? 0 : 1]\n const lo = Math.max(Math.min(a[axis], b[axis]), mid - half), hi = Math.min(Math.max(a[axis], b[axis]), mid + half)\n if (hi - lo < 1e-6) continue\n const p: Vec3 = [a[0], a[1], a[2]], q: Vec3 = [b[0], b[1], b[2]]\n p[axis] = lo\n q[axis] = hi\n out.push([p, q])\n }\n return out\n}\n\n/** Steel mass in kg of bars of `diameter` metres. */\nexport const rebarMass = (bars: readonly Bar[], diameter: number, density = STEEL_DENSITY): number => {\n let length = 0\n for (const [a, b] of bars) length += Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]) + Math.abs(a[2] - b[2])\n return Math.PI * (diameter / 2) * (diameter / 2) * length * density\n}\n","[\n {\n \"id\": \"steel\",\n \"density\": 7850,\n \"hpPerKg\": 400,\n \"penetration\": 110,\n \"ductility\": 0.9,\n \"fracture\": \"none\",\n \"damageScale\": {\n \"slash\": 0.1,\n \"blunt\": 0.8\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"sparks\",\n \"ricochetDeg\": 20,\n \"thermal\": {\n \"meltC\": 1450,\n \"meltRate\": 0.05,\n \"conductivity\": 0.5,\n \"heatCapacity\": 3\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 2000000\n },\n {\n \"id\": \"cast_iron\",\n \"density\": 7200,\n \"hpPerKg\": 150,\n \"penetration\": 160,\n \"ductility\": 0.2,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.08,\n 0.3\n ],\n \"damageScale\": {\n \"slash\": 0.1,\n \"blunt\": 1.2\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"chips\",\n \"ricochetDeg\": 15,\n \"thermal\": {\n \"meltC\": 1200,\n \"meltRate\": 0.05,\n \"conductivity\": 0.45,\n \"heatCapacity\": 3\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 1500000\n },\n {\n \"id\": \"aluminium\",\n \"density\": 2700,\n \"hpPerKg\": 250,\n \"penetration\": 60,\n \"ductility\": 0.85,\n \"fracture\": \"none\",\n \"damageScale\": {\n \"slash\": 0.2\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"sparks\",\n \"ricochetDeg\": 15,\n \"thermal\": {\n \"meltC\": 660,\n \"meltRate\": 0.06,\n \"conductivity\": 0.8,\n \"heatCapacity\": 1.5\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 800000\n },\n {\n \"id\": \"copper\",\n \"density\": 8960,\n \"hpPerKg\": 300,\n \"penetration\": 70,\n \"ductility\": 0.95,\n \"fracture\": \"none\",\n \"damageScale\": {\n \"slash\": 0.2\n },\n \"hitDebris\": \"sparks\",\n \"breakDebris\": \"sparks\",\n \"ricochetDeg\": 15,\n \"thermal\": {\n \"meltC\": 1085,\n \"meltRate\": 0.05,\n \"conductivity\": 1,\n \"heatCapacity\": 2.5\n },\n \"visual\": {\n \"glows\": true\n },\n \"tags\": [\n \"metal\",\n \"conductive\"\n ],\n \"compressive\": 1000000\n },\n {\n \"id\": \"wood_soft\",\n \"density\": 500,\n \"hpPerKg\": 90,\n \"penetration\": 9,\n \"ductility\": 0.35,\n \"fracture\": \"splinter\",\n \"fragmentSize\": [\n 0.03,\n 0.15\n ],\n \"damageScale\": {\n \"blunt\": 1.2,\n \"slash\": 1.5\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"splinters\",\n \"thermal\": {\n \"ignitionC\": 300,\n \"flameC\": 800,\n \"fuelFraction\": 0.9,\n \"burnRate\": 0.012,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 100000\n },\n {\n \"id\": \"wood_hard\",\n \"density\": 750,\n \"hpPerKg\": 140,\n \"penetration\": 14,\n \"ductility\": 0.3,\n \"fracture\": \"splinter\",\n \"fragmentSize\": [\n 0.03,\n 0.2\n ],\n \"damageScale\": {\n \"slash\": 1.2\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"splinters\",\n \"thermal\": {\n \"ignitionC\": 330,\n \"flameC\": 800,\n \"fuelFraction\": 0.9,\n \"burnRate\": 0.01,\n \"conductivity\": 0.06,\n \"heatCapacity\": 1.4,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 150000\n },\n {\n \"id\": \"plywood\",\n \"density\": 600,\n \"hpPerKg\": 70,\n \"penetration\": 7,\n \"ductility\": 0.3,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.1,\n 0.4\n ],\n \"damageScale\": {\n \"slash\": 1.3\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"splinters\",\n \"thermal\": {\n \"ignitionC\": 300,\n \"flameC\": 800,\n \"fuelFraction\": 0.85,\n \"burnRate\": 0.013,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 60000\n },\n {\n \"id\": \"mdf\",\n \"density\": 750,\n \"hpPerKg\": 45,\n \"penetration\": 6,\n \"ductility\": 0.15,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.08,\n 0.35\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"ignitionC\": 290,\n \"flameC\": 750,\n \"fuelFraction\": 0.85,\n \"burnRate\": 0.014,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 30000\n },\n {\n \"id\": \"glass\",\n \"density\": 2500,\n \"hpPerKg\": 12,\n \"penetration\": 6,\n \"ductility\": 0.02,\n \"fracture\": \"shatter\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"blunt\": 1.5\n },\n \"hitDebris\": \"shards\",\n \"breakDebris\": \"shards\",\n \"ricochetDeg\": 8,\n \"thermal\": {\n \"meltC\": 1400,\n \"meltRate\": 0.03,\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5,\n \"thermalShockC\": 150\n },\n \"visual\": {\n \"glows\": true,\n \"transparent\": true\n },\n \"tags\": [\n \"glass\",\n \"brittle\"\n ],\n \"compressive\": 100000\n },\n {\n \"id\": \"tempered_glass\",\n \"density\": 2500,\n \"hpPerKg\": 30,\n \"penetration\": 9,\n \"ductility\": 0.02,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.006,\n 0.02\n ],\n \"hitDebris\": \"shards\",\n \"breakDebris\": \"shards\",\n \"ricochetDeg\": 8,\n \"thermal\": {\n \"meltC\": 1400,\n \"meltRate\": 0.03,\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5,\n \"thermalShockC\": 250\n },\n \"visual\": {\n \"glows\": true,\n \"transparent\": true\n },\n \"tags\": [\n \"glass\",\n \"brittle\"\n ],\n \"compressive\": 200000\n },\n {\n \"id\": \"ceramic\",\n \"density\": 2400,\n \"hpPerKg\": 25,\n \"penetration\": 12,\n \"ductility\": 0.02,\n \"fracture\": \"shatter\",\n \"fragmentSize\": [\n 0.03,\n 0.12\n ],\n \"damageScale\": {\n \"blunt\": 1.3\n },\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"shards\",\n \"thermal\": {\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5,\n \"thermalShockC\": 200\n },\n \"tags\": [\n \"ceramic\",\n \"brittle\"\n ],\n \"compressive\": 150000\n },\n {\n \"id\": \"concrete\",\n \"density\": 2300,\n \"hpPerKg\": 14,\n \"penetration\": 18,\n \"ductility\": 0.03,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"explosive\": 1.2\n },\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.15,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 444000\n },\n {\n \"id\": \"brick\",\n \"density\": 1900,\n \"hpPerKg\": 12,\n \"penetration\": 14,\n \"ductility\": 0.05,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.04,\n 0.12\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.15,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 40000\n },\n {\n \"id\": \"plaster\",\n \"density\": 850,\n \"hpPerKg\": 18,\n \"penetration\": 3,\n \"ductility\": 0.05,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.05,\n 0.3\n ],\n \"hitDebris\": \"dust\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.1,\n \"heatCapacity\": 1.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 8000\n },\n {\n \"id\": \"stone\",\n \"density\": 2700,\n \"hpPerKg\": 25,\n \"penetration\": 25,\n \"ductility\": 0.03,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.06,\n 0.3\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.2,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"masonry\",\n \"brittle\"\n ],\n \"compressive\": 300000\n },\n {\n \"id\": \"plastic\",\n \"density\": 1100,\n \"hpPerKg\": 60,\n \"penetration\": 8,\n \"ductility\": 0.5,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.05,\n 0.3\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"chips\",\n \"thermal\": {\n \"ignitionC\": 400,\n \"flameC\": 700,\n \"fuelFraction\": 0.8,\n \"burnRate\": 0.02,\n \"meltC\": 200,\n \"meltRate\": 0.06,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1,\n \"smoke\": \"black\"\n },\n \"visual\": {\n \"charColor\": 855309\n },\n \"tags\": [\n \"plastic\",\n \"flammable\"\n ],\n \"compressive\": 40000\n },\n {\n \"id\": \"rubber\",\n \"density\": 1100,\n \"hpPerKg\": 80,\n \"penetration\": 12,\n \"ductility\": 0.9,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.05,\n 0.2\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 350,\n \"flameC\": 750,\n \"fuelFraction\": 0.6,\n \"burnRate\": 0.015,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1.2,\n \"smoke\": \"black\"\n },\n \"visual\": {\n \"charColor\": 855309\n },\n \"tags\": [\n \"rubber\",\n \"flammable\"\n ],\n \"compressive\": 20000\n },\n {\n \"id\": \"fabric\",\n \"density\": 400,\n \"hpPerKg\": 20,\n \"penetration\": 0.8,\n \"ductility\": 0.8,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"slash\": 4,\n \"ballistic\": 0.5\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 230,\n \"flameC\": 600,\n \"fuelFraction\": 1,\n \"burnRate\": 0.05,\n \"conductivity\": 0.03,\n \"heatCapacity\": 0.6,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"fabric\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 500\n },\n {\n \"id\": \"foam\",\n \"density\": 30,\n \"hpPerKg\": 15,\n \"penetration\": 0.5,\n \"ductility\": 0.7,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.03,\n 0.15\n ],\n \"damageScale\": {\n \"slash\": 2,\n \"ballistic\": 0.4\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 250,\n \"flameC\": 900,\n \"fuelFraction\": 0.95,\n \"burnRate\": 0.09,\n \"conductivity\": 0.02,\n \"heatCapacity\": 0.5,\n \"smoke\": \"black\"\n },\n \"visual\": {\n \"charColor\": 855309\n },\n \"tags\": [\n \"fabric\",\n \"flammable\"\n ],\n \"compressive\": 100\n },\n {\n \"id\": \"leather\",\n \"density\": 900,\n \"hpPerKg\": 50,\n \"penetration\": 4,\n \"ductility\": 0.8,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.05,\n 0.25\n ],\n \"damageScale\": {\n \"slash\": 2\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 320,\n \"flameC\": 650,\n \"fuelFraction\": 0.7,\n \"burnRate\": 0.01,\n \"conductivity\": 0.05,\n \"heatCapacity\": 1,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"fabric\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 2000\n },\n {\n \"id\": \"paper\",\n \"density\": 700,\n \"hpPerKg\": 8,\n \"penetration\": 0.3,\n \"ductility\": 0.5,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.03,\n 0.15\n ],\n \"damageScale\": {\n \"slash\": 3\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 230,\n \"flameC\": 600,\n \"fuelFraction\": 1,\n \"burnRate\": 0.06,\n \"conductivity\": 0.03,\n \"heatCapacity\": 0.5,\n \"smoke\": \"grey\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"fabric\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 500\n },\n {\n \"id\": \"foliage\",\n \"density\": 150,\n \"hpPerKg\": 20,\n \"penetration\": 0.5,\n \"ductility\": 0.6,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.03,\n 0.1\n ],\n \"damageScale\": {\n \"slash\": 4\n },\n \"hitDebris\": \"leaves\",\n \"breakDebris\": \"leaves\",\n \"thermal\": {\n \"ignitionC\": 300,\n \"flameC\": 700,\n \"fuelFraction\": 0.8,\n \"burnRate\": 0.08,\n \"conductivity\": 0.03,\n \"heatCapacity\": 0.8,\n \"smoke\": \"white\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"plant\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 500\n },\n {\n \"id\": \"green_wood\",\n \"density\": 650,\n \"hpPerKg\": 5,\n \"penetration\": 10,\n \"ductility\": 0.5,\n \"fracture\": \"splinter\",\n \"fragmentSize\": [\n 0.03,\n 0.2\n ],\n \"damageScale\": {\n \"slash\": 1.3,\n \"ballistic\": 0.1\n },\n \"hitDebris\": \"splinters\",\n \"breakDebris\": \"leaves\",\n \"thermal\": {\n \"ignitionC\": 400,\n \"flameC\": 700,\n \"fuelFraction\": 0.8,\n \"burnRate\": 0.006,\n \"conductivity\": 0.06,\n \"heatCapacity\": 2,\n \"smoke\": \"white\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"plant\",\n \"wood\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 60000\n },\n {\n \"id\": \"cactus\",\n \"density\": 900,\n \"hpPerKg\": 30,\n \"penetration\": 2,\n \"ductility\": 0.6,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.04,\n 0.15\n ],\n \"damageScale\": {\n \"slash\": 3\n },\n \"hitDebris\": \"fibers\",\n \"breakDebris\": \"fibers\",\n \"thermal\": {\n \"ignitionC\": 450,\n \"flameC\": 650,\n \"fuelFraction\": 0.3,\n \"burnRate\": 0.01,\n \"conductivity\": 0.05,\n \"heatCapacity\": 3,\n \"smoke\": \"white\"\n },\n \"visual\": {\n \"charColor\": 1709072\n },\n \"tags\": [\n \"plant\",\n \"organic\",\n \"flammable\"\n ],\n \"compressive\": 5000\n },\n {\n \"id\": \"flesh_fruit\",\n \"density\": 950,\n \"hpPerKg\": 15,\n \"penetration\": 1.5,\n \"ductility\": 0.7,\n \"fracture\": \"tear\",\n \"fragmentSize\": [\n 0.02,\n 0.08\n ],\n \"damageScale\": {\n \"slash\": 2\n },\n \"hitDebris\": \"drips\",\n \"breakDebris\": \"drips\",\n \"thermal\": {\n \"conductivity\": 0.05,\n \"heatCapacity\": 3\n },\n \"tags\": [\n \"plant\",\n \"organic\"\n ],\n \"compressive\": 1000\n },\n {\n \"id\": \"wax\",\n \"density\": 900,\n \"hpPerKg\": 30,\n \"penetration\": 3,\n \"ductility\": 0.5,\n \"fracture\": \"snap\",\n \"fragmentSize\": [\n 0.05,\n 0.2\n ],\n \"hitDebris\": \"chips\",\n \"breakDebris\": \"chips\",\n \"thermal\": {\n \"ignitionC\": 230,\n \"flameC\": 700,\n \"fuelFraction\": 0.9,\n \"burnRate\": 0.02,\n \"meltC\": 60,\n \"meltRate\": 0.2,\n \"conductivity\": 0.05,\n \"heatCapacity\": 0.8,\n \"smoke\": \"grey\"\n },\n \"tags\": [\n \"wax\",\n \"flammable\"\n ],\n \"compressive\": 5000\n },\n {\n \"id\": \"soil\",\n \"density\": 1300,\n \"hpPerKg\": 3,\n \"penetration\": 5,\n \"ductility\": 0.3,\n \"fracture\": \"crumble\",\n \"fragmentSize\": [\n 0.03,\n 0.12\n ],\n \"hitDebris\": \"dust\",\n \"breakDebris\": \"dust\",\n \"thermal\": {\n \"conductivity\": 0.1,\n \"heatCapacity\": 2.5\n },\n \"tags\": [\n \"soil\",\n \"masonry\"\n ],\n \"compressive\": 20000\n }\n]","{\n \"cast iron\": \"cast_iron\",\n \"cast_iron\": \"cast_iron\",\n \"castiron\": \"cast_iron\",\n \"metal\": \"steel\",\n \"steel\": \"steel\",\n \"iron\": \"steel\",\n \"chrome\": \"steel\",\n \"alumin\": \"aluminium\",\n \"alu_\": \"aluminium\",\n \"alu-\": \"aluminium\",\n \"alu \": \"aluminium\",\n \"copper\": \"copper\",\n \"brass\": \"copper\",\n \"bronze\": \"copper\",\n \"wood\": \"wood_soft\",\n \"timber\": \"wood_soft\",\n \"plank\": \"wood_soft\",\n \"lumber\": \"wood_soft\",\n \"pine\": \"wood_soft\",\n \"hardwood\": \"wood_hard\",\n \"oak\": \"wood_hard\",\n \"plywood\": \"plywood\",\n \"mdf\": \"mdf\",\n \"chipboard\": \"mdf\",\n \"glass\": \"glass\",\n \"window\": \"glass\",\n \"mirror\": \"glass\",\n \"tempered\": \"tempered_glass\",\n \"windshield\": \"tempered_glass\",\n \"fabric\": \"fabric\",\n \"cloth\": \"fabric\",\n \"cushion\": \"fabric\",\n \"sofa\": \"fabric\",\n \"curtain\": \"fabric\",\n \"carpet\": \"fabric\",\n \"textile\": \"fabric\",\n \"canvas\": \"fabric\",\n \"foam\": \"foam\",\n \"sponge\": \"foam\",\n \"mattress\": \"foam\",\n \"leather\": \"leather\",\n \"paper\": \"paper\",\n \"cardboard\": \"paper\",\n \"leaf\": \"foliage\",\n \"leaves\": \"foliage\",\n \"foliage\": \"foliage\",\n \"bush\": \"foliage\",\n \"grass\": \"foliage\",\n \"trunk\": \"green_wood\",\n \"branch\": \"green_wood\",\n \"twig\": \"green_wood\",\n \"cactus\": \"cactus\",\n \"fruit\": \"flesh_fruit\",\n \"apple\": \"flesh_fruit\",\n \"melon\": \"flesh_fruit\",\n \"wax\": \"wax\",\n \"candle\": \"wax\",\n \"concrete\": \"concrete\",\n \"cement\": \"concrete\",\n \"brick\": \"brick\",\n \"tile\": \"ceramic\",\n \"ceramic\": \"ceramic\",\n \"porcelain\": \"ceramic\",\n \"stone\": \"stone\",\n \"rock\": \"stone\",\n \"marble\": \"stone\",\n \"plaster\": \"plaster\",\n \"drywall\": \"plaster\",\n \"gypsum\": \"plaster\",\n \"plastic\": \"plastic\",\n \"pvc\": \"plastic\",\n \"acrylic\": \"plastic\",\n \"rubber\": \"rubber\",\n \"tire\": \"rubber\",\n \"tyre\": \"rubber\",\n \"soil\": \"soil\",\n \"dirt\": \"soil\",\n \"potting\": \"soil\",\n \"mud\": \"soil\"\n}","import materialsJson from './data/materials.json'\nimport hintsJson from './data/material-hints.json'\nimport { aabbOf, quatFromEuler, shapeDims } from './math'\nimport type { JointKind, JointSpec, MaterialDef, MaterialId, PartShape, PartSpec, ToolKind } from './types'\n\n/** Built-in materials (data in `src/data/materials.json`). Override or extend with the `materials` option of `createDestruction`. */\nexport const MATERIALS: MaterialDef[] = materialsJson as unknown as MaterialDef[]\n\n/** Default joint strength (joint hit points), tools that undo it and seconds of tool work. */\nexport const JOINT_DEFAULTS: Record<JointKind, { strength: number; tools: ToolKind[]; seconds: number }> = {\n screw: { strength: 80, tools: ['screwdriver'], seconds: 2.5 },\n bolt: { strength: 200, tools: ['wrench'], seconds: 4 },\n nail: { strength: 60, tools: ['pry_bar', 'hammer'], seconds: 2 },\n weld: { strength: 600, tools: ['cutting_torch', 'saw'], seconds: 8 },\n glue: { strength: 50, tools: ['pry_bar', 'knife'], seconds: 3 },\n hinge: { strength: 120, tools: ['screwdriver'], seconds: 3 },\n clip: { strength: 20, tools: ['hand'], seconds: 0.6 },\n tie: { strength: 15, tools: ['knife', 'hand'], seconds: 1 },\n mortar: { strength: 400, tools: ['hammer'], seconds: 6 },\n fused: { strength: 1000, tools: [], seconds: 0 },\n stem: { strength: 40, tools: ['knife', 'saw', 'hand'], seconds: 1.5 },\n rebar: { strength: 1500, tools: ['cutting_torch', 'saw'], seconds: 20 },\n resting: { strength: 30, tools: ['hand'], seconds: 1 },\n}\n\nconst has = (m: MaterialDef, tag: string) => !!m.tags && m.tags.includes(tag)\n\n/**\n * The joint kind that fits two materials: glass is glued (clipped to plastic), soft things are tied, plants share a stem, masonry gets mortar,\n * metal is welded, wood is screwed, plastic clips. `inferJoints` refines weld to bolt for thick metal and screw to nail for thin wood.\n */\nexport const JOINT_BY_MATERIALS = (a: MaterialDef, b: MaterialDef): JointKind => {\n const any = (tag: string) => has(a, tag) || has(b, tag)\n const both = (tag: string) => has(a, tag) && has(b, tag)\n if (any('glass')) return any('plastic') ? 'clip' : 'glue'\n if (any('fabric')) return 'tie'\n if (both('plant')) return 'stem'\n if (any('plant')) return 'tie'\n if (both('masonry')) return 'mortar'\n if (any('masonry') && any('metal')) return 'bolt'\n if (both('metal')) return 'weld'\n if (any('plastic')) return 'clip'\n if (any('rubber') || any('wax')) return 'glue'\n return 'screw'\n}\n\nconst MATERIAL_MAP: ReadonlyMap<MaterialId, MaterialDef> = new Map(MATERIALS.map((m) => [m.id, m]))\n\nconst HINTS = Object.entries(hintsJson as Record<string, string>).sort((x, y) => y[0].length - x[0].length)\n\n/** Guess a material id from a mesh or node name (case-insensitive substring; the longest keyword wins). */\nexport const guessMaterial = (name: string): MaterialId | undefined => {\n const n = name.toLowerCase()\n for (const [key, id] of HINTS) if (n.includes(key)) return id\n return undefined\n}\n\n/** Volume of a shape in m³. */\nexport const partVolume = (shape: PartShape): number => {\n if (shape.kind === 'box') return shape.size[0] * shape.size[1] * shape.size[2]\n if (shape.kind === 'cylinder') return Math.PI * shape.radius * shape.radius * shape.height\n return (4 / 3) * Math.PI * shape.radius ** 3\n}\n\n/** Mass of a part in kg: its `mass`, or density × volume × fill. */\nexport const partMass = (part: PartSpec, material: MaterialDef): number => part.mass ?? material.density * partVolume(part.shape) * (part.fill ?? 1)\n\n/** Wall thickness of a part in metres (see `PartSpec.thickness`). */\nexport const partThickness = (part: PartSpec): number => {\n const dims = shapeDims(part.shape)\n const min = Math.min(dims[0], dims[1], dims[2])\n return Math.max(1e-4, Math.min(part.thickness ?? min * (part.fill ?? 1), min))\n}\n\n/**\n * Joints for touching parts. Two parts touch when their axis-aligned bounds (after rotation), grown by `tolerance` metres, overlap. The kind comes\n * from `JOINT_BY_MATERIALS`; thick metal pairs (smallest dimension of both >= 2 cm) get a `bolt` instead of a `weld`, and thin wood pairs (either\n * under 2 cm) a `nail` instead of a `screw`.\n */\nexport const inferJoints = (parts: PartSpec[], tolerance = 0.01, materials: ReadonlyMap<string, MaterialDef> = MATERIAL_MAP): JointSpec[] => {\n const boxes = parts.map((p) => aabbOf(p.shape, p.position, quatFromEuler(...(p.rotation ?? [0, 0, 0]))))\n const out: JointSpec[] = []\n for (let i = 0; i < parts.length; i++) {\n for (let j = i + 1; j < parts.length; j++) {\n const a = boxes[i], b = boxes[j]\n let touch = true\n for (let k = 0; k < 3 && touch; k++) if (a.min[k] - tolerance > b.max[k] || b.min[k] - tolerance > a.max[k]) touch = false\n if (!touch) continue\n const ma = materials.get(parts[i].material)\n const mb = materials.get(parts[j].material)\n let kind: JointKind = ma && mb ? JOINT_BY_MATERIALS(ma, mb) : 'screw'\n const thin = Math.min(partThickness(parts[i]), partThickness(parts[j]))\n if (kind === 'weld' && thin >= 0.02) kind = 'bolt'\n if (kind === 'screw' && ma && mb && has(ma, 'wood') && has(mb, 'wood') && thin < 0.02) kind = 'nail'\n out.push({ id: `${parts[i].id}~${parts[j].id}`, a: parts[i].id, b: parts[j].id, kind })\n }\n }\n return out\n}\n\n/**\n * Load in kg a structural part carries before it fails: `structure.capacity`, else `material.compressive` (default 20 000 kg/m²) times the\n * section. The section is the product of the two smallest dimensions (thickness times longest dimension for slabs; thickness times horizontal length for walls); foundations get x10.\n */\nexport const partCapacity = (part: PartSpec, material: MaterialDef): number => {\n if (part.structure?.capacity !== undefined) return part.structure.capacity\n const d = shapeDims(part.shape).sort((a, b) => a - b)\n const role = part.structure?.role\n const sh = shapeDims(part.shape)\n const section = role === 'wall' || role === 'partition' ? Math.min(sh[0], sh[2]) * Math.max(sh[0], sh[2]) : role === 'slab' ? d[0] * d[2] : d[0] * d[1]\n return Math.max(1, section * (material.compressive ?? 20000) * (role === 'foundation' ? 10 : 1))\n}\n\n\n/**\n * Multiplier of blunt damage on brittle parts (ductility < 0.3): up to x4.7 for fully brittle materials (glass, ceramic, stone), times a thinness\n * term that follows bending stress (1 / thickness squared, x1 at 2 cm or more, at most x25). A 3 mm glass bottle breaks from a 1.5 m drop; a\n * concrete block (thick) is only ever x4.4.\n */\nexport const fragility = (ductility: number, thickness: number): number => {\n if (ductility >= 0.3) return 1\n return (1 + (4 * (0.3 - ductility)) / 0.3) * Math.min(25, Math.max(1, (0.02 / Math.max(thickness, 1e-4)) ** 2))\n}\n","import { chainDelayOf, drawChainDelay, FIRE_PRIME_C, shotDamageFractionOf } from './chain'\nimport type { ChainTrigger } from './chain'\nimport { planFragments } from './fracture'\nimport type { PlannedFragment } from './fracture'\nimport { cellsOutside, cellsWithin, marksInBox, planeAxes, unitGrid } from './breach'\nimport type { LocalHole, UnitCell } from './breach'\nimport { layersEnergy, layersThickness, MAX_SPALLS, outerLayer, resolveLayer, thinAxisOf } from './layers'\nimport type { LayerRT } from './layers'\nimport { clipBarsToDisc, rebarBars, rebarMass } from './rebar'\nimport { JOINT_DEFAULTS, inferJoints, MATERIALS, partCapacity, partMass, partThickness, partVolume, fragility } from './materials'\nimport { aabbOf, createRng, distanceToShape, quat, quatFromEuler, rayShape, rotateVec, shapeArea, shapeBound, shapeDims, surfacePoint, toLocal, toWorld, vec } from './math'\nimport type { DestructibleImpl } from './contracts'\nimport type {\n AddOptions, Crack, DamageType, DebrisKind, DestructibleSpec, Dent, DestructionEvent, DestructionEventType, DestructionOptions, DestructionSnapshot,\n DamageStage, DestructionWorld, Fragment, Hit, HitResult, Hole, JointSpec, JointState, MaterialDef, MaterialId, ObjectRuntime, ObjectState, PartRuntime, PartSpec,\n PartState, Quat, RayHit, ToolKind, Vec3,\n} from './types'\n\n/** Hit points removed per joule (before the material's `damageScale`). */\nconst DMG_PER_J = 0.02\n/** Fraction of a blast's energy that reaches a part at distance 0. */\nconst BLAST_COUPLING = 0.1\nconst FLAMMABLE_FLUIDS = ['gas', 'fuel']\n/** Staged parts: default breach radius (m), blast multiplier on the breach area, area a part must lose to open (m²), and the share of capacity the bare cage keeps. */\nconst BREACH_RADIUS = 0.55\nconst BREACH_BLAST_FACTOR = 6\nconst BREACH_AREA = 0.25\nconst RESIDUAL_CAPACITY = 0.15\n/** Unit-sized fragments of a whole wall: at most this many times `maxFragments`. A breach picks its units from a grid of up to `BREACH_GRID_CAP`. */\nconst UNIT_FRAGMENT_FACTOR = 4\nconst BREACH_GRID_CAP = 4096\n\n/** A cut only goes through a slice of the part, so a part longer than `CUT_SLICE` costs no more to cut than a 1 m piece of the same section. */\nconst CUT_SLICE = 1\nconst cutFactorOf = (shape: PartSpec['shape']): number => clamp(Math.max(...shapeDims(shape)) / CUT_SLICE, 1, 50)\n\ninterface PartRT {\n spec: PartSpec\n mat: MaterialDef\n st: PartState\n q: Quat\n /** Current object-local position (the spec's, unless moved by `setPartPose`). */\n pos: Vec3\n mass0: number\n fuel0: number\n area: number\n thickness: number\n /** Slash damage multiplier: longest dimension / 1 m (1..50). */\n cutFactor: number\n dims: Vec3\n bound: number\n rt: PartRuntime\n /** Structural role other than `none`. */\n structural: boolean\n anchored: boolean\n cap: number\n /** The part has layers, units, reinforcement or a breach: it goes through damage stages. */\n staged: boolean\n /** Axis the part is thinnest along (the wall's depth). */\n thin: number\n layers: LayerRT[]\n}\n\ninterface JointRT {\n spec: Required<JointSpec>\n st: JointState\n ia: number\n ib: number\n bears: boolean | 'a_on_b' | 'b_on_a'\n /** Object-local position. */\n pos: Vec3\n step: number\n}\n\ninterface ObjRT {\n id: string\n spec: DestructibleSpec\n st: ObjectState\n parts: PartRT[]\n byId: Map<string, PartRT>\n idx: Map<string, number>\n joints: JointRT[]\n jointMap: Map<string, JointRT>\n byPart: Map<string, JointRT[]>\n /** Local bounding sphere. */\n bc: Vec3\n br: number\n active: boolean\n tmp: number[]\n hasStructure: boolean\n dirty: boolean\n maxStress: number\n collapsed: Set<string>\n /** Structural parts with no support path to an anchored part (they fall). */\n unsup: boolean[]\n anyAnchor: boolean\n /** Creation order of the object in this world: breaks ties between parts that go off at the same time. */\n order: number\n}\n\ninterface Carry {\n parts: Map<string, { st: PartState; rt: PartRuntime }>\n joints: Map<string, { st: JointState; step: number }>\n collapsed?: string[]\n}\n\ninterface Loc {\n p: PartRT\n point: Vec3\n normal: Vec3\n dir: Vec3\n pathLen: number\n}\n\ninterface ImplRT {\n impl: DestructibleImpl\n position: Vec3\n rotation: Quat\n /** Part pose overrides set by `setPartPose` (object-local). */\n poses: Map<string, { pos: Vec3; q: Quat }>\n}\n\ninterface Blast {\n point: Vec3\n energy: number\n radius: number\n source?: string\n}\n\nconst clamp = (v: number, a: number, b: number) => Math.max(a, Math.min(b, v))\n/** Share of its capacity a structural part still has: a bare rebar cage keeps the reinforcement's residual, a breached part loses what left it. */\nconst capacityScale = (p: PartRT): number => {\n if (p.st.stripped) return p.spec.reinforcement?.residualCapacity ?? RESIDUAL_CAPACITY\n return p.rt.removed ? Math.max(0.05, 1 - p.rt.removed / p.mass0) : 1\n}\nconst isLost = (p: PartRT) => p.st.status === 'broken' || p.st.status === 'melted' || p.st.status === 'ashes'\nconst clone = <T>(v: T): T => structuredClone(v)\n/**\n * Fraction of a structural part's hit points lost per second while its stress is above 1. A floor of 0.12 makes even a barely overloaded part\n * give way in about 8 s (a rate proportional to the excess alone never finishes: stress 1.02 would take two minutes), then it grows with the\n * excess and tops out at 0.6: stress 1.1 fails in ~4.5 s, 1.5 in ~1.9 s and anything above 1.7 in ~1.7 s. Deterministic: depends only on stress.\n */\nconst overloadRate = (stress: number) => Math.min(0.6, 0.12 + 0.8 * (stress - 1))\nconst updateBound = (o: ObjRT) => {\n if (!o.parts.length) return\n const c: Vec3 = [0, 0, 0]\n for (const p of o.parts) for (let k = 0; k < 3; k++) c[k] += p.pos[k] / o.parts.length\n let r = 0\n for (const p of o.parts) r = Math.max(r, vec.distance(c, p.pos) + p.bound)\n o.bc = c\n o.br = r\n}\nconst AXIS = { x: 0, y: 1, z: 2 } as const\n\nexport const createDestruction = (options: DestructionOptions = {}): DestructionWorld => {\n const materials = new Map<MaterialId, MaterialDef>()\n for (const m of MATERIALS) materials.set(m.id, m)\n for (const m of options.materials ?? []) materials.set(m.id, m)\n const ambient = options.ambientC ?? 20\n const maxFragments = options.maxFragments ?? 24\n const maxDents = options.maxDents ?? 24\n const maxHoles = options.maxHoles ?? 32\n const fireSpread = options.fireSpread ?? 0.6\n const breachRadius = options.breach?.radius ?? BREACH_RADIUS\n const breachBlastFactor = options.breach?.blastFactor ?? BREACH_BLAST_FACTOR\n const rng = createRng(options.seed ?? 1)\n const rnd = () => rng.next()\n\n let time = 0\n let counter = 0\n const objects = new Map<string, ObjRT>()\n const listeners = new Map<string, Set<(e: DestructionEvent) => void>>()\n let cur: DestructionEvent[] = []\n const blasts: Blast[] = []\n /** Explosive parts that were primed and wait for their delay. */\n const primed = new Map<PartRT, ObjRT>()\n let orderCounter = 0\n const impls = new Map<string, ImplRT>()\n const taken = (id: string) => objects.has(id) || impls.has(id)\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Events\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const emit = (e: DestructionEvent) => {\n cur.push(e)\n options.onEvent?.(e)\n const all = listeners.get('*')\n if (all) for (const fn of [...all]) fn(e)\n const typed = listeners.get(e.type)\n if (typed) for (const fn of [...typed]) fn(e)\n }\n const base = (o: ObjRT, source?: string): { object: string; time: number; source?: string } =>\n source === undefined ? { object: o.id, time } : { object: o.id, time, source }\n\n const pendingCollapse = new Map<ObjRT, string | undefined>()\n let runDepth = 0\n\n /** Blasts queued by parts that exploded; each can prime or set off more parts. It ends: a part goes off once and is primed once, so the queue only grows by parts not yet lost. */\n const drainBlasts = () => {\n for (let blast = blasts.shift(); blast; blast = blasts.shift()) blastWorld(blast.point, blast.energy, blast.radius, blast.source)\n }\n\n const run = <T>(fn: () => T): { value: T; events: DestructionEvent[] } => {\n const prev = cur\n const mine: DestructionEvent[] = []\n cur = mine\n runDepth++\n try {\n const value = fn()\n drainBlasts()\n if (runDepth === 1) flushCollapse()\n return { value, events: mine }\n } finally {\n runDepth--\n cur = prev\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Building objects\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const nextId = () => {\n let id: string\n do id = `obj_${++counter}`\n while (taken(id))\n return id\n }\n\n const freshRuntime = (): PartRuntime => ({ meltEmitted: 0, dripT: 0, prevTemp: ambient, shockT: 0, jet: false })\n\n const resolveSpec = (spec: DestructibleSpec): DestructibleSpec => {\n const out = clone(spec)\n const joints = out.joints ?? inferJoints(out.parts, 0.01, materials)\n const structural = (id: string) => {\n const role = out.parts.find((p) => p.id === id)?.structure?.role\n return role !== undefined && role !== 'none'\n }\n out.joints = joints.map((j) => {\n const def = JOINT_DEFAULTS[j.kind]\n return {\n id: j.id ?? `${j.a}~${j.b}`, a: j.a, b: j.b, kind: j.kind, strength: j.strength ?? def.strength, tools: j.tools ?? [...def.tools], seconds: j.seconds ?? def.seconds,\n bears: j.bears ?? (structural(j.a) && structural(j.b)),\n }\n })\n return out\n }\n\n const build = (spec: DestructibleSpec, id: string, pos: Vec3, rot: Quat, carry?: Carry): ObjRT => {\n const st: ObjectState = { id, position: [pos[0], pos[1], pos[2]], rotation: [rot[0], rot[1], rot[2], rot[3]], parts: [], joints: [], groups: [], destroyed: false }\n if (spec.name !== undefined) st.name = spec.name\n const o: ObjRT = {\n id, spec, st, parts: [], byId: new Map(), idx: new Map(), joints: [], jointMap: new Map(), byPart: new Map(), bc: [0, 0, 0], br: 0, active: false, tmp: [], hasStructure: false, dirty: false, maxStress: 0, collapsed: new Set(carry?.collapsed ?? []), unsup: [], anyAnchor: false, order: ++orderCounter,\n }\n for (const ps of spec.parts) {\n if (o.byId.has(ps.id)) throw new Error(`duplicate part id \"${ps.id}\"`)\n const mat = materials.get(ps.material)\n if (!mat) throw new Error(`unknown material \"${ps.material}\" on part \"${ps.id}\"`)\n const mass0 = partMass(ps, mat)\n const maxHp = Math.max(1, ps.hp ?? mass0 * mat.hpPerKg)\n const fuel0 = mat.thermal.ignitionC !== undefined ? mass0 * (mat.thermal.fuelFraction ?? 0) : 0\n const c = carry?.parts.get(ps.id)\n const staged = !!(ps.layers?.length || ps.reinforcement || ps.units || ps.breach)\n const layers = (ps.layers ?? []).map((l, i) => {\n const lm = materials.get(l.material)\n if (!lm) throw new Error(`unknown material \"${l.material}\" on layer ${i} of part \"${ps.id}\"`)\n return resolveLayer(l, i, lm)\n })\n if (ps.reinforcement && !materials.has(ps.reinforcement.material)) throw new Error(`unknown material \"${ps.reinforcement.material}\" on the reinforcement of part \"${ps.id}\"`)\n const pst: PartState = c?.st ?? {\n id: ps.id, material: ps.material, status: 'intact', hp: maxHp, maxHp, mass: mass0, temperature: ambient, burning: false, fuel: fuel0, char: 0, melt: 0,\n dents: [], holes: [], cracks: [], group: 0, ...(staged ? { stage: 0 as DamageStage } : {}),\n }\n if (!c && ps.contains) pst.liters = ps.contains.liters\n const p: PartRT = {\n spec: ps, mat, st: pst, q: quatFromEuler(...(ps.rotation ?? [0, 0, 0])), pos: [ps.position[0], ps.position[1], ps.position[2]], mass0, fuel0, area: shapeArea(ps.shape), thickness: partThickness(ps), cutFactor: cutFactorOf(ps.shape),\n dims: shapeDims(ps.shape), bound: shapeBound(ps.shape), rt: c?.rt ?? { ...freshRuntime(), prevTemp: pst.temperature },\n structural: !!ps.structure && ps.structure.role !== 'none', anchored: !!ps.anchored || ps.structure?.role === 'foundation', cap: ps.structure ? partCapacity(ps, mat) : 0,\n staged, thin: thinAxisOf(shapeDims(ps.shape)), layers,\n }\n if (p.structural) o.hasStructure = true\n if (p.rt.chainDue !== undefined && !isLost(p)) primed.set(p, o)\n o.idx.set(ps.id, o.parts.length)\n o.parts.push(p)\n o.byId.set(ps.id, p)\n o.st.parts.push(pst)\n o.byPart.set(ps.id, [])\n }\n for (const js of spec.joints ?? []) {\n const r = js as Required<JointSpec>\n const ia = o.idx.get(r.a), ib = o.idx.get(r.b)\n if (ia === undefined || ib === undefined) throw new Error(`joint \"${r.id}\" references an unknown part`)\n if (o.jointMap.has(r.id)) throw new Error(`duplicate joint id \"${r.id}\"`)\n const pa = o.parts[ia], pb = o.parts[ib]\n const A = aabbOf(pa.spec.shape, pa.spec.position, pa.q)\n const B = aabbOf(pb.spec.shape, pb.spec.position, pb.q)\n const pos: Vec3 = [0, 0, 0]\n for (let k = 0; k < 3; k++) pos[k] = (Math.max(A.min[k], B.min[k]) + Math.min(A.max[k], B.max[k])) / 2\n const bears: JointRT['bears'] = r.bears ?? (pa.structural && pb.structural)\n const c = carry?.joints.get(r.id)\n const jst: JointState = c?.st ?? { id: r.id, a: r.a, b: r.b, kind: r.kind, hp: r.strength, maxHp: r.strength, progress: 0, open: false }\n const j: JointRT = { spec: r, st: jst, ia, ib, bears, pos, step: c?.step ?? 0 }\n o.joints.push(j)\n o.jointMap.set(r.id, j)\n o.byPart.get(r.a)!.push(j)\n o.byPart.get(r.b)!.push(j)\n o.st.joints.push(jst)\n }\n // open joints whose parts are no longer both here (left behind by `splitGroup`) stay listed, inert, so callers still see them open\n for (const [jid, c] of carry?.joints ?? []) if (c.st.open && !o.jointMap.has(jid)) o.st.joints.push(c.st)\n updateBound(o)\n o.anyAnchor = o.parts.some((p) => p.anchored)\n o.unsup = o.parts.map(() => false)\n solveStructure(o)\n recomputeGroups(o)\n o.st.destroyed = o.parts.length > 0 && o.parts.every(isLost)\n o.active = o.maxStress > 0.8 || o.parts.some((p) => p.st.burning || p.st.temperature > ambient + 0.5 || (p.st.liters ?? 0) > 0)\n return o\n }\n\n const recomputeGroups = (o: ObjRT) => {\n const n = o.parts.length\n const parent = Array.from({ length: n }, (_, i) => i)\n const find = (i: number): number => {\n while (parent[i] !== i) {\n parent[i] = parent[parent[i]]\n i = parent[i]\n }\n return i\n }\n const union = (a: number, b: number) => {\n parent[find(a)] = find(b)\n }\n const live = (j: JointRT) => !j.st.open && !isLost(o.parts[j.ia]) && !isLost(o.parts[j.ib])\n if (o.unsup.some(Boolean)) {\n // parts that lost every support fall: cut them from the supported pieces; loose non-structural parts follow the part they hang on\n for (const j of o.joints) if (live(j) && !o.unsup[j.ia] && !o.unsup[j.ib]) union(j.ia, j.ib)\n const supported = new Set<number>()\n for (let i = 0; i < n; i++) if (!isLost(o.parts[i]) && !o.unsup[i] && (o.parts[i].structural || o.parts[i].anchored)) supported.add(find(i))\n for (const j of o.joints) {\n if (!live(j) || !(o.unsup[j.ia] || o.unsup[j.ib])) continue\n if (o.unsup[j.ia] && o.unsup[j.ib]) union(j.ia, j.ib)\n else {\n const u = o.unsup[j.ia] ? j.ia : j.ib\n const other = u === j.ia ? j.ib : j.ia\n if (!o.parts[other].structural && !supported.has(find(other))) union(u, other)\n }\n }\n } else for (const j of o.joints) if (live(j)) union(j.ia, j.ib)\n const comps = new Map<number, number[]>()\n for (let i = 0; i < n; i++) {\n if (isLost(o.parts[i])) continue\n const r = find(i)\n const l = comps.get(r)\n if (l) l.push(i)\n else comps.set(r, [i])\n }\n const list = [...comps.values()].map((ix) => ({\n ix,\n anchored: ix.some((i) => o.parts[i].anchored),\n mass: ix.reduce((s, i) => s + o.parts[i].st.mass, 0),\n }))\n list.sort((a, b) => (a.anchored === b.anchored ? (b.mass - a.mass) || (a.ix[0] - b.ix[0]) : a.anchored ? -1 : 1))\n o.st.groups = list.map((g) => g.ix.map((i) => o.parts[i].spec.id))\n for (const p of o.parts) if (isLost(p)) p.st.group = -1\n list.forEach((g, gi) => g.ix.forEach((i) => (o.parts[i].st.group = gi)))\n }\n\n /** Which part `r` rests on over joint `j` (index), or -1 when the joint does not let `r` rest on its other end. */\n const restsOn = (j: JointRT, r: number): number => {\n const b = j.bears\n if (!b) return -1\n if (b === true) return j.ia === r ? j.ib : j.ia\n if (b === 'a_on_b') return j.ia === r ? j.ib : -1\n return j.ib === r ? j.ia : -1\n }\n\n /** Distribute own mass plus carried load down the bearing graph to the anchored parts; mark parts without any support path. */\n const solveStructure = (o: ObjRT) => {\n o.maxStress = 0\n if (!o.hasStructure) return\n const parts = o.parts\n const n = parts.length\n const dist = new Array<number>(n).fill(-1)\n const queue: number[] = []\n const ok = (i: number) => parts[i].structural && !isLost(parts[i])\n const isPartition = (i: number) => parts[i].spec.structure?.role === 'partition'\n for (let i = 0; i < n; i++) if (ok(i) && parts[i].anchored) {\n dist[i] = 0\n queue.push(i)\n }\n for (let h = 0; h < queue.length; h++) {\n const s = queue[h]\n if (isPartition(s)) continue\n for (const j of o.byPart.get(parts[s].spec.id)!) {\n if (j.st.open || !j.bears) continue\n const r = j.ia === s ? j.ib : j.ia\n if (dist[r] >= 0 || !ok(r) || restsOn(j, r) !== s) continue\n dist[r] = dist[s] + 1\n queue.push(r)\n }\n }\n const incoming = new Array<number>(n).fill(0)\n for (let h = queue.length - 1; h >= 0; h--) {\n const i = queue[h]\n const total = parts[i].st.mass + incoming[i]\n parts[i].st.load = total\n const lower: number[] = []\n for (const j of o.byPart.get(parts[i].spec.id)!) {\n if (j.st.open || !j.bears) continue\n const k = restsOn(j, i)\n if (k >= 0 && dist[k] >= 0 && dist[k] < dist[i] && !isPartition(k)) lower.push(k)\n }\n for (const k of lower) incoming[k] += total / lower.length\n }\n for (let i = 0; i < n; i++) {\n const p = parts[i]\n o.unsup[i] = false\n if (!p.structural) continue\n if (dist[i] < 0 || isLost(p)) {\n p.st.load = p.st.mass\n p.st.stress = 0\n o.unsup[i] = o.anyAnchor && !isLost(p)\n continue\n }\n p.st.stress = p.st.load! / (p.cap * capacityScale(p))\n if (p.st.stress > o.maxStress) o.maxStress = p.st.stress\n }\n if (o.maxStress > 0.8) o.active = true\n }\n\n /**\n * Ask for a collapse report. It is not computed right away: a blow can break several parts in one go (a column and the roof's supports, or a\n * column whose joint opens just before the column itself fractures), so the groups are examined once, after every loss of the operation.\n */\n const collapseCheck = (o: ObjRT, src?: string) => {\n if (!o.hasStructure || !o.parts.some((p) => p.anchored)) return\n if (!pendingCollapse.has(o)) pendingCollapse.set(o, src)\n }\n\n /** Report the groups of remaining structural parts that lost every anchor (each part is reported once). */\n const flushCollapse = () => {\n for (const [o, src] of [...pendingCollapse]) {\n pendingCollapse.delete(o)\n if (!objects.has(o.id) || objects.get(o.id) !== o) continue\n for (const g of o.st.groups) {\n const ps = g.map((id) => o.byId.get(id)!).filter((p) => !isLost(p) && !o.collapsed.has(p.spec.id))\n if (ps.length === 0 || g.some((id) => o.byId.get(id)!.anchored) || !ps.some((p) => p.structural)) continue\n for (const p of ps) {\n o.collapsed.add(p.spec.id)\n p.st.status = 'collapsed'\n setStage(o, p, 3, {}, src)\n }\n emit({ ...base(o, src), type: 'collapse', parts: ps.map((p) => p.spec.id), mass: ps.reduce((sum, p) => sum + p.st.mass, 0) })\n }\n }\n }\n\n const getObj = (id: string): ObjRT => {\n const o = objects.get(id)\n if (!o) throw new Error(`unknown object \"${id}\"`)\n return o\n }\n const getPart = (o: ObjRT, id: string): PartRT => {\n const p = o.byId.get(id)\n if (!p) throw new Error(`unknown part \"${id}\" in object \"${o.id}\"`)\n return p\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Geometry in world space\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const partXf = (o: ObjRT, p: PartRT): { c: Vec3; q: Quat } => ({ c: toWorld(o.st.position, o.st.rotation, p.pos), q: quat.mul(o.st.rotation, p.q) })\n const objLocal = (o: ObjRT, w: Vec3) => toLocal(o.st.position, o.st.rotation, w)\n const objLocalDir = (o: ObjRT, w: Vec3) => rotateVec(quat.conjugate(o.st.rotation), w)\n const jointWorld = (o: ObjRT, j: JointRT) => toWorld(o.st.position, o.st.rotation, j.pos)\n const distToPart = (o: ObjRT, p: PartRT, w: Vec3) => {\n const { c, q } = partXf(o, p)\n return distanceToShape(p.spec.shape, toLocal(c, q, w))\n }\n const partWorldAabb = (o: ObjRT, p: PartRT) => {\n const { c, q } = partXf(o, p)\n return aabbOf(p.spec.shape, c, q)\n }\n\n interface PartRay { t0: number; t1: number; n: Vec3 }\n const rayPartRaw = (pos: Vec3, rot: Quat, spec: PartSpec, pq: Quat, origin: Vec3, d: Vec3, lp: Vec3 = spec.position): PartRay | null => {\n const c = toWorld(pos, rot, lp)\n const q = quat.mul(rot, pq)\n const qi = quat.conjugate(q)\n const r = rayShape(spec.shape, rotateVec(qi, vec.sub(origin, c)), rotateVec(qi, d))\n return r ? { t0: r.t0, t1: r.t1, n: rotateVec(q, r.n0) } : null\n }\n const rayPart = (o: ObjRT, p: PartRT, origin: Vec3, d: Vec3): PartRay | null => rayPartRaw(o.st.position, o.st.rotation, p.spec, p.q, origin, d, p.pos)\n\n const raySphereMiss = (origin: Vec3, d: Vec3, c: Vec3, r: number, maxDist: number): boolean => {\n const oc = vec.sub(origin, c)\n const b = vec.dot(oc, d)\n const cc = vec.dot(oc, oc) - r * r\n if (cc > 0 && b > 0) return true\n const disc = b * b - cc\n if (disc < 0) return true\n return -b - Math.sqrt(disc) > maxDist\n }\n\n const raycastInternal = (origin: Vec3, dir: Vec3, maxDist: number, ignore?: Set<string>): (RayHit & { pathLen: number }) | null => {\n const d = vec.normalize(dir)\n let best: (RayHit & { pathLen: number }) | null = null\n for (const o of objects.values()) {\n if (raySphereMiss(origin, d, toWorld(o.st.position, o.st.rotation, o.bc), o.br, best ? Math.min(maxDist, best.distance) : maxDist)) continue\n for (const p of o.parts) {\n if (isLost(p) || ignore?.has(`${o.id}\\0${p.spec.id}`)) continue\n const r = rayPart(o, p, origin, d)\n if (!r || r.t0 < 0 || r.t0 > maxDist) continue\n if (p.st.opening && insideOpening(o, p, vec.madd(origin, d, r.t0))) continue\n if (!best || r.t0 < best.distance) best = { object: o.id, part: p.spec.id, point: vec.madd(origin, d, r.t0), normal: r.n, distance: r.t0, pathLen: r.t1 - r.t0 }\n }\n }\n for (const im of impls.values()) {\n for (const ps of im.impl.describe().parts) {\n if (ignore?.has(`${im.impl.id}\\0${ps.id}`)) continue\n const ov = im.poses.get(ps.id)\n const r = rayPartRaw(im.position, im.rotation, ps, ov?.q ?? quatFromEuler(...(ps.rotation ?? [0, 0, 0])), origin, d, ov?.pos)\n if (!r || r.t0 < 0 || r.t0 > maxDist) continue\n if (!best || r.t0 < best.distance) best = { object: im.impl.id, part: ps.id, point: vec.madd(origin, d, r.t0), normal: r.n, distance: r.t0, pathLen: r.t1 - r.t0 }\n }\n }\n return best\n }\n\n // impl hosting\n const implHit = (im: ImplRT, hit: Hit): HitResult => {\n let h = hit\n if (hit.space === 'local') {\n h = { ...hit, space: 'world', point: toWorld(im.position, im.rotation, hit.point) }\n if (hit.direction) h.direction = rotateVec(im.rotation, hit.direction)\n }\n const start = cur.length\n for (const e of im.impl.hit(h) ?? []) emit(e.time === undefined ? { ...e, time } : e)\n const mine = cur.slice(start)\n const res: HitResult = { object: im.impl.id, damage: 0, penetrated: false, exitEnergy: 0, events: mine, point: hit.point }\n for (const e of mine) {\n if (e.type === 'damage') res.damage += e.amount\n if (e.type === 'hole' && e.hole.through) res.penetrated = true\n if (res.part === undefined && 'part' in e) res.part = (e as { part: string }).part\n }\n return res\n }\n\n const implJointPos = (im: ImplRT, a: string, b: string): Vec3 | null => {\n const parts = im.impl.describe().parts\n const pa = parts.find((p) => p.id === a), pb = parts.find((p) => p.id === b)\n if (!pa || !pb) return null\n const A = aabbOf(pa.shape, pa.position, quatFromEuler(...(pa.rotation ?? [0, 0, 0])))\n const B = aabbOf(pb.shape, pb.position, quatFromEuler(...(pb.rotation ?? [0, 0, 0])))\n const pos: Vec3 = [0, 0, 0]\n for (let k = 0; k < 3; k++) pos[k] = (Math.max(A.min[k], B.min[k]) + Math.min(A.max[k], B.max[k])) / 2\n return toWorld(im.position, im.rotation, pos)\n }\n\n /** Find the part a hit lands on: a short ray along `dir`, else the nearest part within `tol`. */\n const locate = (o: ObjRT, point: Vec3, dir: Vec3 | undefined, tol: number, only?: PartRT): Loc | null => {\n const cands = only ? [only] : o.parts\n if (dir && vec.length(dir) > 1e-9) {\n const d = vec.normalize(dir)\n const origin = vec.madd(point, d, -0.05)\n let best: Loc | null = null\n let bestT = Infinity\n let inside: Loc | null = null\n for (const p of cands) {\n if (isLost(p)) continue\n const r = rayPart(o, p, origin, d)\n if (!r) continue\n if (r.t0 >= 0 && r.t0 <= 0.15) {\n if (r.t0 < bestT) {\n bestT = r.t0\n best = { p, point: vec.madd(origin, d, r.t0), normal: r.n, dir: d, pathLen: Math.max(r.t1 - r.t0, 1e-4) }\n }\n } else if (r.t0 < 0 && r.t1 > 0 && !inside) {\n inside = { p, point, normal: vec.scale(d, -1), dir: d, pathLen: Math.max(r.t1 - 0.05, p.thickness) }\n }\n }\n if (best) return best\n if (inside) return inside\n }\n let np: PartRT | null = null\n let nd = Infinity\n for (const p of cands) {\n if (isLost(p)) continue\n const dd = distToPart(o, p, point)\n if (dd < nd) {\n nd = dd\n np = p\n }\n }\n if (!np || nd > tol) return null\n const { c, q } = partXf(o, np)\n const sp = surfacePoint(np.spec.shape, toLocal(c, q, point))\n const normal = rotateVec(q, sp.normal)\n return { p: np, point: toWorld(c, q, sp.point), normal, dir: dir && vec.length(dir) > 1e-9 ? vec.normalize(dir) : vec.scale(normal, -1), pathLen: np.thickness }\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Marks on parts\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const markDamaged = (p: PartRT) => {\n if (p.st.status === 'intact') p.st.status = 'damaged'\n }\n\n const addDent = (o: ObjRT, p: PartRT, wp: Vec3, wn: Vec3, radius: number, depth: number, src?: string) => {\n const dent: Dent = { point: objLocal(o, wp), normal: objLocalDir(o, wn), radius, depth }\n const arr = p.st.dents\n let ni = -1, nd = Infinity\n for (let i = 0; i < arr.length; i++) {\n const dd = vec.distance(arr[i].point, dent.point)\n if (dd < nd) {\n nd = dd\n ni = i\n }\n }\n if (ni >= 0 && (arr.length >= maxDents || nd < arr[ni].radius * 0.6)) {\n arr[ni].depth = Math.min(0.1, Math.max(arr[ni].depth, depth) + depth * 0.3)\n arr[ni].radius = Math.max(arr[ni].radius, radius)\n } else arr.push(dent)\n markDamaged(p)\n emit({ ...base(o, src), type: 'dent', part: p.spec.id, dent, worldPoint: wp })\n }\n\n const addHole = (o: ObjRT, p: PartRT, wp: Vec3, wn: Vec3, diameter: number, through: boolean, exit?: Vec3, src?: string) => {\n const hole: Hole = { point: objLocal(o, wp), normal: objLocalDir(o, wn), diameter, through }\n p.st.holes.push(hole)\n if (p.st.holes.length > maxHoles) p.st.holes.shift()\n markDamaged(p)\n emit({ ...base(o, src), type: 'hole', part: p.spec.id, hole, worldPoint: wp, ...(exit ? { exitPoint: exit } : {}) })\n setStage(o, p, 1, {}, src)\n return hole\n }\n\n const addCrack = (o: ObjRT, p: PartRT, wp: Vec3, wn: Vec3, length: number, src?: string) => {\n const crack: Crack = { point: objLocal(o, wp), normal: objLocalDir(o, wn), length: Math.min(length, Math.max(p.bound, 0.05)), rays: 5 + Math.floor(rnd() * 5) }\n p.st.cracks.push(crack)\n if (p.st.cracks.length > 16) p.st.cracks.shift()\n markDamaged(p)\n emit({ ...base(o, src), type: 'crack', part: p.spec.id, crack, worldPoint: wp })\n setStage(o, p, 1, {}, src)\n }\n\n const debris = (o: ObjRT, p: PartRT, kind: DebrisKind, point: Vec3, normal: Vec3, count: number, speed: number, src?: string) =>\n emit({ ...base(o, src), type: 'debris', part: p.spec.id, kind, point, normal, count, speed })\n\n const holeRate = (hole: Hole, pressurized: boolean) => (pressurized ? 0.5 : 0.1) * (hole.diameter / 0.009)\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Failure, joints\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const detachEvents = (o: ObjRT, opened: JointRT[], by: 'break' | 'tool' | 'part_lost', src?: string) => {\n for (const j of opened) emit({ ...base(o, src), type: 'detach', joint: j.spec.id, parts: [j.spec.a, j.spec.b], by, groups: o.st.groups.map((g) => [...g]) })\n }\n\n const checkDestroyed = (o: ObjRT, src?: string) => {\n if (!o.st.destroyed && o.parts.length > 0 && o.parts.every(isLost)) {\n o.st.destroyed = true\n emit({ ...base(o, src), type: 'destroyed' })\n }\n }\n\n const partLost = (o: ObjRT, p: PartRT, src?: string) => {\n const opened: JointRT[] = []\n for (const j of o.byPart.get(p.spec.id) ?? []) {\n if (j.st.open) continue\n j.st.open = true\n j.st.openedBy = 'part_lost'\n opened.push(j)\n }\n solveStructure(o)\n recomputeGroups(o)\n detachEvents(o, opened, 'part_lost', src)\n collapseCheck(o, src)\n checkDestroyed(o, src)\n }\n\n /**\n * Distance from a world point to the joint's contact region: the overlap box of the two parts' bounds (or, when they only nearly touch, the box\n * of the gap between them). Measuring to the joint centre would make a thick part untouchable: a blow on a trunk's surface is half the trunk's\n * width away from a joint that sits on its axis.\n */\n const jointReach = (o: ObjRT, j: JointRT, point: Vec3): number => {\n const A = partWorldAabb(o, o.parts[j.ia]), B = partWorldAabb(o, o.parts[j.ib])\n let d2 = 0\n for (let k = 0; k < 3; k++) {\n const lo = Math.min(Math.max(A.min[k], B.min[k]), Math.min(A.max[k], B.max[k]))\n const hi = Math.max(Math.max(A.min[k], B.min[k]), Math.min(A.max[k], B.max[k]))\n const d = point[k] < lo ? lo - point[k] : point[k] > hi ? point[k] - hi : 0\n d2 += d * d\n }\n return Math.sqrt(d2)\n }\n /** How far from the contact region a blow still counts: half the smallest dimension of the smaller part, at least 6 cm. */\n const jointReachLimit = (o: ObjRT, j: JointRT): number => {\n const pa = o.parts[j.ia], pb = o.parts[j.ib]\n const small = pa.dims[0] * pa.dims[1] * pa.dims[2] <= pb.dims[0] * pb.dims[1] * pb.dims[2] ? pa : pb\n return Math.max(0.06, 0.5 * Math.min(small.dims[0], small.dims[1], small.dims[2]))\n }\n\n const wearJoints = (o: ObjRT, p: PartRT, amount: number, near?: Vec3, radius = 0.06, src?: string, split = false) => {\n if (amount <= 0) return\n const mine = (o.byPart.get(p.spec.id) ?? []).filter((j) => !j.st.open)\n if (split && mine.length) amount /= mine.length\n for (const j of mine) {\n if (j.st.open) continue\n // the rebar of a reinforced part is its cage: blows do not wear it, only a torch or a saw cuts it (or the cage itself giving way)\n if (j.spec.kind === 'rebar' && (o.parts[j.ia].spec.reinforcement || o.parts[j.ib].spec.reinforcement)) continue\n if (near && jointReach(o, j, near) > Math.max(radius, jointReachLimit(o, j))) continue\n j.st.hp -= amount\n if (j.st.hp <= 0) {\n j.st.hp = 0\n j.st.open = true\n j.st.openedBy = 'break'\n solveStructure(o)\n recomputeGroups(o)\n detachEvents(o, [j], 'break', src)\n collapseCheck(o, src)\n }\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Damage stages: spall, breach, reinforcement cage\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const setStage = (o: ObjRT, p: PartRT, stage: DamageStage, extra: { opening?: { center: Vec3; radius: number }; fragments?: Fragment[] } = {}, src?: string) => {\n if (!p.staged || (p.st.stage ?? 0) >= stage) return\n p.st.stage = stage\n emit({ ...base(o, src), type: 'stage', part: p.spec.id, stage, ...extra })\n }\n\n /** `1` when the outward normal points along the part's local +thin axis, else `-1`. */\n const faceOf = (o: ObjRT, p: PartRT, worldNormal: Vec3): number => (rotateVec(quat.conjugate(partXf(o, p).q), worldNormal)[p.thin] >= 0 ? 1 : -1)\n\n const spallOuter = (o: ObjRT, p: PartRT, wp: Vec3, face: number, normal: Vec3, radius: number, src?: string) => {\n if (p.layers.length === 0) return\n const lp = objLocal(o, wp)\n const layer = outerLayer(p.layers, p.rt.spalls, face, lp)\n if (!layer) return\n const spalls = (p.rt.spalls ??= [])\n spalls.push([layer.index, face, lp[0], lp[1], lp[2], radius])\n if (spalls.length > MAX_SPALLS) spalls.shift()\n markDamaged(p)\n emit({ ...base(o, src), type: 'spall', part: p.spec.id, layer: layer.index, point: wp, area: Math.PI * radius * radius })\n debris(o, p, layer.mat.hitDebris, wp, normal, 5, 2, src)\n setStage(o, p, 1, {}, src)\n }\n\n const insideOpening = (o: ObjRT, p: PartRT, objectPoint: Vec3): boolean => {\n const op = p.st.opening\n if (!op) return false\n const [u, v] = planeAxes(p.thin)\n const lp = toLocal(p.pos, p.q, objectPoint)\n const lc = toLocal(p.pos, p.q, op.center)\n return Math.hypot(lp[u] - lc[u], lp[v] - lc[v]) <= op.radius\n }\n\n /** Square metres of wall a blow removes: the volume its damage takes out, over the thickness it crosses. */\n const breachAreaOf = (p: PartRT, damage: number, blast: boolean): number =>\n (damage / (p.mat.hpPerKg * p.mat.density) / Math.max(p.thickness, 0.005)) * (blast ? breachBlastFactor : 1)\n\n const localHolesOf = (p: PartRT): LocalHole[] =>\n p.st.holes.map((h) => ({ point: toLocal(p.pos, p.q, h.point), normal: rotateVec(quat.conjugate(p.q), h.normal), diameter: h.diameter }))\n\n const unitsOf = (p: PartRT) => p.spec.units ?? { size: [p.mat.fragmentSize?.[1] ?? 0.2, p.mat.fragmentSize?.[1] ?? 0.2, p.thickness] as Vec3, bond: 'stack' as const }\n\n const FRAGMENT_SHAPE = { shatter: 'shard', splinter: 'splinter', tear: 'scrap' } as const\n\n /** Unit-sized fragments of `cells` (part-local), thrown from `hitW`; the holes that fell on a unit stay on it as `marks`. */\n const cellFragments = (o: ObjRT, p: PartRT, cells: readonly UnitCell[], hitW: Vec3, dir: Vec3 | null, speed: number, mass: number, tag: string): Fragment[] => {\n const { c, q } = partXf(o, p)\n const holes = p.st.holes.length > 0 ? localHolesOf(p) : []\n const [u, v] = planeAxes(p.thin)\n const faceArea = (cell: UnitCell) => cell.size[u] * cell.size[v]\n const total = cells.reduce((sum, cell) => sum + faceArea(cell), 0) || 1\n const shape = p.spec.units ? 'chunk' : FRAGMENT_SHAPE[p.mat.fracture as keyof typeof FRAGMENT_SHAPE] ?? 'chunk'\n return cells.map((cell, i) => {\n const cw = toWorld(c, q, cell.center)\n const out = vec.normalize(vec.sub(cw, hitW), [0, 1, 0])\n const dv = dir ? vec.normalize(vec.madd(out, dir, 0.6)) : out\n const k = speed * (0.6 + 0.8 * rnd())\n const marks = marksInBox(cell.center, cell.size, undefined, holes)\n return {\n id: `${p.spec.id}#${tag}${i}`, part: p.spec.id, material: p.spec.material, shape, center: cw, size: [cell.size[0], cell.size[1], cell.size[2]], rotation: q,\n velocity: [dv[0] * k, dv[1] * k + 0.5 * rnd(), dv[2] * k], angularVelocity: [(rnd() - 0.5) * 8, (rnd() - 0.5) * 8, (rnd() - 0.5) * 8],\n mass: (mass * faceArea(cell)) / total, ...(marks.length > 0 ? { marks } : {}),\n }\n })\n }\n\n const worldBars = (o: ObjRT, p: PartRT, bars: ReadonlyArray<readonly [Vec3, Vec3]>): Array<[Vec3, Vec3]> => {\n const { c, q } = partXf(o, p)\n return bars.map(([a, b]) => [toWorld(c, q, a), toWorld(c, q, b)])\n }\n\n /** A blow that made through damage of `area` m² at `wp` (world): adds up with the earlier ones within the breach radius, and opens the part past its threshold. */\n const addBreach = (o: ObjRT, p: PartRT, wp: Vec3, area: number, energy: number, dir: Vec3 | null, src?: string) => {\n if (!p.staged || area <= 0 || (p.st.stage ?? 0) >= 2 || p.st.stripped || isLost(p)) return\n const lp = objLocal(o, wp)\n const list = (p.rt.breach ??= [])\n list.push([lp[0], lp[1], lp[2], area])\n if (list.length > MAX_SPALLS) list.shift()\n let total = 0\n const sum: Vec3 = [0, 0, 0]\n for (const [x, y, z, a] of list) {\n if (vec.distance([x, y, z], lp) > breachRadius) continue\n total += a\n sum[0] += x * a\n sum[1] += y * a\n sum[2] += z * a\n }\n if (total < (p.spec.breach?.area ?? BREACH_AREA)) return\n openBreach(o, p, [sum[0] / total, sum[1] / total, sum[2] / total], total, energy, dir, src)\n }\n\n /**\n * Stage 2: the units around `center` (object-local) come out as fragments the size of one unit, the part keeps an opening and its mass drops. An\n * opening as wide as the part cuts it in two (a column, a lintel): that is a fracture instead.\n */\n const openBreach = (o: ObjRT, p: PartRT, center: Vec3, total: number, energy: number, dir: Vec3 | null, src?: string) => {\n const [u, v] = planeAxes(p.thin)\n const radius = clamp(Math.sqrt(total / Math.PI), Math.sqrt((p.spec.breach?.area ?? BREACH_AREA) / Math.PI), breachRadius)\n const lc = toLocal(p.pos, p.q, center)\n lc[p.thin] = 0\n const { c, q } = partXf(o, p)\n const worldCenter = toWorld(c, q, lc)\n if (2 * radius >= Math.min(p.dims[u], p.dims[v])) {\n failPart(o, p, worldCenter, dir, energy, 12, src)\n return\n }\n const cells = cellsWithin(unitGrid(p.dims, p.thin, unitsOf(p), BREACH_GRID_CAP), p.thin, lc, radius)\n const removed = (p.st.mass * cells.reduce((sum, cell) => sum + cell.size[u] * cell.size[v], 0)) / (p.dims[u] * p.dims[v])\n const speed = clamp(Math.sqrt((2 * energy * 0.1) / Math.max(removed, 0.05)), 0.5, 8)\n const fragments = cellFragments(o, p, cells, worldCenter, dir, speed, removed, 'b')\n const holes = localHolesOf(p)\n p.st.holes = p.st.holes.filter((_, i) => !cells.some((cell) => marksInBox(cell.center, cell.size, undefined, [holes[i]!]).length > 0))\n p.st.mass = Math.max(0, p.st.mass - removed)\n p.rt.removed = (p.rt.removed ?? 0) + removed\n p.st.opening = { center: objLocal(o, worldCenter), radius }\n markDamaged(p)\n setStage(o, p, 1, {}, src)\n setStage(o, p, 2, { opening: { center: worldCenter, radius }, fragments }, src)\n debris(o, p, p.mat.breakDebris, worldCenter, vec.scale(dir ?? [0, 1, 0], -1), 14, 3, src)\n const reinforcement = p.spec.reinforcement\n if (reinforcement) {\n const bars = worldBars(o, p, clipBarsToDisc(rebarBars(p.dims, p.thin, reinforcement.spacing), u, v, [lc[u], lc[v]], radius + 0.05))\n if (bars.length > 0) emit({ ...base(o, src), type: 'expose', part: p.spec.id, bars })\n }\n if (p.structural) solveStructure(o)\n }\n\n /** The concrete of a reinforced part is gone: the part stays as its rebar cage, with the capacity the reinforcement leaves it. */\n const stripPart = (o: ObjRT, p: PartRT, reinforcement: NonNullable<PartSpec['reinforcement']>, src?: string) => {\n const bars = rebarBars(p.dims, p.thin, reinforcement.spacing)\n p.st.stripped = true\n p.st.hp = p.st.maxHp\n p.st.mass = rebarMass(bars, reinforcement.diameter, materials.get(reinforcement.material)?.density)\n p.st.holes = []\n p.st.burning = false\n p.rt.jet = false\n markDamaged(p)\n emit({ ...base(o, src), type: 'expose', part: p.spec.id, bars: worldBars(o, p, bars) })\n solveStructure(o)\n collapseCheck(o, src)\n }\n\n /** The units of the part that are still there (the opening of a breach is already gone), as a fragment plan. */\n const unitFragmentPlan = (p: PartRT, cap: number): PlannedFragment[] => {\n const grid = unitGrid(p.dims, p.thin, unitsOf(p), cap)\n const op = p.st.opening\n const cells = op ? cellsOutside(grid, p.thin, toLocal(p.pos, p.q, op.center), op.radius) : grid\n const [u, v] = planeAxes(p.thin)\n return cells.map((cell) => ({ center: cell.center, size: cell.size, q: quat.identity(), shape: 'chunk' as const, weight: cell.size[u] * cell.size[v] }))\n }\n\n /** The bare cage gives way (overload, a blast, a cut that finishes): the part is lost for good. */\n const loseCage = (o: ObjRT, p: PartRT, src?: string) => {\n p.st.status = 'broken'\n p.st.hp = 0\n p.st.mass = 0\n emit({ ...base(o, src), type: 'expose', part: p.spec.id, bars: [] })\n debris(o, p, 'sparks', partXf(o, p).c, [0, 1, 0], 6, 3, src)\n partLost(o, p, src)\n }\n\n /** Part hit points reached 0 (or it was forced to explode): fragments, debris, joints open. */\n const failPart = (o: ObjRT, p: PartRT, origin: Vec3 | null, dir: Vec3 | null, fragEnergy: number, cap: number, src?: string) => {\n if (isLost(p)) return\n if (p.st.stripped) {\n loseCage(o, p, src)\n return\n }\n const ex = p.spec.explodes\n const style = p.mat.fracture === 'none' ? 'snap' : p.mat.fracture\n const { c, q } = partXf(o, p)\n const hitW = origin ?? c\n const grain = p.spec.grain ? AXIS[p.spec.grain] : undefined\n const hitLocal = toLocal(c, q, hitW)\n const unitPlan = p.spec.units ? unitFragmentPlan(p, maxFragments * UNIT_FRAGMENT_FACTOR) : []\n const plan = unitPlan.length > 0 ? unitPlan : planFragments({\n style, dims: p.dims, thickness: p.thickness, grain, hit: hitLocal, fragmentSize: p.mat.fragmentSize ?? [0.04, 0.2], maxFragments, rnd,\n })\n const holes = p.st.holes.length > 0 ? localHolesOf(p) : []\n const mass = p.st.mass\n const totW = plan.reduce((s, f) => s + f.weight, 0) || 1\n const energy = ex ? ex.energy * 0.2 : fragEnergy\n const speed = clamp(Math.sqrt((2 * energy) / Math.max(mass, 0.05)), 0.3, ex ? 40 : cap)\n const fragments: Fragment[] = plan.map((f, i) => {\n const cw = toWorld(c, q, f.center)\n const out = vec.normalize(vec.sub(cw, hitW), [0, 1, 0])\n const dv = dir ? vec.normalize(vec.madd(out, dir, 0.6)) : out\n const k = speed * (0.6 + 0.8 * rnd())\n const marks = marksInBox(f.center, f.size, f.q, holes)\n return {\n id: `${p.spec.id}#${i}`, part: p.spec.id, material: p.spec.material, shape: f.shape, center: cw, size: f.size, rotation: quat.mul(q, f.q),\n velocity: [dv[0] * k, dv[1] * k + 0.5 * rnd(), dv[2] * k],\n angularVelocity: [(rnd() - 0.5) * 12, (rnd() - 0.5) * 12, (rnd() - 0.5) * 12],\n mass: (mass * f.weight) / totW, ...(marks.length > 0 ? { marks } : {}),\n }\n })\n const reinforcement = p.spec.reinforcement\n if (!reinforcement) {\n p.st.status = 'broken'\n p.st.hp = 0\n p.st.mass = 0\n p.st.burning = false\n p.rt.jet = false\n }\n emit({ ...base(o, src), type: 'fracture', part: p.spec.id, style, fragments, point: hitW })\n debris(o, p, p.mat.breakDebris, c, [0, 1, 0], clamp(Math.round(Math.cbrt(partVolume(p.spec.shape)) * 30), 3, 20), 2, src)\n setStage(o, p, 3, {}, src)\n if (reinforcement) {\n stripPart(o, p, reinforcement, src)\n return\n }\n if (ex) {\n emit({ ...base(o, src), type: 'explode', part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius })\n blasts.push({ point: c, energy: ex.energy, radius: ex.radius, source: src })\n }\n partLost(o, p, src)\n }\n\n /**\n * Sets an explosive part off from outside (`explodes.chain`): it will explode after the delay of `trigger`, once. The delay is one draw\n * from the world seed, so the same inputs give the same order of blasts.\n */\n const prime = (o: ObjRT, p: PartRT, trigger: ChainTrigger, src?: string) => {\n const spec = chainDelayOf(p.spec, trigger)\n if (spec === undefined || isLost(p) || p.rt.chainDue !== undefined) return\n const delay = drawChainDelay(spec, rnd)\n p.rt.chainDue = time + delay\n primed.set(p, o)\n o.active = true\n emit({ ...base(o, src), type: 'primed', part: p.spec.id, point: partXf(o, p).c, trigger, delay })\n }\n\n const CHAIN_TRIGGER_OF: Partial<Record<DamageType, ChainTrigger>> = { ballistic: 'shot', explosive: 'explosion' }\n\n /** Remove hit points. Returns the amount actually removed. */\n const applyDamage = (o: ObjRT, p: PartRT, amount: number, type: DamageType, origin: Vec3 | null, dir: Vec3 | null, fragEnergy: number, cap: number, src?: string): number => {\n if (isLost(p) || amount <= 0) return 0\n const prev = p.st.hp\n p.st.hp -= amount\n markDamaged(p)\n const trigger = CHAIN_TRIGGER_OF[type]\n const chained = trigger !== undefined && chainDelayOf(p.spec, trigger) !== undefined\n // a bullet or a blast sets a chained part off after its delay instead of tearing it apart on the spot\n if (chained && p.st.hp <= 0 && p.rt.chainDue === undefined) p.st.hp = Math.min(prev, 1)\n if (p.st.hp <= 0 && p.mat.fracture === 'none' && !p.spec.explodes) p.st.hp = Math.min(prev, 1)\n const done = prev - p.st.hp\n if (done > 0) emit({ ...base(o, src), type: 'damage', part: p.spec.id, amount: done, hp: Math.max(0, p.st.hp), damageType: type })\n if (p.st.hp <= 0) failPart(o, p, origin, dir, fragEnergy, cap, src)\n else if (chained && (trigger === 'explosion' || 1 - p.st.hp / p.st.maxHp >= shotDamageFractionOf(p.spec))) prime(o, p, trigger, src)\n return done\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Hits\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n interface BallisticOut { penetrated: boolean; exitEnergy: number; exitPoint?: Vec3; damage: number }\n\n const ballistic = (o: ObjRT, p: PartRT, entry: Vec3, n: Vec3, d: Vec3, E: number, caliber: number, pathLen: number, src?: string): BallisticOut => {\n const mat = p.mat\n // a bare cage and an opening do not stop a bullet\n if (p.st.stripped || (p.st.opening && insideOpening(o, p, objLocal(o, entry)))) {\n return { penetrated: true, exitEnergy: E, exitPoint: vec.madd(entry, d, Math.min(pathLen, p.thickness)), damage: 0 }\n }\n const sin = Math.min(1, Math.abs(vec.dot(d, n)))\n const angle = (Math.asin(sin) * 180) / Math.PI\n const slant = Math.max(sin, 0.3)\n const effM = p.thickness / slant\n const face = p.layers.length > 0 ? faceOf(o, p, n) : 1\n const exitLocal = objLocal(o, vec.madd(entry, d, Math.min(pathLen, effM)))\n const coats = p.layers.length > 0 ? layersEnergy(p.layers, p.rt.spalls, face, objLocal(o, entry)) + layersEnergy(p.layers, p.rt.spalls, -face, exitLocal) : 0\n // each coat adds penetration x thickness to the core's; a part without layers keeps the plain formula\n const thr = coats > 0 ? (mat.penetration * p.thickness * 1000 + coats) / slant : mat.penetration * effM * 1000\n const penetrated = E > thr\n // a thin brittle shell that shatters (a pane, a bottle) is lost to one bullet that a thick block of the same glass shrugs off: the same\n // fragility factor that melee uses for blunt hits (1 for ductile materials and for shells 2 cm or thicker, up to x118 for 3 mm glass)\n const scale = (mat.damageScale?.ballistic ?? 1) * (mat.fracture === 'shatter' ? fragility(mat.ductility, p.thickness) : 1)\n const id = p.spec.id\n if (!penetrated && mat.ricochetDeg && angle < mat.ricochetDeg) {\n const r = vec.sub(d, vec.scale(n, 2 * vec.dot(d, n)))\n emit({ ...base(o, src), type: 'ricochet', part: id, point: entry, direction: vec.normalize(r), energy: E * 0.4 })\n debris(o, p, mat.hitDebris, entry, n, 3, 3, src)\n const dmg = applyDamage(o, p, E * DMG_PER_J * scale * 0.2, 'ballistic', entry, d, E * 0.1, 12, src)\n return { penetrated: false, exitEnergy: 0, damage: dmg }\n }\n if (p.layers.length > 0) spallOuter(o, p, entry, face, n, Math.max(0.03, (caliber / 1000) * 4), src)\n const brittle = mat.ductility < 0.3\n const ratio = E / Math.max(thr, 1e-6)\n const crackLen = clamp(0.03 + ratio * 0.2, 0.03, 0.8)\n let exitPoint: Vec3 | undefined\n if (penetrated) {\n exitPoint = vec.madd(entry, d, Math.min(pathLen, effM + layersThickness(p.layers, face) / slant + layersThickness(p.layers, -face) / slant))\n const hole = addHole(o, p, entry, n, (caliber / 1000) * (mat.ductility >= 0.3 ? 1 : 1.5), true, exitPoint, src)\n if (p.layers.length > 0) spallOuter(o, p, exitPoint, -face, vec.scale(n, -1), Math.max(0.03, (caliber / 1000) * 4), src)\n addBreach(o, p, entry, Math.PI * (hole.diameter / 2) * (hole.diameter / 2), E, d, src)\n if (brittle && mat.fracture === 'shatter') addCrack(o, p, entry, n, crackLen, src)\n if (p.spec.contains && (p.st.liters ?? 0) > 0) {\n emit({\n ...base(o, src), type: 'leak', part: id, fluid: p.spec.contains.fluid, point: entry, direction: n, rate: holeRate(hole, !!p.spec.contains.pressurized),\n pressurized: !!p.spec.contains.pressurized,\n })\n }\n } else if (mat.ductility >= 0.5) {\n addDent(o, p, entry, n, Math.max((caliber * 3) / 1000, 0.012), clamp(Math.min(Math.max(p.thickness * 3, 0.003), ratio * 0.01), 0.001, 0.05), src)\n } else if (brittle) {\n addCrack(o, p, entry, n, crackLen, src)\n if (mat.fracture !== 'shatter') addHole(o, p, entry, n, caliber / 1000, false, undefined, src)\n } else addHole(o, p, entry, n, caliber / 1000, false, undefined, src)\n debris(o, p, mat.hitDebris, entry, n, clamp(Math.round(E / 60) + 2, 2, 14), clamp(Math.sqrt(E) / 6, 1, 8), src)\n // a bullet only wears the joints of the part it hits, by the energy the part absorbed (a through-and-through shot transfers little)\n wearJoints(o, p, (penetrated ? thr : E) * 0.02, undefined, 0, src, true)\n const dmg = applyDamage(o, p, E * DMG_PER_J * scale, 'ballistic', entry, d, E * 0.1, 12, src)\n return { penetrated, exitEnergy: penetrated ? E - thr : 0, exitPoint, damage: dmg }\n }\n\n const melee = (o: ObjRT, p: PartRT, kind: 'blunt' | 'slash', E: number, point: Vec3, n: Vec3, d: Vec3, contactR: number, src?: string): number => {\n const mat = p.mat\n const thrMm = mat.penetration * p.thickness * 1000\n // brittle thin shells (a bottle, a mug, a pane) break from a knock that a thick block shrugs off\n const fragile = kind === 'blunt' ? fragility(mat.ductility, p.thickness) : 1\n const Ec = E * fragile\n if (E > 0) {\n if (kind === 'blunt') {\n if (mat.ductility >= 0.5) addDent(o, p, point, n, Math.max(contactR, 0.015), clamp(E * 0.0001, 0.001, 0.06), src)\n else if (mat.ductility < 0.3) {\n if (Ec >= 5) addCrack(o, p, point, n, clamp(0.04 + Math.min(Ec, E * 6) * 0.0008, 0.04, 0.6), src)\n } else if (E >= thrMm * 0.2) addDent(o, p, point, n, Math.max(contactR, 0.015), clamp(E * 0.00006, 0.001, 0.04), src)\n } else if (mat.fracture === 'tear') {\n addHole(o, p, point, n, clamp(0.02 + E * 0.0005, 0.02, 0.3), true, undefined, src)\n } else if (mat.ductility >= 0.5) {\n addDent(o, p, point, n, Math.max(contactR, 0.01), clamp(E * 0.00004, 0.0005, 0.02), src)\n }\n debris(o, p, mat.hitDebris, point, n, clamp(Math.round(E / 25) + 1, 1, 10), clamp(Math.sqrt(E) / 8, 1, 6), src)\n }\n if (kind === 'blunt') wearJoints(o, p, E * 0.3, undefined, 0, src)\n else wearJoints(o, p, E * 0.3, point, 0.06, src)\n if (kind === 'blunt' && E > 0 && p.layers.length > 0) spallOuter(o, p, point, faceOf(o, p, n), n, Math.max(contactR, 0.05), src)\n const scale = mat.damageScale?.[kind] ?? 1\n const done = applyDamage(o, p, Ec * DMG_PER_J * scale * (kind === 'slash' ? p.cutFactor : 1), kind, point, d, E * 0.1, 12, src)\n addBreach(o, p, point, breachAreaOf(p, done, false), E, d, src)\n return done\n }\n\n const blastObject = (o: ObjRT, point: Vec3, energy: number, radius: number, src?: string): HitResult => {\n const start = cur.length\n const res: HitResult = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] }\n for (const p of o.parts) {\n if (isLost(p)) continue\n const { c, q } = partXf(o, p)\n const lp = toLocal(c, q, point)\n const dist = distanceToShape(p.spec.shape, lp)\n if (dist >= radius) continue\n const f = (1 - dist / radius) ** 2\n const Ein = energy * f * BLAST_COUPLING\n const sp = surfacePoint(p.spec.shape, lp)\n const wp = toWorld(c, q, sp.point)\n const wn = rotateVec(q, sp.normal)\n if (!res.part) {\n res.part = p.spec.id\n res.point = wp\n }\n const mat = p.mat\n if (Ein > 20) {\n if (mat.ductility >= 0.5) addDent(o, p, wp, wn, clamp(0.05 + Math.sqrt(Ein) * 0.002, 0.05, 0.4), clamp(0.004 + Ein * 0.00002, 0.004, 0.08), src)\n else if (mat.ductility < 0.3 && Ein > 60) addCrack(o, p, wp, wn, clamp(0.05 + Ein * 0.0005, 0.05, 1), src)\n debris(o, p, mat.hitDebris, wp, wn, clamp(Math.round(Ein / 80) + 1, 1, 12), clamp(Math.sqrt(Ein) / 4, 2, 15), src)\n }\n const th = mat.thermal\n if (th.ignitionC !== undefined && p.st.fuel > 0) {\n p.st.temperature += 300 * f\n o.active = true\n if (f >= 0.25 && !p.st.burning) {\n p.st.temperature = Math.max(p.st.temperature, th.ignitionC + 1)\n checkIgnite(o, p, src)\n }\n }\n wearJoints(o, p, Ein * 0.5, undefined, 0, src)\n if (Ein > 20 && p.layers.length > 0) spallOuter(o, p, wp, faceOf(o, p, wn), wn, clamp(0.05 + Math.sqrt(Ein) * 0.002, 0.05, 0.4), src)\n const dealt = applyDamage(o, p, Ein * DMG_PER_J * (mat.damageScale?.explosive ?? 1), 'explosive', point, null, Ein * 0.3, 40, src)\n res.damage += dealt\n addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src)\n }\n res.events = cur.slice(start)\n return res\n }\n\n const blastWorld = (point: Vec3, energy: number, radius: number, src?: string): HitResult[] => {\n const out: HitResult[] = []\n for (const o of [...objects.values()]) {\n if (vec.distance(toWorld(o.st.position, o.st.rotation, o.bc), point) - o.br >= radius) continue\n const r = blastObject(o, point, energy, radius, src)\n if (r.part) out.push(r)\n }\n for (const im of [...impls.values()]) {\n const inRange = im.impl.describe().parts.some((ps) => {\n const ov = im.poses.get(ps.id)\n const c = toWorld(im.position, im.rotation, ov?.pos ?? ps.position)\n const q = quat.mul(im.rotation, ov?.q ?? quatFromEuler(...(ps.rotation ?? [0, 0, 0])))\n return distanceToShape(ps.shape, toLocal(c, q, point)) < radius\n })\n if (inRange) out.push(implHit(im, { type: 'explosive', point, energy, radius, ...(src !== undefined ? { source: src } : {}) }))\n }\n return out\n }\n\n const heatObject = (o: ObjRT, point: Vec3, T: number, radius: number, duration: number, src?: string): HitResult => {\n const start = cur.length\n const res: HitResult = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] }\n for (const p of o.parts) {\n if (isLost(p)) continue\n const dist = distToPart(o, p, point)\n if (dist >= radius) continue\n const f = clamp(1 - dist / radius, 0.25, 1)\n if (!res.part) {\n res.part = p.spec.id\n res.point = point\n }\n if (T > p.st.temperature) {\n const k = (0.8 * f) / (p.mat.thermal.heatCapacity ?? 1)\n p.st.temperature += (T - p.st.temperature) * (1 - Math.exp(-k * duration))\n }\n o.active = true\n checkIgnite(o, p, src)\n }\n res.events = cur.slice(start)\n return res\n }\n\n const doHit = (o: ObjRT, hit: Hit, only?: PartRT): HitResult => {\n let point = hit.point\n let dir = hit.direction\n if (hit.space === 'local') {\n point = toWorld(o.st.position, o.st.rotation, point)\n if (dir) dir = rotateVec(o.st.rotation, dir)\n }\n const src = hit.source\n const start = cur.length\n let res: HitResult = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] }\n const E = hit.energy ?? 0\n if (hit.type === 'ballistic') {\n const loc = locate(o, point, dir, 0.05, only)\n if (loc) {\n const out = ballistic(o, loc.p, loc.point, loc.normal, loc.dir, E, hit.caliber ?? 9, loc.pathLen, src)\n res = { ...res, part: loc.p.spec.id, point: loc.point, damage: out.damage, penetrated: out.penetrated, exitEnergy: out.exitEnergy }\n }\n } else if (hit.type === 'blunt' || hit.type === 'slash') {\n const radius = hit.radius ?? 0\n const loc = locate(o, point, dir, Math.max(0.05, radius), only)\n if (loc) {\n res.part = loc.p.spec.id\n res.point = loc.point\n res.damage += melee(o, loc.p, hit.type, E, loc.point, loc.normal, loc.dir, radius || 0.03, src)\n if (radius > 0.1 && !only) {\n for (const p of o.parts) {\n if (p === loc.p || isLost(p)) continue\n const dd = distToPart(o, p, point)\n if (dd >= radius) continue\n const { c, q } = partXf(o, p)\n const sp = surfacePoint(p.spec.shape, toLocal(c, q, point))\n res.damage += melee(o, p, hit.type, E * (1 - dd / radius) ** 2, toWorld(c, q, sp.point), rotateVec(q, sp.normal), loc.dir, radius, src)\n }\n }\n }\n } else if (hit.type === 'explosive') {\n res = blastObject(o, point, E, hit.radius ?? 2, src)\n } else {\n res = heatObject(o, point, hit.temperature ?? 800, hit.radius ?? 0.25, hit.duration ?? 1, src)\n }\n res.events = cur.slice(start)\n return res\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // Fire, heat, melting, leaks\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n const checkIgnite = (o: ObjRT, p: PartRT, src?: string) => {\n const th = p.mat.thermal\n if (isLost(p) || p.st.burning || th.ignitionC === undefined || p.st.fuel <= 0 || p.st.temperature < th.ignitionC) return\n p.st.burning = true\n p.st.temperature = Math.max(p.st.temperature, th.flameC ?? 800)\n o.active = true\n markDamaged(p)\n emit({ ...base(o, src), type: 'ignite', part: p.spec.id, point: partXf(o, p).c })\n }\n\n const syncMass = (p: PartRT) => {\n p.st.mass = Math.max(0, p.mass0 * (1 - p.st.melt) - (p.fuel0 - p.st.fuel))\n }\n\n const burnStep = (o: ObjRT, p: PartRT, dt: number) => {\n const th = p.mat.thermal\n const use = Math.min((th.burnRate ?? 0.01) * p.area * dt, p.st.fuel)\n p.st.fuel -= use\n syncMass(p)\n if (p.structural) o.dirty = true\n p.st.temperature = th.flameC ?? 800\n markDamaged(p)\n if (p.fuel0 > 0) {\n p.st.char = clamp(1 - p.st.fuel / p.fuel0, 0, 1)\n p.st.hp = Math.min(p.st.hp, Math.max(1, p.st.maxHp * (p.st.fuel / p.fuel0)))\n }\n if (p.st.fuel <= 1e-9) {\n p.st.fuel = 0\n p.st.burning = false\n p.st.char = 1\n const c = partXf(o, p).c\n if ((th.fuelFraction ?? 0) >= 0.8) {\n p.st.status = 'ashes'\n p.st.hp = 0\n p.st.mass = p.mass0 * (1 - (th.fuelFraction ?? 0))\n emit({ ...base(o), type: 'burnout', part: p.spec.id, point: c })\n debris(o, p, 'ash', c, [0, 1, 0], clamp(Math.round(Math.cbrt(partVolume(p.spec.shape)) * 30), 3, 20), 1)\n partLost(o, p)\n } else {\n emit({ ...base(o), type: 'burnout', part: p.spec.id, point: c })\n }\n }\n }\n\n const meltStep = (o: ObjRT, p: PartRT, dt: number) => {\n const th = p.mat.thermal\n if (th.meltC === undefined || p.st.temperature <= th.meltC) return\n const rate = (th.meltRate ?? 0.05) * ((p.st.temperature - th.meltC) / 100)\n p.st.melt = Math.min(1, p.st.melt + rate * dt)\n syncMass(p)\n if (p.structural) o.dirty = true\n markDamaged(p)\n p.rt.dripT += dt\n if (p.rt.dripT >= 0.25) {\n p.rt.dripT -= 0.25\n const b = partWorldAabb(o, p)\n const pt: Vec3 = [b.min[0] + (b.max[0] - b.min[0]) * (0.2 + 0.6 * rnd()), b.min[1], b.min[2] + (b.max[2] - b.min[2]) * (0.2 + 0.6 * rnd())]\n emit({ ...base(o), type: 'drip', part: p.spec.id, point: pt, material: p.mat.id })\n }\n if (p.st.melt - p.rt.meltEmitted >= 0.05 || p.st.melt >= 1) {\n p.rt.meltEmitted = p.st.melt\n emit({ ...base(o), type: 'melt', part: p.spec.id, melt: p.st.melt })\n }\n if (p.st.melt >= 1) {\n p.st.status = 'melted'\n p.st.hp = 0\n p.st.mass = 0\n p.st.burning = false\n p.rt.jet = false\n partLost(o, p)\n }\n }\n\n const stepObject = (o: ObjRT, dt: number, sources: Array<{ o: ObjRT; p: PartRT; flame: number }>) => {\n const parts = o.parts\n const T0 = o.tmp\n T0.length = parts.length\n for (let i = 0; i < parts.length; i++) T0[i] = parts[i].st.temperature\n let hot = false\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i]\n if (isLost(p)) continue\n const th = p.mat.thermal\n const hc = th.heatCapacity ?? 1\n const s = p.st\n if (p.rt.jet) {\n s.temperature = Math.max(s.temperature, 900)\n } else if (s.burning) {\n burnStep(o, p, dt)\n if (isLost(p)) continue\n }\n if (!s.burning && !p.rt.jet) {\n // conduction from hotter neighbours through closed joints, then cooling\n let dT = 0\n let maxN = s.temperature\n for (const j of o.byPart.get(p.spec.id)!) {\n if (j.st.open) continue\n const k = j.ia === i ? j.ib : j.ia\n if (isLost(parts[k]) || T0[k] <= T0[i]) continue\n const c = (th.conductivity + parts[k].mat.thermal.conductivity) / 2\n dT += (T0[k] - T0[i]) * (1 - Math.exp((-1.2 * c * dt) / hc))\n if (T0[k] > maxN) maxN = T0[k]\n }\n if (dT > 0) s.temperature = Math.min(s.temperature + dT, maxN)\n s.temperature += (ambient - s.temperature) * (1 - Math.exp(-dt / (20 * hc)))\n if (Math.abs(s.temperature - ambient) < 0.05) s.temperature = ambient\n }\n meltStep(o, p, dt)\n if (isLost(p)) continue\n checkIgnite(o, p)\n const ex = p.spec.explodes\n if (ex && chainDelayOf(p.spec, 'fire') !== undefined) {\n if (s.temperature >= (ex.atC ?? FIRE_PRIME_C)) prime(o, p, 'fire')\n } else if (ex && ex.atC !== undefined && s.temperature >= ex.atC) {\n failPart(o, p, null, null, 0, 40)\n continue\n }\n // leaks\n const cont = p.spec.contains\n if (cont && (s.liters ?? 0) > 0) {\n let rate = 0\n for (const h of s.holes) if (h.through) rate += holeRate(h, !!cont.pressurized)\n if (rate > 0) {\n s.liters = Math.max(0, (s.liters ?? 0) - rate * dt)\n hot = true\n if (FLAMMABLE_FLUIDS.includes(cont.fluid) && s.temperature >= 350 && !p.rt.jet) {\n if (ex && chainDelayOf(p.spec, 'fire') !== undefined) {\n prime(o, p, 'fire')\n continue\n }\n if (ex) {\n failPart(o, p, null, null, 0, 40)\n continue\n }\n p.rt.jet = true\n s.burning = true\n emit({ ...base(o), type: 'ignite', part: p.spec.id, point: partXf(o, p).c })\n }\n }\n }\n if (p.rt.jet && (s.liters ?? 0) <= 0) {\n p.rt.jet = false\n s.burning = false\n emit({ ...base(o), type: 'extinguish', part: p.spec.id })\n }\n // thermal shock\n const sc = th.thermalShockC\n if (sc !== undefined) {\n p.rt.shockT = Math.max(0, p.rt.shockT - dt)\n const rate = Math.abs(s.temperature - p.rt.prevTemp) / dt\n p.rt.prevTemp = s.temperature\n if (rate > sc && p.rt.shockT <= 0) {\n p.rt.shockT = 1\n const { c, q } = partXf(o, p)\n const lp: Vec3 = [(rnd() - 0.5) * p.dims[0], (rnd() - 0.5) * p.dims[1], (rnd() - 0.5) * p.dims[2]]\n const sp = surfacePoint(p.spec.shape, lp)\n addCrack(o, p, toWorld(c, q, sp.point), rotateVec(q, sp.normal), 0.1 + (rate / sc) * 0.1)\n applyDamage(o, p, p.st.maxHp * 0.25, 'heat', null, null, 5, 3)\n if (isLost(p)) continue\n }\n }\n if (s.burning || p.rt.jet) sources.push({ o, p, flame: p.rt.jet ? 900 : th.flameC ?? 800 })\n if (s.burning || p.rt.jet || s.temperature > ambient + 0.5) hot = true\n }\n if (o.hasStructure) {\n if (o.dirty) {\n o.dirty = false\n solveStructure(o)\n }\n for (const p of parts) {\n if (!p.structural || isLost(p)) continue\n const stress = p.st.stress ?? 0\n p.rt.stressT = Math.max(0, (p.rt.stressT ?? 0) - dt)\n if (stress > 1) {\n if (p.rt.stressT <= 0) {\n p.rt.stressT = 0.5\n emit({ ...base(o), type: 'stress', part: p.spec.id, stress, load: p.st.load ?? 0 })\n }\n applyDamage(o, p, overloadRate(stress) * p.st.maxHp * dt, 'blunt', null, null, 5, 3)\n } else if (stress > 0.8 && p.mat.ductility < 0.3 && p.rt.stressT <= 0 && p.st.cracks.length < 6) {\n p.rt.stressT = 0.5\n const { c, q } = partXf(o, p)\n const sp = surfacePoint(p.spec.shape, [(rnd() - 0.5) * p.dims[0], (rnd() - 0.5) * p.dims[1], (rnd() - 0.5) * p.dims[2]])\n addCrack(o, p, toWorld(c, q, sp.point), rotateVec(q, sp.normal), 0.1 + (stress - 0.8) * 0.5)\n }\n }\n if (o.maxStress > 0.8) hot = true\n }\n o.active = hot\n }\n\n const spread = (sources: Array<{ o: ObjRT; p: PartRT; flame: number }>, dt: number) => {\n for (const src of sources) {\n if (!src.p.st.burning && !src.p.rt.jet) continue\n const sc = toWorld(src.o.st.position, src.o.st.rotation, src.p.pos)\n const A = partWorldAabb(src.o, src.p)\n for (const o of objects.values()) {\n if (o === src.o) continue\n if (vec.distance(toWorld(o.st.position, o.st.rotation, o.bc), sc) > o.br + src.p.bound + fireSpread) continue\n for (const q of o.parts) {\n if (isLost(q) || q.st.burning) continue\n const B = partWorldAabb(o, q)\n const gap = Math.hypot(\n Math.max(0, A.min[0] - B.max[0], B.min[0] - A.max[0]),\n Math.max(0, A.min[1] - B.max[1], B.min[1] - A.max[1]),\n Math.max(0, A.min[2] - B.max[2], B.min[2] - A.max[2]),\n )\n if (gap >= fireSpread || src.flame <= q.st.temperature) continue\n const f = 1 - gap / fireSpread\n q.st.temperature += (src.flame - q.st.temperature) * (1 - Math.exp((-0.6 * f * dt) / (q.mat.thermal.heatCapacity ?? 1)))\n o.active = true\n }\n }\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------------------------------\n // World API\n // -------------------------------------------------------------------------------------------------------------------------------------------\n\n /** The primed part that goes off first: earliest due time, then the older object, then the part listed first. */\n const nextPrimed = (until: number): { o: ObjRT; p: PartRT } | null => {\n let best: { o: ObjRT; p: PartRT } | null = null\n for (const [p, o] of primed) {\n if (objects.get(o.id) !== o || isLost(p)) {\n primed.delete(p)\n continue\n }\n const due = p.rt.chainDue as number\n if (due > until) continue\n if (!best) best = { o, p }\n else {\n const bestDue = best.p.rt.chainDue as number\n if (due < bestDue || (due === bestDue && (o.order < best.o.order || (o.order === best.o.order && (o.idx.get(p.spec.id) ?? 0) < (best.o.idx.get(best.p.spec.id) ?? 0))))) best = { o, p }\n }\n }\n return best\n }\n\n /**\n * Explodes the primed parts whose delay ran out by `until`, one at a time in order of time; each blast is resolved before the next part goes off,\n * so a part it primes counts its delay from that moment, not from the end of the frame.\n */\n const detonatePrimed = (until: number) => {\n const end = time\n for (let next = nextPrimed(until); next; next = nextPrimed(until)) {\n primed.delete(next.p)\n time = Math.max(0, Math.min(end, next.p.rt.chainDue as number))\n next.p.rt.chainDue = undefined\n failPart(next.o, next.p, null, null, 0, 40)\n drainBlasts()\n }\n time = end\n }\n\n /** Collapse events are produced after the whole operation: make sure the result of the operation carries them. */\n const withCollapses = (r: { value: HitResult[]; events: DestructionEvent[] }): HitResult[] => {\n const last = r.value[r.value.length - 1]\n if (!last) return r.value\n for (const e of r.events) if (e.type === 'collapse' && !r.value.some((h) => h.events.includes(e))) last.events.push(e)\n return r.value\n }\n\n const whole = (fn: () => HitResult): HitResult => {\n const r = run(fn)\n r.value.events = r.events\n return r.value\n }\n\n const world: DestructionWorld = {\n materials,\n get time() {\n return time\n },\n add(spec, opts: AddOptions = {}) {\n const id = opts.id ?? nextId()\n if (taken(id)) throw new Error(`object \"${id}\" already exists`)\n objects.set(id, build(resolveSpec(spec), id, opts.position ?? [0, 0, 0], opts.rotation ?? [0, 0, 0, 1]))\n return id\n },\n register(impl, opts: AddOptions = {}) {\n const id = opts.id ?? impl.id\n if (taken(id)) throw new Error(`object \"${id}\" already exists`)\n impls.set(id, { impl, position: opts.position ?? [0, 0, 0], rotation: opts.rotation ?? [0, 0, 0, 1], poses: new Map() })\n return id\n },\n setPartPose(objectId, partId, position, rotation) {\n const q = quatFromEuler(...(rotation ?? [0, 0, 0]))\n const im = impls.get(objectId)\n if (im) {\n im.impl.setPartPose?.(partId, position, rotation)\n im.poses.set(partId, { pos: [position[0], position[1], position[2]], q })\n return\n }\n const o = getObj(objectId)\n const p = getPart(o, partId)\n p.pos = [position[0], position[1], position[2]]\n p.q = q\n updateBound(o)\n },\n remove(id) {\n objects.delete(id)\n impls.delete(id)\n },\n has: (id) => taken(id),\n ids: () => [...objects.keys(), ...impls.keys()],\n setTransform(id, position, rotation) {\n const im = impls.get(id)\n if (im) {\n im.position = [position[0], position[1], position[2]]\n im.rotation = [rotation[0], rotation[1], rotation[2], rotation[3]]\n return\n }\n const o = getObj(id)\n o.st.position = [position[0], position[1], position[2]]\n o.st.rotation = [rotation[0], rotation[1], rotation[2], rotation[3]]\n },\n splitGroup(id, group, newId) {\n if (impls.has(id)) throw new Error(`object \"${id}\" is a registered DestructibleImpl and cannot be split; its module owns its pieces`)\n const o = getObj(id)\n if (o.st.groups.length < 2) return id\n const names = o.st.groups[group]\n if (!names) throw new Error(`object \"${id}\" has no group ${group}`)\n const moved = new Set(names)\n const nid = newId ?? nextId()\n if (objects.has(nid)) throw new Error(`object \"${nid}\" already exists`)\n // an open joint between the two objects stays with the original\n const carryFor = (keep: (pid: string) => boolean, keepOpen: (a: string, b: string) => boolean = () => false): Carry => ({\n parts: new Map(o.parts.filter((p) => keep(p.spec.id)).map((p) => [p.spec.id, { st: p.st, rt: p.rt }])),\n joints: new Map([\n ...o.joints.filter((j) => (keep(j.spec.a) && keep(j.spec.b)) || (j.st.open && keepOpen(j.spec.a, j.spec.b))).map((j): [string, { st: JointState; step: number }] => [j.spec.id, { st: j.st, step: j.step }]),\n ...o.st.joints.filter((st) => st.open && !o.jointMap.has(st.id) && keepOpen(st.a, st.b)).map((st): [string, { st: JointState; step: number }] => [st.id, { st, step: 0 }]),\n ]),\n collapsed: [...o.collapsed].filter(keep),\n })\n const sub = (keep: (pid: string) => boolean): DestructibleSpec => {\n const s: DestructibleSpec = { parts: o.spec.parts.filter((p) => keep(p.id)), joints: (o.spec.joints ?? []).filter((j) => keep(j.a) && keep(j.b)) }\n if (o.spec.name !== undefined) s.name = o.spec.name\n if (o.spec.tags) s.tags = [...o.spec.tags]\n return clone(s)\n }\n const inNew = (pid: string) => moved.has(pid)\n const inOld = (pid: string) => !moved.has(pid)\n const pos = o.st.position, rot = o.st.rotation\n const fresh = build(sub(inNew), nid, pos, rot, carryFor(inNew, (a, b) => inNew(a) && inNew(b)))\n const rest = build(sub(inOld), id, pos, rot, carryFor(inOld, (a, b) => !(inNew(a) && inNew(b))))\n objects.set(id, rest)\n objects.set(nid, fresh)\n return nid\n },\n hit(objectId, h) {\n const im = impls.get(objectId)\n if (im) return whole(() => implHit(im, h))\n const o = getObj(objectId)\n return whole(() => doHit(o, h))\n },\n hitPart(objectId, partId, h) {\n const im = impls.get(objectId)\n if (im) return whole(() => implHit(im, h))\n const o = getObj(objectId)\n const p = getPart(o, partId)\n return whole(() => doHit(o, h, p))\n },\n explode(point, energy, radius, source) {\n return withCollapses(run(() => blastWorld(point, energy, radius, source)))\n },\n raycast(origin, direction, maxDistance = Infinity) {\n const r = raycastInternal(origin, direction, maxDistance)\n return r ? { object: r.object, part: r.part, point: r.point, normal: r.normal, distance: r.distance } : null\n },\n shoot(origin, direction, energy, caliber, source) {\n return withCollapses(run(() => {\n const results: HitResult[] = []\n const d = vec.normalize(direction)\n const ignore = new Set<string>()\n let org = origin\n let E = energy\n for (let i = 0; i < 4 && E > 0; i++) {\n const rh = raycastInternal(org, d, Infinity, ignore)\n if (!rh) break\n const im = impls.get(rh.object)\n if (im) {\n const r = implHit(im, { type: 'ballistic', point: rh.point, direction: d, energy: E, caliber, ...(source !== undefined ? { source } : {}) })\n r.part = rh.part\n r.point = rh.point\n r.exitEnergy = r.penetrated ? E * 0.5 : 0\n results.push(r)\n ignore.add(`${im.impl.id}\\0${rh.part}`)\n if (!r.penetrated) break\n org = vec.madd(rh.point, d, Math.min(rh.pathLen, 0.05) + 0.001)\n E = r.exitEnergy\n continue\n }\n const o = getObj(rh.object)\n const p = getPart(o, rh.part)\n const start = cur.length\n const out = ballistic(o, p, rh.point, rh.normal, d, E, caliber, rh.pathLen, source)\n results.push({ object: o.id, part: p.spec.id, point: rh.point, damage: out.damage, penetrated: out.penetrated, exitEnergy: out.exitEnergy, events: cur.slice(start) })\n ignore.add(`${o.id}\\0${p.spec.id}`)\n if (!out.penetrated || !out.exitPoint) break\n org = vec.madd(out.exitPoint, d, 0.001)\n E = out.exitEnergy\n }\n return results\n }))\n },\n disassemble(objectId, jointId, tool: ToolKind, dt) {\n const im = impls.get(objectId)\n if (im) return im.impl.disassemble ? im.impl.disassemble(jointId, tool, dt) : -1\n const o = getObj(objectId)\n const j = o.jointMap.get(jointId)\n if (!j || !j.spec.tools.includes(tool)) return -1\n if (j.st.open) return 1\n return run(() => {\n j.st.progress = Math.min(1, j.st.progress + (j.spec.seconds > 0 ? dt / j.spec.seconds : 1))\n if (j.st.progress >= 1 - 1e-9) j.st.progress = 1\n const step = Math.floor(j.st.progress * 10 + 1e-9)\n if (step > j.step || j.st.progress >= 1) {\n j.step = step\n emit({ ...base(o), type: 'disassemble_progress', joint: j.spec.id, tool, progress: j.st.progress })\n }\n if (j.st.progress >= 1) {\n j.st.open = true\n j.st.openedBy = 'tool'\n solveStructure(o)\n recomputeGroups(o)\n detachEvents(o, [j], 'tool')\n collapseCheck(o)\n }\n return j.st.progress\n }).value\n },\n workableJoints(objectId, tool) {\n const im = impls.get(objectId)\n if (im) {\n const spec = im.impl.describe()\n return im.impl.state().joints.filter((js) => {\n const j = (spec.joints ?? []).find((x) => (x.id ?? `${x.a}~${x.b}`) === js.id)\n return !js.open && !!j && (j.tools ?? JOINT_DEFAULTS[j.kind].tools).includes(tool)\n })\n }\n return getObj(objectId).joints.filter((j) => !j.st.open && j.spec.tools.includes(tool)).map((j) => j.st)\n },\n nearestJoint(objectId, point, maxDistance = 0.3, tool) {\n const im = impls.get(objectId)\n // Candidates: closed joints with their world position and whether `tool` can undo them.\n const cands: { st: JointState; d: number; ok: boolean }[] = []\n if (im) {\n const spec = im.impl.describe()\n for (const js of im.impl.state().joints) {\n if (js.open) continue\n const pos = implJointPos(im, js.a, js.b)\n const j = (spec.joints ?? []).find((x) => (x.id ?? `${x.a}~${x.b}`) === js.id)\n cands.push({ st: js, d: pos ? vec.distance(pos, point) : Infinity, ok: !!j && (j.tools ?? JOINT_DEFAULTS[j.kind].tools).includes(tool as ToolKind) })\n }\n } else {\n const o = getObj(objectId)\n for (const j of o.joints) {\n if (j.st.open) continue\n cands.push({ st: j.st, d: vec.distance(jointWorld(o, j), point), ok: tool ? j.spec.tools.includes(tool) : true })\n }\n }\n const pick = (only: boolean): JointState | null => {\n let best: JointState | null = null\n let bd = maxDistance\n for (const c of cands) {\n if (only && !c.ok) continue\n if (c.d <= bd) {\n bd = c.d\n best = c.st\n }\n }\n return best\n }\n return (tool ? pick(true) : null) ?? pick(false)\n },\n extinguish(objectId, partId, coolC = 200) {\n const im = impls.get(objectId)\n if (im) {\n run(() => im.impl.extinguish?.(partId))\n return\n }\n const o = getObj(objectId)\n run(() => {\n for (const p of partId ? [getPart(o, partId)] : o.parts) {\n if (isLost(p)) continue\n if (p.st.burning) {\n p.st.burning = false\n p.rt.jet = false\n emit({ ...base(o), type: 'extinguish', part: p.spec.id })\n }\n p.st.temperature = Math.max(ambient, p.st.temperature - coolC)\n }\n o.active = true\n })\n },\n setLiters(objectId, partId, liters) {\n if (impls.has(objectId)) return\n const p = getPart(getObj(objectId), partId)\n if (!p.spec.contains) return\n p.st.liters = clamp(liters, 0, p.spec.contains.liters)\n getObj(objectId).active = true\n },\n update(dt) {\n if (!(dt > 0)) return []\n return run(() => {\n time += dt\n const sources: Array<{ o: ObjRT; p: PartRT; flame: number }> = []\n for (const o of [...objects.values()]) if (o.active) stepObject(o, dt, sources)\n if (sources.length) spread(sources, dt)\n detonatePrimed(time)\n for (const im of [...impls.values()]) {\n if (!im.impl.update) continue\n for (const e of im.impl.update(dt) ?? []) emit(e.time === undefined ? { ...e, time } : e)\n }\n }).events\n },\n state: (id) => objects.get(id)?.st ?? impls.get(id)?.impl.state() ?? null,\n snapshot: (id) => {\n const st = objects.get(id)?.st ?? impls.get(id)?.impl.state()\n return st ? clone(st) : null\n },\n part: (id, partId) => objects.get(id)?.byId.get(partId)?.st ?? impls.get(id)?.impl.state().parts.find((p) => p.id === partId) ?? null,\n reset(id) {\n const im = impls.get(id)\n if (im) {\n im.impl.reset?.()\n return\n }\n const o = getObj(id)\n objects.set(id, build(o.spec, id, o.st.position, o.st.rotation))\n },\n on(type: DestructionEventType | '*', fn) {\n let set = listeners.get(type)\n if (!set) listeners.set(type, (set = new Set()))\n set.add(fn)\n return () => {\n set!.delete(fn)\n }\n },\n serialize(): DestructionSnapshot {\n return {\n version: 1,\n time,\n rng: rng.state(),\n counter,\n objects: [...objects.values()].map((o) => {\n const runtime: ObjectRuntime = { parts: {}, joints: {}, collapsed: [...o.collapsed] }\n for (const p of o.parts) runtime.parts[p.spec.id] = clone(p.rt)\n for (const j of o.joints) runtime.joints[j.spec.id] = j.step\n return { id: o.id, spec: clone(o.spec), state: clone(o.st), runtime }\n }),\n ...(impls.size\n ? { impls: [...impls.values()].map((im) => ({ id: im.impl.id, position: [...im.position] as Vec3, rotation: [...im.rotation] as Quat, data: im.impl.serialize?.() })) }\n : {}),\n }\n },\n load(snap) {\n if (snap.version !== 1) throw new Error(`unsupported snapshot version ${String(snap.version)}`)\n objects.clear()\n time = snap.time\n rng.set(snap.rng)\n counter = snap.counter ?? 0\n for (const e of snap.objects) {\n const state = clone(e.state)\n const carry: Carry = {\n parts: new Map(\n state.parts.map((st) => [st.id, { st, rt: e.runtime?.parts[st.id] ? clone(e.runtime.parts[st.id]) : { ...freshRuntime(), prevTemp: st.temperature } }]),\n ),\n joints: new Map(state.joints.map((st) => [st.id, { st, step: e.runtime?.joints[st.id] ?? 0 }])),\n collapsed: e.runtime?.collapsed,\n }\n objects.set(e.id, build(clone(e.spec), e.id, state.position, state.rotation, carry))\n }\n for (const e of snap.impls ?? []) {\n const im = impls.get(e.id)\n if (!im) continue\n im.position = [e.position[0], e.position[1], e.position[2]]\n im.rotation = [e.rotation[0], e.rotation[1], e.rotation[2], e.rotation[3]]\n if (e.data !== undefined) im.impl.load?.(e.data)\n }\n },\n }\n return world\n}\n","[\n {\n \"id\": \"brick_wall_plastered\",\n \"name\": \"Plastered brick wall\",\n \"core\": { \"material\": \"brick\", \"thickness\": 0.09 },\n \"layers\": [{ \"material\": \"plaster\", \"thickness\": 0.02, \"faces\": \"both\" }],\n \"units\": { \"size\": [0.23, 0.075, 0.11], \"bond\": \"running\", \"mortar\": \"plaster\" },\n \"breach\": { \"area\": 0.25 }\n },\n {\n \"id\": \"concrete_block_wall\",\n \"name\": \"Concrete block wall\",\n \"core\": { \"material\": \"concrete\", \"thickness\": 0.14 },\n \"fill\": 0.55,\n \"units\": { \"size\": [0.39, 0.19, 0.14], \"bond\": \"running\", \"mortar\": \"plaster\" },\n \"breach\": { \"area\": 0.25 }\n },\n {\n \"id\": \"reinforced_concrete\",\n \"name\": \"Reinforced concrete wall\",\n \"core\": { \"material\": \"concrete\", \"thickness\": 0.2 },\n \"reinforcement\": { \"material\": \"steel\", \"spacing\": 0.18, \"diameter\": 0.008, \"residualCapacity\": 0.15 },\n \"units\": { \"size\": [0.6, 0.42, 0.2], \"bond\": \"stack\", \"mortar\": \"concrete\" },\n \"breach\": { \"area\": 0.25 }\n },\n {\n \"id\": \"drywall\",\n \"name\": \"Drywall partition on steel studs\",\n \"core\": { \"material\": \"plaster\", \"thickness\": 0.0125 },\n \"layers\": [{ \"material\": \"plaster\", \"thickness\": 0.0125, \"faces\": \"+\" }],\n \"depth\": 0.095,\n \"breach\": { \"area\": 0.25 }\n },\n {\n \"id\": \"wood_frame_wall\",\n \"name\": \"Wood frame wall\",\n \"core\": { \"material\": \"plywood\", \"thickness\": 0.012 },\n \"layers\": [{ \"material\": \"plaster\", \"thickness\": 0.0125, \"faces\": \"-\" }],\n \"depth\": 0.1135,\n \"breach\": { \"area\": 0.25 }\n },\n {\n \"id\": \"log_wall\",\n \"name\": \"Log wall\",\n \"core\": { \"material\": \"wood_soft\", \"thickness\": 0.2 },\n \"fill\": 0.785,\n \"breach\": { \"area\": 0.25 }\n },\n {\n \"id\": \"sheet_metal_shack\",\n \"name\": \"Corrugated sheet metal wall\",\n \"core\": { \"material\": \"steel\", \"thickness\": 0.0006 },\n \"depth\": 0.02,\n \"breach\": { \"area\": 0.25 }\n },\n {\n \"id\": \"glass_pane\",\n \"name\": \"Glass pane\",\n \"core\": { \"material\": \"glass\", \"thickness\": 0.006 },\n \"breach\": { \"area\": 0.1 }\n }\n]\n","import assembliesJson from './data/assemblies.json'\nimport { MATERIALS } from './materials'\nimport type { MaterialDef, MaterialId, PartBreach, PartSpec, PartUnits, Reinforcement, SurfaceLayer, Vec3 } from './types'\n\n/**\n * A wall as a builder builds it: a core with coats, the masonry unit it is laid in, its rebar and when it breaches. Dimensions are metres (data in\n * `src/data/assemblies.json`); `assemblyPart` turns one into a `PartSpec`. Extend or override with `registerAssembly`.\n */\nexport interface AssemblyDef {\n id: string\n name: string\n /** `thickness` is the core's, in metres: what a bullet has to get through besides the coats. */\n core: { material: MaterialId; thickness: number }\n /** Coats, outermost first. */\n layers?: readonly SurfaceLayer[]\n /** Physical depth of the wall when it is not core plus coats (a drywall partition is mostly air between the boards). */\n depth?: number\n /** Solid fraction of the core (hollow blocks, round logs): scales its mass and the thickness a bullet crosses. Default 1. */\n fill?: number\n units?: PartUnits\n reinforcement?: Reinforcement\n breach?: PartBreach\n}\n\nexport interface AssemblyPartOptions {\n id: string\n /** Along the part's x axis. */\n width: number\n /** Along the part's y axis. */\n height: number\n position: Vec3\n rotation?: Vec3\n structure?: PartSpec['structure']\n /** Other `PartSpec` fields (tags, anchored, hp...). */\n extra?: Partial<PartSpec>\n /** Materials to read densities from (default the built-in `MATERIALS`). */\n materials?: ReadonlyMap<MaterialId, MaterialDef>\n}\n\n/** Built-in assemblies; `registerAssembly` adds to this list. */\nexport const ASSEMBLIES: AssemblyDef[] = assembliesJson as unknown as AssemblyDef[]\n\nexport const registerAssembly = (def: AssemblyDef): void => {\n const at = ASSEMBLIES.findIndex((a) => a.id === def.id)\n if (at >= 0) ASSEMBLIES[at] = def\n else ASSEMBLIES.push(def)\n}\n\nexport const getAssembly = (id: string): AssemblyDef | undefined => ASSEMBLIES.find((a) => a.id === id)\n\nconst faceCount = (layer: SurfaceLayer): number => (layer.faces === 'both' ? 2 : 1)\n\n/** Physical depth of the wall in metres. */\nexport const assemblyDepth = (def: AssemblyDef): number => def.depth ?? def.core.thickness + (def.layers ?? []).reduce((sum, l) => sum + l.thickness * faceCount(l), 0)\n\n/**\n * The wall as a box `[width, height, depth]` (thin along local z) with the assembly's layers, units, rebar and breach. Mass is the core (times `fill`)\n * plus the coats; `thickness` is the core's, so each coat adds its own `penetration x thickness` to what a bullet must cross.\n */\nexport const assemblyPart = (assemblyId: string, options: AssemblyPartOptions): PartSpec => {\n const def = getAssembly(assemblyId)\n if (!def) throw new Error(`unknown assembly \"${assemblyId}\"`)\n const densityOf = (id: MaterialId): number => {\n const m = options.materials?.get(id) ?? MATERIALS.find((x) => x.id === id)\n if (!m) throw new Error(`unknown material \"${id}\" in assembly \"${assemblyId}\"`)\n return m.density\n }\n const fill = def.fill ?? 1\n const area = options.width * options.height\n const coreMass = area * def.core.thickness * fill * densityOf(def.core.material)\n const layerMass = (def.layers ?? []).reduce((sum, l) => sum + area * l.thickness * faceCount(l) * densityOf(l.material), 0)\n return {\n id: options.id,\n material: def.core.material,\n shape: { kind: 'box', size: [options.width, options.height, assemblyDepth(def)] },\n position: options.position,\n ...(options.rotation ? { rotation: options.rotation } : {}),\n mass: coreMass + layerMass,\n thickness: def.core.thickness * fill,\n ...(def.layers ? { layers: def.layers.map((l) => ({ ...l })) } : {}),\n ...(def.units ? { units: { ...def.units, size: [...def.units.size] as Vec3 } } : {}),\n ...(def.reinforcement ? { reinforcement: { ...def.reinforcement } } : {}),\n ...(def.breach ? { breach: { ...def.breach } } : {}),\n ...(options.structure ? { structure: options.structure } : {}),\n ...options.extra,\n }\n}\n","import type { DestructibleSpec, JointSpec, MaterialId, PartSpec } from './types'\n\nexport interface FrameOptions {\n /** Total length along x between the outer column centres, metres (default 8). */\n spanX?: number\n /** Total length along z (default 8). */\n spanZ?: number\n /** Columns along x (at least 2, default 3). */\n columnsX?: number\n /** Columns along z (at least 2, default 3). */\n columnsZ?: number\n /** Height of one floor from slab top to the underside of the next slab, metres (default 3). */\n height?: number\n /** Number of floors (default 1). */\n floors?: number\n /** Brick walls on every perimeter bay of every floor; the first bay of the ground floor on the -z side gets a door opening (default false). */\n walls?: boolean\n /** A thin roof slab resting on the top beams (default true); without it the top floor is open. */\n roof?: boolean\n columnSize?: number\n beamHeight?: number\n slabThickness?: number\n wallThickness?: number\n doorWidth?: number\n doorHeight?: number\n /** Material of foundations, columns, beams, slabs and roof (default `concrete`). */\n material?: MaterialId\n wallMaterial?: MaterialId\n /** Override the load capacity of every column, kg (see `PartState.load`). */\n columnCapacity?: number\n}\n\n/**\n * A parametric test structure: a grid of columns on foundations, beams between the column tops, one slab per floor (the last one a roof), and\n * optional brick walls with a door. Joints are explicit and directional: columns rest on foundations (or on the slab below) with `rebar`, beams on\n * columns, slabs on beams, the roof rests on the top beams, walls hang on their columns with `mortar`. Part ids: `foundation_i_j`, `column_f_i_j`,\n * `beam_x_f_i_j`, `beam_z_f_i_j`, `slab_f`, `roof`, `wall_*`, `door`. Ground is y = 0 (the top of the foundations).\n */\nexport const buildFrame = (o: FrameOptions = {}): DestructibleSpec => {\n const spanX = o.spanX ?? 8, spanZ = o.spanZ ?? 8\n const nx = Math.max(2, o.columnsX ?? 3), nz = Math.max(2, o.columnsZ ?? 3)\n const H = o.height ?? 3, floors = Math.max(1, o.floors ?? 1)\n const cs = o.columnSize ?? 0.3, bh = o.beamHeight ?? 0.3, bw = 0.2, T = o.slabThickness ?? 0.2, wt = o.wallThickness ?? 0.2\n const dw = o.doorWidth ?? 1, dh = o.doorHeight ?? 2.1\n const mat = o.material ?? 'concrete', wmat = o.wallMaterial ?? 'brick'\n const roof = o.roof ?? true\n const xs = Array.from({ length: nx }, (_, i) => -spanX / 2 + (i * spanX) / (nx - 1))\n const zs = Array.from({ length: nz }, (_, j) => -spanZ / 2 + (j * spanZ) / (nz - 1))\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n const on = (a: string, b: string, kind: JointSpec['kind']) => joints.push({ id: `${a}~${b}`, a, b, kind, bears: 'a_on_b' })\n\n for (let i = 0; i < nx; i++) {\n for (let j = 0; j < nz; j++) {\n parts.push({\n id: `foundation_${i}_${j}`, material: mat, shape: { kind: 'box', size: [cs * 2.2, 0.3, cs * 2.2] }, position: [xs[i], -0.15, zs[j]],\n structure: { role: 'foundation' }, anchored: true,\n })\n }\n }\n for (let f = 0; f < floors; f++) {\n const yb = f * (H + T)\n const top = yb + H\n const last = f === floors - 1\n const slabId = last && roof ? 'roof' : `slab_${f}`\n for (let i = 0; i < nx; i++) {\n for (let j = 0; j < nz; j++) {\n const id = `column_${f}_${i}_${j}`\n parts.push({\n id, material: mat, shape: { kind: 'box', size: [cs, H, cs] }, position: [xs[i], yb + H / 2, zs[j]],\n structure: o.columnCapacity === undefined ? { role: 'column' } : { role: 'column', capacity: o.columnCapacity },\n })\n on(id, f === 0 ? `foundation_${i}_${j}` : `slab_${f - 1}`, 'rebar')\n }\n }\n const beams: string[] = []\n const beam = (id: string, size: [number, number, number], pos: [number, number, number], c1: string, c2: string) => {\n parts.push({ id, material: mat, shape: { kind: 'box', size }, position: pos, structure: { role: 'beam' } })\n on(id, c1, 'rebar')\n on(id, c2, 'rebar')\n beams.push(id)\n }\n for (let j = 0; j < nz; j++) {\n for (let i = 0; i < nx - 1; i++) {\n beam(`beam_x_${f}_${i}_${j}`, [xs[i + 1] - xs[i] - cs, bh, bw], [(xs[i] + xs[i + 1]) / 2, top - bh / 2, zs[j]], `column_${f}_${i}_${j}`, `column_${f}_${i + 1}_${j}`)\n }\n }\n for (let i = 0; i < nx; i++) {\n for (let j = 0; j < nz - 1; j++) {\n beam(`beam_z_${f}_${i}_${j}`, [bw, bh, zs[j + 1] - zs[j] - cs], [xs[i], top - bh / 2, (zs[j] + zs[j + 1]) / 2], `column_${f}_${i}_${j}`, `column_${f}_${i}_${j + 1}`)\n }\n }\n const thick = last && roof ? T * 0.75 : T\n parts.push({\n id: slabId, material: mat, shape: { kind: 'box', size: [spanX + cs + 0.2, thick, spanZ + cs + 0.2] }, position: [0, top + thick / 2, 0],\n structure: { role: last && roof ? 'roof' : 'slab' },\n })\n for (const b of beams) on(slabId, b, last && roof ? 'resting' : 'rebar')\n\n if (o.walls) {\n const wh = H - bh\n const wy = yb + wh / 2\n const wall = (id: string, size: [number, number, number], pos: [number, number, number], supports: string[]) => {\n parts.push({ id, material: wmat, shape: { kind: 'box', size }, position: pos, structure: { role: 'wall' } })\n for (const s of supports) on(id, s, 'mortar')\n }\n for (const j of [0, nz - 1]) {\n for (let i = 0; i < nx - 1; i++) {\n const c1 = `column_${f}_${i}_${j}`, c2 = `column_${f}_${i + 1}_${j}`\n const avail = xs[i + 1] - xs[i] - cs\n if (f === 0 && j === 0 && i === 0 && avail > dw + 0.4) {\n const side = (avail - dw) / 2\n const lx = xs[i] + cs / 2 + side / 2, rx = xs[i + 1] - cs / 2 - side / 2\n wall(`wall_door_left`, [side, wh, wt], [lx, wy, zs[j]], [c1])\n wall(`wall_door_right`, [side, wh, wt], [rx, wy, zs[j]], [c2])\n const lh = wh - dh\n wall(`wall_door_lintel`, [dw, lh, wt], [xs[i] + cs / 2 + side + dw / 2, yb + dh + lh / 2, zs[j]], ['wall_door_left', 'wall_door_right'])\n parts.push({ id: 'door', material: 'wood_hard', shape: { kind: 'box', size: [dw - 0.04, dh, 0.05] }, position: [xs[i] + cs / 2 + side + dw / 2, yb + dh / 2, zs[j]], tags: ['door'] })\n joints.push({ id: 'door~wall_door_left', a: 'door', b: 'wall_door_left', kind: 'hinge', bears: false })\n } else wall(`wall_x_${f}_${i}_${j}`, [avail, wh, wt], [(xs[i] + xs[i + 1]) / 2, wy, zs[j]], [c1, c2])\n }\n }\n for (const i of [0, nx - 1]) {\n for (let j = 0; j < nz - 1; j++) {\n wall(`wall_z_${f}_${i}_${j}`, [wt, wh, zs[j + 1] - zs[j] - cs], [xs[i], wy, (zs[j] + zs[j + 1]) / 2], [`column_${f}_${i}_${j}`, `column_${f}_${i}_${j + 1}`])\n }\n }\n }\n }\n return { name: 'frame', parts, joints, tags: ['structure'] }\n}\n","import { createDestruction } from './world'\nimport type { DestructibleSpec, SizeStructureOptions, StructureRole } from './types'\n\n/**\n * Sizes the load capacity of a structure the way an engineer would, from the loads the world itself computes. The intact spec goes through the\n * same load solver `createDestruction` uses, and each structural part (`structure.role` other than `none`) gets `structure.capacity = load / safety`,\n * so its at-rest stress is exactly `safety` (`safetyByRole` overrides it per role). With `redundancy` set, every part whose role is in\n * `redundancyRoles` (default `column`) is also removed in turn and the capacity of the parts that would carry more is raised so they stay at or below\n * `redundancy`. Parts without `structure`, with role `none`, or with no support path to an\n * anchored part are left as they are. The spec is not modified; a copy is returned.\n */\nexport const sizeStructure = (spec: DestructibleSpec, options: SizeStructureOptions = {}): DestructibleSpec => {\n const safety = options.safety ?? 0.65\n const redundancy = options.redundancy\n const redundancyRoles: readonly StructureRole[] = options.redundancyRoles ?? ['column']\n const safetyOf = (role: StructureRole): number => options.safetyByRole?.[role] ?? safety\n const loads = (s: DestructibleSpec): Map<string, { load: number; stress: number }> => {\n const w = createDestruction(options.materials ? { materials: options.materials } : {})\n const id = w.add(s)\n return new Map(w.state(id)!.parts.map((p) => [p.id, { load: p.load ?? 0, stress: p.stress ?? 0 }]))\n }\n const out = structuredClone(spec)\n const base = loads(out)\n const need = new Map<string, number>()\n for (const p of out.parts) {\n if (!p.structure || p.structure.role === 'none') continue\n const b = base.get(p.id)\n if (!b || b.stress <= 0) continue\n need.set(p.id, b.load / safetyOf(p.structure.role))\n }\n if (redundancy !== undefined) {\n for (const col of out.parts) {\n if (!col.structure || !redundancyRoles.includes(col.structure.role)) continue\n const reduced: DestructibleSpec = {\n ...out,\n parts: out.parts.filter((p) => p.id !== col.id),\n joints: (out.joints ?? []).filter((j) => j.a !== col.id && j.b !== col.id),\n }\n // joints are inferred when the spec has none; removing a part then removes its joints with it\n if (!out.joints) delete reduced.joints\n const l = loads(reduced)\n for (const [id, n] of need) {\n const r = l.get(id)\n if (r && r.stress > 0) need.set(id, Math.max(n, r.load / redundancy))\n }\n }\n }\n for (const p of out.parts) {\n const n = need.get(p.id)\n if (n !== undefined) p.structure = { ...p.structure!, capacity: n }\n }\n return out\n}\n","import type { DamageType, DestructionEventType, FractureStyle, JointKind, PartStatus, StructureRole, ToolKind } from './types'\n\n/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type DestructionLocale = 'en' | 'pt-BR'\n\nexport interface DestructionStrings {\n /** Display name per material id (see `MATERIALS`). Unknown ids are not listed. */\n materialNames: Record<string, string>\n partStatus: Record<PartStatus, string>\n jointKinds: Record<JointKind, string>\n toolKinds: Record<ToolKind, string>\n damageTypes: Record<DamageType, string>\n /** Short label per event type, for logs and kill-feed style text. */\n eventLabels: Record<DestructionEventType, string>\n fractureStyles: Record<FractureStyle, string>\n structureRoles: Record<StructureRole, string>\n}\n\nexport const locales: Record<DestructionLocale, DestructionStrings> = {\n en: {\n materialNames: {\n steel: 'steel', cast_iron: 'cast iron', aluminium: 'aluminium', copper: 'copper', wood_soft: 'softwood', wood_hard: 'hardwood', plywood: 'plywood',\n mdf: 'MDF', glass: 'glass', tempered_glass: 'tempered glass', ceramic: 'ceramic', concrete: 'concrete', brick: 'brick', plaster: 'plaster',\n stone: 'stone', plastic: 'plastic', rubber: 'rubber', fabric: 'fabric', foam: 'foam', leather: 'leather', paper: 'paper', foliage: 'foliage',\n green_wood: 'green wood', cactus: 'cactus', flesh_fruit: 'fruit', wax: 'wax', soil: 'soil',\n },\n partStatus: { intact: 'intact', damaged: 'damaged', collapsed: 'collapsed', broken: 'broken', melted: 'melted', ashes: 'ashes' },\n jointKinds: {\n screw: 'screw', bolt: 'nut and bolt', nail: 'nail', weld: 'weld', glue: 'glue', hinge: 'hinge', clip: 'clip', tie: 'tie', mortar: 'mortar',\n fused: 'fused', stem: 'stem', rebar: 'rebar', resting: 'resting',\n },\n toolKinds: {\n hand: 'hand', screwdriver: 'screwdriver', wrench: 'wrench', pry_bar: 'pry bar', saw: 'saw', cutting_torch: 'cutting torch', knife: 'knife', hammer: 'hammer',\n },\n damageTypes: { ballistic: 'ballistic', blunt: 'blunt', slash: 'slash', explosive: 'explosive', fire: 'fire', heat: 'heat' },\n eventLabels: {\n damage: 'damage', dent: 'dent', hole: 'hole', crack: 'crack', ricochet: 'ricochet', debris: 'debris', fracture: 'broke', detach: 'came loose',\n disassemble_progress: 'taking apart', ignite: 'caught fire', extinguish: 'put out', burnout: 'burned to ash', melt: 'melting', drip: 'dripping',\n leak: 'leak', explode: 'exploded', primed: 'about to explode', stress: 'overload', collapse: 'collapsed', spall: 'plaster came off', stage: 'damage stage', expose: 'rebar bare', body: 'body', destroyed: 'destroyed',\n },\n fractureStyles: { shatter: 'shatter', crumble: 'crumble', splinter: 'splinter', tear: 'tear', snap: 'snap', none: 'none' },\n structureRoles: { foundation: 'foundation', column: 'column', beam: 'beam', slab: 'slab', wall: 'wall', partition: 'partition', roof: 'roof', stair: 'stairs', none: 'none' },\n },\n 'pt-BR': {\n materialNames: {\n steel: 'aço', cast_iron: 'ferro fundido', aluminium: 'alumínio', copper: 'cobre', wood_soft: 'madeira macia', wood_hard: 'madeira de lei',\n plywood: 'compensado', mdf: 'MDF', glass: 'vidro', tempered_glass: 'vidro temperado', ceramic: 'cerâmica', concrete: 'concreto', brick: 'tijolo',\n plaster: 'gesso', stone: 'pedra', plastic: 'plástico', rubber: 'borracha', fabric: 'tecido', foam: 'espuma', leather: 'couro', paper: 'papel',\n foliage: 'folhagem', green_wood: 'madeira verde', cactus: 'cacto', flesh_fruit: 'fruta', wax: 'cera', soil: 'terra',\n },\n partStatus: { intact: 'intacto', damaged: 'danificado', collapsed: 'desabado', broken: 'quebrado', melted: 'derretido', ashes: 'cinzas' },\n jointKinds: {\n screw: 'parafuso', bolt: 'porca e parafuso', nail: 'prego', weld: 'solda', glue: 'cola', hinge: 'dobradiça', clip: 'encaixe', tie: 'amarração',\n mortar: 'argamassa', fused: 'fundido', stem: 'caule', rebar: 'vergalhão', resting: 'apoiado',\n },\n toolKinds: {\n hand: 'mão', screwdriver: 'chave de fenda', wrench: 'chave inglesa', pry_bar: 'pé de cabra', saw: 'serra', cutting_torch: 'maçarico', knife: 'faca', hammer: 'martelo',\n },\n damageTypes: { ballistic: 'tiro', blunt: 'impacto', slash: 'corte', explosive: 'explosão', fire: 'fogo', heat: 'calor' },\n eventLabels: {\n damage: 'dano', dent: 'amassado', hole: 'furo', crack: 'trinca', ricochet: 'ricochete', debris: 'estilhaços', fracture: 'quebrou', detach: 'soltou',\n disassemble_progress: 'desmontando', ignite: 'pegou fogo', extinguish: 'apagou', burnout: 'virou cinza', melt: 'derretendo', drip: 'pingando',\n leak: 'vazamento', explode: 'explodiu', primed: 'prestes a explodir', stress: 'sobrecarga', collapse: 'desabou', spall: 'reboco soltou', stage: 'estágio de dano', expose: 'vergalhão à mostra', body: 'corpo', destroyed: 'destruído',\n },\n fractureStyles: { shatter: 'estilhaçar', crumble: 'esfarelar', splinter: 'lascar', tear: 'rasgar', snap: 'partir', none: 'nenhuma' },\n structureRoles: { foundation: 'fundação', column: 'pilar', beam: 'viga', slab: 'laje', wall: 'parede', partition: 'divisória', roof: 'telhado', stair: 'escada', none: 'nenhum' },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined): DestructionStrings => locales[(locale as DestructionLocale) ?? 'en'] ?? locales.en\n","import type { DamageType, DestructibleSpec, DestructionEvent, Hit, JointSpec, ObjectState, ToolKind, Vec3 } from './destruction'\n\n/**\n * What a game module implements for an object whose behaviour it owns (a vehicle with its own panel deformation, a creature, a machine). The\n * world (`DestructionWorld.register`) hosts it next to its own objects: raycast, shoot, explode, hit, disassemble, extinguish, update, state,\n * reset and `on` all route to it.\n *\n * Space: the impl receives hits in WORLD space and returns events in WORLD space (it owns its transform; the transform given to `register` or\n * `setTransform` is only used by the world for raycasts and blast range). Every event must carry `object === id` and name parts listed by\n * `describe()`.\n */\nexport interface DestructibleImpl {\n readonly id: string\n readonly name?: string\n /** Parts, joints and structure in the impl's local space, for raycast, inspector and log. Called often: keep it cheap. */\n describe(): DestructibleSpec\n /** Apply one hit (see `IMPACT_CONTRACT` for the fields per type) and return the events it caused. */\n hit(hit: Hit): DestructionEvent[]\n /** Advance fire, melting, collapse and other timed behaviour. */\n update?(dt: number): DestructionEvent[]\n state(): ObjectState\n reset?(): void\n /** Same contract as `DestructionWorld.disassemble`: progress 0..1, or -1 when the tool cannot undo the joint. */\n disassemble?(jointId: string, tool: ToolKind, dt: number): number\n extinguish?(partId?: string): void\n /** Optional: an animation moved a part; `position` / `rotation` (Euler XYZ, radians) are object-local. Keep raycast and hit shapes in sync. */\n setPartPose?(partId: string, position: Vec3, rotation?: Vec3): void\n /** Plain JSON of the impl's own state, stored in `DestructionSnapshot.impls`. */\n serialize?(): unknown\n load?(data: unknown): void\n}\n\n/** The fields a weapon or hazard must put in a `Hit`, per damage type. THE impact contract. */\nexport interface ImpactContract {\n required: string[]\n optional: string[]\n note: string\n}\n\nexport const IMPACT_CONTRACT: Record<DamageType, ImpactContract> = {\n ballistic: { required: ['type', 'point', 'direction', 'energy', 'caliber'], optional: ['space', 'source'], note: 'bullets and pellets: joules and diameter in millimetres' },\n blunt: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'contact radius in metres (default 3 cm)' },\n slash: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'axes, knives, machetes' },\n explosive: { required: ['type', 'point', 'energy', 'radius'], optional: ['space', 'source'], note: 'point is the centre of the blast, radius the range in metres' },\n fire: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'flame temperature in °C; duration in seconds (call every frame with `dt`)' },\n heat: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'heat without flame (cutting torch, hot plate)' },\n}\n\n/** Problems with a hit according to the impact contract (empty when it is valid). */\nexport const checkHit = (hit: Hit): string[] => {\n const c = IMPACT_CONTRACT[hit.type]\n if (!c) return [`unknown damage type \"${String(hit.type)}\"`]\n const out: string[] = []\n for (const f of c.required) {\n const v = (hit as unknown as Record<string, unknown>)[f]\n if (v === undefined || (Array.isArray(v) ? v.some((n) => !Number.isFinite(n)) : typeof v === 'number' && !Number.isFinite(v))) out.push(`${hit.type} hit needs \"${f}\"`)\n }\n return out\n}\n\nexport interface CheckOptions {\n /**\n * Ids of every material the impl may use (the contracts package does not know the materials of your world: pass the ids of\n * `world.materials`, or the built-in plus your own). When omitted, the material check is skipped.\n */\n materials?: Iterable<string>\n}\n\nconst finiteJson = (v: unknown, path: string, out: string[]) => {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) out.push(`${path} is not a finite number`)\n } else if (Array.isArray(v)) v.forEach((x, i) => finiteJson(x, `${path}[${i}]`, out))\n else if (v && typeof v === 'object') for (const [k, x] of Object.entries(v)) finiteJson(x, `${path}.${k}`, out)\n else if (typeof v === 'function' || typeof v === 'symbol' || typeof v === 'bigint') out.push(`${path} is not JSON`)\n}\n\n/**\n * Contract checker for the test room (it needs no world): `describe()` is valid, a 500 J ballistic hit at a part centre returns well-formed events of this impl, `state()`\n * matches `describe()`, hit points never go negative, `update(0.016)` returns an array and every event is JSON-serializable. It hits the impl\n * (and calls `reset()` afterwards when there is one).\n */\nexport const checkDestructible = (impl: DestructibleImpl, options: CheckOptions = {}): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const known = options.materials ? new Set(options.materials) : null\n let spec: DestructibleSpec | undefined\n try {\n spec = impl.describe()\n } catch (e) {\n return { ok: false, problems: [`describe() threw: ${String(e)}`] }\n }\n if (!spec || !Array.isArray(spec.parts) || spec.parts.length === 0) return { ok: false, problems: ['describe() must return at least one part'] }\n const ids = new Set<string>()\n for (const p of spec.parts) {\n if (ids.has(p.id)) problems.push(`duplicate part id \"${p.id}\"`)\n ids.add(p.id)\n if (known && !known.has(p.material)) problems.push(`part \"${p.id}\" has unknown material \"${p.material}\"`)\n if (!p.shape || !['box', 'cylinder', 'sphere'].includes(p.shape.kind)) problems.push(`part \"${p.id}\" has no valid shape`)\n if (!Array.isArray(p.position) || p.position.length !== 3) problems.push(`part \"${p.id}\" has no position`)\n }\n const jointIds = new Set<string>()\n for (const j of (spec.joints ?? []) as JointSpec[]) {\n if (!ids.has(j.a) || !ids.has(j.b)) problems.push(`joint \"${j.id ?? `${j.a}~${j.b}`}\" references an unknown part`)\n const jid = j.id ?? `${j.a}~${j.b}`\n if (jointIds.has(jid)) problems.push(`duplicate joint id \"${jid}\"`)\n jointIds.add(jid)\n }\n const checkState = (label: string) => {\n let st: ObjectState\n try {\n st = impl.state()\n } catch (e) {\n problems.push(`state() threw ${label}: ${String(e)}`)\n return\n }\n const sids = st.parts.map((p) => p.id).sort().join(',')\n if (sids !== [...ids].sort().join(',')) problems.push(`state() part ids do not match describe() ${label}`)\n for (const p of st.parts) if (!(p.hp >= 0)) problems.push(`part \"${p.id}\" has negative or invalid hp ${label}`)\n }\n const checkEvents = (events: unknown, label: string) => {\n if (!Array.isArray(events)) {\n problems.push(`${label} must return an array`)\n return\n }\n const evs = events as DestructionEvent[]\n evs.forEach((e, i) => {\n if (e.object !== impl.id) problems.push(`${label} event ${i} (${e.type}) has object \"${String(e.object)}\", expected \"${impl.id}\"`)\n const part = (e as { part?: string }).part\n if (part !== undefined && !ids.has(part)) problems.push(`${label} event ${i} (${e.type}) names unknown part \"${part}\"`)\n })\n const bad: string[] = []\n finiteJson(evs, 'events', bad)\n problems.push(...bad.map((b) => `${label}: ${b}`))\n try {\n const s = JSON.stringify(evs)\n if (JSON.stringify(JSON.parse(s)) !== s) problems.push(`${label} events do not survive a JSON round trip`)\n } catch (e) {\n problems.push(`${label} events are not JSON-serializable: ${String(e)}`)\n }\n }\n checkState('before the hit')\n const target = spec.parts[0]\n try {\n const hit: Hit = { type: 'ballistic', point: [target.position[0], target.position[1], target.position[2]], direction: [0, 0, -1], energy: 500, caliber: 9 }\n checkEvents(impl.hit(hit), 'hit()')\n } catch (e) {\n problems.push(`hit() threw: ${String(e)}`)\n }\n checkState('after the hit')\n if (impl.update) {\n try {\n checkEvents(impl.update(0.016), 'update()')\n } catch (e) {\n problems.push(`update() threw: ${String(e)}`)\n }\n checkState('after update')\n }\n try {\n impl.reset?.()\n } catch (e) {\n problems.push(`reset() threw: ${String(e)}`)\n }\n return { ok: problems.length === 0, problems }\n}\n","/** The slots of a body an item can cover (the item slot vocabulary: game-items imports it from here). */\nexport type BodySlot = 'head' | 'eyes' | 'torso' | 'arms' | 'hands' | 'legs' | 'feet' | 'over'\n\n/** The 11 segments of the detailed body model (the Arsenal ids). */\nexport type SegmentKind = 'head' | 'jaw' | 'neck' | 'torso' | 'pelvis' | 'upperArm' | 'forearm' | 'hand' | 'thigh' | 'shin' | 'foot'\n\n/** The 6 regions of the crowd model (the game regions 0..5). */\nexport type BodyRegion = 'head' | 'torso' | 'armL' | 'armR' | 'legL' | 'legR'\n\n/** Bits of the `missing` mask of a body. The instanced body shader reads them, so the values are part of the contract. */\nexport const MISSING_BITS = {\n head: 1,\n armL: 2,\n armR: 4,\n legL: 8,\n legR: 16,\n armLBroken: 32,\n armRBroken: 64,\n legLBroken: 128,\n legRBroken: 256,\n jaw: 512,\n} as const\n","import type { DestructibleSpec, PartSpec } from './destruction'\n\nexport interface CheckSpecOptions {\n /** Known material ids. When given, every part's material must be one of them. */\n materials?: Iterable<string>\n}\n\nexport interface SpecReport {\n /** False when there is at least one problem (warnings do not count). */\n ok: boolean\n problems: string[]\n /** Things that are legal but probably wrong, e.g. structural parts that cannot reach an anchored part. */\n warnings: string[]\n}\n\nconst STRUCTURE_ROLES = ['foundation', 'column', 'beam', 'slab', 'wall', 'partition', 'roof', 'stair', 'none']\nconst BEARS = [true, false, 'a_on_b', 'b_on_a']\n\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\nconst positive = (n: unknown): boolean => finite(n) && n > 0\nconst vec3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every(finite)\nconst nonNegative = (n: unknown): boolean => n === undefined || (finite(n) && n >= 0)\n\nconst FACES = ['both', '+', '-']\nconst BONDS = ['running', 'stack']\n\n/** Layers, reinforcement, units and breach: known materials, finite positive sizes. */\nconst checkStagedFields = (p: PartSpec | undefined, label: string, materials: Set<string> | null, problems: string[]): void => {\n const known = (m: unknown, what: string): void => {\n if (materials && !materials.has(m as string)) problems.push(`${label} ${what} has unknown material \"${String(m)}\"`)\n }\n ;(p?.layers ?? []).forEach((l, i) => {\n known(l?.material, `layer ${i}`)\n if (!positive(l?.thickness)) problems.push(`${label} layer ${i} thickness must be finite and positive`)\n if (!FACES.includes(l?.faces)) problems.push(`${label} layer ${i} has an invalid faces \"${String(l?.faces)}\"`)\n })\n const r = p?.reinforcement\n if (r) {\n known(r.material, 'reinforcement')\n if (!positive(r.spacing) || !positive(r.diameter)) problems.push(`${label} reinforcement spacing and diameter must be finite and positive`)\n if (r.residualCapacity !== undefined && !(finite(r.residualCapacity) && r.residualCapacity >= 0 && r.residualCapacity <= 1)) problems.push(`${label} reinforcement residualCapacity must be between 0 and 1`)\n }\n const u = p?.units\n if (u) {\n known(u.mortar, 'units mortar')\n if (!vec3(u.size) || !u.size.every(positive)) problems.push(`${label} units size must be three finite positive numbers`)\n if (!BONDS.includes(u.bond)) problems.push(`${label} units has an invalid bond \"${String(u.bond)}\"`)\n }\n if (p?.breach && p.breach.area !== undefined && !positive(p.breach.area)) problems.push(`${label} breach area must be finite and positive`)\n}\n\n/**\n * Static checks on a `DestructibleSpec` (no world needed), for items that give a `spec` instead of an `impl`: unique part ids, known materials\n * (when `options.materials` is given), joints that reference existing, different parts, finite positive sizes, non-negative mass / hp / capacity,\n * valid structure roles and `bears` directions. A structural part with no path of joints to an anchored part is a warning, not a problem: it\n * is allowed, it just falls.\n */\nexport const checkSpec = (spec: DestructibleSpec, options: CheckSpecOptions = {}): SpecReport => {\n const problems: string[] = []\n const warnings: string[] = []\n const materials = options.materials ? new Set(options.materials) : null\n const parts = Array.isArray(spec?.parts) ? spec.parts : []\n if (!Array.isArray(spec?.parts) || parts.length === 0) problems.push('the spec needs at least one part')\n const ids = new Set<string>()\n for (const p of parts) {\n const id = String(p?.id ?? '')\n const label = `part \"${id}\"`\n if (id === '') problems.push('a part has no id')\n else if (ids.has(id)) problems.push(`duplicate part id \"${id}\"`)\n ids.add(id)\n if (materials && !materials.has(p?.material)) problems.push(`${label} has unknown material \"${String(p?.material)}\"`)\n else if (typeof p?.material !== 'string' || p.material === '') problems.push(`${label} needs a material`)\n const s = p?.shape\n if (s?.kind === 'box') {\n if (!Array.isArray(s.size) || s.size.length !== 3 || !s.size.every(positive)) problems.push(`${label} box size must be three finite positive numbers`)\n } else if (s?.kind === 'cylinder') {\n if (!positive(s.radius) || !positive(s.height)) problems.push(`${label} cylinder radius and height must be finite and positive`)\n } else if (s?.kind === 'sphere') {\n if (!positive(s.radius)) problems.push(`${label} sphere radius must be finite and positive`)\n } else problems.push(`${label} has an unknown shape`)\n if (!vec3(p?.position)) problems.push(`${label} needs a finite position [x, y, z]`)\n if (p?.rotation !== undefined && !vec3(p.rotation)) problems.push(`${label} has an invalid rotation`)\n for (const f of ['mass', 'hp', 'thickness'] as const) if (!nonNegative(p?.[f])) problems.push(`${label} ${f} must be a finite number >= 0`)\n if (p?.fill !== undefined && !(finite(p.fill) && p.fill >= 0 && p.fill <= 1)) problems.push(`${label} fill must be between 0 and 1`)\n if (p?.structure) {\n if (!STRUCTURE_ROLES.includes(p.structure.role)) problems.push(`${label} has an invalid structure role \"${String(p.structure.role)}\"`)\n if (!nonNegative(p.structure.capacity)) problems.push(`${label} structure capacity must be a finite number >= 0`)\n }\n if (p?.contains && !nonNegative(p.contains.liters)) problems.push(`${label} contains.liters must be a finite number >= 0`)\n checkStagedFields(p, label, materials, problems)\n }\n\n const jointIds = new Set<string>()\n const edges: Array<[string, string]> = []\n for (const j of spec?.joints ?? []) {\n const id = j.id ?? `${j.a}~${j.b}`\n const label = `joint \"${id}\"`\n if (jointIds.has(id)) problems.push(`duplicate joint id \"${id}\"`)\n jointIds.add(id)\n if (!ids.has(j.a)) problems.push(`${label} references unknown part \"${String(j.a)}\"`)\n if (!ids.has(j.b)) problems.push(`${label} references unknown part \"${String(j.b)}\"`)\n if (j.a === j.b) problems.push(`${label} joins part \"${String(j.a)}\" to itself`)\n if (j.bears !== undefined && !BEARS.includes(j.bears)) problems.push(`${label} has an invalid bears \"${String(j.bears)}\"`)\n if (!nonNegative(j.strength)) problems.push(`${label} strength must be a finite number >= 0`)\n if (!nonNegative(j.seconds)) problems.push(`${label} seconds must be a finite number >= 0`)\n if (j.bears !== false && ids.has(j.a) && ids.has(j.b) && j.a !== j.b) edges.push([j.a, j.b])\n }\n\n // structural parts must reach an anchored part over the joints (only when the spec lists its joints: otherwise they are inferred later)\n const structural = parts.filter((p) => p?.structure && p.structure.role !== 'none')\n if (structural.length && spec.joints) {\n const anchored = parts.filter((p) => p.anchored || p.structure?.role === 'foundation').map((p) => p.id)\n const adj = new Map<string, string[]>()\n for (const [a, b] of edges) {\n adj.set(a, [...(adj.get(a) ?? []), b])\n adj.set(b, [...(adj.get(b) ?? []), a])\n }\n const seen = new Set(anchored)\n const queue = [...anchored]\n while (queue.length) {\n for (const n of adj.get(queue.pop()!) ?? []) {\n if (seen.has(n)) continue\n seen.add(n)\n queue.push(n)\n }\n }\n const lost = structural.filter((p) => !seen.has(p.id)).map((p) => p.id)\n if (lost.length) warnings.push(`structural part(s) ${lost.map((i) => `\"${i}\"`).join(', ')} cannot reach an anchored part, so they will fall`)\n }\n return { ok: problems.length === 0, problems, warnings }\n}\n","import type { Hit, Vec3 } from './destruction'\n\n/**\n * A ballistic shot (one per pellet) as a weapon module produces it. Plain data: any damage model can consume it (`shotToHit` makes the `Hit`).\n */\nexport interface Shot {\n origin: Vec3\n /** Unit vector. */\n direction: Vec3\n /** Muzzle energy in joules. */\n energy: number\n /** Bullet diameter in millimetres. */\n caliber: number\n /** snake_case calibre id, e.g. `9x19`. */\n caliberId: string\n /** Muzzle speed in m/s. */\n speed: number\n /** Projectile mass in grams (one pellet for a shotgun load). */\n mass?: number\n /** Energy at a distance in metres, with the calibre's drag. */\n energyAt(distance: number): number\n pellet: number\n /** snake_case weapon id. */\n weapon: string\n source?: string\n}\n\n/** One use of a non-firearm (melee swing, flame tick, heat tick, throw, tool tick, extinguisher tick). */\nexport type Use =\n | { kind: 'melee'; damage: 'blunt' | 'slash'; energy: number; radius: number; reach: number; origin: Vec3; direction: Vec3 }\n | { kind: 'flame'; temperature: number; radius: number; range: number; cone: boolean; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'heat'; temperature: number; radius: number; range: number; duration: number; origin: Vec3; direction: Vec3 }\n | {\n kind: 'throw'\n energy: number\n radius: number\n fuse: number\n velocity: Vec3\n origin: Vec3\n fire?: { temperature: number; radius: number; seconds: number }\n /** Explosive id (`m67`, `molotov`, `pg7v`...): the host looks the numbers up in the arsenal. Absent on a plain thrown object. */\n explosive?: string\n /** What sets it off: `timer` after `fuse` seconds, `impact` on the first hit once armed. */\n trigger?: 'timer' | 'impact'\n /** Metres the projectile must fly before an impact sets it off; closer, it hits without exploding (rocket launchers). */\n armDistance?: number\n /** Radius in metres of the wounding area (`radius` is the lethal one). */\n injuryRadius?: number\n /** Seconds the blast stuns whoever is inside the injury radius (flashbang). */\n stunSeconds?: number\n /** Seconds the thrower held it after pulling the pin: `fuse` is what was left of the full fuse when it left the hand. */\n cooked?: number\n /** Went off in the thrower's hand (held past the fuse): no velocity, `fuse` is 0 and the blast is at `origin`. */\n inHand?: boolean\n }\n /** An explosive set down where the trigger is pulled (mine, C4, charge): it waits for its trigger instead of flying. */\n | {\n kind: 'place'\n explosive: string\n /** `wire`: something trips it; `remote`: the player fires it; `timer`: after `fuse` seconds. */\n triggers: readonly ('timer' | 'wire' | 'remote')[]\n energy: number\n /** Lethal radius in metres. */\n radius: number\n injuryRadius: number\n /** Cone the blast goes through, in front of `direction` (mine); absent for a blast in every direction. */\n cone?: { halfAngleDeg: number; length: number }\n /** The wire a `wire` charge stretches from where it is set down: metres out, degrees from its facing (counter-clockwise from above) and metres above it. */\n tripwire?: { length: number; angleDeg: number; height: number }\n fuse?: number\n origin: Vec3\n direction: Vec3\n }\n /** The blast behind a rocket launcher: dangerous inside `radius` metres, in the cone around `direction` (pointing away from the target). */\n | { kind: 'backblast'; radius: number; halfAngleDeg: number; origin: Vec3; direction: Vec3 }\n | { kind: 'tool'; tool: string; reach: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'extinguish'; range: number; coolC: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'hand'; reach: number; origin: Vec3; direction: Vec3 }\n\n/**\n * The `Hit` a ballistic shot makes at `point` (world space): the energy is what is left of the shot at that distance from its origin\n * (`shot.energyAt`), the direction and calibre come from the shot. `normal` (the surface normal at the point, when the caller knows it) does not\n * change the hit; it is accepted so that callers can pass what their raycast returned and so that a stricter implementation could use it.\n */\nexport const shotToHit = (shot: Shot, point: Vec3, normal?: Vec3): Hit => {\n void normal\n const dx = point[0] - shot.origin[0]\n const dy = point[1] - shot.origin[1]\n const dz = point[2] - shot.origin[2]\n const distance = Math.hypot(dx, dy, dz)\n return {\n type: 'ballistic',\n point: [point[0], point[1], point[2]],\n direction: [shot.direction[0], shot.direction[1], shot.direction[2]],\n energy: shot.energyAt(distance),\n caliber: shot.caliber,\n ...(shot.mass === undefined ? {} : { mass: shot.mass }),\n source: shot.source ?? shot.weapon,\n }\n}\n","import type { Vec3 } from './destruction'\n\n/** Pose of one part (or of the whole item) at a key: position offset in metres and Euler XYZ rotation in radians, both relative to the rest pose. */\nexport interface AnimationPose {\n position?: Vec3\n rotation?: Vec3\n}\n\nexport interface AnimationKey {\n /** Seconds from the start of the clip. */\n t: number\n /** Pose of the item's root. */\n position?: Vec3\n rotation?: Vec3\n /** Poses of named parts: the key is a destruction part id (a pistol `reload` moves `mag`; a car door `open` rotates `door_l`). */\n parts?: Record<string, AnimationPose>\n}\n\nexport interface AnimationEventSpec {\n /** Seconds from the start of the clip. */\n t: number\n /** snake_case type the host maps (`sound`, `eject_casing`, `door_latch`...). */\n type: string\n data?: Record<string, unknown>\n}\n\n/** A use animation a module brings with its item. Poses between keys are interpolated by the player (the test room does it linearly). */\nexport interface AnimationClipSpec {\n /** snake_case: `reload`, `open`, `drink`... Unique within the item. */\n id: string\n /** Seconds. */\n duration: number\n keys: AnimationKey[]\n events?: AnimationEventSpec[]\n}\n\n/** What an item exposes when it brings its own animations. */\nexport interface ItemAnimationContract {\n animations: AnimationClipSpec[]\n}\n\nconst finite3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every((n) => typeof n === 'number' && Number.isFinite(n))\n\n/**\n * Problems with a clip (empty when it is valid): a snake_case id, a positive finite duration, at least one key, key and event times inside\n * `[0, duration]` and not going backwards, finite vectors, every named part one of `partIds`, event types that are non-empty strings and\n * JSON-serializable event data.\n */\nexport const checkAnimation = (clip: AnimationClipSpec, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const parts = new Set(partIds)\n const id = String(clip?.id ?? '')\n if (!/^[a-z][a-z0-9_]*$/.test(id)) problems.push(`clip id \"${id}\" must be snake_case`)\n const label = `clip \"${id}\"`\n if (!(typeof clip?.duration === 'number' && Number.isFinite(clip.duration) && clip.duration > 0)) problems.push(`${label} needs a positive finite duration`)\n const dur = typeof clip?.duration === 'number' && clip.duration > 0 ? clip.duration : Infinity\n if (!Array.isArray(clip?.keys) || clip.keys.length === 0) {\n problems.push(`${label} needs at least one key`)\n return { ok: false, problems }\n }\n let prev = -Infinity\n clip.keys.forEach((k, i) => {\n if (!(typeof k.t === 'number' && Number.isFinite(k.t)) || k.t < 0 || k.t > dur + 1e-9) problems.push(`${label} key ${i} has t=${String(k.t)} outside 0..${dur}`)\n else if (k.t < prev) problems.push(`${label} key ${i} goes back in time (${k.t} < ${prev})`)\n else prev = k.t\n for (const f of ['position', 'rotation'] as const) if (k[f] !== undefined && !finite3(k[f])) problems.push(`${label} key ${i} has an invalid ${f}`)\n for (const [pid, pose] of Object.entries(k.parts ?? {})) {\n if (!parts.has(pid)) problems.push(`${label} key ${i} moves unknown part \"${pid}\"`)\n for (const f of ['position', 'rotation'] as const) if (pose?.[f] !== undefined && !finite3(pose[f])) problems.push(`${label} key ${i} part \"${pid}\" has an invalid ${f}`)\n }\n })\n let prevEv = -Infinity\n ;(clip.events ?? []).forEach((e, i) => {\n if (!(typeof e.t === 'number' && Number.isFinite(e.t)) || e.t < 0 || e.t > dur + 1e-9) problems.push(`${label} event ${i} has t=${String(e.t)} outside 0..${dur}`)\n else if (e.t < prevEv) problems.push(`${label} event ${i} goes back in time`)\n else prevEv = e.t\n if (typeof e.type !== 'string' || e.type === '') problems.push(`${label} event ${i} needs a type`)\n try {\n JSON.stringify(e.data ?? {})\n } catch {\n problems.push(`${label} event ${i} data is not JSON`)\n }\n })\n return { ok: problems.length === 0, problems }\n}\n","import type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from './animation'\nimport { checkAnimation } from './animation'\nimport type { HostEvent } from './module'\n\n/** Clips a tool can bring, one per move of its cycle. A tool brings the ones it has; a missing clip is simply not played. */\nexport const TOOL_CLIP = {\n DRAW: 'draw',\n SHOT: 'shot',\n MISFIRE: 'misfire',\n EMPTY: 'empty',\n CYCLE: 'cycle',\n RELOAD: 'reload',\n FEED: 'feed',\n FAULT: 'fault',\n CLEAR: 'clear',\n SAFETY_ON: 'safety_on',\n SAFETY_OFF: 'safety_off',\n MODE: 'mode',\n /** A throwable with the pin out, held until it is thrown. */\n COOK: 'cook',\n /** The stock folds, unfolds, slides in or out (variants `fold`, `unfold`, `collapse`, `extend`). */\n STOCK: 'stock',\n /** A light or a laser is switched (variants `on`, `off`). */\n TOGGLE: 'toggle',\n} as const\nexport type ToolClipId = (typeof TOOL_CLIP)[keyof typeof TOOL_CLIP]\n\n/** What a renderer does when a rule event arrives. `variant` picks `<clip>_<variant>` when the tool has it, else `<clip>`. */\nexport type ToolAnimationStep =\n | { readonly type: 'play'; readonly clip: ToolClipId; readonly variant?: string; readonly duration?: number; readonly repeat?: number }\n /** Move the clip that is playing to the marker (a clip event `stage` with `data.stage`) the rule just reached. */\n | { readonly type: 'sync'; readonly stage: string }\n /** The rule says the phase is over: the clip jumps to its end if it is still running. */\n | { readonly type: 'finish'; readonly clip: ToolClipId }\n\nconst stockVariant = (event: Extract<HostEvent, { type: 'stock' }>): string => {\n const isFolding = event.kind === undefined ? false : event.kind.includes('fold')\n if (event.state === 'collapsed') return isFolding ? 'fold' : 'collapse'\n return isFolding ? 'unfold' : 'extend'\n}\n\n/** The move a host event asks of the tool in hand, or null when it has no motion. */\nexport const toolAnimationStep = (event: HostEvent): ToolAnimationStep | null => {\n switch (event.type) {\n case 'tool':\n return { type: 'play', clip: TOOL_CLIP.DRAW, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'shot':\n return { type: 'play', clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) }\n case 'misfire':\n return { type: 'play', clip: TOOL_CLIP.MISFIRE }\n case 'empty':\n return { type: 'play', clip: TOOL_CLIP.EMPTY }\n case 'mode':\n return { type: 'play', clip: TOOL_CLIP.MODE, variant: event.mode }\n case 'fault':\n return { type: 'play', clip: TOOL_CLIP.FAULT, variant: event.fault }\n case 'clear':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CLEAR }\n return { type: 'play', clip: TOOL_CLIP.CLEAR, variant: event.fault, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'safety':\n return { type: 'play', clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF }\n case 'cycle':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CYCLE }\n return { type: 'play', clip: TOOL_CLIP.CYCLE, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'reload':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.RELOAD }\n return { type: 'play', clip: TOOL_CLIP.RELOAD, ...(event.kind === undefined ? {} : { variant: event.kind }), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'stage':\n return { type: 'sync', stage: event.stage }\n case 'feed':\n return { type: 'play', clip: TOOL_CLIP.FEED }\n case 'cook':\n if (event.phase === 'start') return { type: 'play', clip: TOOL_CLIP.COOK, duration: event.fuse }\n return { type: 'finish', clip: TOOL_CLIP.COOK }\n case 'stock':\n return { type: 'play', clip: TOOL_CLIP.STOCK, variant: stockVariant(event), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'toggle':\n return { type: 'play', clip: TOOL_CLIP.TOGGLE, variant: event.on ? 'on' : 'off' }\n default:\n return null\n }\n}\n\n/** Where a renderer puts the poses: every part of the tool by id (the ids the clips move), and the whole tool. Poses are offsets from rest. */\nexport interface ToolRig {\n setPartPose(partId: string, pose: AnimationPose): void\n setRootPose?(pose: AnimationPose): void\n}\n\n/** Clips by id, with the variants as `<clip>_<variant>`. */\nexport type ToolClipSet = Readonly<Record<string, AnimationClipSpec>>\n\n/** A renderer's tool animator: feed it the host events and the frame time. */\nexport interface ToolAnimator {\n handle(event: HostEvent): void\n update(dt: number): void\n /** Ids of the clips playing now. */\n readonly playing: readonly string[]\n dispose(): void\n}\n\nexport const STAGE_EVENT = 'stage'\n\n/** The clip with its times (keys and events) scaled so that it lasts `duration` seconds. */\nexport const scaleClip = (clip: AnimationClipSpec, duration: number): AnimationClipSpec => {\n const factor = clip.duration > 0 ? duration / clip.duration : 1\n return {\n ...clip,\n duration,\n keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),\n ...(clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}),\n }\n}\n\nconst ZERO: [number, number, number] = [0, 0, 0]\nconst mix = (from: readonly number[], to: readonly number[], fraction: number): [number, number, number] => [\n (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,\n (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,\n (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction,\n]\n\n/** Pose of the whole tool (`partId` undefined) or of one part at `time`, linear between keys; a key that does not name it means rest. */\nexport const sampleClip = (clip: AnimationClipSpec, partId: string | undefined, time: number): { position: [number, number, number]; rotation: [number, number, number] } => {\n const points = clip.keys.map((key) => {\n const pose = partId === undefined ? key : key.parts?.[partId]\n return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO }\n })\n const first = points[0]\n if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO })\n const last = points[points.length - 1]\n if (!last) return { position: ZERO, rotation: ZERO }\n if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) }\n const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)))\n const from = points[index]\n const to = points[index + 1]\n if (!from || !to) return { position: ZERO, rotation: ZERO }\n const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0\n return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) }\n}\n\n/** Problems with a clip set (empty when valid): each key is the clip id (or `<clip>_<variant>`), every clip passes `checkAnimation`, and a `stage` event names its stage. */\nexport const checkToolClips = (clips: ToolClipSet, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const parts = [...partIds]\n const problems: string[] = []\n for (const [key, clip] of Object.entries(clips)) {\n if (clip.id !== key) problems.push(`clip \"${key}\" has the id \"${clip.id}\"`)\n if (!(clip.duration > 0)) problems.push(`clip \"${key}\" has no duration`)\n problems.push(...checkAnimation(clip, parts).problems)\n for (const event of clip.events ?? []) if (event.type === STAGE_EVENT && typeof event.data?.stage !== 'string') problems.push(`clip \"${key}\" has a stage event without data.stage`)\n }\n return { ok: problems.length === 0, problems }\n}\n\ninterface Instance {\n readonly name: string\n readonly clip: AnimationClipSpec\n time: number\n delay: number\n fired: number\n}\n\nexport interface ToolClipPlayerOptions {\n clips: ToolClipSet\n rig: ToolRig\n /** Called for each clip event as its time passes (`eject_casing`, `drop_magazine`, `stage`...). */\n onEvent?(event: AnimationEventSpec, clip: string): void\n /** Seconds between the rounds of a `repeat` (a burst): default 0.1. */\n repeatInterval?(): number\n}\n\n/** The default player of a tool's clips: runs the steps of `toolAnimationStep` against a rig, scaled to the duration the rule gives. */\nexport interface ToolClipPlayer {\n apply(step: ToolAnimationStep): void\n update(dt: number): void\n readonly playing: readonly string[]\n}\n\nexport const createToolClipPlayer = (options: ToolClipPlayerOptions): ToolClipPlayer => {\n const { clips, rig, onEvent } = options\n let instances: Instance[] = []\n\n const find = (clip: string, variant?: string): { name: string; clip: AnimationClipSpec } | undefined => {\n const name = variant !== undefined && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip\n const found = clips[name]\n return found ? { name, clip: found } : undefined\n }\n\n const render = (instance: Instance): void => {\n const time = Math.min(instance.time, instance.clip.duration)\n const root = sampleClip(instance.clip, undefined, time)\n if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root)\n const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})))\n for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time))\n }\n\n const fireEvents = (instance: Instance, upTo: number): void => {\n const events = instance.clip.events ?? []\n while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {\n const event = events[instance.fired]\n instance.fired += 1\n if (event) onEvent?.(event, instance.name)\n }\n }\n\n return {\n apply(step) {\n if (step.type === 'sync') {\n for (const instance of instances) {\n const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage)\n if (marker && instance.time < marker.t) instance.time = marker.t\n }\n return\n }\n if (step.type === 'finish') {\n for (const instance of instances) {\n if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue\n fireEvents(instance, instance.clip.duration)\n instance.time = instance.clip.duration\n }\n return\n }\n const found = find(step.clip, step.variant)\n if (!found) return\n const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip\n const interval = options.repeatInterval?.() ?? 0.1\n instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0)\n for (let round = 0; round < (step.repeat ?? 1); round++) {\n instances.push({ name: found.name, clip, time: 0, delay: round * interval, fired: 0 })\n }\n },\n update(dt) {\n for (const instance of instances) {\n const carried = instance.delay > 0 ? dt - instance.delay : dt\n if (instance.delay > 0) {\n instance.delay = Math.max(0, instance.delay - dt)\n if (instance.delay > 0) continue\n }\n instance.time += carried\n fireEvents(instance, instance.time)\n render(instance)\n }\n instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration)\n },\n get playing() {\n return instances.map((instance) => instance.name)\n },\n }\n}\n","type PlainObject = Record<string, unknown>\ntype Entry = { readonly id: string }\n\n/** Keys that would reach the prototype of the result when a patch comes from parsed JSON. */\nconst UNSAFE_KEYS: ReadonlySet<string> = new Set(['__proto__', 'constructor', 'prototype'])\n\nconst isPlainObject = (value: unknown): value is PlainObject =>\n typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype\n\n/** Recursively optional; arrays and functions are replaced as a whole, objects are merged. */\nexport type DeepPartial<TValue> = TValue extends (...args: never[]) => unknown\n ? TValue\n : TValue extends readonly unknown[]\n ? TValue\n : TValue extends object\n ? { [TKey in keyof TValue]?: DeepPartial<TValue[TKey]> }\n : TValue\n\n/** Merges `patch` over `base`: plain objects merge field by field, arrays, functions and primitives replace. `undefined` in the patch is ignored. */\nexport const deepMerge = <TBase extends object>(base: TBase, patch: object | undefined): TBase => {\n if (!patch) return base\n const result: PlainObject = { ...(base as PlainObject) }\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined || UNSAFE_KEYS.has(key)) continue\n const current = result[key]\n result[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value\n }\n return result as TBase\n}\n\n/** The shipped entries with the ones from `extra` added or, when the id exists, replaced. */\nexport const mergeById = <TEntry extends Entry>(shipped: readonly TEntry[], extra: readonly TEntry[] | undefined): Map<string, TEntry> => {\n const entries = new Map<string, TEntry>()\n for (const entry of [...shipped, ...(extra ?? [])]) entries.set(entry.id, entry)\n return entries\n}\n\n/** Applies `patch` by id; a patch for an id that does not exist is ignored. */\nexport const applyPatches = <TEntry extends Entry>(entries: Map<string, TEntry>, patches: Readonly<Record<string, DeepPartial<TEntry> | Partial<TEntry>>> | undefined): void => {\n for (const [id, patch] of Object.entries(patches ?? {})) {\n const entry = entries.get(id)\n if (entry) entries.set(id, deepMerge(entry, patch))\n }\n}\n\nexport const removeIds = (entries: Map<string, unknown>, ids: readonly string[] | undefined): void => {\n for (const id of ids ?? []) entries.delete(id)\n}\n","import type { Vec3 } from './destruction'\n\n/**\n * The bench of a module: controls, layers and counters it declares as data. The host keeps the values, draws them in a generic way and hands\n * every change back through `ModuleHost.bench`. Nothing here is specific to a kind of module.\n */\nexport type ControlValue = number | boolean | string\n\nexport interface ChoiceOption {\n readonly id: string\n readonly name: string\n}\n\ninterface ControlBase {\n /** snake_case, unique across the module's controls, layers and metrics. */\n readonly id: string\n /** Display name, already translated for the locale the host asked for. */\n readonly name: string\n readonly hint?: string\n readonly hidden?: boolean\n}\n\nexport interface NumberControl extends ControlBase {\n readonly kind: 'number'\n readonly min: number\n readonly max: number\n readonly step?: number\n readonly unit?: string\n readonly default: number\n}\n\nexport interface BooleanControl extends ControlBase {\n readonly kind: 'boolean'\n readonly default: boolean\n}\n\nexport interface ChoiceControl extends ControlBase {\n readonly kind: 'choice'\n readonly options: readonly ChoiceOption[]\n readonly default: string\n}\n\n/** A button: no value, only the press. */\nexport interface ActionControl extends ControlBase {\n readonly kind: 'action'\n}\n\nexport type ModuleControl = NumberControl | BooleanControl | ChoiceControl | ActionControl\n\n/** Something of the module the viewer turns on or off (smoke, flash, casings). */\nexport interface ModuleLayer {\n readonly id: string\n readonly name: string\n /** On unless `false`. */\n readonly default?: boolean\n}\n\n/** Pulled: the room calls read only when it samples (~4 Hz, or on TestRoom.metrics()). */\nexport interface ModuleMetric {\n readonly id: string\n readonly name: string\n readonly unit?: string\n /** Budget: the host shows a bar and warns past it. */\n readonly max?: number\n readonly digits?: number\n read(): number | string\n}\n\nexport type BenchChange =\n | { readonly kind: 'control'; readonly id: string; readonly value: ControlValue }\n | { readonly kind: 'layer'; readonly id: string; readonly on: boolean }\n | { readonly kind: 'action'; readonly id: string }\n\nexport interface ControlPatch {\n readonly hidden?: boolean\n readonly disabled?: boolean\n readonly options?: readonly ChoiceOption[]\n readonly value?: ControlValue\n}\n\n/** What the host lends a module that declares a bench: the current values and the changes. */\nexport interface ModuleBench {\n value(id: string): ControlValue | undefined\n layer(id: string): boolean\n /** Right after attach returns, the host sends one change per control (not actions) and per layer, in declaration order. */\n onChange(listener: (change: BenchChange) => void): () => void\n /** `value` sets without emitting (no echo loops); `options` falls back to the first option if the value is no longer offered. */\n patch(id: string, patch: ControlPatch): void\n /** Move the host camera (a near / middle / far choice). */\n look(eye: Vec3, target: Vec3): void\n}\n\nexport interface BenchReport {\n readonly ok: boolean\n readonly problems: readonly string[]\n}\n\nexport interface BenchDeclaration {\n readonly controls?: readonly ModuleControl[]\n readonly layers?: readonly ModuleLayer[]\n readonly metrics?: readonly ModuleMetric[]\n}\n\nconst SNAKE_CASE = /^[a-z][a-z0-9_]*$/\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\n\nfunction checkControl(control: ModuleControl, problems: string[]): void {\n const label = `control \"${control.id}\"`\n if (control.kind === 'number') {\n if (!finite(control.min) || !finite(control.max) || control.min >= control.max) problems.push(`${label} needs min < max`)\n if (control.step !== undefined && !(finite(control.step) && control.step > 0)) problems.push(`${label} needs a step > 0`)\n if (!finite(control.default) || control.default < control.min || control.default > control.max) problems.push(`${label} default ${String(control.default)} is outside ${control.min}..${control.max}`)\n return\n }\n if (control.kind !== 'choice') return\n if (control.options.length === 0) {\n problems.push(`${label} needs at least one option`)\n return\n }\n const seen = new Set<string>()\n for (const option of control.options) {\n if (seen.has(option.id)) problems.push(`${label} repeats option \"${option.id}\"`)\n seen.add(option.id)\n }\n if (!seen.has(control.default)) problems.push(`${label} default \"${control.default}\" is not among its options`)\n}\n\n/** snake_case ids unique across controls, layers and metrics; min < max; step > 0; default in range; options non-empty, unique, default among them; metric max > 0. */\nexport function checkBench(declared: BenchDeclaration): BenchReport {\n const problems: string[] = []\n const ids = new Set<string>()\n const claim = (kind: string, id: string): void => {\n if (!SNAKE_CASE.test(id)) problems.push(`${kind} id \"${id}\" must be snake_case`)\n if (ids.has(id)) problems.push(`duplicate id \"${id}\" across controls, layers and metrics`)\n ids.add(id)\n }\n for (const control of declared.controls ?? []) {\n claim('control', control.id)\n checkControl(control, problems)\n }\n for (const layer of declared.layers ?? []) claim('layer', layer.id)\n for (const metric of declared.metrics ?? []) {\n claim('metric', metric.id)\n if (metric.max !== undefined && !(finite(metric.max) && metric.max > 0)) problems.push(`metric \"${metric.id}\" needs a max > 0`)\n }\n return { ok: problems.length === 0, problems }\n}\n","import { checkDestructible as check } from '@adatechnology/game-contracts'\nimport type { CheckOptions as ContractCheckOptions, DestructibleImpl } from '@adatechnology/game-contracts'\nimport { MATERIALS } from './materials'\n\n// The contract itself lives in @adatechnology/game-contracts (a module depends only on that); re-exported here so that no import breaks.\nexport { IMPACT_CONTRACT, checkHit } from '@adatechnology/game-contracts'\nexport type { DestructibleImpl, ImpactContract } from '@adatechnology/game-contracts'\n\nexport interface CheckOptions {\n /** Ids of custom materials the impl uses besides the built-in `MATERIALS`. */\n materials?: string[]\n}\n\n/**\n * `checkDestructible` of `@adatechnology/game-contracts`, with the built-in `MATERIALS` (plus `options.materials`) as the known material ids.\n * It hits the impl (and calls `reset()` afterwards when there is one).\n */\nexport const checkDestructible = (impl: DestructibleImpl, options: CheckOptions = {}): { ok: boolean; problems: string[] } => {\n const contractOptions: ContractCheckOptions = { materials: [...MATERIALS.map((m) => m.id), ...(options.materials ?? [])] }\n return check(impl, contractOptions)\n}\n"],"mappings":"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","names":["checkDestructible","n0","n1","a","c","t0","t1","dy","inside","sign","n","a","b","th","u","v","clamp","pos","dmg","spread","checkDestructible"]}
|