@adatechnology/game-animals-three 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/animate-bird.ts","../src/animate-quadruped.ts","../src/animate-snake.ts","../src/bird.ts","../src/context.ts","../src/extras.ts","../src/quadruped.ts","../src/textures.ts","../src/profile.ts","../src/snake.ts","../src/visual-state.ts","../src/views.ts","../src/line-up.ts","../src/test-area/module.ts","../src/test-area/scenarios.ts","../src/test-area/text.ts"],"sourcesContent":["/**\n * @adatechnology/game-animals-three: the three.js drawing of the animals, a literal port of the Bichos do Vale builders (`quad`, `bird`, `snake`) and\n * their animation, with the alive / infected / dead looks for every species, the joints and split views, and a GPU node skin for crowds.\n */\nimport { GAIT_PHASES } from '@adatechnology/game-animals'\nimport type { AnimalSpecies, AnimalVisualState, GaitPhases } from '@adatechnology/game-animals'\nimport { collectReferencedNodes, createNodeSkin } from '@adatechnology/game-props3d'\nimport type { NodeSkin } from '@adatechnology/game-props3d'\nimport type * as THREE_NS from 'three'\n\nimport { animateBird } from './animate-bird'\nimport { animateQuadruped } from './animate-quadruped'\nimport { animateSnake } from './animate-snake'\nimport type { AnimateParams } from './animate-types'\nimport { buildBird } from './bird'\nimport { createRig, createStream } from './context'\nimport { BIRD_EXTRAS, QUADRUPED_EXTRAS } from './extras'\nimport { buildQuadruped } from './quadruped'\nimport { buildSnake } from './snake'\nimport type { AnimalRig, AnimalsThreeOptions, DocumentLike, Three } from './types'\nimport { applyVisualState } from './visual-state'\nimport { setJointView, setSplit, updateSplit } from './views'\n\nexport type { AnimalLeg, AnimalPivot, AnimalRig, AnimalWing, AnimalsThreeOptions, CanvasLike, DocumentLike, Three } from './types'\nexport type { AnimateParams } from './animate-types'\nexport type { BirdExtra, BirdParts, ExtraContext, QuadrupedExtra, QuadrupedParts } from './extras'\nexport { BIRD_EXTRAS, QUADRUPED_EXTRAS } from './extras'\nexport { lineUpAnimals } from './line-up'\nexport type { LineUpOptions } from './line-up'\nexport { profileGeometry } from './profile'\nexport { createCoatTexture } from './textures'\nexport { applyVisualState } from './visual-state'\nexport { setJointView, setSplit, updateSplit } from './views'\n\nexport type AnimalsThree = {\n /** Builds one animal from its species; consumes one number of the stream for the start phase unless `phase` is given. */\n build(species: AnimalSpecies, buildOptions?: { readonly phase?: number }): AnimalRig\n /** Advances the animation of one animal (steps, flight, wings, head, tail, a dead one lying down). */\n animate(rig: AnimalRig, params: AnimateParams): void\n setVisualState(rig: AnimalRig, state: AnimalVisualState): void\n setJointView(rig: AnimalRig, on: boolean): void\n setSplit(rig: AnimalRig, on: boolean): void\n updateSplit(rig: AnimalRig, delta: number): void\n /** One mesh that stands for the whole tree, for crowds: call `skin.update()` each frame after `animate`. */\n createSkin(rig: AnimalRig): NodeSkin\n readonly jointMaterial: THREE_NS.MeshStandardMaterial\n}\n\nconst countTriangles = (root: THREE_NS.Object3D): number => {\n let triangles = 0\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh) return\n const geometry = mesh.geometry\n triangles += geometry.index ? geometry.index.count / 3 : geometry.attributes.position.count / 3\n })\n return Math.round(triangles)\n}\n\nexport const createAnimalsThree = (THREE: Three, options: AnimalsThreeOptions = {}): AnimalsThree => {\n const random = options.random ?? createStream(options.seed ?? 7)\n const documentOf = (): DocumentLike => {\n const found = options.document ?? (globalThis as { document?: DocumentLike }).document\n if (!found) throw new Error('game-animals-three: a species with a coat texture needs `options.document` (no global document found)')\n return found\n }\n const jointMaterial = new THREE.MeshStandardMaterial({ color: 0xe0a548, emissive: 0xe0a548, emissiveIntensity: 0.8, roughness: 0.4 })\n const gaits: Readonly<Record<'walk' | 'trot' | 'gallop', GaitPhases>> = GAIT_PHASES\n\n return {\n jointMaterial,\n build(species, buildOptions = {}) {\n const rig = createRig(THREE, species, { phase: buildOptions.phase ?? random() * 6 })\n if (species.body.kind === 'snake') buildSnake(THREE, rig)\n else if (species.body.kind === 'bird') buildBird(THREE, rig, { extra: BIRD_EXTRAS[species.id] })\n else buildQuadruped(THREE, rig, { document: species.body.texture ? documentOf() : (undefined as never), extra: QUADRUPED_EXTRAS[species.id] })\n rig.triangles = countTriangles(rig.root)\n rig.root.traverse((object) => {\n if ((object as THREE_NS.Mesh).isMesh) object.userData.speciesId = species.id\n })\n return rig\n },\n animate(rig, params) {\n const kind = rig.species.body.kind\n if (kind === 'snake') animateSnake(THREE, rig, params)\n else if (kind === 'bird') animateBird(rig, params)\n else animateQuadruped(rig, params, gaits)\n },\n setVisualState: (rig, state) => applyVisualState(THREE, rig, state),\n setJointView: (rig, on) => setJointView(rig, on, jointMaterial),\n setSplit,\n updateSplit,\n createSkin: (rig) => createNodeSkin(THREE, rig.root, { nodes: collectReferencedNodes(rig, ['species']) }),\n }\n}\nexport { createAnimalsTestModule, ANIMALS_AREA_ID, ANIMAL_ITEM_PREFIX } from './test-area/module'\nexport type { AnimalsContext } from './test-area/scenarios'\nexport type { AnimalsTestOptions, OutbreakLike } from './test-area/types'\n","import type { BirdSpec } from '@adatechnology/game-animals'\n\nimport type { AnimateParams } from './animate-types'\nimport type { AnimalRig } from './types'\n\nconst { PI } = Math\n\n/** Advances a bird's cycle (page: `animBird`): steps, flight for the species that fly, wings, peck, alarm, tail. */\nexport const animateBird = (rig: AnimalRig, params: AnimateParams): void => {\n const { time: t, delta: dt, clip } = params\n const species = rig.species\n const spec = species.body as BirdSpec\n const isVulture = species.id === 'vulture'\n const isChicken = species.id === 'chicken'\n const isLapwing = species.id === 'southern_lapwing'\n const flying = clip === 'run' && !isChicken\n const hz = clip === 'run' && !flying ? species.runHz : clip === 'walk' ? species.walkHz : 0\n rig.phase += dt * (flying ? (isVulture ? 1.1 : 4.5) : hz) * 2 * PI\n const targetHeight = flying ? rig.size * 1.2 : 0\n rig.trunk.position.y += (targetHeight - rig.trunk.position.y) * Math.min(1, dt * 3)\n rig.legs.forEach((leg, index) => {\n if (flying) {\n leg.hip.rotation.x = 1.2\n leg.knee.rotation.x = -1.6\n } else if (clip === 'idle') {\n leg.hip.rotation.x = 0\n leg.knee.rotation.x = 0\n } else {\n const phase = rig.phase + index * PI\n leg.hip.rotation.x = -Math.sin(phase) * 0.45\n leg.knee.rotation.x = -Math.max(0, Math.cos(phase)) * 0.7\n }\n leg.foot.rotation.x = -(leg.hip.rotation.x + leg.knee.rotation.x)\n })\n rig.wings.forEach((wing) => {\n const { side, shoulder, elbow } = wing\n if (flying) {\n const flap = isVulture ? 0.25 + Math.sin(rig.phase) * 0.18 : Math.sin(rig.phase) * 0.9\n shoulder.rotation.y += (0 - shoulder.rotation.y) * Math.min(1, dt * 6)\n shoulder.rotation.z = side * flap\n elbow.rotation.z = side * (isVulture ? 0.08 : Math.sin(rig.phase - 0.6) * 0.4)\n elbow.rotation.y = 0\n shoulder.scale.x += (1 - shoulder.scale.x) * Math.min(1, dt * 6)\n } else {\n const alert = isLapwing && clip === 'idle' ? Math.max(0, Math.sin(t * 1.3)) * 0.9 : 0\n const flutter = isChicken && clip === 'run' ? Math.abs(Math.sin(rig.phase * 1.5)) * 0.8 : 0\n shoulder.rotation.y += ((side * PI) / 2 * 0.97 - alert * side * 0.9 - shoulder.rotation.y) * Math.min(1, dt * 6)\n shoulder.rotation.z = side * (-0.06 + flutter + alert * 0.6)\n elbow.rotation.z = side * 0.04\n elbow.rotation.y = 0\n shoulder.scale.x += ((alert > 0.1 ? 1 : 0.58) - shoulder.scale.x) * Math.min(1, dt * 6)\n }\n })\n const peck = isChicken && clip === 'idle' ? Math.max(0, Math.sin(t * 1.6)) ** 8 * 1.2 : 0\n if (rig.neck) {\n rig.neck.rotation.x = rig.neckAngle + (clip === 'walk' && !isVulture ? Math.max(0, Math.sin(rig.phase * 2)) * 0.35 : 0) + peck + (flying ? 0.6 : 0)\n rig.neck.rotation.y = clip === 'idle' ? Math.sin(t * 0.9) * 0.5 : 0\n }\n if (rig.jaw) rig.jaw.rotation.x = isLapwing && clip === 'idle' ? Math.max(0, Math.sin(t * 1.3)) * Math.abs(Math.sin(t * 14)) * 0.5 : 0\n if (rig.tailRoot) rig.tailRoot.rotation.x = (spec.tailA || 0) + (flying ? 0.6 : 0)\n}\n","import type { GaitPhases, QuadrupedSpec } from '@adatechnology/game-animals'\n\nimport type { AnimateParams } from './animate-types'\nimport type { AnimalRig } from './types'\n\nconst { PI } = Math\n\n/** Advances a quadruped's step cycle (page: `animQuad`): legs by gait phase, trunk bob, neck, head, jaw and tail; a dead one lies down. */\nexport const animateQuadruped = (rig: AnimalRig, params: AnimateParams, gaits: { readonly walk: GaitPhases; readonly trot: GaitPhases; readonly gallop: GaitPhases }): void => {\n const { time: t, delta: dt, clip } = params\n const species = rig.species\n const spec = species.body as QuadrupedSpec\n if (rig.dead) {\n rig.root.rotation.z += (PI / 2 * 0.97 - rig.root.rotation.z) * Math.min(1, dt * 3)\n rig.root.position.y += (spec.R * (spec.sx || 1) * 0.85 - rig.root.position.y) * Math.min(1, dt * 3)\n rig.legs.forEach((leg) => {\n leg.hip.rotation.x = leg.angle1 + (leg.isFront ? -0.5 : 0.4)\n leg.knee.rotation.x = 0.05\n leg.foot.rotation.x = 0\n })\n if (rig.neck) rig.neck.rotation.x = rig.neckAngle + 0.35\n if (rig.jaw) rig.jaw.rotation.x = 0.25\n return\n }\n const hz = (clip === 'run' ? species.runHz : clip === 'walk' ? species.walkHz : 0) * (rig.infected ? 1.2 : 1)\n rig.phase += dt * hz * 2 * PI\n const gait = clip === 'run' ? (species.gallop ? gaits.gallop : gaits.trot) : gaits.walk\n const amplitude = clip === 'run' ? 0.62 : 0.34\n const flex = clip === 'run' ? 1.15 : 0.75\n rig.legs.forEach((leg, index) => {\n if (clip === 'idle') {\n leg.hip.rotation.x = leg.angle1\n leg.knee.rotation.x = leg.angle2\n } else {\n const phase = rig.phase + (gait[index] as number)\n const limit = rig.infected && index === 1 ? 0.35 : 1\n leg.hip.rotation.x = leg.angle1 - Math.sin(phase) * amplitude * limit\n leg.knee.rotation.x = leg.angle2 + Math.max(0, Math.cos(phase)) * flex * limit\n }\n leg.foot.rotation.x = -(leg.hip.rotation.x + leg.knee.rotation.x) * 0.85\n })\n const bob = clip === 'idle' ? 0 : Math.abs(Math.sin(rig.phase)) * (clip === 'run' ? 0.05 : 0.018) * rig.size\n rig.trunk.position.y = bob * 0.6\n const bodyGroup = rig.bodyGroup\n if (bodyGroup) {\n bodyGroup.rotation.x = clip === 'run' && species.gallop ? Math.sin(rig.phase + PI * 0.4) * 0.07 : 0\n bodyGroup.scale.y = 1 + (clip === 'idle' ? Math.sin(t * 2.2) * 0.012 : 0)\n }\n const low = rig.infected ? 0.35 : 0\n if (rig.neck) {\n rig.neck.rotation.x = rig.neckAngle + low + (clip === 'idle' ? Math.sin(t * 0.7) * 0.08 : Math.sin(rig.phase * 2) * 0.04)\n rig.neck.rotation.y = clip === 'idle' ? Math.sin(t * 0.45) * 0.35 : 0\n }\n if (rig.head) rig.head.rotation.z = rig.infected ? Math.sin(t * 11) * Math.sin(t * 1.7) * 0.12 : 0\n if (rig.jaw) rig.jaw.rotation.x = rig.infected ? 0.25 + Math.max(0, Math.sin(t * 6)) * 0.25 : clip === 'run' ? 0.12 : 0\n const wagging = species.id === 'dog' && !rig.infected\n rig.tail.forEach((segment, index) => {\n segment.rotation.z = Math.sin(t * (wagging ? 9 : 2.2) - index * 0.6) * (wagging ? 0.35 : 0.12)\n })\n}\n","import type * as THREE_NS from 'three'\n\nimport type { AnimateParams } from './animate-types'\nimport type { AnimalRig, Three } from './types'\n\nconst { PI } = Math\n\n/** The path of the body for a clip: crawling in a wave, or coiled with the head up in an S (and striking when `strike` rises). */\nconst bodyPath = (THREE: Three, rig: AnimalRig, params: AnimateParams, spacing: number): THREE_NS.Vector3[] => {\n const { time: t, clip } = params\n const points: THREE_NS.Vector3[] = []\n for (let index = 0; index < rig.segmentCount; index++) {\n let x: number\n let z: number\n let y = 0\n if (clip === 'walk') {\n z = 0.6 - index * spacing\n x = Math.sin(rig.phase * 2.2 - index * 0.42) * 0.08 * Math.min(1, index / 6 + 0.3)\n } else {\n const strike = clip === 'run' ? Math.max(0, Math.sin(t * 2.2)) ** 6 : 0\n if (index < 9) {\n const k = index / 9\n z = 0.08 + (1 - k) * 0.12 + strike * (1 - k) * 0.35\n y = (1 - k) * 0.13 * (1 - strike * 0.6)\n x = Math.sin(k * PI * 1.6) * 0.05 * (1 - strike)\n } else {\n const angle = (index - 9) * 0.36\n const radius = 0.16 - (index - 9) * 0.0045\n x = Math.cos(angle) * radius\n z = Math.sin(angle) * radius - 0.05\n y = (index - 9) * 0.0012\n }\n }\n points.push(new THREE.Vector3(x, y, z))\n }\n return points\n}\n\n/** Advances a snake (page: `animSnake`): lays the 34 segments along the path of the clip, then the head, jaw and tongue. */\nexport const animateSnake = (THREE: Three, rig: AnimalRig, params: AnimateParams): void => {\n const { time: t, delta: dt, clip } = params\n const spacing = rig.segmentLength * (params.split ? 1.5 : 1)\n if (clip === 'walk') rig.phase += dt * 2.4\n const points = bodyPath(THREE, rig, params, spacing)\n const at = (index: number): THREE_NS.Vector3 => points[index] as THREE_NS.Vector3\n for (let index = 0; index < rig.segmentCount; index++) {\n const group = (rig.segments[index] as AnimalRig['segments'][number]).group\n group.position.copy(at(index))\n const direction = index === 0 ? at(0).clone().sub(at(1)) : at(index - 1).clone().sub(at(index))\n group.rotation.set(0, Math.atan2(direction.x, direction.z), 0)\n group.rotateX(-Math.atan2(direction.y, Math.hypot(direction.x, direction.z)))\n }\n const head = rig.head as THREE_NS.Group\n const headDirection = at(0).clone().sub(at(1)).normalize()\n head.position.copy(at(0)).addScaledVector(headDirection, 0.02)\n head.rotation.set(0, Math.atan2(headDirection.x, headDirection.z), 0)\n head.rotateX(-Math.atan2(headDirection.y, Math.hypot(headDirection.x, headDirection.z)) * 0.5)\n const jaw = rig.jaw as THREE_NS.Group\n jaw.rotation.x = clip === 'run' ? Math.max(0, Math.sin(t * 2.2)) ** 6 * 0.9 : 0\n const tongue = rig.tongue as THREE_NS.Mesh\n tongue.visible = Math.sin(t * 5) > 0.3\n tongue.scale.z = 1 + Math.sin(t * 20) * 0.3\n}\n","import { birdSize } from '@adatechnology/game-animals'\nimport type { BirdSpec } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport { addMesh, createRigTools } from './context'\nimport type { BirdExtra } from './extras'\nimport type { AnimalRig, Three } from './types'\n\nconst buildWings = (THREE: Three, rig: AnimalRig, spec: BirdSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; dark: THREE_NS.MeshStandardMaterial }): void => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, main, dark } = parts\n for (const side of [-1, 1]) {\n const shoulder = tools.pivot(bodyGroup, side * spec.r * spec.s[0] * 1.02, spec.r * 0.22, spec.r * 0.3, new THREE.Vector3(side * 0.12, 0.03, 0).multiplyScalar(rig.size))\n tools.joint(shoulder, spec.r * 0.14, main, 0, 0, 0)\n tools.ball(shoulder, 0.5, spec.wingM ? tools.material(spec.wingM) : dark, side * spec.wi * 0.5, 0, -spec.wc * 0.3, spec.wi * 1.05, spec.r * 0.16, spec.wc)\n const elbow = tools.pivot(shoulder, side * spec.wi, 0, 0, new THREE.Vector3(side * 0.06, 0, 0).multiplyScalar(rig.size))\n tools.joint(elbow, spec.r * 0.1, main, 0, 0, 0)\n tools.ball(elbow, 0.5, dark, side * spec.wo * 0.45, 0, -spec.wc * 0.32, spec.wo * 1.05, spec.r * 0.12, spec.wc * 0.75)\n if (spec.fingers) {\n for (let finger = 0; finger < 4; finger++) {\n addMesh(THREE, elbow, new THREE.BoxGeometry(spec.wo * 0.35, spec.r * 0.03, spec.wc * 0.12), dark, side * (spec.wo + spec.wo * 0.12), 0, -spec.wc * 0.05 - finger * spec.wc * 0.18, 0, side * (0.05 + finger * 0.12), 0)\n }\n }\n if (spec.spur) addMesh(THREE, elbow, new THREE.ConeGeometry(spec.r * 0.06, spec.r * 0.25, 5), tools.material(0xc0302a), 0, 0, spec.wc * 0.2, Math.PI / 2, 0, 0)\n rig.wings.push({ shoulder, elbow, side })\n }\n}\n\nconst buildLegs = (THREE: Three, rig: AnimalRig, spec: BirdSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; leg: THREE_NS.MeshStandardMaterial }): void => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, main, leg } = parts\n for (const side of [-1, 1]) {\n const hip = tools.pivot(bodyGroup, side * spec.r * 0.38, -spec.r * 0.55, spec.r * 0.05, new THREE.Vector3(side * 0.06, -0.05, 0).multiplyScalar(rig.size))\n tools.joint(hip, spec.r * 0.18, main, 0, 0, 0)\n tools.limb(hip, spec.r * 0.16, spec.r * 0.09, spec.shank, spec.featherLeg ? main : leg)\n const ankle = tools.pivot(hip, 0, -spec.shank, 0, new THREE.Vector3(0, -0.04, 0).multiplyScalar(rig.size))\n tools.joint(ankle, spec.r * 0.06, leg, 0, 0, 0)\n tools.limb(ankle, spec.r * 0.055, spec.r * 0.05, spec.tars, leg)\n const foot = tools.pivot(ankle, 0, -spec.tars, 0)\n for (const angle of [-0.45, 0, 0.45]) addMesh(THREE, foot, new THREE.BoxGeometry(spec.r * 0.05, spec.r * 0.04, spec.r * 0.55).translate(0, 0, spec.r * 0.25), leg, 0, -spec.r * 0.02, 0, 0, angle, 0)\n addMesh(THREE, foot, new THREE.BoxGeometry(spec.r * 0.05, spec.r * 0.04, spec.r * 0.25).translate(0, 0, -spec.r * 0.12), leg, 0, -spec.r * 0.02, 0)\n rig.legs.push({ hip, knee: ankle, foot, isFront: false, angle1: 0.35, angle2: -0.5, side })\n }\n}\n\n/** Builds a bird: body, tail, two wings with shoulder and elbow pivots, neck, head with beak and jaw, eyes, the species' extra parts, and two legs. */\nexport const buildBird = (THREE: Three, rig: AnimalRig, options: { extra?: BirdExtra }): AnimalRig => {\n const spec = rig.species.body as BirdSpec\n const tools = createRigTools(THREE, rig)\n const colors = spec.c\n const main = tools.material(colors.main)\n const dark = tools.material(colors.dark)\n const leg = tools.material(colors.leg)\n const beak = tools.material(colors.beak, { roughness: 0.5 })\n const belly = tools.material(colors.belly || colors.main)\n rig.main = main\n const hipY = spec.tars + spec.shank * 0.9\n rig.size = birdSize(spec)\n const bodyGroup = tools.pivot(rig.trunk, 0, hipY + spec.r * 0.55, 0)\n rig.bodyGroup = bodyGroup\n bodyGroup.rotation.x = spec.pitch || 0\n tools.ball(bodyGroup, spec.r, main, 0, 0, 0, spec.s[0], spec.s[1], spec.s[2])\n tools.ball(bodyGroup, spec.r * 0.9, belly, 0, -spec.r * 0.22, spec.r * 0.15, spec.s[0] * 0.9, spec.s[1] * 0.8, spec.s[2] * 0.85)\n const tail = tools.pivot(bodyGroup, 0, spec.r * 0.15, -spec.r * spec.s[2] * 0.85, new THREE.Vector3(0, 0, -0.08).multiplyScalar(rig.size))\n tail.rotation.x = spec.tailA || -0.3\n rig.tailRoot = tail\n addMesh(THREE, tail, new THREE.BoxGeometry(spec.tailW, spec.r * 0.08, spec.tailL).translate(0, 0, -spec.tailL / 2), spec.tailM ? tools.material(spec.tailM) : dark)\n buildWings(THREE, rig, spec, { bodyGroup, main, dark })\n const neck = tools.pivot(bodyGroup, 0, spec.r * 0.45, spec.r * spec.s[2] * 0.75, new THREE.Vector3(0, 0.05, 0.08).multiplyScalar(rig.size))\n neck.rotation.x = spec.neckA\n rig.neck = neck\n rig.neckAngle = spec.neckA\n tools.joint(neck, spec.nr * 1.1, spec.neckM ? tools.material(spec.neckM) : main, 0, 0, 0)\n addMesh(THREE, neck, new THREE.CylinderGeometry(spec.nr * 0.85, spec.nr, spec.nl, 12).translate(0, spec.nl / 2, 0), spec.neckM ? tools.material(spec.neckM) : main)\n const head = tools.pivot(neck, 0, spec.nl, 0, new THREE.Vector3(0, 0.05, 0.05).multiplyScalar(rig.size))\n head.rotation.x = -spec.neckA + (spec.headA || 0)\n rig.head = head\n rig.headAngle = head.rotation.x\n const headMaterial = spec.headM ? tools.material(spec.headM) : main\n tools.ball(head, spec.hr, headMaterial, 0, 0, 0, spec.hs ? spec.hs[0] : 1, spec.hs ? spec.hs[1] : 1, spec.hs ? spec.hs[2] : 1.1)\n addMesh(THREE, head, new THREE.ConeGeometry(spec.br, spec.bl, 8).rotateX(Math.PI / 2).translate(0, 0, spec.bl / 2), beak, 0, -spec.hr * 0.1, spec.hr * 0.85, spec.hook || 0, 0, 0)\n const jaw = tools.pivot(head, 0, -spec.hr * 0.25, spec.hr * 0.8)\n rig.jaw = jaw\n addMesh(THREE, jaw, new THREE.ConeGeometry(spec.br * 0.7, spec.bl * 0.85, 8).rotateX(Math.PI / 2).translate(0, 0, spec.bl * 0.42), beak).scale.set(1, 0.5, 1)\n tools.eyes(head, spec.hr * 0.17, spec.hr * 0.68, spec.hr * 0.2, spec.hr * 0.35)\n if (spec.eyeC && rig.eyeMaterial) {\n rig.eyeMaterial.color.set(spec.eyeC)\n rig.eyeMaterial.userData.base = rig.eyeMaterial.color.clone()\n }\n options.extra?.({ THREE, rig, tools }, { bodyGroup, head, neck, main, dark })\n buildLegs(THREE, rig, spec, { bodyGroup, main, leg })\n return rig\n}\n","import type * as THREE_NS from 'three'\n\nimport type { AnimalRig, AnimalsThreeOptions, Three } from './types'\n\nexport type MaterialExtras = Partial<THREE_NS.MeshStandardMaterialParameters>\n\n/** The mulberry32 stream of the page (`rng`): the same numbers for the same seed. */\nexport const createStream = (seed: number): (() => number) => {\n let state = seed\n return () => {\n state |= 0\n state = (state + 0x6d2b79f5) | 0\n let t = Math.imul(state ^ (state >>> 15), 1 | state)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** The page's `add`: a mesh at a position and rotation under a parent, casting and receiving shadows. */\nexport const addMesh = (\n THREE: Three,\n parent: THREE_NS.Object3D,\n geometry: THREE_NS.BufferGeometry,\n material: THREE_NS.Material,\n x?: number,\n y?: number,\n z?: number,\n rx?: number,\n ry?: number,\n rz?: number,\n): THREE_NS.Mesh => {\n const mesh = new THREE.Mesh(geometry, material)\n mesh.position.set(x || 0, y || 0, z || 0)\n if (rx || ry || rz) mesh.rotation.set(rx || 0, ry || 0, rz || 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n parent.add(mesh)\n return mesh\n}\n\n/** The part builders of the page's `Animal` (`M`, `ball`, `limb`, `joint`, `pivot`), bound to one rig. */\nexport type RigTools = {\n material(color: number, extras?: MaterialExtras): THREE_NS.MeshStandardMaterial\n ball(parent: THREE_NS.Object3D, radius: number, material: THREE_NS.Material, x?: number, y?: number, z?: number, sx?: number, sy?: number, sz?: number): THREE_NS.Mesh\n /** A cylinder hanging from the origin; `radius1` is the one the page calls the top, but the geometry takes it as the bottom (kept as the page has it). */\n limb(parent: THREE_NS.Object3D, radius1: number, radius2: number, length: number, material: THREE_NS.Material): THREE_NS.Mesh\n joint(parent: THREE_NS.Object3D, radius: number, material: THREE_NS.Material, x?: number, y?: number, z?: number): THREE_NS.Mesh\n pivot(parent: THREE_NS.Object3D, x: number, y: number, z: number, offset?: THREE_NS.Vector3): THREE_NS.Group\n eyes(head: THREE_NS.Object3D, radius: number, x: number, y: number, z: number): void\n}\n\nexport const createRigTools = (THREE: Three, rig: AnimalRig): RigTools => {\n const tools: RigTools = {\n material(color, extras) {\n const material = new THREE.MeshStandardMaterial(Object.assign({ color, roughness: 0.8, metalness: 0, flatShading: false }, extras || {}))\n material.userData.base = material.color.clone()\n rig.materials.push(material)\n return material\n },\n ball(parent, radius, material, x, y, z, sx, sy, sz) {\n const mesh = addMesh(THREE, parent, new THREE.SphereGeometry(radius, 16, 12), material, x, y, z)\n if (sx) mesh.scale.set(sx, sy as number, sz as number)\n return mesh\n },\n limb: (parent, radius1, radius2, length, material) => addMesh(THREE, parent, new THREE.CylinderGeometry(radius2, radius1, length, 14, 1).translate(0, -length / 2, 0), material),\n joint(parent, radius, material, x, y, z) {\n const joint = tools.ball(parent, radius, material, x, y, z)\n joint.userData.joint = 1\n rig.joints.push(joint)\n return joint\n },\n pivot(parent, x, y, z, offset) {\n const group = new THREE.Group()\n group.position.set(x, y, z)\n parent.add(group)\n rig.pivots.push({ group, rest: group.position.clone(), offset: offset || new THREE.Vector3() })\n return group\n },\n eyes(head, radius, x, y, z) {\n const eyeMaterial = tools.material(0x111111, { roughness: 0.25 })\n rig.eyeMaterial = eyeMaterial\n for (const side of [-1, 1]) rig.eyes.push(tools.ball(head, radius, eyeMaterial, side * x, y, z))\n },\n }\n return tools\n}\n\nexport const createRig = (THREE: Three, species: AnimalRig['species'], options: AnimalsThreeOptions & { phase: number }): AnimalRig => {\n const rig: AnimalRig = {\n species,\n root: new THREE.Group(),\n trunk: new THREE.Group(),\n materials: [],\n joints: [],\n pivots: [],\n legs: [],\n tail: [],\n ears: [],\n infectionParts: [],\n eyes: [],\n wings: [],\n segments: [],\n phase: options.phase,\n size: 1,\n segmentLength: 0,\n segmentCount: 0,\n home: new THREE.Vector3(),\n infected: false,\n dead: false,\n neckAngle: 0,\n headAngle: 0,\n triangles: 0,\n }\n rig.root.add(rig.trunk)\n return rig\n}\n","import type * as THREE_NS from 'three'\n\nimport { addMesh } from './context'\nimport type { RigTools } from './context'\nimport type { HeadSpecOf, NeckSpecOf } from './extras-types'\nimport type { AnimalRig, Three } from './types'\n\nexport type ExtraContext = { readonly THREE: Three; readonly rig: AnimalRig; readonly tools: RigTools }\n\nexport type QuadrupedParts = {\n readonly bodyGroup: THREE_NS.Group\n readonly head: THREE_NS.Group\n readonly neck: THREE_NS.Group\n readonly main: THREE_NS.MeshStandardMaterial\n readonly belly: THREE_NS.MeshStandardMaterial\n readonly dark: THREE_NS.MeshStandardMaterial\n readonly L: number\n readonly Rb: number\n readonly bodyY: number\n readonly hd: HeadSpecOf\n readonly nk: NeckSpecOf\n}\n\nexport type BirdParts = {\n readonly bodyGroup: THREE_NS.Group\n readonly head: THREE_NS.Group\n readonly neck: THREE_NS.Group\n readonly main: THREE_NS.MeshStandardMaterial\n readonly dark: THREE_NS.MeshStandardMaterial\n}\n\nexport type QuadrupedExtra = (context: ExtraContext, parts: QuadrupedParts) => void\nexport type BirdExtra = (context: ExtraContext, parts: BirdParts) => void\n\nconst cow: QuadrupedExtra = ({ THREE, tools }, k) => {\n tools.ball(k.bodyGroup, 0.2, k.main, 0, k.Rb * 1.1, k.L * 0.33, 0.95, 1.1, 1.1) // hump\n tools.ball(k.neck, 0.13, k.main, 0, 0.12, 0.08, 0.55, 1.4, 1.05) // dewlap\n for (const side of [-1, 1]) addMesh(THREE, k.head, new THREE.ConeGeometry(0.025, 0.13, 8), tools.material(0xcfc6a8), side * 0.12, k.hd.r * 1.05, k.hd.r * 0.05, 0, 0, side * -0.9)\n}\n\nconst horse: QuadrupedExtra = ({ THREE, rig, tools }, k) => {\n for (let index = 0; index < 9; index++) addMesh(THREE, k.neck, new THREE.BoxGeometry(0.035, 0.16, 0.08), k.dark, 0, 0.06 + index * 0.065, -0.12 + index * 0.004, -0.25, 0, 0) // mane\n addMesh(THREE, k.head, new THREE.BoxGeometry(0.03, 0.12, 0.06), k.dark, 0, k.hd.r * 1.05, k.hd.r * 0.3, 0.6, 0, 0) // forelock\n const last = rig.tail[rig.tail.length - 1] as THREE_NS.Group\n tools.ball(last, 0.08, k.dark, 0, -0.42, 0, 0.7, 4.5, 0.7) // tail hair\n}\n\nconst wildBoar: QuadrupedExtra = ({ THREE, tools }, k) => {\n for (let index = 0; index < 12; index++) addMesh(THREE, k.bodyGroup, new THREE.BoxGeometry(0.03, 0.1, 0.06), k.dark, 0, k.Rb * 1.12 - index * 0.004, k.L * 0.38 - index * 0.06, -0.2, 0, 0) // bristles\n for (const side of [-1, 1])\n addMesh(THREE, k.head, new THREE.ConeGeometry(0.012, 0.09, 6), tools.material(0xe8e0cc), side * 0.07, k.hd.r * -0.25 + 0.03, k.hd.r * 0.25 + k.hd.r * k.hd.s[2] * 0.55 + 0.13, -0.6, 0, side * 0.5) // tusks\n}\n\nconst chicken: BirdExtra = ({ tools }, k) => {\n const red = tools.material(0xc0281e)\n for (let index = 0; index < 4; index++) tools.ball(k.head, 0.014, red, 0, 0.045, -0.012 + index * 0.014, 0.5, 1, 0.8) // comb\n tools.ball(k.head, 0.012, red, 0, -0.04, 0.04, 0.5, 1.3, 0.7) // wattle\n}\n\nconst southernLapwing: BirdExtra = ({ THREE, tools }, k) => {\n const black = tools.material(0x161616)\n tools.ball(k.bodyGroup, 0.05, black, 0, 0.03, 0.08, 1.1, 0.9, 0.6) // breast patch\n addMesh(THREE, k.head, new THREE.BoxGeometry(0.006, 0.006, 0.06).translate(0, 0, -0.03), black, 0, 0.025, -0.01, 0.5, 0, 0) // crest\n tools.ball(k.head, 0.026, black, 0, -0.005, 0.02, 1.05, 0.7, 0.9) // cap\n}\n\n/** The parts the page builds with code for five species (the page's `extra` closures), by species id. */\nexport const QUADRUPED_EXTRAS: Readonly<Record<string, QuadrupedExtra>> = { cow, horse, wild_boar: wildBoar }\nexport const BIRD_EXTRAS: Readonly<Record<string, BirdExtra>> = { chicken, southern_lapwing: southernLapwing }\n","import { quadrupedLayout } from '@adatechnology/game-animals'\nimport type { QuadrupedSpec } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport { addMesh, createRigTools } from './context'\nimport { createCoatTexture } from './textures'\nimport { profileGeometry } from './profile'\nimport type { AnimalRig, DocumentLike, Three } from './types'\nimport type { QuadrupedExtra } from './extras'\n\nconst RIB_COUNT = 4\n\ntype LegDefinition = readonly [number, number, 'F' | 'H']\n\nconst LEG_DEFINITIONS: readonly LegDefinition[] = [\n [1, 1, 'F'],\n [-1, 1, 'F'],\n [1, -1, 'H'],\n [-1, -1, 'H'],\n]\n\n/** The body and the four legs of a quadruped (page: the first half of `quad`). */\nconst buildBodyAndLegs = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, main: THREE_NS.MeshStandardMaterial, belly: THREE_NS.MeshStandardMaterial, dark: THREE_NS.MeshStandardMaterial) => {\n const tools = createRigTools(THREE, rig)\n const { L, R: radius } = spec\n const leg = spec.leg\n const layout = quadrupedLayout(spec)\n const { frontHipHeight, hindHipHeight, footHeight, bodyHeight, span } = layout\n const frontAngle1 = leg.fa1 ?? 0.06\n const frontAngle2 = leg.fa2 ?? -0.08\n const hindAngle1 = leg.ha1 ?? -0.32\n const hindAngle2 = leg.ha2 ?? 0.58\n rig.size = layout.size\n const bodyGroup = tools.pivot(rig.trunk, 0, bodyHeight, 0)\n rig.bodyGroup = bodyGroup\n const body = addMesh(THREE, bodyGroup, profileGeometry(THREE, L, spec.prof.map((value) => value * radius)), main)\n body.scale.set(spec.sx || 1, spec.sy || 1, 1)\n body.rotation.x = Math.atan2(hindHipHeight - frontHipHeight, span) * 0.6\n rig.body = body\n const belt = addMesh(THREE, bodyGroup, profileGeometry(THREE, L * 0.8, spec.prof.map((value) => value * 0.8 * radius)), belly)\n belt.scale.set((spec.sx || 1) * 0.92, (spec.sy || 1) * 0.85, 1)\n belt.position.y = -radius * 0.2\n LEG_DEFINITIONS.forEach(([sx, sz, kind]) => {\n const front = kind === 'F'\n const upper = front ? leg.fu : leg.hu\n const lower = front ? leg.fl : leg.hl\n const height = front ? frontHipHeight : hindHipHeight\n const hip = tools.pivot(rig.trunk, sx * radius * (spec.sx || 1) * 0.55, height, (sz * span) / 2, new THREE.Vector3(sx * 0.18, -0.06, sz * 0.12).multiplyScalar(rig.size))\n tools.ball(hip, leg.r * (front ? 1.9 : 2.3), main, 0, -upper * 0.18, front ? 0 : -leg.r * 0.3, 0.75, 1.25, 1)\n tools.joint(hip, leg.r * 1.15, main, 0, 0, 0)\n tools.limb(hip, leg.r * 1.25, leg.r * 0.95, upper, main)\n const knee = tools.pivot(hip, 0, -upper, 0, new THREE.Vector3(0, -0.07 * rig.size, 0))\n tools.joint(knee, leg.r * 0.95, main, 0, 0, 0)\n tools.limb(knee, leg.r * 0.92, leg.r * 0.68, lower, main)\n const foot = tools.pivot(knee, 0, -lower, 0, new THREE.Vector3(0, -0.05 * rig.size, 0))\n if (leg.hoof) {\n tools.joint(foot, leg.r * 0.72, dark, 0, 0, 0)\n addMesh(THREE, foot, new THREE.CylinderGeometry(leg.r * 0.8, leg.r * 1.05, footHeight, 12).translate(0, -footHeight / 2, 0), dark)\n } else {\n tools.joint(foot, leg.r * 0.66, main, 0, 0, 0)\n tools.ball(foot, leg.r * 0.95, leg.dark ? dark : main, 0, -footHeight * 0.55, leg.r * 0.5, 1, 0.62, 1.45)\n }\n rig.legs.push({ hip, knee, foot, isFront: front, angle1: front ? frontAngle1 : hindAngle1, angle2: front ? frontAngle2 : hindAngle2, side: sx })\n })\n return { bodyGroup, bodyHeight }\n}\n\nconst buildHead = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; belly: THREE_NS.MeshStandardMaterial; nose: THREE_NS.MeshStandardMaterial }) => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, main, belly, nose } = parts\n const { L, R: radius } = spec\n const neckSpec = spec.neck\n const headSpec = spec.head\n const neck = tools.pivot(bodyGroup, 0, radius * (spec.sy || 1) * (neckSpec.y ?? 0.35), (L / 2) * (neckSpec.z ?? 0.78), new THREE.Vector3(0, 0.05, 0.12).multiplyScalar(rig.size))\n neck.rotation.x = neckSpec.ang\n rig.neck = neck\n rig.neckAngle = neckSpec.ang\n tools.joint(neck, neckSpec.r * 1.05, main, 0, 0, 0)\n addMesh(THREE, neck, new THREE.CylinderGeometry(neckSpec.r2 || neckSpec.r * 0.85, neckSpec.r, neckSpec.len, 14).translate(0, neckSpec.len / 2, 0), main)\n const head = tools.pivot(neck, 0, neckSpec.len, 0, new THREE.Vector3(0, 0.06, 0.08).multiplyScalar(rig.size))\n head.rotation.x = -neckSpec.ang + (headSpec.down || 0)\n rig.head = head\n rig.headAngle = head.rotation.x\n tools.joint(head, neckSpec.r2 || neckSpec.r * 0.85, main, 0, 0, 0)\n tools.ball(head, headSpec.r, main, 0, headSpec.r * 0.25, headSpec.r * 0.25, headSpec.s[0], headSpec.s[1], headSpec.s[2])\n const snoutZ = headSpec.r * 0.25 + headSpec.r * headSpec.s[2] * 0.55\n const snout = addMesh(THREE, head, new THREE.CylinderGeometry(headSpec.sr2, headSpec.sr1, headSpec.sl, 14).rotateX(Math.PI / 2), headSpec.muzzle ? tools.material(headSpec.muzzle) : main, 0, headSpec.r * (headSpec.sy ?? 0), snoutZ + headSpec.sl / 2)\n snout.scale.set(1, headSpec.sq || 1, 1)\n tools.ball(head, headSpec.sr2 * 1.02, nose, 0, headSpec.r * (headSpec.sy ?? 0) + headSpec.sr2 * 0.1, snoutZ + headSpec.sl, 1, 0.85 * (headSpec.sq || 1), 0.45)\n const jaw = tools.pivot(head, 0, headSpec.r * (headSpec.sy ?? 0) - headSpec.sr1 * 0.55 * (headSpec.sq || 1), snoutZ - headSpec.sr1 * 0.2, new THREE.Vector3(0, -0.04, 0.04).multiplyScalar(rig.size))\n rig.jaw = jaw\n addMesh(THREE, jaw, new THREE.CylinderGeometry(headSpec.sr2 * 0.7, headSpec.sr1 * 0.75, headSpec.sl * 0.92, 12).rotateX(Math.PI / 2).translate(0, 0, headSpec.sl * 0.46), belly).scale.set(1, 0.45, 1)\n const blood = tools.ball(jaw, headSpec.sr2 * 0.9, rig.woundMaterial || (rig.woundMaterial = new THREE.MeshStandardMaterial({ color: 0x6a100c, roughness: 0.3 })), 0, 0.0, headSpec.sl * 0.9, 1.1, 0.6, 0.6)\n tools.eyes(head, headSpec.r * 0.13, headSpec.r * headSpec.s[0] * 0.52, headSpec.r * 0.5, headSpec.r * 0.25 + headSpec.r * headSpec.s[2] * 0.55)\n const ears = spec.ears\n for (const side of [-1, 1]) {\n const earGroup = tools.pivot(head, side * headSpec.r * headSpec.s[0] * 0.55, headSpec.r * (0.25 + headSpec.s[1] * 0.75), headSpec.r * 0.1, new THREE.Vector3(side * 0.04, 0.04, 0).multiplyScalar(rig.size))\n rig.ears.push(earGroup)\n if (ears.t === 'cone') addMesh(THREE, earGroup, new THREE.ConeGeometry(ears.s * 0.45, ears.s, 8).translate(0, ears.s / 2, 0), main, 0, 0, 0, ears.fwd || 0, 0, side * -(ears.tilt ?? 0.3))\n else if (ears.t === 'round') tools.ball(earGroup, ears.s, main, 0, ears.s * 0.4, 0, 1, 1, 0.35)\n else if (ears.t === 'flop') {\n const ear = tools.ball(earGroup, ears.s, main, side * ears.s * 0.9, -ears.s * 0.1, 0, 1.5, 0.45, 0.7)\n ear.rotation.z = side * -0.25\n }\n }\n return { neck, head, blood, neckSpec, headSpec }\n}\n\nconst buildTail = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; dark: THREE_NS.MeshStandardMaterial }): void => {\n const tools = createRigTools(THREE, rig)\n const tailSpec = spec.tail\n if (!tailSpec || !tailSpec.n) return\n const { bodyGroup, main, dark } = parts\n const { L, R: radius } = spec\n let parent = tools.pivot(bodyGroup, 0, radius * (spec.sy || 1) * (tailSpec.y ?? 0.3), (-L / 2) * 0.95, new THREE.Vector3(0, 0.02, -0.12).multiplyScalar(rig.size))\n parent.rotation.x = tailSpec.ang\n rig.tailRoot = parent\n const segmentLength = tailSpec.len / tailSpec.n\n for (let index = 0; index < tailSpec.n; index++) {\n const radius1 = tailSpec.r * (1 - (index / tailSpec.n) * 0.6)\n const radius2 = tailSpec.r * (1 - ((index + 1) / tailSpec.n) * 0.6)\n tools.limb(parent, radius1, radius2, segmentLength, tailSpec.dark && index === tailSpec.n - 1 ? dark : main)\n tools.joint(parent, radius1, main, 0, 0, 0)\n rig.tail.push(parent)\n if (index < tailSpec.n - 1) {\n const next = tools.pivot(parent, 0, -segmentLength, 0)\n next.rotation.x = tailSpec.curl || 0\n parent = next\n } else if (tailSpec.tuft) tools.ball(parent, tailSpec.r * 2.2, dark, 0, -segmentLength - tailSpec.r, 0, 1, 1.8, 1)\n }\n if (tailSpec.bushy) tools.ball(rig.tail[0] as THREE_NS.Group, tailSpec.r * 2.2, dark, 0, -tailSpec.len * 0.55, 0, 1, (tailSpec.len * 2.2) / tailSpec.r / 6, 1)\n}\n\n/** Wounds, ribs and the blood of the jaw: shown only while the animal is infected (page: the end of `quad`). */\nconst buildInfectionParts = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, parts: { bodyGroup: THREE_NS.Group; neck: THREE_NS.Group; blood: THREE_NS.Mesh; neckSpec: QuadrupedSpec['neck'] }): void => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, neck, blood, neckSpec } = parts\n const { L, R: radius } = spec\n const sideX = radius * (spec.sx || 1)\n const sideY = radius * (spec.sy || 1)\n const list: THREE_NS.Object3D[] = [blood]\n const wound = (parent: THREE_NS.Object3D, size: number, x: number, y: number, z: number, sx: number, sy: number, sz: number): THREE_NS.Mesh =>\n tools.ball(parent, size, rig.woundMaterial || (rig.woundMaterial = new THREE.MeshStandardMaterial({ color: 0x5a120e, roughness: 0.45 })), x, y, z, sx || 1, sy || 1, sz || 1)\n list.push(wound(bodyGroup, radius * 0.28, sideX * 0.92, sideY * 0.15, L * 0.05, 0.35, 1, 1.3))\n list.push(wound(bodyGroup, radius * 0.2, -sideX * 0.9, sideY * 0.3, -L * 0.2, 0.35, 1, 1.1))\n list.push(wound(neck, neckSpec.r * 0.5, neckSpec.r * 0.85, neckSpec.len * 0.5, 0, 0.4, 1, 1))\n const bone = tools.material(0xd9cfb8, { roughness: 0.6 })\n for (let index = 0; index < RIB_COUNT; index++) {\n const rib = addMesh(THREE, bodyGroup, new THREE.TorusGeometry(radius * 0.95, radius * 0.035, 6, 16, Math.PI * 0.42), bone, sideX * 0.12, sideY * 0.05, L * 0.12 - index * L * 0.07, 0, Math.PI / 2, -0.3)\n rib.scale.set(1, 1.02 * (spec.sy || 1), spec.sx || 1)\n list.push(rib)\n }\n rig.infectionParts.push(...list)\n list.forEach((part) => (part.visible = false))\n}\n\n/** Builds a quadruped: body, four legs on hip-knee-foot pivots, neck, head with jaw and eyes, ears, tail, the species' extra parts, and the infection parts. */\nexport const buildQuadruped = (THREE: Three, rig: AnimalRig, options: { document: DocumentLike; extra?: QuadrupedExtra }): AnimalRig => {\n const spec = rig.species.body as QuadrupedSpec\n const tools = createRigTools(THREE, rig)\n const colors = spec.c\n const texture = spec.texture ? createCoatTexture(THREE, options.document, spec.texture) : undefined\n const main = tools.material(texture ? 0xffffff : colors.main, texture ? { map: texture } : undefined)\n const belly = tools.material(colors.belly)\n const dark = tools.material(colors.dark)\n const nose = tools.material(colors.nose || colors.dark, { roughness: 0.4 })\n rig.main = main\n rig.dark = dark\n const { bodyGroup, bodyHeight } = buildBodyAndLegs(THREE, rig, spec, main, belly, dark)\n const { neck, head, blood, neckSpec, headSpec } = buildHead(THREE, rig, spec, { bodyGroup, main, belly, nose })\n buildTail(THREE, rig, spec, { bodyGroup, main, dark })\n options.extra?.({ THREE, rig, tools }, { bodyGroup, head, neck, main, belly, dark, L: spec.L, Rb: spec.R, bodyY: bodyHeight, hd: headSpec, nk: neckSpec })\n if (rig.species.outcome === 'turns') buildInfectionParts(THREE, rig, spec, { bodyGroup, neck, blood, neckSpec })\n else blood.visible = false\n return rig\n}\n","import type { TextureMarker } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport { createStream } from './context'\nimport type { CanvasLike, DocumentLike, Three } from './types'\n\ntype Painter = {\n fillStyle: string\n strokeStyle: string\n lineWidth: number\n fillRect(x: number, y: number, width: number, height: number): void\n beginPath(): void\n arc(x: number, y: number, radius: number, from: number, to: number): void\n stroke(): void\n fill(): void\n}\n\nconst canvasTexture = (THREE: Three, document: DocumentLike, width: number, height: number, draw: (painter: Painter, width: number, height: number) => void): THREE_NS.CanvasTexture => {\n const canvas: CanvasLike = document.createElement('canvas')\n canvas.width = width\n canvas.height = height\n draw(canvas.getContext('2d') as Painter, width, height)\n const texture = new THREE.CanvasTexture(canvas as unknown as HTMLCanvasElement)\n texture.colorSpace = THREE.SRGBColorSpace\n return texture\n}\n\nconst spotsTexture = (THREE: Three, document: DocumentLike, base: string, spot: string): THREE_NS.CanvasTexture =>\n canvasTexture(THREE, document, 256, 256, (painter, width, height) => {\n painter.fillStyle = base\n painter.fillRect(0, 0, width, height)\n const next = createStream(11)\n for (let index = 0; index < 70; index++) {\n const x = next() * width\n const y = next() * height\n const radius = 5 + next() * 7\n painter.strokeStyle = spot\n painter.lineWidth = 3\n painter.beginPath()\n painter.arc(x, y, radius, 0, 7)\n painter.stroke()\n painter.fillStyle = 'rgba(120,70,20,.45)'\n painter.beginPath()\n painter.arc(x, y, radius * 0.6, 0, 7)\n painter.fill()\n }\n for (let index = 0; index < 60; index++) {\n painter.fillStyle = spot\n painter.beginPath()\n painter.arc(next() * width, next() * height, 1.5 + next() * 2.5, 0, 7)\n painter.fill()\n }\n })\n\nconst stripesTexture = (THREE: Three, document: DocumentLike, base: string, stripe: string): THREE_NS.CanvasTexture =>\n canvasTexture(THREE, document, 128, 128, (painter, width) => {\n painter.fillStyle = base\n painter.fillRect(0, 0, width, 128)\n painter.fillStyle = stripe\n for (let index = 0; index < 9; index++) painter.fillRect(0, index * 14 + (index % 2) * 3, width, 4)\n })\n\n/** The coat texture a species spec asks for (cat stripes, jaguar rosettes), painted on a canvas. */\nexport const createCoatTexture = (THREE: Three, document: DocumentLike, marker: TextureMarker): THREE_NS.CanvasTexture =>\n marker.kind === 'stripes' ? stripesTexture(THREE, document, marker.base, marker.stripe) : spotsTexture(THREE, document, marker.base, marker.spot)\n","import type * as THREE_NS from 'three'\n\nimport type { Three } from './types'\n\n/** A body of revolution whose radius follows `profile` along the length, rear to front, closed by a point at each end. */\nexport const profileGeometry = (THREE: Three, length: number, profile: readonly number[], segments?: number): THREE_NS.LatheGeometry => {\n const points = profile.map((radius, index) => new THREE.Vector2(index / (profile.length - 1), radius))\n const curve = new THREE.SplineCurve(points)\n const outline: THREE_NS.Vector2[] = []\n outline.push(new THREE.Vector2(0.001, -length / 2 - 0.0))\n for (let step = 0; step <= 30; step++) {\n const point = curve.getPoint(step / 30)\n outline.push(new THREE.Vector2(Math.max(0.001, point.y), -length / 2 + point.x * length))\n }\n outline.push(new THREE.Vector2(0.001, length / 2))\n return new THREE.LatheGeometry(outline, segments || 22).rotateX(Math.PI / 2)\n}\n","import { addMesh, createRigTools } from './context'\nimport type { AnimalRig, Three } from './types'\n\nconst SEGMENT_COUNT = 34\nconst SEGMENT_LENGTH = 0.042\n\n/** Builds a snake: 34 spheres on their own groups along the trunk (the animation lays them on a path), a head with a jaw and a tongue. */\nexport const buildSnake = (THREE: Three, rig: AnimalRig): AnimalRig => {\n const tools = createRigTools(THREE, rig)\n rig.size = 0.5\n rig.segmentLength = SEGMENT_LENGTH\n rig.segmentCount = SEGMENT_COUNT\n const primary = tools.material(0x7a6a4a)\n const secondary = tools.material(0x3a2e22)\n const belly = tools.material(0xb8a888)\n rig.main = primary\n for (let index = 0; index < SEGMENT_COUNT; index++) {\n const t = index / (SEGMENT_COUNT - 1)\n const radius = 0.012 + 0.03 * Math.sin(Math.min(1, t * 1.15) * Math.PI) * (t < 0.1 ? 0.75 + t * 2.5 : 1) + (t < 0.05 ? 0.012 : 0)\n const material = index % 4 === 1 || index % 4 === 2 ? secondary : primary\n const group = new THREE.Group()\n rig.trunk.add(group)\n const sphere = tools.ball(group, radius, material, 0, radius, 0, 1, 0.78, 1.5)\n sphere.userData.joint = index % 3 === 0 ? 1 : 0\n if (index % 3 === 0) rig.joints.push(sphere)\n rig.segments.push({ group, radius })\n }\n const head = new THREE.Group()\n rig.trunk.add(head)\n rig.head = head\n tools.ball(head, 0.032, primary, 0, 0.03, 0.025, 1.25, 0.6, 1.45)\n tools.ball(head, 0.024, secondary, 0, 0.04, 0.0, 1.3, 0.4, 0.9)\n tools.ball(head, 0.02, primary, 0, 0.028, 0.06, 0.85, 0.55, 1.1)\n const jaw = new THREE.Group()\n jaw.position.set(0, 0.018, 0.0)\n head.add(jaw)\n rig.jaw = jaw\n tools.ball(jaw, 0.026, belly, 0, 0, 0.035, 1.1, 0.35, 1.5)\n tools.eyes(head, 0.006, 0.03, 0.04, 0.045)\n rig.tongue = addMesh(THREE, head, new THREE.BoxGeometry(0.004, 0.002, 0.05), tools.material(0xb02020), 0, 0.024, 0.1)\n return rig\n}\n","import type { AnimalVisualState } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport type { AnimalRig, Three } from './types'\n\nconst INFECTED_TINT = 0x7d8a66\nconst POOL_COLOR = 0x3a0806\n\n/**\n * Applies a visual state (page: `setInfected`, with the dead look for every species): infected greys the coat, glows the eyes, shows the wounds and hides\n * the first ear; dead lets the animation lay the body down and shows a blood pool at `home`. The pool goes under `rig.root.parent`; with no parent yet,\n * it is created hidden from the scene and `rig.pool` is for the caller to add.\n */\nexport const applyVisualState = (THREE: Three, rig: AnimalRig, state: AnimalVisualState): void => {\n rig.infected = state === 'infected'\n rig.dead = state === 'dead'\n const tint = new THREE.Color(INFECTED_TINT)\n rig.materials.forEach((material) => {\n if (material === rig.eyeMaterial || material === rig.woundMaterial) return\n material.color.copy(material.userData.base as THREE_NS.Color)\n if (rig.infected) material.color.lerp(tint, 0.45).multiplyScalar(0.72)\n })\n const eye = rig.eyeMaterial\n if (eye) {\n if (rig.infected) {\n eye.color.set(0xdcd8b0)\n eye.emissive = new THREE.Color(0x8a8660)\n eye.emissiveIntensity = 0.8\n } else {\n eye.color.copy(eye.userData.base as THREE_NS.Color)\n eye.emissive = new THREE.Color(0)\n }\n }\n rig.infectionParts.forEach((part) => (part.visible = rig.infected))\n const firstEar = rig.ears[0]\n if (firstEar) firstEar.visible = !rig.infected\n if (!rig.dead) {\n rig.root.rotation.z = 0\n rig.root.position.y = 0\n }\n if (rig.pool) {\n rig.pool.visible = rig.dead\n return\n }\n if (!rig.dead) return\n const pool = new THREE.Mesh(new THREE.CircleGeometry(1, 22).rotateX(-Math.PI / 2), new THREE.MeshStandardMaterial({ color: POOL_COLOR, roughness: 0.25 }))\n pool.position.set(rig.home.x, 0.005, rig.home.z + 0.1)\n pool.receiveShadow = true\n pool.scale.setScalar(rig.size * 0.45)\n rig.root.parent?.add(pool)\n rig.pool = pool\n}\n","import type * as THREE_NS from 'three'\n\nimport type { AnimalRig } from './types'\n\n/** The \"joints\" view (page: `setJoint`): the coat turns see-through and every joint ball shows in `jointMaterial`. */\nexport const setJointView = (rig: AnimalRig, on: boolean, jointMaterial: THREE_NS.Material): void => {\n rig.materials.forEach((material) => {\n if (material === rig.eyeMaterial) return\n material.transparent = on\n material.opacity = on ? 0.28 : 1\n material.depthWrite = !on\n material.needsUpdate = true\n })\n rig.joints.forEach((joint) => {\n if (on) joint.userData.restMaterial ??= joint.material\n joint.material = on ? jointMaterial : (joint.userData.restMaterial as THREE_NS.Material)\n joint.renderOrder = on ? 2 : 0\n })\n}\n\n/** The \"split\" view (page: `setSplit`): sets where each pivot should go, the rest position or the rest plus its offset; `updateSplit` moves it there. */\nexport const setSplit = (rig: AnimalRig, on: boolean): void => {\n rig.pivots.forEach((pivot) => {\n pivot.group.userData.target = on ? pivot.rest.clone().add(pivot.offset) : pivot.rest.clone()\n })\n}\n\n/** Moves each pivot toward its split target (the page does it in the frame loop: a lerp of 5 per second). */\nexport const updateSplit = (rig: AnimalRig, delta: number): void => {\n rig.pivots.forEach((pivot) => {\n const target = pivot.group.userData.target as THREE_NS.Vector3 | undefined\n if (target) pivot.group.position.lerp(target, Math.min(1, delta * 5))\n })\n}\n","import { lineUpLength } from '@adatechnology/game-animals'\n\nimport type { AnimalRig } from './types'\n\nexport type LineUpOptions = {\n /** X where the row starts (page: -19). */\n readonly start?: number\n /** Gap between animals (page: 0.85). */\n readonly gap?: number\n /** Heading of the animals, radians (page: 1.1; snakes 2.2). */\n readonly yaw?: number\n readonly snakeYaw?: number\n}\n\n/** Puts the animals in a row on the x axis, each given room by its length, the row centred on the origin, and keeps each place as `home` (page: the line-up). */\nexport const lineUpAnimals = (rigs: readonly AnimalRig[], options: LineUpOptions = {}): void => {\n const start = options.start ?? -19\n const gap = options.gap ?? 0.85\n let cursor = start\n for (const rig of rigs) {\n const length = lineUpLength(rig.species.body)\n cursor += length / 2\n rig.root.position.set(cursor, 0, 0)\n rig.home = rig.root.position.clone()\n rig.root.rotation.y = rig.species.body.kind === 'snake' ? (options.snakeYaw ?? 2.2) : (options.yaw ?? 1.1)\n cursor += length / 2 + gap\n }\n const offset = -(cursor - gap + start) / 2\n for (const rig of rigs) {\n rig.root.position.x += offset\n rig.home.x += offset\n }\n}\n","import { lineUpLength, visualStateOf } from '@adatechnology/game-animals'\nimport type { AnimalSpecies, AnimalVisualState } from '@adatechnology/game-animals'\nimport type { BenchChange, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ModuleScenario, TestableItem, TestableModule } from '@adatechnology/game-contracts'\nimport type { NodeSkin } from '@adatechnology/game-props3d'\nimport type * as THREE_NS from 'three'\n\nimport { createAnimalsThree } from '../index'\nimport type { AnimalsThree } from '../index'\nimport type { AnimalRig, Three } from '../types'\nimport { createScenarios } from './scenarios'\nimport type { AnimalsContext, ScenarioDeps } from './scenarios'\nimport { TEXT } from './text'\nimport type { AnimalsTestOptions, OutbreakLike } from './types'\n\nexport const ANIMALS_AREA_ID = 'animals_area'\nexport const ANIMAL_ITEM_PREFIX = 'animal_'\nconst SKIN_COUNT = 40\nconst SKIN_FIELD = { x0: -18, z0: -10, columns: 8, gap: 4.5 }\nconst DEFAULT_TIME_SCALE = 60\n\ntype Fate = NonNullable<ReturnType<OutbreakLike['bite']>>\ntype Placed = { readonly id: string; readonly rig: AnimalRig; fate?: Fate; counted?: 'turned' | 'dead' }\n\n/**\n * The animals test area as a `TestableModule`: the species of the pack in a row, each drawn by the Bichos do Vale builders, with the alive / infected / dead looks, the gait,\n * the joints and split views, the rings for how far its sound carries and how far a carcass lures, the outbreak rule with an accelerated bite clock, and a field of 40 animals\n * drawn as node skins. The species and the outbreak rule come in by option, so this package knows no game.\n */\nexport function createAnimalsTestModule(options: AnimalsTestOptions = {}): TestableModule<AnimalsContext> & { readonly placed: ReadonlyMap<string, unknown> } {\n const locale = options.locale ?? 'pt-BR'\n const text = TEXT[locale] ?? (TEXT['pt-BR'] as (typeof TEXT)[string])\n const species = options.species ?? []\n const settings = { visual: 'alive' as AnimalVisualState, gait: 'walk', speed: 1, outbreak: true, timeScale: DEFAULT_TIME_SCALE }\n let three: Three | null = null\n let animals: AnimalsThree | null = null\n let host: ModuleHost | null = null\n let outbreak: OutbreakLike | null = null\n let time = 0\n let clock = 0\n let skinGroup: THREE_NS.Group | null = null\n let skins: { rig: AnimalRig; skin: NodeSkin }[] = []\n let rings: THREE_NS.Object3D[] = []\n const placed = new Map<string, Placed>()\n const random = (): number => 0.5\n const drawSeed = options.seed ?? 7\n const bitten = () => ({ turned: [...placed.values()].filter((p) => p.counted === 'turned').length, dead: [...placed.values()].filter((p) => p.counted === 'dead').length })\n\n const ensure = (THREE: Three): AnimalsThree => {\n three = THREE\n animals ??= createAnimalsThree(THREE, { seed: drawSeed, ...(options.document ? { document: options.document } : {}) })\n return animals\n }\n const rebuildOutbreak = (): void => {\n outbreak = options.createOutbreak ? options.createOutbreak({ species, enabled: settings.outbreak, timeScale: settings.timeScale }) : null\n }\n rebuildOutbreak()\n\n const item = (animal: AnimalSpecies): TestableItem => ({\n id: `${ANIMAL_ITEM_PREFIX}${animal.id}`,\n name: animal.name[locale as 'en'] ?? animal.id,\n movable: false,\n build: (THREE: unknown) => {\n const rig = ensure(THREE as Three).build(animal)\n // the room puts the tree in its scene right after this; trees that never reach it are dropped at the next frame\n placed.set(rig.root.uuid, { id: rig.root.uuid, rig })\n if (settings.visual !== 'alive') animals?.setVisualState(rig, settings.visual)\n return rig.root\n },\n })\n\n const statusOf = (entry: Placed): void => {\n if (!entry.fate || !outbreak) return\n const state = outbreak.stateOf(entry.fate, clock)\n if (state === 'incubating') return\n entry.counted = state === 'turned' ? 'turned' : 'dead'\n animals?.setVisualState(entry.rig, visualStateOf(entry.rig.species.outcome, true, state === 'dead'))\n }\n\n const clearRings = (): void => {\n for (const ring of rings) ring.parent?.remove(ring)\n rings = []\n }\n const refreshLayers = (): void => {\n if (!host?.bench || !animals || !three) return\n clearRings()\n for (const entry of placed.values()) {\n animals.setJointView(entry.rig, host.bench.layer('joints'))\n animals.setSplit(entry.rig, host.bench.layer('split'))\n }\n const ring = (radius: number, color: number, parent: THREE_NS.Object3D): void => {\n const mesh = new (three as Three).Mesh(new (three as Three).RingGeometry(radius - 0.15, radius, 96).rotateX(-Math.PI / 2), new (three as Three).MeshBasicMaterial({ color, transparent: true, opacity: 0.55, depthWrite: false }))\n mesh.position.y = 0.03\n parent.add(mesh)\n rings.push(mesh)\n }\n for (const entry of placed.values()) {\n if (!entry.rig.root.parent) continue\n const radius = entry.rig.species.soundRangeMetres\n if (host.bench.layer('sound_range') && radius) ring(radius, 0x44aaff, entry.rig.root)\n const lure = entry.rig.species.outbreak?.carcass?.lureRadiusMetres\n if (host.bench.layer('carcass_lure') && lure) ring(lure, 0xff5533, entry.rig.root)\n }\n }\n\n const addSkins = (): void => {\n if (!animals || !three || !host) return\n skinGroup ??= new three.Group()\n if (!skinGroup.parent) (host.scene as THREE_NS.Object3D).add(skinGroup)\n for (let index = skins.length; index < SKIN_COUNT; index++) {\n const animal = species[index % Math.max(1, species.length)] as AnimalSpecies\n const rig = animals.build(animal)\n const skin = animals.createSkin(rig)\n rig.root.position.set(SKIN_FIELD.x0 + (index % SKIN_FIELD.columns) * SKIN_FIELD.gap, 0, SKIN_FIELD.z0 - Math.floor(index / SKIN_FIELD.columns) * SKIN_FIELD.gap)\n // the tree still drives the animation, but only the skin is drawn\n rig.root.traverse((object) => {\n if ((object as THREE_NS.Mesh).isMesh) object.visible = false\n })\n skinGroup.add(rig.root, skin.mesh)\n skins.push({ rig, skin })\n }\n }\n const clearSkins = (): void => {\n skinGroup?.parent?.remove(skinGroup)\n skinGroup = null\n skins = []\n }\n\n const applyVisual = (): void => {\n for (const entry of placed.values()) {\n if (entry.fate) continue\n animals?.setVisualState(entry.rig, settings.visual)\n }\n }\n\n const onChange = (change: BenchChange): void => {\n if (change.kind === 'layer') return refreshLayers()\n if (change.kind === 'action') {\n if (change.id === 'bite_all') {\n for (const entry of placed.values()) {\n entry.fate = outbreak?.bite(entry.rig.species.id, random, clock)\n if (entry.fate) animals?.setVisualState(entry.rig, visualStateOf(entry.rig.species.outcome, true))\n }\n } else if (change.id === 'recover') {\n for (const entry of placed.values()) {\n delete entry.fate\n delete entry.counted\n animals?.setVisualState(entry.rig, settings.visual)\n }\n } else if (change.id === 'skin_40') addSkins()\n else if (change.id === 'clear_skins') clearSkins()\n return\n }\n switch (change.id) {\n case 'visual_state': settings.visual = String(change.value) as AnimalVisualState; applyVisual(); break\n case 'gait': settings.gait = String(change.value); break\n case 'speed': settings.speed = Number(change.value); break\n case 'outbreak': settings.outbreak = Boolean(change.value); if (outbreak) outbreak.enabled = settings.outbreak; break\n case 'time_scale': settings.timeScale = Number(change.value); rebuildOutbreak(); break\n default: break\n }\n }\n\n const frame = (dt: number): void => {\n time += dt * settings.speed\n clock += dt\n for (const [id, entry] of placed) {\n if (!entry.rig.root.parent) {\n placed.delete(id)\n continue\n }\n statusOf(entry)\n animals?.animate(entry.rig, { time, delta: dt * settings.speed, clip: settings.gait, split: host?.bench?.layer('split') ?? false })\n animals?.updateSplit(entry.rig, dt)\n }\n for (const { rig, skin } of skins) {\n animals?.animate(rig, { time, delta: dt * settings.speed, clip: settings.gait })\n rig.root.updateMatrixWorld(true)\n skin.update()\n }\n }\n\n const countMeshes = (only?: 'skins'): { drawCalls: number; triangles: number } => {\n let drawCalls = 0\n let triangles = 0\n const count = (root: THREE_NS.Object3D): void =>\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh || !mesh.visible) return\n drawCalls += 1\n const geometry = mesh.geometry\n triangles += geometry.index ? geometry.index.count / 3 : geometry.attributes.position.count / 3\n })\n if (only !== 'skins') for (const entry of placed.values()) count(entry.rig.root)\n for (const { skin } of skins) count(skin.mesh)\n return { drawCalls, triangles: Math.round(triangles) }\n }\n\n const deps: ScenarioDeps = {\n text: text.scenarios,\n species: () => species,\n ensure: () => ensure((three ?? host?.THREE) as Three),\n outbreak: () => outbreak,\n rebuildOutbreak: (enabled) => {\n settings.outbreak = enabled\n rebuildOutbreak()\n return outbreak\n },\n skins: () => {\n ensure((three ?? host?.THREE) as Three)\n addSkins()\n return { count: skins.length, meshes: countMeshes('skins'), nodes: skins[0]?.skin.nodes.length ?? 0, rich: skins[0]?.rig.triangles ?? 0 }\n },\n clearSkins,\n }\n\n return {\n id: ANIMALS_AREA_ID,\n name: text.name,\n group: text.group,\n get placed() {\n return placed\n },\n items: () => species.map(item),\n area: (): ModuleArea => {\n // the page's line-up: each animal given room by its length (and a gap), the row centred on the origin\n const gap = 0.85\n let cursor = 0\n const spots = species.map((animal) => {\n const length = lineUpLength(animal.body)\n const x = cursor + length / 2\n cursor += length + gap\n return { animal, x }\n })\n const offset = -(cursor - gap) / 2\n return {\n placements: spots.map(({ animal, x }) => ({ item: `${ANIMAL_ITEM_PREFIX}${animal.id}`, position: [x + offset, 0, 0], rotationY: animal.body.kind === 'snake' ? 2.2 : 1.1 })),\n view: { eye: [0, 4, Math.max(10, (cursor - gap) * 0.55)], target: [0, 0.6, 0] },\n }\n },\n controls: (): ModuleControl[] => [\n { kind: 'choice', id: 'visual_state', name: text.controls.visual_state, hint: text.hints.visual_state, options: (['alive', 'infected', 'dead'] as const).map((id) => ({ id, name: text.options.visual_state[id] as string })), default: 'alive' },\n { kind: 'choice', id: 'gait', name: text.controls.gait, hint: text.hints.gait, options: (['idle', 'walk', 'run'] as const).map((id) => ({ id, name: text.options.gait[id] as string })), default: 'walk' },\n { kind: 'number', id: 'speed', name: text.controls.speed, min: 0, max: 4, step: 0.25, default: 1 },\n { kind: 'boolean', id: 'outbreak', name: text.controls.outbreak, hint: text.hints.outbreak, default: true },\n { kind: 'number', id: 'time_scale', name: text.controls.time_scale, hint: text.hints.time_scale, min: 1, max: 600, step: 1, default: DEFAULT_TIME_SCALE },\n { kind: 'action', id: 'bite_all', name: text.actions.bite_all },\n { kind: 'action', id: 'recover', name: text.actions.recover },\n { kind: 'action', id: 'skin_40', name: text.actions.skin_40 },\n { kind: 'action', id: 'clear_skins', name: text.actions.clear_skins },\n ],\n layers: (): ModuleLayer[] => (['joints', 'split', 'sound_range', 'carcass_lure'] as const).map((id) => ({ id, name: text.layers[id], default: false })),\n metrics: (): ModuleMetric[] => [\n { id: 'animals', name: text.metrics.animals, read: () => placed.size + skins.length },\n { id: 'draw_calls', name: text.metrics.draw_calls, read: () => countMeshes().drawCalls },\n { id: 'triangles', name: text.metrics.triangles, read: () => countMeshes().triangles },\n { id: 'nodes_per_skin', name: text.metrics.nodes_per_skin, read: () => skins[0]?.skin.nodes.length ?? 0 },\n { id: 'incubating', name: text.metrics.incubating, read: () => [...placed.values()].filter((p) => p.fate && !p.counted).length },\n { id: 'turned', name: text.metrics.turned, read: () => bitten().turned },\n { id: 'dead', name: text.metrics.dead, read: () => bitten().dead },\n ],\n scenarios: (): ModuleScenario<AnimalsContext>[] => createScenarios(deps),\n attach(lent) {\n host = lent\n ensure(lent.THREE as Three)\n const stopChange = lent.bench?.onChange(onChange)\n const stopFrame = lent.onFrame(frame)\n return () => {\n stopChange?.()\n stopFrame()\n clearRings()\n clearSkins()\n host = null\n }\n },\n }\n\n}\n","import { visualStateOf } from '@adatechnology/game-animals'\nimport type { AnimalSpecies } from '@adatechnology/game-animals'\nimport type { ModuleScenario } from '@adatechnology/game-contracts'\n\nimport type { AnimalsThree } from '../index'\nimport type { OutbreakLike } from './types'\n\n/** What a scenario needs of the room: the pass/fail line and time. The test room's `ScenarioContext` has both. */\nexport type AnimalsContext = { expect(condition: boolean, label: string, data?: Record<string, unknown>): void; step(seconds: number): void }\n\nexport type ScenarioDeps = {\n readonly text: Readonly<Record<string, string>>\n species(): readonly AnimalSpecies[]\n ensure(): AnimalsThree\n outbreak(): OutbreakLike | null\n rebuildOutbreak(enabled: boolean): OutbreakLike | null\n skins(): { count: number; meshes: { drawCalls: number; triangles: number }; nodes: number; rich: number }\n clearSkins(): void\n}\n\nconst SKIN_COUNT = 40\n\nexport const createScenarios = (deps: ScenarioDeps): ModuleScenario<AnimalsContext>[] => {\n const scenario = (id: string, run: ModuleScenario<AnimalsContext>['run']): ModuleScenario<AnimalsContext> => ({ id, name: deps.text[id] ?? id, run })\n const rate = () => 0.5\n return [\n scenario('visual_states', ({ expect }) => {\n const animals = deps.ensure()\n for (const species of deps.species()) {\n const rig = animals.build(species)\n animals.setVisualState(rig, 'infected')\n expect(rig.infected && !rig.dead, `${species.id}: infected`)\n animals.setVisualState(rig, 'dead')\n expect(rig.dead && !rig.infected, `${species.id}: dead`)\n animals.setVisualState(rig, 'alive')\n expect(!rig.dead && !rig.infected, `${species.id}: alive again`)\n }\n }),\n scenario('gait_moves_legs', ({ expect }) => {\n const animals = deps.ensure()\n const species = deps.species().find((entry) => entry.body.kind === 'quadruped')\n if (!species) return expect(false, 'no quadruped among the species')\n const rig = animals.build(species)\n animals.animate(rig, { time: 0, delta: 0, clip: 'walk' })\n const before = rig.legs.map((leg) => leg.hip.rotation.x)\n animals.animate(rig, { time: 0.4, delta: 0.4, clip: 'walk' })\n expect(rig.legs.some((leg, index) => leg.hip.rotation.x !== before[index]), `${species.id}: a walk step swings a hip`)\n }),\n scenario('outbreak_rule', ({ expect }) => {\n const turns = deps.species().find((entry) => entry.outcome === 'turns')\n const immune = deps.species().find((entry) => entry.outcome === 'immune')\n const on = deps.rebuildOutbreak(true)\n if (!on || !turns) return expect(false, 'no outbreak rule or no species that turns')\n expect(on.bite(turns.id, rate, 0) !== undefined, `a bite on ${turns.id} starts a fate with the rule on`)\n if (immune) expect(on.bite(immune.id, rate, 0) === undefined, `${immune.id} shrugs the bite off`)\n const off = deps.rebuildOutbreak(false)\n expect(off?.bite(turns.id, rate, 0) === undefined, 'with the rule off a bite does nothing')\n deps.rebuildOutbreak(true)\n }),\n scenario('carcass_lure', ({ expect }) => {\n const outbreak = deps.rebuildOutbreak(true)\n const dies = deps.species().find((entry) => entry.outbreak?.carcass)\n if (!outbreak || !dies) return expect(false, 'no outbreak rule or no species that leaves a carcass')\n const carcass = outbreak.carcass(dies.id, [0, 0, 0], 0)\n expect(carcass !== undefined, `${dies.id} leaves a carcass`)\n if (!carcass) return\n expect(outbreak.lures(carcass, carcass.lureRadiusMetres - 1, 1), 'a zombie inside the radius is drawn')\n expect(!outbreak.lures(carcass, carcass.lureRadiusMetres + 1, 1), 'a zombie outside it is not')\n }),\n scenario('bite_to_turn_timer', ({ expect }) => {\n const outbreak = deps.rebuildOutbreak(true)\n const turns = deps.species().find((entry) => entry.outcome === 'turns')\n if (!outbreak || !turns) return expect(false, 'no outbreak rule or no species that turns')\n const fate = outbreak.bite(turns.id, rate, 0)\n if (!fate) return expect(false, 'the bite took')\n expect(outbreak.stateOf(fate, 0) === 'incubating', 'it incubates at first')\n expect(outbreak.stateOf(fate, fate.dueAt + 1) === 'turned', 'it has turned once the time is up (the bench clock runs it accelerated)')\n expect(visualStateOf(turns.outcome, true) === 'infected', 'and shows the infected look')\n }),\n scenario('skins_40', ({ expect }) => {\n const result = deps.skins()\n expect(result.count === SKIN_COUNT, `${SKIN_COUNT} animals are in the field`, { count: result.count })\n expect(result.meshes.drawCalls <= SKIN_COUNT + 16, 'the skins are about one draw call each', result.meshes)\n expect(result.nodes > 0, 'each skin keeps the nodes the animation moves', { nodes: result.nodes })\n deps.clearSkins()\n }),\n ]\n}\n","export type AnimalsText = {\n group: string\n name: string\n controls: Record<'visual_state' | 'gait' | 'speed' | 'outbreak' | 'time_scale', string>\n hints: Record<'visual_state' | 'gait' | 'outbreak' | 'time_scale', string>\n options: { visual_state: Record<string, string>; gait: Record<string, string> }\n actions: Record<'bite_all' | 'recover' | 'skin_40' | 'clear_skins', string>\n layers: Record<'joints' | 'split' | 'sound_range' | 'carcass_lure', string>\n metrics: Record<'animals' | 'draw_calls' | 'triangles' | 'nodes_per_skin' | 'incubating' | 'turned' | 'dead', string>\n scenarios: Record<string, string>\n}\n\nexport const TEXT: Record<string, AnimalsText> = {\n en: {\n group: 'Animals',\n name: 'Animals area',\n controls: { visual_state: 'Visual state', gait: 'Gait', speed: 'Animation speed', outbreak: 'Outbreak rule', time_scale: 'Bite clock' },\n hints: {\n visual_state: 'The look of every animal: alive, infected (grey coat, glowing eyes, wounds) or dead (lying down, a pool of blood)',\n gait: 'idle, walk or run; the cycle of each species runs at its own rate',\n outbreak: 'Off: a bite does nothing. On: a species that turns incubates and turns, one that dies dies, the rest shrug it off',\n time_scale: 'Game seconds per real second for the bite timers (60: ten minutes pass in ten seconds)',\n },\n options: { visual_state: { alive: 'Alive', infected: 'Infected', dead: 'Dead' }, gait: { idle: 'Idle', walk: 'Walk', run: 'Run' } },\n actions: { bite_all: 'Bite every animal', recover: 'Heal every animal', skin_40: 'Add 40 animals as node skins', clear_skins: 'Remove the skins' },\n layers: { joints: 'Joints', split: 'Split view', sound_range: 'Sound range', carcass_lure: 'Carcass lure radius' },\n metrics: { animals: 'Animals', draw_calls: 'Draw calls', triangles: 'Triangles', nodes_per_skin: 'Nodes per skin', incubating: 'Incubating', turned: 'Turned', dead: 'Dead' },\n scenarios: {\n visual_states: 'Alive, infected and dead for every species',\n gait_moves_legs: 'The gait moves the legs',\n outbreak_rule: 'Outbreak rule on and off',\n carcass_lure: 'A carcass lures zombies within its radius',\n bite_to_turn_timer: 'Bite, incubation, turn (accelerated)',\n skins_40: '40 animals as node skins',\n },\n },\n 'pt-BR': {\n group: 'Animais',\n name: 'Área de animais',\n controls: { visual_state: 'Estado visual', gait: 'Andar', speed: 'Velocidade da animação', outbreak: 'Regra de surto', time_scale: 'Relógio da mordida' },\n hints: {\n visual_state: 'O aspecto de todos os bichos: vivo, infectado (pelo cinza, olhos brilhando, feridas) ou morto (deitado, poça de sangue)',\n gait: 'idle, walk ou run; o ciclo de cada espécie anda no seu ritmo',\n outbreak: 'Desligada: a mordida não faz nada. Ligada: a espécie que vira incuba e vira, a que morre morre, as outras não sentem',\n time_scale: 'Segundos de jogo por segundo real nos prazos da mordida (60: dez minutos passam em dez segundos)',\n },\n options: { visual_state: { alive: 'Vivo', infected: 'Infectado', dead: 'Morto' }, gait: { idle: 'Parado', walk: 'Andando', run: 'Correndo' } },\n actions: { bite_all: 'Morder todos os bichos', recover: 'Curar todos os bichos', skin_40: 'Pôr 40 bichos como pele de nós', clear_skins: 'Tirar as peles' },\n layers: { joints: 'Juntas', split: 'Vista aberta', sound_range: 'Alcance do som', carcass_lure: 'Raio de atração da carcaça' },\n metrics: { animals: 'Bichos', draw_calls: 'Chamadas de desenho', triangles: 'Triângulos', nodes_per_skin: 'Nós por pele', incubating: 'Incubando', turned: 'Viraram', dead: 'Morreram' },\n scenarios: {\n visual_states: 'Vivo, infectado e morto em cada espécie',\n gait_moves_legs: 'O andar mexe as pernas',\n outbreak_rule: 'Regra de surto ligada e desligada',\n carcass_lure: 'A carcaça atrai zumbis dentro do raio',\n bite_to_turn_timer: 'Mordida, incubação, vira (acelerado)',\n skins_40: '40 bichos como pele de nós',\n },\n },\n}\n"],"mappings":"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","names":["PI","PI","lineUpLength","visualStateOf","SKIN_COUNT","visualStateOf","lineUpLength"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/animate-bird.ts","../src/animate-quadruped.ts","../src/animate-snake.ts","../src/bird.ts","../src/context.ts","../src/extras.ts","../src/quadruped.ts","../src/textures.ts","../src/profile.ts","../src/snake.ts","../src/visual-state.ts","../src/views.ts","../src/audio/recipes.ts","../src/audio/calls.json","../src/audio/sound.ts","../src/line-up.ts","../src/test-area/module.ts","../src/test-area/scenarios.ts","../src/test-area/text.ts"],"sourcesContent":["/**\n * @adatechnology/game-animals-three: the three.js drawing of the animals, a literal port of the Bichos do Vale builders (`quad`, `bird`, `snake`) and\n * their animation, with the alive / infected / dead looks for every species, the joints and split views, and a GPU node skin for crowds.\n */\nimport { GAIT_PHASES } from '@adatechnology/game-animals'\nimport type { AnimalSpecies, AnimalVisualState, GaitPhases } from '@adatechnology/game-animals'\nimport { collectReferencedNodes, createNodeSkin } from '@adatechnology/game-props3d'\nimport type { NodeSkin } from '@adatechnology/game-props3d'\nimport type * as THREE_NS from 'three'\n\nimport { animateBird } from './animate-bird'\nimport { animateQuadruped } from './animate-quadruped'\nimport { animateSnake } from './animate-snake'\nimport type { AnimateParams } from './animate-types'\nimport { buildBird } from './bird'\nimport { createRig, createStream } from './context'\nimport { BIRD_EXTRAS, QUADRUPED_EXTRAS } from './extras'\nimport { buildQuadruped } from './quadruped'\nimport { buildSnake } from './snake'\nimport type { AnimalRig, AnimalsThreeOptions, DocumentLike, Three } from './types'\nimport { applyVisualState } from './visual-state'\nimport { setJointView, setSplit, updateSplit } from './views'\n\nexport { ANIMAL_SOUND_BANK, ANIMAL_SOUNDS, COW_MOO, DOG_BARK, HEN_CLUCK, LAPWING_CALL } from './audio/recipes'\nexport { ANIMAL_CALLS, ANIMAL_CALL_SOURCES, createAnimalSound } from './audio/sound'\nexport type { AnimalCall, AnimalSound, AnimalSoundOptions, AnimalSoundSink } from './audio/sound'\nexport type { AnimalLeg, AnimalPivot, AnimalRig, AnimalWing, AnimalsThreeOptions, CanvasLike, DocumentLike, Three } from './types'\nexport type { AnimateParams } from './animate-types'\nexport type { BirdExtra, BirdParts, ExtraContext, QuadrupedExtra, QuadrupedParts } from './extras'\nexport { BIRD_EXTRAS, QUADRUPED_EXTRAS } from './extras'\nexport { lineUpAnimals } from './line-up'\nexport type { LineUpOptions } from './line-up'\nexport { profileGeometry } from './profile'\nexport { createCoatTexture } from './textures'\nexport { applyVisualState } from './visual-state'\nexport { setJointView, setSplit, updateSplit } from './views'\n\nexport type AnimalsThree = {\n /** Builds one animal from its species; consumes one number of the stream for the start phase unless `phase` is given. */\n build(species: AnimalSpecies, buildOptions?: { readonly phase?: number }): AnimalRig\n /** Advances the animation of one animal (steps, flight, wings, head, tail, a dead one lying down). */\n animate(rig: AnimalRig, params: AnimateParams): void\n setVisualState(rig: AnimalRig, state: AnimalVisualState): void\n setJointView(rig: AnimalRig, on: boolean): void\n setSplit(rig: AnimalRig, on: boolean): void\n updateSplit(rig: AnimalRig, delta: number): void\n /** One mesh that stands for the whole tree, for crowds: call `skin.update()` each frame after `animate`. */\n createSkin(rig: AnimalRig): NodeSkin\n readonly jointMaterial: THREE_NS.MeshStandardMaterial\n}\n\nconst countTriangles = (root: THREE_NS.Object3D): number => {\n let triangles = 0\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh) return\n const geometry = mesh.geometry\n triangles += geometry.index ? geometry.index.count / 3 : geometry.attributes.position.count / 3\n })\n return Math.round(triangles)\n}\n\nexport const createAnimalsThree = (THREE: Three, options: AnimalsThreeOptions = {}): AnimalsThree => {\n const random = options.random ?? createStream(options.seed ?? 7)\n const documentOf = (): DocumentLike => {\n const found = options.document ?? (globalThis as { document?: DocumentLike }).document\n if (!found) throw new Error('game-animals-three: a species with a coat texture needs `options.document` (no global document found)')\n return found\n }\n const jointMaterial = new THREE.MeshStandardMaterial({ color: 0xe0a548, emissive: 0xe0a548, emissiveIntensity: 0.8, roughness: 0.4 })\n const gaits: Readonly<Record<'walk' | 'trot' | 'gallop', GaitPhases>> = GAIT_PHASES\n\n return {\n jointMaterial,\n build(species, buildOptions = {}) {\n const rig = createRig(THREE, species, { phase: buildOptions.phase ?? random() * 6 })\n if (species.body.kind === 'snake') buildSnake(THREE, rig)\n else if (species.body.kind === 'bird') buildBird(THREE, rig, { extra: BIRD_EXTRAS[species.id] })\n else buildQuadruped(THREE, rig, { document: species.body.texture ? documentOf() : (undefined as never), extra: QUADRUPED_EXTRAS[species.id] })\n rig.triangles = countTriangles(rig.root)\n rig.root.traverse((object) => {\n if ((object as THREE_NS.Mesh).isMesh) object.userData.speciesId = species.id\n })\n return rig\n },\n animate(rig, params) {\n const kind = rig.species.body.kind\n if (kind === 'snake') animateSnake(THREE, rig, params)\n else if (kind === 'bird') animateBird(rig, params)\n else animateQuadruped(rig, params, gaits)\n },\n setVisualState: (rig, state) => applyVisualState(THREE, rig, state),\n setJointView: (rig, on) => setJointView(rig, on, jointMaterial),\n setSplit,\n updateSplit,\n createSkin: (rig) => createNodeSkin(THREE, rig.root, { nodes: collectReferencedNodes(rig, ['species']) }),\n }\n}\nexport { createAnimalsTestModule, ANIMALS_AREA_ID, ANIMAL_ITEM_PREFIX } from './test-area/module'\nexport type { AnimalsContext } from './test-area/scenarios'\nexport type { AnimalsTestOptions, OutbreakLike } from './test-area/types'\n","import type { BirdSpec } from '@adatechnology/game-animals'\n\nimport type { AnimateParams } from './animate-types'\nimport type { AnimalRig } from './types'\n\nconst { PI } = Math\n\n/** Advances a bird's cycle (page: `animBird`): steps, flight for the species that fly, wings, peck, alarm, tail. */\nexport const animateBird = (rig: AnimalRig, params: AnimateParams): void => {\n const { time: t, delta: dt, clip } = params\n const species = rig.species\n const spec = species.body as BirdSpec\n const isVulture = species.id === 'vulture'\n const isChicken = species.id === 'chicken'\n const isLapwing = species.id === 'southern_lapwing'\n const flying = clip === 'run' && !isChicken\n const hz = clip === 'run' && !flying ? species.runHz : clip === 'walk' ? species.walkHz : 0\n rig.phase += dt * (flying ? (isVulture ? 1.1 : 4.5) : hz) * 2 * PI\n const targetHeight = flying ? rig.size * 1.2 : 0\n rig.trunk.position.y += (targetHeight - rig.trunk.position.y) * Math.min(1, dt * 3)\n rig.legs.forEach((leg, index) => {\n if (flying) {\n leg.hip.rotation.x = 1.2\n leg.knee.rotation.x = -1.6\n } else if (clip === 'idle') {\n leg.hip.rotation.x = 0\n leg.knee.rotation.x = 0\n } else {\n const phase = rig.phase + index * PI\n leg.hip.rotation.x = -Math.sin(phase) * 0.45\n leg.knee.rotation.x = -Math.max(0, Math.cos(phase)) * 0.7\n }\n leg.foot.rotation.x = -(leg.hip.rotation.x + leg.knee.rotation.x)\n })\n rig.wings.forEach((wing) => {\n const { side, shoulder, elbow } = wing\n if (flying) {\n const flap = isVulture ? 0.25 + Math.sin(rig.phase) * 0.18 : Math.sin(rig.phase) * 0.9\n shoulder.rotation.y += (0 - shoulder.rotation.y) * Math.min(1, dt * 6)\n shoulder.rotation.z = side * flap\n elbow.rotation.z = side * (isVulture ? 0.08 : Math.sin(rig.phase - 0.6) * 0.4)\n elbow.rotation.y = 0\n shoulder.scale.x += (1 - shoulder.scale.x) * Math.min(1, dt * 6)\n } else {\n const alert = isLapwing && clip === 'idle' ? Math.max(0, Math.sin(t * 1.3)) * 0.9 : 0\n const flutter = isChicken && clip === 'run' ? Math.abs(Math.sin(rig.phase * 1.5)) * 0.8 : 0\n shoulder.rotation.y += ((side * PI) / 2 * 0.97 - alert * side * 0.9 - shoulder.rotation.y) * Math.min(1, dt * 6)\n shoulder.rotation.z = side * (-0.06 + flutter + alert * 0.6)\n elbow.rotation.z = side * 0.04\n elbow.rotation.y = 0\n shoulder.scale.x += ((alert > 0.1 ? 1 : 0.58) - shoulder.scale.x) * Math.min(1, dt * 6)\n }\n })\n const peck = isChicken && clip === 'idle' ? Math.max(0, Math.sin(t * 1.6)) ** 8 * 1.2 : 0\n if (rig.neck) {\n rig.neck.rotation.x = rig.neckAngle + (clip === 'walk' && !isVulture ? Math.max(0, Math.sin(rig.phase * 2)) * 0.35 : 0) + peck + (flying ? 0.6 : 0)\n rig.neck.rotation.y = clip === 'idle' ? Math.sin(t * 0.9) * 0.5 : 0\n }\n if (rig.jaw) rig.jaw.rotation.x = isLapwing && clip === 'idle' ? Math.max(0, Math.sin(t * 1.3)) * Math.abs(Math.sin(t * 14)) * 0.5 : 0\n if (rig.tailRoot) rig.tailRoot.rotation.x = (spec.tailA || 0) + (flying ? 0.6 : 0)\n}\n","import type { GaitPhases, QuadrupedSpec } from '@adatechnology/game-animals'\n\nimport type { AnimateParams } from './animate-types'\nimport type { AnimalRig } from './types'\n\nconst { PI } = Math\n\n/** Advances a quadruped's step cycle (page: `animQuad`): legs by gait phase, trunk bob, neck, head, jaw and tail; a dead one lies down. */\nexport const animateQuadruped = (rig: AnimalRig, params: AnimateParams, gaits: { readonly walk: GaitPhases; readonly trot: GaitPhases; readonly gallop: GaitPhases }): void => {\n const { time: t, delta: dt, clip } = params\n const species = rig.species\n const spec = species.body as QuadrupedSpec\n if (rig.dead) {\n rig.root.rotation.z += (PI / 2 * 0.97 - rig.root.rotation.z) * Math.min(1, dt * 3)\n rig.root.position.y += (spec.R * (spec.sx || 1) * 0.85 - rig.root.position.y) * Math.min(1, dt * 3)\n rig.legs.forEach((leg) => {\n leg.hip.rotation.x = leg.angle1 + (leg.isFront ? -0.5 : 0.4)\n leg.knee.rotation.x = 0.05\n leg.foot.rotation.x = 0\n })\n if (rig.neck) rig.neck.rotation.x = rig.neckAngle + 0.35\n if (rig.jaw) rig.jaw.rotation.x = 0.25\n return\n }\n const hz = (clip === 'run' ? species.runHz : clip === 'walk' ? species.walkHz : 0) * (rig.infected ? 1.2 : 1)\n rig.phase += dt * hz * 2 * PI\n const gait = clip === 'run' ? (species.gallop ? gaits.gallop : gaits.trot) : gaits.walk\n const amplitude = clip === 'run' ? 0.62 : 0.34\n const flex = clip === 'run' ? 1.15 : 0.75\n rig.legs.forEach((leg, index) => {\n if (clip === 'idle') {\n leg.hip.rotation.x = leg.angle1\n leg.knee.rotation.x = leg.angle2\n } else {\n const phase = rig.phase + (gait[index] as number)\n const limit = rig.infected && index === 1 ? 0.35 : 1\n leg.hip.rotation.x = leg.angle1 - Math.sin(phase) * amplitude * limit\n leg.knee.rotation.x = leg.angle2 + Math.max(0, Math.cos(phase)) * flex * limit\n }\n leg.foot.rotation.x = -(leg.hip.rotation.x + leg.knee.rotation.x) * 0.85\n })\n const bob = clip === 'idle' ? 0 : Math.abs(Math.sin(rig.phase)) * (clip === 'run' ? 0.05 : 0.018) * rig.size\n rig.trunk.position.y = bob * 0.6\n const bodyGroup = rig.bodyGroup\n if (bodyGroup) {\n bodyGroup.rotation.x = clip === 'run' && species.gallop ? Math.sin(rig.phase + PI * 0.4) * 0.07 : 0\n bodyGroup.scale.y = 1 + (clip === 'idle' ? Math.sin(t * 2.2) * 0.012 : 0)\n }\n const low = rig.infected ? 0.35 : 0\n if (rig.neck) {\n rig.neck.rotation.x = rig.neckAngle + low + (clip === 'idle' ? Math.sin(t * 0.7) * 0.08 : Math.sin(rig.phase * 2) * 0.04)\n rig.neck.rotation.y = clip === 'idle' ? Math.sin(t * 0.45) * 0.35 : 0\n }\n if (rig.head) rig.head.rotation.z = rig.infected ? Math.sin(t * 11) * Math.sin(t * 1.7) * 0.12 : 0\n if (rig.jaw) rig.jaw.rotation.x = rig.infected ? 0.25 + Math.max(0, Math.sin(t * 6)) * 0.25 : clip === 'run' ? 0.12 : 0\n const wagging = species.id === 'dog' && !rig.infected\n rig.tail.forEach((segment, index) => {\n segment.rotation.z = Math.sin(t * (wagging ? 9 : 2.2) - index * 0.6) * (wagging ? 0.35 : 0.12)\n })\n}\n","import type * as THREE_NS from 'three'\n\nimport type { AnimateParams } from './animate-types'\nimport type { AnimalRig, Three } from './types'\n\nconst { PI } = Math\n\n/** The path of the body for a clip: crawling in a wave, or coiled with the head up in an S (and striking when `strike` rises). */\nconst bodyPath = (THREE: Three, rig: AnimalRig, params: AnimateParams, spacing: number): THREE_NS.Vector3[] => {\n const { time: t, clip } = params\n const points: THREE_NS.Vector3[] = []\n for (let index = 0; index < rig.segmentCount; index++) {\n let x: number\n let z: number\n let y = 0\n if (clip === 'walk') {\n z = 0.6 - index * spacing\n x = Math.sin(rig.phase * 2.2 - index * 0.42) * 0.08 * Math.min(1, index / 6 + 0.3)\n } else {\n const strike = clip === 'run' ? Math.max(0, Math.sin(t * 2.2)) ** 6 : 0\n if (index < 9) {\n const k = index / 9\n z = 0.08 + (1 - k) * 0.12 + strike * (1 - k) * 0.35\n y = (1 - k) * 0.13 * (1 - strike * 0.6)\n x = Math.sin(k * PI * 1.6) * 0.05 * (1 - strike)\n } else {\n const angle = (index - 9) * 0.36\n const radius = 0.16 - (index - 9) * 0.0045\n x = Math.cos(angle) * radius\n z = Math.sin(angle) * radius - 0.05\n y = (index - 9) * 0.0012\n }\n }\n points.push(new THREE.Vector3(x, y, z))\n }\n return points\n}\n\n/** Advances a snake (page: `animSnake`): lays the 34 segments along the path of the clip, then the head, jaw and tongue. */\nexport const animateSnake = (THREE: Three, rig: AnimalRig, params: AnimateParams): void => {\n const { time: t, delta: dt, clip } = params\n const spacing = rig.segmentLength * (params.split ? 1.5 : 1)\n if (clip === 'walk') rig.phase += dt * 2.4\n const points = bodyPath(THREE, rig, params, spacing)\n const at = (index: number): THREE_NS.Vector3 => points[index] as THREE_NS.Vector3\n for (let index = 0; index < rig.segmentCount; index++) {\n const group = (rig.segments[index] as AnimalRig['segments'][number]).group\n group.position.copy(at(index))\n const direction = index === 0 ? at(0).clone().sub(at(1)) : at(index - 1).clone().sub(at(index))\n group.rotation.set(0, Math.atan2(direction.x, direction.z), 0)\n group.rotateX(-Math.atan2(direction.y, Math.hypot(direction.x, direction.z)))\n }\n const head = rig.head as THREE_NS.Group\n const headDirection = at(0).clone().sub(at(1)).normalize()\n head.position.copy(at(0)).addScaledVector(headDirection, 0.02)\n head.rotation.set(0, Math.atan2(headDirection.x, headDirection.z), 0)\n head.rotateX(-Math.atan2(headDirection.y, Math.hypot(headDirection.x, headDirection.z)) * 0.5)\n const jaw = rig.jaw as THREE_NS.Group\n jaw.rotation.x = clip === 'run' ? Math.max(0, Math.sin(t * 2.2)) ** 6 * 0.9 : 0\n const tongue = rig.tongue as THREE_NS.Mesh\n tongue.visible = Math.sin(t * 5) > 0.3\n tongue.scale.z = 1 + Math.sin(t * 20) * 0.3\n}\n","import { birdSize } from '@adatechnology/game-animals'\nimport type { BirdSpec } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport { addMesh, createRigTools } from './context'\nimport type { BirdExtra } from './extras'\nimport type { AnimalRig, Three } from './types'\n\nconst buildWings = (THREE: Three, rig: AnimalRig, spec: BirdSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; dark: THREE_NS.MeshStandardMaterial }): void => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, main, dark } = parts\n for (const side of [-1, 1]) {\n const shoulder = tools.pivot(bodyGroup, side * spec.r * spec.s[0] * 1.02, spec.r * 0.22, spec.r * 0.3, new THREE.Vector3(side * 0.12, 0.03, 0).multiplyScalar(rig.size))\n tools.joint(shoulder, spec.r * 0.14, main, 0, 0, 0)\n tools.ball(shoulder, 0.5, spec.wingM ? tools.material(spec.wingM) : dark, side * spec.wi * 0.5, 0, -spec.wc * 0.3, spec.wi * 1.05, spec.r * 0.16, spec.wc)\n const elbow = tools.pivot(shoulder, side * spec.wi, 0, 0, new THREE.Vector3(side * 0.06, 0, 0).multiplyScalar(rig.size))\n tools.joint(elbow, spec.r * 0.1, main, 0, 0, 0)\n tools.ball(elbow, 0.5, dark, side * spec.wo * 0.45, 0, -spec.wc * 0.32, spec.wo * 1.05, spec.r * 0.12, spec.wc * 0.75)\n if (spec.fingers) {\n for (let finger = 0; finger < 4; finger++) {\n addMesh(THREE, elbow, new THREE.BoxGeometry(spec.wo * 0.35, spec.r * 0.03, spec.wc * 0.12), dark, side * (spec.wo + spec.wo * 0.12), 0, -spec.wc * 0.05 - finger * spec.wc * 0.18, 0, side * (0.05 + finger * 0.12), 0)\n }\n }\n if (spec.spur) addMesh(THREE, elbow, new THREE.ConeGeometry(spec.r * 0.06, spec.r * 0.25, 5), tools.material(0xc0302a), 0, 0, spec.wc * 0.2, Math.PI / 2, 0, 0)\n rig.wings.push({ shoulder, elbow, side })\n }\n}\n\nconst buildLegs = (THREE: Three, rig: AnimalRig, spec: BirdSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; leg: THREE_NS.MeshStandardMaterial }): void => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, main, leg } = parts\n for (const side of [-1, 1]) {\n const hip = tools.pivot(bodyGroup, side * spec.r * 0.38, -spec.r * 0.55, spec.r * 0.05, new THREE.Vector3(side * 0.06, -0.05, 0).multiplyScalar(rig.size))\n tools.joint(hip, spec.r * 0.18, main, 0, 0, 0)\n tools.limb(hip, spec.r * 0.16, spec.r * 0.09, spec.shank, spec.featherLeg ? main : leg)\n const ankle = tools.pivot(hip, 0, -spec.shank, 0, new THREE.Vector3(0, -0.04, 0).multiplyScalar(rig.size))\n tools.joint(ankle, spec.r * 0.06, leg, 0, 0, 0)\n tools.limb(ankle, spec.r * 0.055, spec.r * 0.05, spec.tars, leg)\n const foot = tools.pivot(ankle, 0, -spec.tars, 0)\n for (const angle of [-0.45, 0, 0.45]) addMesh(THREE, foot, new THREE.BoxGeometry(spec.r * 0.05, spec.r * 0.04, spec.r * 0.55).translate(0, 0, spec.r * 0.25), leg, 0, -spec.r * 0.02, 0, 0, angle, 0)\n addMesh(THREE, foot, new THREE.BoxGeometry(spec.r * 0.05, spec.r * 0.04, spec.r * 0.25).translate(0, 0, -spec.r * 0.12), leg, 0, -spec.r * 0.02, 0)\n rig.legs.push({ hip, knee: ankle, foot, isFront: false, angle1: 0.35, angle2: -0.5, side })\n }\n}\n\n/** Builds a bird: body, tail, two wings with shoulder and elbow pivots, neck, head with beak and jaw, eyes, the species' extra parts, and two legs. */\nexport const buildBird = (THREE: Three, rig: AnimalRig, options: { extra?: BirdExtra }): AnimalRig => {\n const spec = rig.species.body as BirdSpec\n const tools = createRigTools(THREE, rig)\n const colors = spec.c\n const main = tools.material(colors.main)\n const dark = tools.material(colors.dark)\n const leg = tools.material(colors.leg)\n const beak = tools.material(colors.beak, { roughness: 0.5 })\n const belly = tools.material(colors.belly || colors.main)\n rig.main = main\n const hipY = spec.tars + spec.shank * 0.9\n rig.size = birdSize(spec)\n const bodyGroup = tools.pivot(rig.trunk, 0, hipY + spec.r * 0.55, 0)\n rig.bodyGroup = bodyGroup\n bodyGroup.rotation.x = spec.pitch || 0\n tools.ball(bodyGroup, spec.r, main, 0, 0, 0, spec.s[0], spec.s[1], spec.s[2])\n tools.ball(bodyGroup, spec.r * 0.9, belly, 0, -spec.r * 0.22, spec.r * 0.15, spec.s[0] * 0.9, spec.s[1] * 0.8, spec.s[2] * 0.85)\n const tail = tools.pivot(bodyGroup, 0, spec.r * 0.15, -spec.r * spec.s[2] * 0.85, new THREE.Vector3(0, 0, -0.08).multiplyScalar(rig.size))\n tail.rotation.x = spec.tailA || -0.3\n rig.tailRoot = tail\n addMesh(THREE, tail, new THREE.BoxGeometry(spec.tailW, spec.r * 0.08, spec.tailL).translate(0, 0, -spec.tailL / 2), spec.tailM ? tools.material(spec.tailM) : dark)\n buildWings(THREE, rig, spec, { bodyGroup, main, dark })\n const neck = tools.pivot(bodyGroup, 0, spec.r * 0.45, spec.r * spec.s[2] * 0.75, new THREE.Vector3(0, 0.05, 0.08).multiplyScalar(rig.size))\n neck.rotation.x = spec.neckA\n rig.neck = neck\n rig.neckAngle = spec.neckA\n tools.joint(neck, spec.nr * 1.1, spec.neckM ? tools.material(spec.neckM) : main, 0, 0, 0)\n addMesh(THREE, neck, new THREE.CylinderGeometry(spec.nr * 0.85, spec.nr, spec.nl, 12).translate(0, spec.nl / 2, 0), spec.neckM ? tools.material(spec.neckM) : main)\n const head = tools.pivot(neck, 0, spec.nl, 0, new THREE.Vector3(0, 0.05, 0.05).multiplyScalar(rig.size))\n head.rotation.x = -spec.neckA + (spec.headA || 0)\n rig.head = head\n rig.headAngle = head.rotation.x\n const headMaterial = spec.headM ? tools.material(spec.headM) : main\n tools.ball(head, spec.hr, headMaterial, 0, 0, 0, spec.hs ? spec.hs[0] : 1, spec.hs ? spec.hs[1] : 1, spec.hs ? spec.hs[2] : 1.1)\n addMesh(THREE, head, new THREE.ConeGeometry(spec.br, spec.bl, 8).rotateX(Math.PI / 2).translate(0, 0, spec.bl / 2), beak, 0, -spec.hr * 0.1, spec.hr * 0.85, spec.hook || 0, 0, 0)\n const jaw = tools.pivot(head, 0, -spec.hr * 0.25, spec.hr * 0.8)\n rig.jaw = jaw\n addMesh(THREE, jaw, new THREE.ConeGeometry(spec.br * 0.7, spec.bl * 0.85, 8).rotateX(Math.PI / 2).translate(0, 0, spec.bl * 0.42), beak).scale.set(1, 0.5, 1)\n tools.eyes(head, spec.hr * 0.17, spec.hr * 0.68, spec.hr * 0.2, spec.hr * 0.35)\n if (spec.eyeC && rig.eyeMaterial) {\n rig.eyeMaterial.color.set(spec.eyeC)\n rig.eyeMaterial.userData.base = rig.eyeMaterial.color.clone()\n }\n options.extra?.({ THREE, rig, tools }, { bodyGroup, head, neck, main, dark })\n buildLegs(THREE, rig, spec, { bodyGroup, main, leg })\n return rig\n}\n","import type * as THREE_NS from 'three'\n\nimport type { AnimalRig, AnimalsThreeOptions, Three } from './types'\n\nexport type MaterialExtras = Partial<THREE_NS.MeshStandardMaterialParameters>\n\n/** The mulberry32 stream of the page (`rng`): the same numbers for the same seed. */\nexport const createStream = (seed: number): (() => number) => {\n let state = seed\n return () => {\n state |= 0\n state = (state + 0x6d2b79f5) | 0\n let t = Math.imul(state ^ (state >>> 15), 1 | state)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** The page's `add`: a mesh at a position and rotation under a parent, casting and receiving shadows. */\nexport const addMesh = (\n THREE: Three,\n parent: THREE_NS.Object3D,\n geometry: THREE_NS.BufferGeometry,\n material: THREE_NS.Material,\n x?: number,\n y?: number,\n z?: number,\n rx?: number,\n ry?: number,\n rz?: number,\n): THREE_NS.Mesh => {\n const mesh = new THREE.Mesh(geometry, material)\n mesh.position.set(x || 0, y || 0, z || 0)\n if (rx || ry || rz) mesh.rotation.set(rx || 0, ry || 0, rz || 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n parent.add(mesh)\n return mesh\n}\n\n/** The part builders of the page's `Animal` (`M`, `ball`, `limb`, `joint`, `pivot`), bound to one rig. */\nexport type RigTools = {\n material(color: number, extras?: MaterialExtras): THREE_NS.MeshStandardMaterial\n ball(parent: THREE_NS.Object3D, radius: number, material: THREE_NS.Material, x?: number, y?: number, z?: number, sx?: number, sy?: number, sz?: number): THREE_NS.Mesh\n /** A cylinder hanging from the origin; `radius1` is the one the page calls the top, but the geometry takes it as the bottom (kept as the page has it). */\n limb(parent: THREE_NS.Object3D, radius1: number, radius2: number, length: number, material: THREE_NS.Material): THREE_NS.Mesh\n joint(parent: THREE_NS.Object3D, radius: number, material: THREE_NS.Material, x?: number, y?: number, z?: number): THREE_NS.Mesh\n pivot(parent: THREE_NS.Object3D, x: number, y: number, z: number, offset?: THREE_NS.Vector3): THREE_NS.Group\n eyes(head: THREE_NS.Object3D, radius: number, x: number, y: number, z: number): void\n}\n\nexport const createRigTools = (THREE: Three, rig: AnimalRig): RigTools => {\n const tools: RigTools = {\n material(color, extras) {\n const material = new THREE.MeshStandardMaterial(Object.assign({ color, roughness: 0.8, metalness: 0, flatShading: false }, extras || {}))\n material.userData.base = material.color.clone()\n rig.materials.push(material)\n return material\n },\n ball(parent, radius, material, x, y, z, sx, sy, sz) {\n const mesh = addMesh(THREE, parent, new THREE.SphereGeometry(radius, 16, 12), material, x, y, z)\n if (sx) mesh.scale.set(sx, sy as number, sz as number)\n return mesh\n },\n limb: (parent, radius1, radius2, length, material) => addMesh(THREE, parent, new THREE.CylinderGeometry(radius2, radius1, length, 14, 1).translate(0, -length / 2, 0), material),\n joint(parent, radius, material, x, y, z) {\n const joint = tools.ball(parent, radius, material, x, y, z)\n joint.userData.joint = 1\n rig.joints.push(joint)\n return joint\n },\n pivot(parent, x, y, z, offset) {\n const group = new THREE.Group()\n group.position.set(x, y, z)\n parent.add(group)\n rig.pivots.push({ group, rest: group.position.clone(), offset: offset || new THREE.Vector3() })\n return group\n },\n eyes(head, radius, x, y, z) {\n const eyeMaterial = tools.material(0x111111, { roughness: 0.25 })\n rig.eyeMaterial = eyeMaterial\n for (const side of [-1, 1]) rig.eyes.push(tools.ball(head, radius, eyeMaterial, side * x, y, z))\n },\n }\n return tools\n}\n\nexport const createRig = (THREE: Three, species: AnimalRig['species'], options: AnimalsThreeOptions & { phase: number }): AnimalRig => {\n const rig: AnimalRig = {\n species,\n root: new THREE.Group(),\n trunk: new THREE.Group(),\n materials: [],\n joints: [],\n pivots: [],\n legs: [],\n tail: [],\n ears: [],\n infectionParts: [],\n eyes: [],\n wings: [],\n segments: [],\n phase: options.phase,\n size: 1,\n segmentLength: 0,\n segmentCount: 0,\n home: new THREE.Vector3(),\n infected: false,\n dead: false,\n neckAngle: 0,\n headAngle: 0,\n triangles: 0,\n }\n rig.root.add(rig.trunk)\n return rig\n}\n","import type * as THREE_NS from 'three'\n\nimport { addMesh } from './context'\nimport type { RigTools } from './context'\nimport type { HeadSpecOf, NeckSpecOf } from './extras-types'\nimport type { AnimalRig, Three } from './types'\n\nexport type ExtraContext = { readonly THREE: Three; readonly rig: AnimalRig; readonly tools: RigTools }\n\nexport type QuadrupedParts = {\n readonly bodyGroup: THREE_NS.Group\n readonly head: THREE_NS.Group\n readonly neck: THREE_NS.Group\n readonly main: THREE_NS.MeshStandardMaterial\n readonly belly: THREE_NS.MeshStandardMaterial\n readonly dark: THREE_NS.MeshStandardMaterial\n readonly L: number\n readonly Rb: number\n readonly bodyY: number\n readonly hd: HeadSpecOf\n readonly nk: NeckSpecOf\n}\n\nexport type BirdParts = {\n readonly bodyGroup: THREE_NS.Group\n readonly head: THREE_NS.Group\n readonly neck: THREE_NS.Group\n readonly main: THREE_NS.MeshStandardMaterial\n readonly dark: THREE_NS.MeshStandardMaterial\n}\n\nexport type QuadrupedExtra = (context: ExtraContext, parts: QuadrupedParts) => void\nexport type BirdExtra = (context: ExtraContext, parts: BirdParts) => void\n\nconst cow: QuadrupedExtra = ({ THREE, tools }, k) => {\n tools.ball(k.bodyGroup, 0.2, k.main, 0, k.Rb * 1.1, k.L * 0.33, 0.95, 1.1, 1.1) // hump\n tools.ball(k.neck, 0.13, k.main, 0, 0.12, 0.08, 0.55, 1.4, 1.05) // dewlap\n for (const side of [-1, 1]) addMesh(THREE, k.head, new THREE.ConeGeometry(0.025, 0.13, 8), tools.material(0xcfc6a8), side * 0.12, k.hd.r * 1.05, k.hd.r * 0.05, 0, 0, side * -0.9)\n}\n\nconst horse: QuadrupedExtra = ({ THREE, rig, tools }, k) => {\n for (let index = 0; index < 9; index++) addMesh(THREE, k.neck, new THREE.BoxGeometry(0.035, 0.16, 0.08), k.dark, 0, 0.06 + index * 0.065, -0.12 + index * 0.004, -0.25, 0, 0) // mane\n addMesh(THREE, k.head, new THREE.BoxGeometry(0.03, 0.12, 0.06), k.dark, 0, k.hd.r * 1.05, k.hd.r * 0.3, 0.6, 0, 0) // forelock\n const last = rig.tail[rig.tail.length - 1] as THREE_NS.Group\n tools.ball(last, 0.08, k.dark, 0, -0.42, 0, 0.7, 4.5, 0.7) // tail hair\n}\n\nconst wildBoar: QuadrupedExtra = ({ THREE, tools }, k) => {\n for (let index = 0; index < 12; index++) addMesh(THREE, k.bodyGroup, new THREE.BoxGeometry(0.03, 0.1, 0.06), k.dark, 0, k.Rb * 1.12 - index * 0.004, k.L * 0.38 - index * 0.06, -0.2, 0, 0) // bristles\n for (const side of [-1, 1])\n addMesh(THREE, k.head, new THREE.ConeGeometry(0.012, 0.09, 6), tools.material(0xe8e0cc), side * 0.07, k.hd.r * -0.25 + 0.03, k.hd.r * 0.25 + k.hd.r * k.hd.s[2] * 0.55 + 0.13, -0.6, 0, side * 0.5) // tusks\n}\n\nconst chicken: BirdExtra = ({ tools }, k) => {\n const red = tools.material(0xc0281e)\n for (let index = 0; index < 4; index++) tools.ball(k.head, 0.014, red, 0, 0.045, -0.012 + index * 0.014, 0.5, 1, 0.8) // comb\n tools.ball(k.head, 0.012, red, 0, -0.04, 0.04, 0.5, 1.3, 0.7) // wattle\n}\n\nconst southernLapwing: BirdExtra = ({ THREE, tools }, k) => {\n const black = tools.material(0x161616)\n tools.ball(k.bodyGroup, 0.05, black, 0, 0.03, 0.08, 1.1, 0.9, 0.6) // breast patch\n addMesh(THREE, k.head, new THREE.BoxGeometry(0.006, 0.006, 0.06).translate(0, 0, -0.03), black, 0, 0.025, -0.01, 0.5, 0, 0) // crest\n tools.ball(k.head, 0.026, black, 0, -0.005, 0.02, 1.05, 0.7, 0.9) // cap\n}\n\n/** The parts the page builds with code for five species (the page's `extra` closures), by species id. */\nexport const QUADRUPED_EXTRAS: Readonly<Record<string, QuadrupedExtra>> = { cow, horse, wild_boar: wildBoar }\nexport const BIRD_EXTRAS: Readonly<Record<string, BirdExtra>> = { chicken, southern_lapwing: southernLapwing }\n","import { quadrupedLayout } from '@adatechnology/game-animals'\nimport type { QuadrupedSpec } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport { addMesh, createRigTools } from './context'\nimport { createCoatTexture } from './textures'\nimport { profileGeometry } from './profile'\nimport type { AnimalRig, DocumentLike, Three } from './types'\nimport type { QuadrupedExtra } from './extras'\n\nconst RIB_COUNT = 4\n\ntype LegDefinition = readonly [number, number, 'F' | 'H']\n\nconst LEG_DEFINITIONS: readonly LegDefinition[] = [\n [1, 1, 'F'],\n [-1, 1, 'F'],\n [1, -1, 'H'],\n [-1, -1, 'H'],\n]\n\n/** The body and the four legs of a quadruped (page: the first half of `quad`). */\nconst buildBodyAndLegs = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, main: THREE_NS.MeshStandardMaterial, belly: THREE_NS.MeshStandardMaterial, dark: THREE_NS.MeshStandardMaterial) => {\n const tools = createRigTools(THREE, rig)\n const { L, R: radius } = spec\n const leg = spec.leg\n const layout = quadrupedLayout(spec)\n const { frontHipHeight, hindHipHeight, footHeight, bodyHeight, span } = layout\n const frontAngle1 = leg.fa1 ?? 0.06\n const frontAngle2 = leg.fa2 ?? -0.08\n const hindAngle1 = leg.ha1 ?? -0.32\n const hindAngle2 = leg.ha2 ?? 0.58\n rig.size = layout.size\n const bodyGroup = tools.pivot(rig.trunk, 0, bodyHeight, 0)\n rig.bodyGroup = bodyGroup\n const body = addMesh(THREE, bodyGroup, profileGeometry(THREE, L, spec.prof.map((value) => value * radius)), main)\n body.scale.set(spec.sx || 1, spec.sy || 1, 1)\n body.rotation.x = Math.atan2(hindHipHeight - frontHipHeight, span) * 0.6\n rig.body = body\n const belt = addMesh(THREE, bodyGroup, profileGeometry(THREE, L * 0.8, spec.prof.map((value) => value * 0.8 * radius)), belly)\n belt.scale.set((spec.sx || 1) * 0.92, (spec.sy || 1) * 0.85, 1)\n belt.position.y = -radius * 0.2\n LEG_DEFINITIONS.forEach(([sx, sz, kind]) => {\n const front = kind === 'F'\n const upper = front ? leg.fu : leg.hu\n const lower = front ? leg.fl : leg.hl\n const height = front ? frontHipHeight : hindHipHeight\n const hip = tools.pivot(rig.trunk, sx * radius * (spec.sx || 1) * 0.55, height, (sz * span) / 2, new THREE.Vector3(sx * 0.18, -0.06, sz * 0.12).multiplyScalar(rig.size))\n tools.ball(hip, leg.r * (front ? 1.9 : 2.3), main, 0, -upper * 0.18, front ? 0 : -leg.r * 0.3, 0.75, 1.25, 1)\n tools.joint(hip, leg.r * 1.15, main, 0, 0, 0)\n tools.limb(hip, leg.r * 1.25, leg.r * 0.95, upper, main)\n const knee = tools.pivot(hip, 0, -upper, 0, new THREE.Vector3(0, -0.07 * rig.size, 0))\n tools.joint(knee, leg.r * 0.95, main, 0, 0, 0)\n tools.limb(knee, leg.r * 0.92, leg.r * 0.68, lower, main)\n const foot = tools.pivot(knee, 0, -lower, 0, new THREE.Vector3(0, -0.05 * rig.size, 0))\n if (leg.hoof) {\n tools.joint(foot, leg.r * 0.72, dark, 0, 0, 0)\n addMesh(THREE, foot, new THREE.CylinderGeometry(leg.r * 0.8, leg.r * 1.05, footHeight, 12).translate(0, -footHeight / 2, 0), dark)\n } else {\n tools.joint(foot, leg.r * 0.66, main, 0, 0, 0)\n tools.ball(foot, leg.r * 0.95, leg.dark ? dark : main, 0, -footHeight * 0.55, leg.r * 0.5, 1, 0.62, 1.45)\n }\n rig.legs.push({ hip, knee, foot, isFront: front, angle1: front ? frontAngle1 : hindAngle1, angle2: front ? frontAngle2 : hindAngle2, side: sx })\n })\n return { bodyGroup, bodyHeight }\n}\n\nconst buildHead = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; belly: THREE_NS.MeshStandardMaterial; nose: THREE_NS.MeshStandardMaterial }) => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, main, belly, nose } = parts\n const { L, R: radius } = spec\n const neckSpec = spec.neck\n const headSpec = spec.head\n const neck = tools.pivot(bodyGroup, 0, radius * (spec.sy || 1) * (neckSpec.y ?? 0.35), (L / 2) * (neckSpec.z ?? 0.78), new THREE.Vector3(0, 0.05, 0.12).multiplyScalar(rig.size))\n neck.rotation.x = neckSpec.ang\n rig.neck = neck\n rig.neckAngle = neckSpec.ang\n tools.joint(neck, neckSpec.r * 1.05, main, 0, 0, 0)\n addMesh(THREE, neck, new THREE.CylinderGeometry(neckSpec.r2 || neckSpec.r * 0.85, neckSpec.r, neckSpec.len, 14).translate(0, neckSpec.len / 2, 0), main)\n const head = tools.pivot(neck, 0, neckSpec.len, 0, new THREE.Vector3(0, 0.06, 0.08).multiplyScalar(rig.size))\n head.rotation.x = -neckSpec.ang + (headSpec.down || 0)\n rig.head = head\n rig.headAngle = head.rotation.x\n tools.joint(head, neckSpec.r2 || neckSpec.r * 0.85, main, 0, 0, 0)\n tools.ball(head, headSpec.r, main, 0, headSpec.r * 0.25, headSpec.r * 0.25, headSpec.s[0], headSpec.s[1], headSpec.s[2])\n const snoutZ = headSpec.r * 0.25 + headSpec.r * headSpec.s[2] * 0.55\n const snout = addMesh(THREE, head, new THREE.CylinderGeometry(headSpec.sr2, headSpec.sr1, headSpec.sl, 14).rotateX(Math.PI / 2), headSpec.muzzle ? tools.material(headSpec.muzzle) : main, 0, headSpec.r * (headSpec.sy ?? 0), snoutZ + headSpec.sl / 2)\n snout.scale.set(1, headSpec.sq || 1, 1)\n tools.ball(head, headSpec.sr2 * 1.02, nose, 0, headSpec.r * (headSpec.sy ?? 0) + headSpec.sr2 * 0.1, snoutZ + headSpec.sl, 1, 0.85 * (headSpec.sq || 1), 0.45)\n const jaw = tools.pivot(head, 0, headSpec.r * (headSpec.sy ?? 0) - headSpec.sr1 * 0.55 * (headSpec.sq || 1), snoutZ - headSpec.sr1 * 0.2, new THREE.Vector3(0, -0.04, 0.04).multiplyScalar(rig.size))\n rig.jaw = jaw\n addMesh(THREE, jaw, new THREE.CylinderGeometry(headSpec.sr2 * 0.7, headSpec.sr1 * 0.75, headSpec.sl * 0.92, 12).rotateX(Math.PI / 2).translate(0, 0, headSpec.sl * 0.46), belly).scale.set(1, 0.45, 1)\n const blood = tools.ball(jaw, headSpec.sr2 * 0.9, rig.woundMaterial || (rig.woundMaterial = new THREE.MeshStandardMaterial({ color: 0x6a100c, roughness: 0.3 })), 0, 0.0, headSpec.sl * 0.9, 1.1, 0.6, 0.6)\n tools.eyes(head, headSpec.r * 0.13, headSpec.r * headSpec.s[0] * 0.52, headSpec.r * 0.5, headSpec.r * 0.25 + headSpec.r * headSpec.s[2] * 0.55)\n const ears = spec.ears\n for (const side of [-1, 1]) {\n const earGroup = tools.pivot(head, side * headSpec.r * headSpec.s[0] * 0.55, headSpec.r * (0.25 + headSpec.s[1] * 0.75), headSpec.r * 0.1, new THREE.Vector3(side * 0.04, 0.04, 0).multiplyScalar(rig.size))\n rig.ears.push(earGroup)\n if (ears.t === 'cone') addMesh(THREE, earGroup, new THREE.ConeGeometry(ears.s * 0.45, ears.s, 8).translate(0, ears.s / 2, 0), main, 0, 0, 0, ears.fwd || 0, 0, side * -(ears.tilt ?? 0.3))\n else if (ears.t === 'round') tools.ball(earGroup, ears.s, main, 0, ears.s * 0.4, 0, 1, 1, 0.35)\n else if (ears.t === 'flop') {\n const ear = tools.ball(earGroup, ears.s, main, side * ears.s * 0.9, -ears.s * 0.1, 0, 1.5, 0.45, 0.7)\n ear.rotation.z = side * -0.25\n }\n }\n return { neck, head, blood, neckSpec, headSpec }\n}\n\nconst buildTail = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, parts: { bodyGroup: THREE_NS.Group; main: THREE_NS.MeshStandardMaterial; dark: THREE_NS.MeshStandardMaterial }): void => {\n const tools = createRigTools(THREE, rig)\n const tailSpec = spec.tail\n if (!tailSpec || !tailSpec.n) return\n const { bodyGroup, main, dark } = parts\n const { L, R: radius } = spec\n let parent = tools.pivot(bodyGroup, 0, radius * (spec.sy || 1) * (tailSpec.y ?? 0.3), (-L / 2) * 0.95, new THREE.Vector3(0, 0.02, -0.12).multiplyScalar(rig.size))\n parent.rotation.x = tailSpec.ang\n rig.tailRoot = parent\n const segmentLength = tailSpec.len / tailSpec.n\n for (let index = 0; index < tailSpec.n; index++) {\n const radius1 = tailSpec.r * (1 - (index / tailSpec.n) * 0.6)\n const radius2 = tailSpec.r * (1 - ((index + 1) / tailSpec.n) * 0.6)\n tools.limb(parent, radius1, radius2, segmentLength, tailSpec.dark && index === tailSpec.n - 1 ? dark : main)\n tools.joint(parent, radius1, main, 0, 0, 0)\n rig.tail.push(parent)\n if (index < tailSpec.n - 1) {\n const next = tools.pivot(parent, 0, -segmentLength, 0)\n next.rotation.x = tailSpec.curl || 0\n parent = next\n } else if (tailSpec.tuft) tools.ball(parent, tailSpec.r * 2.2, dark, 0, -segmentLength - tailSpec.r, 0, 1, 1.8, 1)\n }\n if (tailSpec.bushy) tools.ball(rig.tail[0] as THREE_NS.Group, tailSpec.r * 2.2, dark, 0, -tailSpec.len * 0.55, 0, 1, (tailSpec.len * 2.2) / tailSpec.r / 6, 1)\n}\n\n/** Wounds, ribs and the blood of the jaw: shown only while the animal is infected (page: the end of `quad`). */\nconst buildInfectionParts = (THREE: Three, rig: AnimalRig, spec: QuadrupedSpec, parts: { bodyGroup: THREE_NS.Group; neck: THREE_NS.Group; blood: THREE_NS.Mesh; neckSpec: QuadrupedSpec['neck'] }): void => {\n const tools = createRigTools(THREE, rig)\n const { bodyGroup, neck, blood, neckSpec } = parts\n const { L, R: radius } = spec\n const sideX = radius * (spec.sx || 1)\n const sideY = radius * (spec.sy || 1)\n const list: THREE_NS.Object3D[] = [blood]\n const wound = (parent: THREE_NS.Object3D, size: number, x: number, y: number, z: number, sx: number, sy: number, sz: number): THREE_NS.Mesh =>\n tools.ball(parent, size, rig.woundMaterial || (rig.woundMaterial = new THREE.MeshStandardMaterial({ color: 0x5a120e, roughness: 0.45 })), x, y, z, sx || 1, sy || 1, sz || 1)\n list.push(wound(bodyGroup, radius * 0.28, sideX * 0.92, sideY * 0.15, L * 0.05, 0.35, 1, 1.3))\n list.push(wound(bodyGroup, radius * 0.2, -sideX * 0.9, sideY * 0.3, -L * 0.2, 0.35, 1, 1.1))\n list.push(wound(neck, neckSpec.r * 0.5, neckSpec.r * 0.85, neckSpec.len * 0.5, 0, 0.4, 1, 1))\n const bone = tools.material(0xd9cfb8, { roughness: 0.6 })\n for (let index = 0; index < RIB_COUNT; index++) {\n const rib = addMesh(THREE, bodyGroup, new THREE.TorusGeometry(radius * 0.95, radius * 0.035, 6, 16, Math.PI * 0.42), bone, sideX * 0.12, sideY * 0.05, L * 0.12 - index * L * 0.07, 0, Math.PI / 2, -0.3)\n rib.scale.set(1, 1.02 * (spec.sy || 1), spec.sx || 1)\n list.push(rib)\n }\n rig.infectionParts.push(...list)\n list.forEach((part) => (part.visible = false))\n}\n\n/** Builds a quadruped: body, four legs on hip-knee-foot pivots, neck, head with jaw and eyes, ears, tail, the species' extra parts, and the infection parts. */\nexport const buildQuadruped = (THREE: Three, rig: AnimalRig, options: { document: DocumentLike; extra?: QuadrupedExtra }): AnimalRig => {\n const spec = rig.species.body as QuadrupedSpec\n const tools = createRigTools(THREE, rig)\n const colors = spec.c\n const texture = spec.texture ? createCoatTexture(THREE, options.document, spec.texture) : undefined\n const main = tools.material(texture ? 0xffffff : colors.main, texture ? { map: texture } : undefined)\n const belly = tools.material(colors.belly)\n const dark = tools.material(colors.dark)\n const nose = tools.material(colors.nose || colors.dark, { roughness: 0.4 })\n rig.main = main\n rig.dark = dark\n const { bodyGroup, bodyHeight } = buildBodyAndLegs(THREE, rig, spec, main, belly, dark)\n const { neck, head, blood, neckSpec, headSpec } = buildHead(THREE, rig, spec, { bodyGroup, main, belly, nose })\n buildTail(THREE, rig, spec, { bodyGroup, main, dark })\n options.extra?.({ THREE, rig, tools }, { bodyGroup, head, neck, main, belly, dark, L: spec.L, Rb: spec.R, bodyY: bodyHeight, hd: headSpec, nk: neckSpec })\n if (rig.species.outcome === 'turns') buildInfectionParts(THREE, rig, spec, { bodyGroup, neck, blood, neckSpec })\n else blood.visible = false\n return rig\n}\n","import type { TextureMarker } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport { createStream } from './context'\nimport type { CanvasLike, DocumentLike, Three } from './types'\n\ntype Painter = {\n fillStyle: string\n strokeStyle: string\n lineWidth: number\n fillRect(x: number, y: number, width: number, height: number): void\n beginPath(): void\n arc(x: number, y: number, radius: number, from: number, to: number): void\n stroke(): void\n fill(): void\n}\n\nconst canvasTexture = (THREE: Three, document: DocumentLike, width: number, height: number, draw: (painter: Painter, width: number, height: number) => void): THREE_NS.CanvasTexture => {\n const canvas: CanvasLike = document.createElement('canvas')\n canvas.width = width\n canvas.height = height\n draw(canvas.getContext('2d') as Painter, width, height)\n const texture = new THREE.CanvasTexture(canvas as unknown as HTMLCanvasElement)\n texture.colorSpace = THREE.SRGBColorSpace\n return texture\n}\n\nconst spotsTexture = (THREE: Three, document: DocumentLike, base: string, spot: string): THREE_NS.CanvasTexture =>\n canvasTexture(THREE, document, 256, 256, (painter, width, height) => {\n painter.fillStyle = base\n painter.fillRect(0, 0, width, height)\n const next = createStream(11)\n for (let index = 0; index < 70; index++) {\n const x = next() * width\n const y = next() * height\n const radius = 5 + next() * 7\n painter.strokeStyle = spot\n painter.lineWidth = 3\n painter.beginPath()\n painter.arc(x, y, radius, 0, 7)\n painter.stroke()\n painter.fillStyle = 'rgba(120,70,20,.45)'\n painter.beginPath()\n painter.arc(x, y, radius * 0.6, 0, 7)\n painter.fill()\n }\n for (let index = 0; index < 60; index++) {\n painter.fillStyle = spot\n painter.beginPath()\n painter.arc(next() * width, next() * height, 1.5 + next() * 2.5, 0, 7)\n painter.fill()\n }\n })\n\nconst stripesTexture = (THREE: Three, document: DocumentLike, base: string, stripe: string): THREE_NS.CanvasTexture =>\n canvasTexture(THREE, document, 128, 128, (painter, width) => {\n painter.fillStyle = base\n painter.fillRect(0, 0, width, 128)\n painter.fillStyle = stripe\n for (let index = 0; index < 9; index++) painter.fillRect(0, index * 14 + (index % 2) * 3, width, 4)\n })\n\n/** The coat texture a species spec asks for (cat stripes, jaguar rosettes), painted on a canvas. */\nexport const createCoatTexture = (THREE: Three, document: DocumentLike, marker: TextureMarker): THREE_NS.CanvasTexture =>\n marker.kind === 'stripes' ? stripesTexture(THREE, document, marker.base, marker.stripe) : spotsTexture(THREE, document, marker.base, marker.spot)\n","import type * as THREE_NS from 'three'\n\nimport type { Three } from './types'\n\n/** A body of revolution whose radius follows `profile` along the length, rear to front, closed by a point at each end. */\nexport const profileGeometry = (THREE: Three, length: number, profile: readonly number[], segments?: number): THREE_NS.LatheGeometry => {\n const points = profile.map((radius, index) => new THREE.Vector2(index / (profile.length - 1), radius))\n const curve = new THREE.SplineCurve(points)\n const outline: THREE_NS.Vector2[] = []\n outline.push(new THREE.Vector2(0.001, -length / 2 - 0.0))\n for (let step = 0; step <= 30; step++) {\n const point = curve.getPoint(step / 30)\n outline.push(new THREE.Vector2(Math.max(0.001, point.y), -length / 2 + point.x * length))\n }\n outline.push(new THREE.Vector2(0.001, length / 2))\n return new THREE.LatheGeometry(outline, segments || 22).rotateX(Math.PI / 2)\n}\n","import { addMesh, createRigTools } from './context'\nimport type { AnimalRig, Three } from './types'\n\nconst SEGMENT_COUNT = 34\nconst SEGMENT_LENGTH = 0.042\n\n/** Builds a snake: 34 spheres on their own groups along the trunk (the animation lays them on a path), a head with a jaw and a tongue. */\nexport const buildSnake = (THREE: Three, rig: AnimalRig): AnimalRig => {\n const tools = createRigTools(THREE, rig)\n rig.size = 0.5\n rig.segmentLength = SEGMENT_LENGTH\n rig.segmentCount = SEGMENT_COUNT\n const primary = tools.material(0x7a6a4a)\n const secondary = tools.material(0x3a2e22)\n const belly = tools.material(0xb8a888)\n rig.main = primary\n for (let index = 0; index < SEGMENT_COUNT; index++) {\n const t = index / (SEGMENT_COUNT - 1)\n const radius = 0.012 + 0.03 * Math.sin(Math.min(1, t * 1.15) * Math.PI) * (t < 0.1 ? 0.75 + t * 2.5 : 1) + (t < 0.05 ? 0.012 : 0)\n const material = index % 4 === 1 || index % 4 === 2 ? secondary : primary\n const group = new THREE.Group()\n rig.trunk.add(group)\n const sphere = tools.ball(group, radius, material, 0, radius, 0, 1, 0.78, 1.5)\n sphere.userData.joint = index % 3 === 0 ? 1 : 0\n if (index % 3 === 0) rig.joints.push(sphere)\n rig.segments.push({ group, radius })\n }\n const head = new THREE.Group()\n rig.trunk.add(head)\n rig.head = head\n tools.ball(head, 0.032, primary, 0, 0.03, 0.025, 1.25, 0.6, 1.45)\n tools.ball(head, 0.024, secondary, 0, 0.04, 0.0, 1.3, 0.4, 0.9)\n tools.ball(head, 0.02, primary, 0, 0.028, 0.06, 0.85, 0.55, 1.1)\n const jaw = new THREE.Group()\n jaw.position.set(0, 0.018, 0.0)\n head.add(jaw)\n rig.jaw = jaw\n tools.ball(jaw, 0.026, belly, 0, 0, 0.035, 1.1, 0.35, 1.5)\n tools.eyes(head, 0.006, 0.03, 0.04, 0.045)\n rig.tongue = addMesh(THREE, head, new THREE.BoxGeometry(0.004, 0.002, 0.05), tools.material(0xb02020), 0, 0.024, 0.1)\n return rig\n}\n","import type { AnimalVisualState } from '@adatechnology/game-animals'\nimport type * as THREE_NS from 'three'\n\nimport type { AnimalRig, Three } from './types'\n\nconst INFECTED_TINT = 0x7d8a66\nconst POOL_COLOR = 0x3a0806\n\n/**\n * Applies a visual state (page: `setInfected`, with the dead look for every species): infected greys the coat, glows the eyes, shows the wounds and hides\n * the first ear; dead lets the animation lay the body down and shows a blood pool at `home`. The pool goes under `rig.root.parent`; with no parent yet,\n * it is created hidden from the scene and `rig.pool` is for the caller to add.\n */\nexport const applyVisualState = (THREE: Three, rig: AnimalRig, state: AnimalVisualState): void => {\n rig.infected = state === 'infected'\n rig.dead = state === 'dead'\n const tint = new THREE.Color(INFECTED_TINT)\n rig.materials.forEach((material) => {\n if (material === rig.eyeMaterial || material === rig.woundMaterial) return\n material.color.copy(material.userData.base as THREE_NS.Color)\n if (rig.infected) material.color.lerp(tint, 0.45).multiplyScalar(0.72)\n })\n const eye = rig.eyeMaterial\n if (eye) {\n if (rig.infected) {\n eye.color.set(0xdcd8b0)\n eye.emissive = new THREE.Color(0x8a8660)\n eye.emissiveIntensity = 0.8\n } else {\n eye.color.copy(eye.userData.base as THREE_NS.Color)\n eye.emissive = new THREE.Color(0)\n }\n }\n rig.infectionParts.forEach((part) => (part.visible = rig.infected))\n const firstEar = rig.ears[0]\n if (firstEar) firstEar.visible = !rig.infected\n if (!rig.dead) {\n rig.root.rotation.z = 0\n rig.root.position.y = 0\n }\n if (rig.pool) {\n rig.pool.visible = rig.dead\n return\n }\n if (!rig.dead) return\n const pool = new THREE.Mesh(new THREE.CircleGeometry(1, 22).rotateX(-Math.PI / 2), new THREE.MeshStandardMaterial({ color: POOL_COLOR, roughness: 0.25 }))\n pool.position.set(rig.home.x, 0.005, rig.home.z + 0.1)\n pool.receiveShadow = true\n pool.scale.setScalar(rig.size * 0.45)\n rig.root.parent?.add(pool)\n rig.pool = pool\n}\n","import type * as THREE_NS from 'three'\n\nimport type { AnimalRig } from './types'\n\n/** The \"joints\" view (page: `setJoint`): the coat turns see-through and every joint ball shows in `jointMaterial`. */\nexport const setJointView = (rig: AnimalRig, on: boolean, jointMaterial: THREE_NS.Material): void => {\n rig.materials.forEach((material) => {\n if (material === rig.eyeMaterial) return\n material.transparent = on\n material.opacity = on ? 0.28 : 1\n material.depthWrite = !on\n material.needsUpdate = true\n })\n rig.joints.forEach((joint) => {\n if (on) joint.userData.restMaterial ??= joint.material\n joint.material = on ? jointMaterial : (joint.userData.restMaterial as THREE_NS.Material)\n joint.renderOrder = on ? 2 : 0\n })\n}\n\n/** The \"split\" view (page: `setSplit`): sets where each pivot should go, the rest position or the rest plus its offset; `updateSplit` moves it there. */\nexport const setSplit = (rig: AnimalRig, on: boolean): void => {\n rig.pivots.forEach((pivot) => {\n pivot.group.userData.target = on ? pivot.rest.clone().add(pivot.offset) : pivot.rest.clone()\n })\n}\n\n/** Moves each pivot toward its split target (the page does it in the frame loop: a lerp of 5 per second). */\nexport const updateSplit = (rig: AnimalRig, delta: number): void => {\n rig.pivots.forEach((pivot) => {\n const target = pivot.group.userData.target as THREE_NS.Vector3 | undefined\n if (target) pivot.group.position.lerp(target, Math.min(1, delta * 5))\n })\n}\n","// The calls of the animals, as recipes of @adatechnology/game-audio: the game's `bichoSom` (jogo L66625), which synthesizes four calls with the same\n// routine (the dog's two filtered clicks, the lapwing's shriek, the hen's cluck, the cow's moo). Linear fall to silence at 70 m, as the page has it; the\n// numbers are drawn and the nodes created in the page's order, so a recipe leaves the trace of the team code (tests/audio.test.ts against\n// tools/golden/fixtures/audio/game-audio.json).\nimport { DISTANCE_CURVES } from '@adatechnology/game-audio'\nimport type { SoundBank, SoundRecipe } from '@adatechnology/game-audio'\n\ntype Call = {\n readonly id: string\n /** The name in the team code. */\n readonly team: string\n readonly count: number\n readonly spacing: number\n readonly seconds: number\n readonly wave: OscillatorType\n readonly frequency: number\n /** The pitch falls to this fraction of itself over each pass. */\n readonly drop: number\n}\n\nconst call = (o: Call): SoundRecipe => ({\n id: o.id,\n bus: 'world',\n order: 'calls',\n duration: o.seconds,\n tail: 0.02,\n // the page makes its gain and filter before it looks at the level\n keepSilent: true,\n layers: [\n {\n repeat: { count: o.count, spacing: o.spacing },\n source: { kind: 'osc', wave: o.wave, frequency: { from: o.frequency, to: o.frequency * o.drop, curve: 'exp', over: 'duration' } },\n filters: { mode: 'serial', bank: [{ type: 'bandpass', frequency: { set: o.frequency * 1.2 }, q: 3 }] },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [0.015, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: DISTANCE_CURVES.animals,\n sources: [`jogo:L66625-66639 bichoSom('${o.team}')`],\n})\n\n/** `latido`: two square clicks 0.22 s apart, 520 Hz falling to 0.6, 0.12 s each. */\nexport const DOG_BARK = call({ id: 'dog_bark', team: 'latido', count: 2, spacing: 0.22, seconds: 0.12, wave: 'square', frequency: 520, drop: 0.6 })\n/** `queroquero`: three squares 0.14 s apart, 2400 Hz falling to 0.6, 0.09 s each. */\nexport const LAPWING_CALL = call({ id: 'lapwing_call', team: 'queroquero', count: 3, spacing: 0.14, seconds: 0.09, wave: 'square', frequency: 2400, drop: 0.6 })\n/** `cacarejo`: four squares 0.14 s apart, 900 Hz falling to 0.6, 0.09 s each. */\nexport const HEN_CLUCK = call({ id: 'hen_cluck', team: 'cacarejo', count: 4, spacing: 0.14, seconds: 0.09, wave: 'square', frequency: 900, drop: 0.6 })\n/** `mugido`: one sawtooth, 140 Hz falling to 0.8, 1.2 s. */\nexport const COW_MOO = call({ id: 'cow_moo', team: 'mugido', count: 1, spacing: 0.14, seconds: 1.2, wave: 'sawtooth', frequency: 140, drop: 0.8 })\n\nexport const ANIMAL_SOUNDS: readonly SoundRecipe[] = [DOG_BARK, LAPWING_CALL, HEN_CLUCK, COW_MOO]\n\nexport const ANIMAL_SOUND_BANK: SoundBank = { id: 'animals_three', sounds: ANIMAL_SOUNDS }\n","{\n \"sources\": [\n \"jogo:L66677 galinha: cacarejo, 6 s between calls, noise 30 m\",\n \"jogo:L66680 quero-quero: queroquero when the player is near (alarme), 8 s, noise 40 m\",\n \"jogo:L66681 vaca: mugido, 30 s, noise 80 m\",\n \"jogo:L66683 cachorro: latido when a zombie is within 12 m, 3 s, noise 60 m\"\n ],\n \"species\": {\n \"chicken\": { \"sound\": \"hen_cluck\", \"cooldown\": 6, \"noiseMetres\": 30 },\n \"southern_lapwing\": { \"sound\": \"lapwing_call\", \"cooldown\": 8, \"noiseMetres\": 40 },\n \"cow\": { \"sound\": \"cow_moo\", \"cooldown\": 30, \"noiseMetres\": 80 },\n \"dog\": { \"sound\": \"dog_bark\", \"cooldown\": 3, \"noiseMetres\": 60 }\n }\n}\n","import type { SoundRequest, Vec3 } from '@adatechnology/game-contracts'\n\nimport { ANIMAL_SOUND_BANK } from './recipes'\nimport callsData from './calls.json'\n\n/** The call of a species: the recipe, the seconds the page waits before the same animal calls again, and the metres its noise reaches the AI (`emitNoise`). */\nexport type AnimalCall = { readonly sound: string; readonly cooldown: number; readonly noiseMetres: number }\n\ntype CallsData = { readonly sources: readonly string[]; readonly species: Readonly<Record<string, AnimalCall>> }\n\nconst DATA = callsData as unknown as CallsData\n\n/** The calls the page delivered, by species id. The other species (horse, pig, boar, capybara, jaguar, cat, vulture, snake, rat) have none: the page gives them no sound. */\nexport const ANIMAL_CALLS: Readonly<Record<string, AnimalCall>> = DATA.species\nexport const ANIMAL_CALL_SOURCES: readonly string[] = DATA.sources\n\n/** The part of the host's sound an animal needs: `play`, and `register` to put the bank in its engine (`createAudioSink(...)` has both). */\nexport type AnimalSoundSink = {\n play(request: SoundRequest): unknown\n register?(bank: unknown): void\n}\n\nexport type AnimalSoundOptions = {\n /** Replaces a species' call; `null` silences it. */\n readonly calls?: Readonly<Record<string, AnimalCall | null>>\n}\n\nexport type AnimalSound = {\n /** The call of a species, if it has one. */\n callOf(speciesId: string): AnimalCall | undefined\n /**\n * Makes the species call where the animal is. `key` is the animal (default the species): the same animal waits out its cooldown, and the call is\n * refused (false) until then. Returns whether a sound was asked for.\n */\n call(speciesId: string, position: Vec3, options?: { readonly volume?: number; readonly key?: string }): boolean\n /** Counts the cooldowns down: call it each frame. */\n update(dt: number): void\n dispose(): void\n}\n\n/**\n * Plays the calls of the animals on the host's sound: the four of the Bichos do Vale (hen, lapwing, cow, dog), positional with the page's linear 70 m\n * fall, each animal waiting out the page's cooldown. The bank is registered in the host's engine.\n */\nexport function createAnimalSound(sink: AnimalSoundSink, options: AnimalSoundOptions = {}): AnimalSound {\n sink.register?.(ANIMAL_SOUND_BANK)\n const calls: Record<string, AnimalCall | null | undefined> = { ...ANIMAL_CALLS, ...options.calls }\n const waiting = new Map<string, number>()\n const callOf = (speciesId: string): AnimalCall | undefined => calls[speciesId] ?? undefined\n return {\n callOf,\n call(speciesId, position, o = {}) {\n const found = callOf(speciesId)\n if (!found) return false\n const key = o.key ?? speciesId\n if ((waiting.get(key) ?? 0) > 0) return false\n waiting.set(key, found.cooldown)\n sink.play({ sound: found.sound, position, ...(o.volume === undefined ? {} : { volume: o.volume }) })\n return true\n },\n update(dt) {\n for (const [key, seconds] of waiting) {\n if (seconds - dt <= 0) waiting.delete(key)\n else waiting.set(key, seconds - dt)\n }\n },\n dispose: () => waiting.clear(),\n }\n}\n","import { lineUpLength } from '@adatechnology/game-animals'\n\nimport type { AnimalRig } from './types'\n\nexport type LineUpOptions = {\n /** X where the row starts (page: -19). */\n readonly start?: number\n /** Gap between animals (page: 0.85). */\n readonly gap?: number\n /** Heading of the animals, radians (page: 1.1; snakes 2.2). */\n readonly yaw?: number\n readonly snakeYaw?: number\n}\n\n/** Puts the animals in a row on the x axis, each given room by its length, the row centred on the origin, and keeps each place as `home` (page: the line-up). */\nexport const lineUpAnimals = (rigs: readonly AnimalRig[], options: LineUpOptions = {}): void => {\n const start = options.start ?? -19\n const gap = options.gap ?? 0.85\n let cursor = start\n for (const rig of rigs) {\n const length = lineUpLength(rig.species.body)\n cursor += length / 2\n rig.root.position.set(cursor, 0, 0)\n rig.home = rig.root.position.clone()\n rig.root.rotation.y = rig.species.body.kind === 'snake' ? (options.snakeYaw ?? 2.2) : (options.yaw ?? 1.1)\n cursor += length / 2 + gap\n }\n const offset = -(cursor - gap + start) / 2\n for (const rig of rigs) {\n rig.root.position.x += offset\n rig.home.x += offset\n }\n}\n","import { lineUpLength, visualStateOf } from '@adatechnology/game-animals'\nimport type { AnimalSpecies, AnimalVisualState } from '@adatechnology/game-animals'\nimport type { BenchChange, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ModuleScenario, TestableItem, TestableModule } from '@adatechnology/game-contracts'\nimport type { NodeSkin } from '@adatechnology/game-props3d'\nimport type * as THREE_NS from 'three'\n\nimport { createAnimalSound } from '../audio/sound'\nimport type { AnimalSound } from '../audio/sound'\nimport { createAnimalsThree } from '../index'\nimport type { AnimalsThree } from '../index'\nimport type { AnimalRig, Three } from '../types'\nimport { createScenarios } from './scenarios'\nimport type { AnimalsContext, ScenarioDeps } from './scenarios'\nimport { TEXT } from './text'\nimport type { AnimalsTestOptions, OutbreakLike } from './types'\n\nexport const ANIMALS_AREA_ID = 'animals_area'\nexport const ANIMAL_ITEM_PREFIX = 'animal_'\nconst SKIN_COUNT = 40\nconst SKIN_FIELD = { x0: -18, z0: -10, columns: 8, gap: 4.5 }\nconst DEFAULT_TIME_SCALE = 60\n\ntype Fate = NonNullable<ReturnType<OutbreakLike['bite']>>\ntype Placed = { readonly id: string; readonly rig: AnimalRig; fate?: Fate; counted?: 'turned' | 'dead' }\n\n/**\n * The animals test area as a `TestableModule`: the species of the pack in a row, each drawn by the Bichos do Vale builders, with the alive / infected / dead looks, the gait,\n * the joints and split views, the rings for how far its sound carries and how far a carcass lures, the outbreak rule with an accelerated bite clock, and a field of 40 animals\n * drawn as node skins. The species and the outbreak rule come in by option, so this package knows no game.\n */\nexport function createAnimalsTestModule(options: AnimalsTestOptions = {}): TestableModule<AnimalsContext> & { readonly placed: ReadonlyMap<string, unknown> } {\n const locale = options.locale ?? 'pt-BR'\n const text = TEXT[locale] ?? (TEXT['pt-BR'] as (typeof TEXT)[string])\n const species = options.species ?? []\n const settings = { visual: 'alive' as AnimalVisualState, gait: 'walk', speed: 1, outbreak: true, timeScale: DEFAULT_TIME_SCALE }\n let three: Three | null = null\n let animals: AnimalsThree | null = null\n let host: ModuleHost | null = null\n let outbreak: OutbreakLike | null = null\n let sound: AnimalSound | null = null\n let time = 0\n let clock = 0\n let skinGroup: THREE_NS.Group | null = null\n let skins: { rig: AnimalRig; skin: NodeSkin }[] = []\n let rings: THREE_NS.Object3D[] = []\n const placed = new Map<string, Placed>()\n const random = (): number => 0.5\n const drawSeed = options.seed ?? 7\n const bitten = () => ({ turned: [...placed.values()].filter((p) => p.counted === 'turned').length, dead: [...placed.values()].filter((p) => p.counted === 'dead').length })\n\n const ensure = (THREE: Three): AnimalsThree => {\n three = THREE\n animals ??= createAnimalsThree(THREE, { seed: drawSeed, ...(options.document ? { document: options.document } : {}) })\n return animals\n }\n const rebuildOutbreak = (): void => {\n outbreak = options.createOutbreak ? options.createOutbreak({ species, enabled: settings.outbreak, timeScale: settings.timeScale }) : null\n }\n rebuildOutbreak()\n\n const item = (animal: AnimalSpecies): TestableItem => ({\n id: `${ANIMAL_ITEM_PREFIX}${animal.id}`,\n name: animal.name[locale as 'en'] ?? animal.id,\n movable: false,\n build: (THREE: unknown) => {\n const rig = ensure(THREE as Three).build(animal)\n // the room puts the tree in its scene right after this; trees that never reach it are dropped at the next frame\n placed.set(rig.root.uuid, { id: rig.root.uuid, rig })\n if (settings.visual !== 'alive') animals?.setVisualState(rig, settings.visual)\n return rig.root\n },\n })\n\n const statusOf = (entry: Placed): void => {\n if (!entry.fate || !outbreak) return\n const state = outbreak.stateOf(entry.fate, clock)\n if (state === 'incubating') return\n entry.counted = state === 'turned' ? 'turned' : 'dead'\n animals?.setVisualState(entry.rig, visualStateOf(entry.rig.species.outcome, true, state === 'dead'))\n }\n\n const clearRings = (): void => {\n for (const ring of rings) ring.parent?.remove(ring)\n rings = []\n }\n const refreshLayers = (): void => {\n if (!host?.bench || !animals || !three) return\n clearRings()\n for (const entry of placed.values()) {\n animals.setJointView(entry.rig, host.bench.layer('joints'))\n animals.setSplit(entry.rig, host.bench.layer('split'))\n }\n const ring = (radius: number, color: number, parent: THREE_NS.Object3D): void => {\n const mesh = new (three as Three).Mesh(new (three as Three).RingGeometry(radius - 0.15, radius, 96).rotateX(-Math.PI / 2), new (three as Three).MeshBasicMaterial({ color, transparent: true, opacity: 0.55, depthWrite: false }))\n mesh.position.y = 0.03\n parent.add(mesh)\n rings.push(mesh)\n }\n for (const entry of placed.values()) {\n if (!entry.rig.root.parent) continue\n const radius = entry.rig.species.soundRangeMetres\n if (host.bench.layer('sound_range') && radius) ring(radius, 0x44aaff, entry.rig.root)\n const lure = entry.rig.species.outbreak?.carcass?.lureRadiusMetres\n if (host.bench.layer('carcass_lure') && lure) ring(lure, 0xff5533, entry.rig.root)\n }\n }\n\n const addSkins = (): void => {\n if (!animals || !three || !host) return\n skinGroup ??= new three.Group()\n if (!skinGroup.parent) (host.scene as THREE_NS.Object3D).add(skinGroup)\n for (let index = skins.length; index < SKIN_COUNT; index++) {\n const animal = species[index % Math.max(1, species.length)] as AnimalSpecies\n const rig = animals.build(animal)\n const skin = animals.createSkin(rig)\n rig.root.position.set(SKIN_FIELD.x0 + (index % SKIN_FIELD.columns) * SKIN_FIELD.gap, 0, SKIN_FIELD.z0 - Math.floor(index / SKIN_FIELD.columns) * SKIN_FIELD.gap)\n // the tree still drives the animation, but only the skin is drawn\n rig.root.traverse((object) => {\n if ((object as THREE_NS.Mesh).isMesh) object.visible = false\n })\n skinGroup.add(rig.root, skin.mesh)\n skins.push({ rig, skin })\n }\n }\n const clearSkins = (): void => {\n skinGroup?.parent?.remove(skinGroup)\n skinGroup = null\n skins = []\n }\n\n const applyVisual = (): void => {\n for (const entry of placed.values()) {\n if (entry.fate) continue\n animals?.setVisualState(entry.rig, settings.visual)\n }\n }\n\n const onChange = (change: BenchChange): void => {\n if (change.kind === 'layer') return refreshLayers()\n if (change.kind === 'action') {\n if (change.id === 'bite_all') {\n for (const entry of placed.values()) {\n entry.fate = outbreak?.bite(entry.rig.species.id, random, clock)\n if (entry.fate) animals?.setVisualState(entry.rig, visualStateOf(entry.rig.species.outcome, true))\n }\n } else if (change.id === 'recover') {\n for (const entry of placed.values()) {\n delete entry.fate\n delete entry.counted\n animals?.setVisualState(entry.rig, settings.visual)\n }\n } else if (change.id === 'call' && sound) {\n for (const [id, entry] of placed) {\n const at = entry.rig.root.getWorldPosition(new (three as Three).Vector3())\n sound.call(entry.rig.species.id, [at.x, at.y + 0.5, at.z], { key: id })\n }\n } else if (change.id === 'skin_40') addSkins()\n else if (change.id === 'clear_skins') clearSkins()\n return\n }\n switch (change.id) {\n case 'visual_state': settings.visual = String(change.value) as AnimalVisualState; applyVisual(); break\n case 'gait': settings.gait = String(change.value); break\n case 'speed': settings.speed = Number(change.value); break\n case 'outbreak': settings.outbreak = Boolean(change.value); if (outbreak) outbreak.enabled = settings.outbreak; break\n case 'time_scale': settings.timeScale = Number(change.value); rebuildOutbreak(); break\n default: break\n }\n }\n\n const frame = (dt: number): void => {\n time += dt * settings.speed\n clock += dt\n sound?.update(dt)\n for (const [id, entry] of placed) {\n if (!entry.rig.root.parent) {\n placed.delete(id)\n continue\n }\n statusOf(entry)\n animals?.animate(entry.rig, { time, delta: dt * settings.speed, clip: settings.gait, split: host?.bench?.layer('split') ?? false })\n animals?.updateSplit(entry.rig, dt)\n }\n for (const { rig, skin } of skins) {\n animals?.animate(rig, { time, delta: dt * settings.speed, clip: settings.gait })\n rig.root.updateMatrixWorld(true)\n skin.update()\n }\n }\n\n const countMeshes = (only?: 'skins'): { drawCalls: number; triangles: number } => {\n let drawCalls = 0\n let triangles = 0\n const count = (root: THREE_NS.Object3D): void =>\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh || !mesh.visible) return\n drawCalls += 1\n const geometry = mesh.geometry\n triangles += geometry.index ? geometry.index.count / 3 : geometry.attributes.position.count / 3\n })\n if (only !== 'skins') for (const entry of placed.values()) count(entry.rig.root)\n for (const { skin } of skins) count(skin.mesh)\n return { drawCalls, triangles: Math.round(triangles) }\n }\n\n const deps: ScenarioDeps = {\n text: text.scenarios,\n species: () => species,\n ensure: () => ensure((three ?? host?.THREE) as Three),\n outbreak: () => outbreak,\n rebuildOutbreak: (enabled) => {\n settings.outbreak = enabled\n rebuildOutbreak()\n return outbreak\n },\n skins: () => {\n ensure((three ?? host?.THREE) as Three)\n addSkins()\n return { count: skins.length, meshes: countMeshes('skins'), nodes: skins[0]?.skin.nodes.length ?? 0, rich: skins[0]?.rig.triangles ?? 0 }\n },\n clearSkins,\n }\n\n return {\n id: ANIMALS_AREA_ID,\n name: text.name,\n group: text.group,\n get placed() {\n return placed\n },\n items: () => species.map(item),\n area: (): ModuleArea => {\n // the page's line-up: each animal given room by its length (and a gap), the row centred on the origin\n const gap = 0.85\n let cursor = 0\n const spots = species.map((animal) => {\n const length = lineUpLength(animal.body)\n const x = cursor + length / 2\n cursor += length + gap\n return { animal, x }\n })\n const offset = -(cursor - gap) / 2\n return {\n placements: spots.map(({ animal, x }) => ({ item: `${ANIMAL_ITEM_PREFIX}${animal.id}`, position: [x + offset, 0, 0], rotationY: animal.body.kind === 'snake' ? 2.2 : 1.1 })),\n view: { eye: [0, 4, Math.max(10, (cursor - gap) * 0.55)], target: [0, 0.6, 0] },\n }\n },\n controls: (): ModuleControl[] => [\n { kind: 'choice', id: 'visual_state', name: text.controls.visual_state, hint: text.hints.visual_state, options: (['alive', 'infected', 'dead'] as const).map((id) => ({ id, name: text.options.visual_state[id] as string })), default: 'alive' },\n { kind: 'choice', id: 'gait', name: text.controls.gait, hint: text.hints.gait, options: (['idle', 'walk', 'run'] as const).map((id) => ({ id, name: text.options.gait[id] as string })), default: 'walk' },\n { kind: 'number', id: 'speed', name: text.controls.speed, min: 0, max: 4, step: 0.25, default: 1 },\n { kind: 'boolean', id: 'outbreak', name: text.controls.outbreak, hint: text.hints.outbreak, default: true },\n { kind: 'number', id: 'time_scale', name: text.controls.time_scale, hint: text.hints.time_scale, min: 1, max: 600, step: 1, default: DEFAULT_TIME_SCALE },\n { kind: 'action', id: 'bite_all', name: text.actions.bite_all },\n { kind: 'action', id: 'recover', name: text.actions.recover },\n { kind: 'action', id: 'call', name: text.actions.call },\n { kind: 'action', id: 'skin_40', name: text.actions.skin_40 },\n { kind: 'action', id: 'clear_skins', name: text.actions.clear_skins },\n ],\n layers: (): ModuleLayer[] => (['joints', 'split', 'sound_range', 'carcass_lure'] as const).map((id) => ({ id, name: text.layers[id], default: false })),\n metrics: (): ModuleMetric[] => [\n { id: 'animals', name: text.metrics.animals, read: () => placed.size + skins.length },\n { id: 'draw_calls', name: text.metrics.draw_calls, read: () => countMeshes().drawCalls },\n { id: 'triangles', name: text.metrics.triangles, read: () => countMeshes().triangles },\n { id: 'nodes_per_skin', name: text.metrics.nodes_per_skin, read: () => skins[0]?.skin.nodes.length ?? 0 },\n { id: 'incubating', name: text.metrics.incubating, read: () => [...placed.values()].filter((p) => p.fate && !p.counted).length },\n { id: 'turned', name: text.metrics.turned, read: () => bitten().turned },\n { id: 'dead', name: text.metrics.dead, read: () => bitten().dead },\n ],\n scenarios: (): ModuleScenario<AnimalsContext>[] => createScenarios(deps),\n attach(lent) {\n host = lent\n ensure(lent.THREE as Three)\n sound = lent.audio && options.sound !== false ? createAnimalSound(lent.audio, options.sound ?? {}) : null\n const stopChange = lent.bench?.onChange(onChange)\n const stopFrame = lent.onFrame(frame)\n return () => {\n stopChange?.()\n stopFrame()\n clearRings()\n clearSkins()\n sound?.dispose()\n sound = null\n host = null\n }\n },\n }\n\n}\n","import { visualStateOf } from '@adatechnology/game-animals'\nimport type { AnimalSpecies } from '@adatechnology/game-animals'\nimport type { ModuleScenario } from '@adatechnology/game-contracts'\n\nimport type { AnimalsThree } from '../index'\nimport type { OutbreakLike } from './types'\n\n/** What a scenario needs of the room: the pass/fail line and time. The test room's `ScenarioContext` has both. */\nexport type AnimalsContext = { expect(condition: boolean, label: string, data?: Record<string, unknown>): void; step(seconds: number): void }\n\nexport type ScenarioDeps = {\n readonly text: Readonly<Record<string, string>>\n species(): readonly AnimalSpecies[]\n ensure(): AnimalsThree\n outbreak(): OutbreakLike | null\n rebuildOutbreak(enabled: boolean): OutbreakLike | null\n skins(): { count: number; meshes: { drawCalls: number; triangles: number }; nodes: number; rich: number }\n clearSkins(): void\n}\n\nconst SKIN_COUNT = 40\n\nexport const createScenarios = (deps: ScenarioDeps): ModuleScenario<AnimalsContext>[] => {\n const scenario = (id: string, run: ModuleScenario<AnimalsContext>['run']): ModuleScenario<AnimalsContext> => ({ id, name: deps.text[id] ?? id, run })\n const rate = () => 0.5\n return [\n scenario('visual_states', ({ expect }) => {\n const animals = deps.ensure()\n for (const species of deps.species()) {\n const rig = animals.build(species)\n animals.setVisualState(rig, 'infected')\n expect(rig.infected && !rig.dead, `${species.id}: infected`)\n animals.setVisualState(rig, 'dead')\n expect(rig.dead && !rig.infected, `${species.id}: dead`)\n animals.setVisualState(rig, 'alive')\n expect(!rig.dead && !rig.infected, `${species.id}: alive again`)\n }\n }),\n scenario('gait_moves_legs', ({ expect }) => {\n const animals = deps.ensure()\n const species = deps.species().find((entry) => entry.body.kind === 'quadruped')\n if (!species) return expect(false, 'no quadruped among the species')\n const rig = animals.build(species)\n animals.animate(rig, { time: 0, delta: 0, clip: 'walk' })\n const before = rig.legs.map((leg) => leg.hip.rotation.x)\n animals.animate(rig, { time: 0.4, delta: 0.4, clip: 'walk' })\n expect(rig.legs.some((leg, index) => leg.hip.rotation.x !== before[index]), `${species.id}: a walk step swings a hip`)\n }),\n scenario('outbreak_rule', ({ expect }) => {\n const turns = deps.species().find((entry) => entry.outcome === 'turns')\n const immune = deps.species().find((entry) => entry.outcome === 'immune')\n const on = deps.rebuildOutbreak(true)\n if (!on || !turns) return expect(false, 'no outbreak rule or no species that turns')\n expect(on.bite(turns.id, rate, 0) !== undefined, `a bite on ${turns.id} starts a fate with the rule on`)\n if (immune) expect(on.bite(immune.id, rate, 0) === undefined, `${immune.id} shrugs the bite off`)\n const off = deps.rebuildOutbreak(false)\n expect(off?.bite(turns.id, rate, 0) === undefined, 'with the rule off a bite does nothing')\n deps.rebuildOutbreak(true)\n }),\n scenario('carcass_lure', ({ expect }) => {\n const outbreak = deps.rebuildOutbreak(true)\n const dies = deps.species().find((entry) => entry.outbreak?.carcass)\n if (!outbreak || !dies) return expect(false, 'no outbreak rule or no species that leaves a carcass')\n const carcass = outbreak.carcass(dies.id, [0, 0, 0], 0)\n expect(carcass !== undefined, `${dies.id} leaves a carcass`)\n if (!carcass) return\n expect(outbreak.lures(carcass, carcass.lureRadiusMetres - 1, 1), 'a zombie inside the radius is drawn')\n expect(!outbreak.lures(carcass, carcass.lureRadiusMetres + 1, 1), 'a zombie outside it is not')\n }),\n scenario('bite_to_turn_timer', ({ expect }) => {\n const outbreak = deps.rebuildOutbreak(true)\n const turns = deps.species().find((entry) => entry.outcome === 'turns')\n if (!outbreak || !turns) return expect(false, 'no outbreak rule or no species that turns')\n const fate = outbreak.bite(turns.id, rate, 0)\n if (!fate) return expect(false, 'the bite took')\n expect(outbreak.stateOf(fate, 0) === 'incubating', 'it incubates at first')\n expect(outbreak.stateOf(fate, fate.dueAt + 1) === 'turned', 'it has turned once the time is up (the bench clock runs it accelerated)')\n expect(visualStateOf(turns.outcome, true) === 'infected', 'and shows the infected look')\n }),\n scenario('skins_40', ({ expect }) => {\n const result = deps.skins()\n expect(result.count === SKIN_COUNT, `${SKIN_COUNT} animals are in the field`, { count: result.count })\n expect(result.meshes.drawCalls <= SKIN_COUNT + 16, 'the skins are about one draw call each', result.meshes)\n expect(result.nodes > 0, 'each skin keeps the nodes the animation moves', { nodes: result.nodes })\n deps.clearSkins()\n }),\n ]\n}\n","export type AnimalsText = {\n group: string\n name: string\n controls: Record<'visual_state' | 'gait' | 'speed' | 'outbreak' | 'time_scale', string>\n hints: Record<'visual_state' | 'gait' | 'outbreak' | 'time_scale', string>\n options: { visual_state: Record<string, string>; gait: Record<string, string> }\n actions: Record<'bite_all' | 'recover' | 'call' | 'skin_40' | 'clear_skins', string>\n layers: Record<'joints' | 'split' | 'sound_range' | 'carcass_lure', string>\n metrics: Record<'animals' | 'draw_calls' | 'triangles' | 'nodes_per_skin' | 'incubating' | 'turned' | 'dead', string>\n scenarios: Record<string, string>\n}\n\nexport const TEXT: Record<string, AnimalsText> = {\n en: {\n group: 'Animals',\n name: 'Animals area',\n controls: { visual_state: 'Visual state', gait: 'Gait', speed: 'Animation speed', outbreak: 'Outbreak rule', time_scale: 'Bite clock' },\n hints: {\n visual_state: 'The look of every animal: alive, infected (grey coat, glowing eyes, wounds) or dead (lying down, a pool of blood)',\n gait: 'idle, walk or run; the cycle of each species runs at its own rate',\n outbreak: 'Off: a bite does nothing. On: a species that turns incubates and turns, one that dies dies, the rest shrug it off',\n time_scale: 'Game seconds per real second for the bite timers (60: ten minutes pass in ten seconds)',\n },\n options: { visual_state: { alive: 'Alive', infected: 'Infected', dead: 'Dead' }, gait: { idle: 'Idle', walk: 'Walk', run: 'Run' } },\n actions: { bite_all: 'Bite every animal', recover: 'Heal every animal', call: 'Make the animals with a call call (hen, lapwing, cow, dog)', skin_40: 'Add 40 animals as node skins', clear_skins: 'Remove the skins' },\n layers: { joints: 'Joints', split: 'Split view', sound_range: 'Sound range', carcass_lure: 'Carcass lure radius' },\n metrics: { animals: 'Animals', draw_calls: 'Draw calls', triangles: 'Triangles', nodes_per_skin: 'Nodes per skin', incubating: 'Incubating', turned: 'Turned', dead: 'Dead' },\n scenarios: {\n visual_states: 'Alive, infected and dead for every species',\n gait_moves_legs: 'The gait moves the legs',\n outbreak_rule: 'Outbreak rule on and off',\n carcass_lure: 'A carcass lures zombies within its radius',\n bite_to_turn_timer: 'Bite, incubation, turn (accelerated)',\n skins_40: '40 animals as node skins',\n },\n },\n 'pt-BR': {\n group: 'Animais',\n name: 'Área de animais',\n controls: { visual_state: 'Estado visual', gait: 'Andar', speed: 'Velocidade da animação', outbreak: 'Regra de surto', time_scale: 'Relógio da mordida' },\n hints: {\n visual_state: 'O aspecto de todos os bichos: vivo, infectado (pelo cinza, olhos brilhando, feridas) ou morto (deitado, poça de sangue)',\n gait: 'idle, walk ou run; o ciclo de cada espécie anda no seu ritmo',\n outbreak: 'Desligada: a mordida não faz nada. Ligada: a espécie que vira incuba e vira, a que morre morre, as outras não sentem',\n time_scale: 'Segundos de jogo por segundo real nos prazos da mordida (60: dez minutos passam em dez segundos)',\n },\n options: { visual_state: { alive: 'Vivo', infected: 'Infectado', dead: 'Morto' }, gait: { idle: 'Parado', walk: 'Andando', run: 'Correndo' } },\n actions: { bite_all: 'Morder todos os bichos', recover: 'Curar todos os bichos', call: 'Fazer os bichos com chamado chamarem (galinha, quero-quero, vaca, cachorro)', skin_40: 'Pôr 40 bichos como pele de nós', clear_skins: 'Tirar as peles' },\n layers: { joints: 'Juntas', split: 'Vista aberta', sound_range: 'Alcance do som', carcass_lure: 'Raio de atração da carcaça' },\n metrics: { animals: 'Bichos', draw_calls: 'Chamadas de desenho', triangles: 'Triângulos', nodes_per_skin: 'Nós por pele', incubating: 'Incubando', turned: 'Viraram', dead: 'Morreram' },\n scenarios: {\n visual_states: 'Vivo, infectado e morto em cada espécie',\n gait_moves_legs: 'O andar mexe as pernas',\n outbreak_rule: 'Regra de surto ligada e desligada',\n carcass_lure: 'A carcaça atrai zumbis dentro do raio',\n bite_to_turn_timer: 'Mordida, incubação, vira (acelerado)',\n skins_40: '40 bichos como pele de nós',\n },\n },\n}\n"],"mappings":"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","names":["PI","PI","lineUpLength","visualStateOf","SKIN_COUNT","visualStateOf","lineUpLength"]}