@adatechnology/game-weather-three 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/index.d.ts +18 -1
- package/dist/index.global.js +72 -45
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +11 -19
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -419,29 +419,21 @@ var TEXTS = {
|
|
|
419
419
|
var weatherVisualTextOf = (locale) => TEXTS[locale] ?? TEXTS[locale.split("-")[0] ?? "en"] ?? TEXTS.en;
|
|
420
420
|
|
|
421
421
|
// src/bench/visual.ts
|
|
422
|
+
var RIG_VEHICLE = "midsize_sedan";
|
|
422
423
|
var LAYER_ORDER = ["far_rain", "near_rain", "mist", "sky", "lightning", "headlights", "haze"];
|
|
423
424
|
var RIG_DEFAULT = [1.6, -2.5, 0];
|
|
424
|
-
function buildRig(THREE) {
|
|
425
|
+
function buildRig(THREE, vehicles, key) {
|
|
425
426
|
const group = new THREE.Group();
|
|
426
427
|
group.name = "weather-lamp-rig";
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
for (const side of [-1, 1]) {
|
|
432
|
-
const lamp = new THREE.Mesh(lampGeometry, lens);
|
|
433
|
-
lamp.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], 2.11);
|
|
434
|
-
group.add(lamp);
|
|
428
|
+
const car = vehicles?.build(key, { quality: "lite" });
|
|
429
|
+
if (car) {
|
|
430
|
+
car.group.position.z = HEADLIGHTS.lamp[2] + 0.1 - car.length / 2;
|
|
431
|
+
group.add(car.group);
|
|
435
432
|
}
|
|
436
|
-
group.add(body);
|
|
437
433
|
return {
|
|
438
434
|
group,
|
|
439
|
-
lens,
|
|
440
435
|
dispose() {
|
|
441
|
-
|
|
442
|
-
body.material.dispose();
|
|
443
|
-
lampGeometry.dispose();
|
|
444
|
-
lens.dispose();
|
|
436
|
+
car?.dispose();
|
|
445
437
|
}
|
|
446
438
|
};
|
|
447
439
|
}
|
|
@@ -466,19 +458,19 @@ function createWeatherVisual(options = {}) {
|
|
|
466
458
|
...options.headlights ? { headlights: options.headlights } : {},
|
|
467
459
|
...options.layers ? { layers: options.layers } : {}
|
|
468
460
|
});
|
|
469
|
-
return attachRig(THREE, host, renderer, options.rig === void 0 ? RIG_DEFAULT : options.rig);
|
|
461
|
+
return attachRig(THREE, host, renderer, options.rig === void 0 ? RIG_DEFAULT : options.rig, options.vehicles?.(THREE), options.rigVehicle ?? RIG_VEHICLE);
|
|
470
462
|
}
|
|
471
463
|
};
|
|
472
464
|
}
|
|
473
|
-
function attachRig(THREE, host, renderer, place) {
|
|
465
|
+
function attachRig(THREE, host, renderer, place, vehicles, key) {
|
|
474
466
|
const scene = host.scene;
|
|
475
|
-
const rig = place === false ? void 0 : buildRig(THREE);
|
|
467
|
+
const rig = place === false ? void 0 : buildRig(THREE, vehicles, key);
|
|
476
468
|
let detach;
|
|
477
469
|
if (rig && place) {
|
|
478
470
|
rig.group.position.set(place[0], 0, place[1]);
|
|
479
471
|
rig.group.rotation.y = place[2];
|
|
480
472
|
scene.add(rig.group);
|
|
481
|
-
detach = renderer.headlights.attach(rig.group
|
|
473
|
+
detach = renderer.headlights.attach(rig.group);
|
|
482
474
|
}
|
|
483
475
|
return {
|
|
484
476
|
update: (dt) => renderer.update(dt),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sky.ts","../src/fog.ts","../src/headlights.ts","../src/heat-haze.ts","../src/lightning.ts","../src/rain-near.ts","../src/rain-curtain.ts","../src/renderer.ts","../src/bench/text.ts","../src/bench/visual.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib, ZoneFog } from './types'\n\n/** The colours of the game's `skyUpdate` (jogo.js `_skyN` and `_skyD`): the sky goes from the night one to the day one with the sun height. */\nexport const SKY_NIGHT = 0x0b0f18\nexport const SKY_DAY = 0x8796a6\n/** The zone fog colour is lit by `0.35 + 0.65 s` (the page's `ZONA_NEBLINA` blend). */\nexport const ZONE_LIGHT = { base: 0.35, sun: 0.65 } as const\n/** The page's zone fog (`ZONA_NEBLINA`): colour and far distance; its weight is the game's to set. */\nexport const ZONE_FOG_DEFAULTS = { color: 0x3a4a3a, far: 60 } as const\n\nexport type Sky = {\n /** The sky colour for this weather: night to day by `sample.sun`, dimmed by `sample.skyScale` (the page's 0.8 in rain), pulled to the zone colour by its weight. */\n update(sample: WeatherSample, zone?: ZoneFog): THREE_NS.Color\n readonly color: THREE_NS.Color\n}\n\n/** Writes the sky into `scene.background` (a `Color`; made when the scene has none) and hands the colour to the fog. */\nexport function createSky(THREE: ThreeLib, scene: { background: unknown }): Sky {\n const night = new THREE.Color(SKY_NIGHT)\n const day = new THREE.Color(SKY_DAY)\n const zoneColor = new THREE.Color(ZONE_FOG_DEFAULTS.color)\n const tint = new THREE.Color()\n const color = new THREE.Color()\n return {\n color,\n update(sample, zone) {\n color.lerpColors(night, day, sample.sun)\n color.multiplyScalar(sample.skyScale)\n if (zone && zone.weight > 0) {\n zoneColor.setHex(zone.color ?? ZONE_FOG_DEFAULTS.color)\n color.lerp(tint.copy(zoneColor).multiplyScalar(ZONE_LIGHT.base + sample.sun * ZONE_LIGHT.sun), zone.weight)\n }\n const background = scene.background as THREE_NS.Color | null | undefined\n if (background && (background as { isColor?: boolean }).isColor) background.copy(color)\n else scene.background = color.clone()\n return color\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { WorkshopEngine } from '@adatechnology/game-vfx'\nimport { ZONE_FOG_DEFAULTS } from './sky'\nimport type { ThreeLib, Vec3, ZoneFog } from './types'\n\n/** The page's linear fog starts at 25 m and, in the zone, at 4 m (`scene.fog.near = lerp(25, 4, weight)`). */\nexport const FOG_NEAR = 25\nexport const FOG_ZONE_NEAR = 4\n/** Below this exponential-squared density the weather uses the linear fog (the clear weathers have 0). */\nexport const FOG_EXP_FROM = 0.0005\n/** exp2 density that sees as far as a linear fog of `far` metres (2 % left): used to blend the zone fog in the exponential case. */\nexport const densityForFar = (far: number): number => Math.sqrt(Math.log(50)) / far\n\nexport type FogValues = { readonly mode: 'linear'; readonly near: number; readonly far: number } | { readonly mode: 'exp2'; readonly density: number }\n\n/** The fog the weather and the zone ask for. Pure. */\nexport function fogOf(sample: WeatherSample, zone?: ZoneFog, expFrom: number = FOG_EXP_FROM): FogValues {\n const weight = zone?.weight ?? 0\n const zoneFar = zone?.far ?? ZONE_FOG_DEFAULTS.far\n if (sample.fogDensity >= expFrom) return { mode: 'exp2', density: sample.fogDensity + (densityForFar(zoneFar) - sample.fogDensity) * weight }\n return { mode: 'linear', near: FOG_NEAR + (FOG_ZONE_NEAR - FOG_NEAR) * weight, far: sample.fogFar + (zoneFar - sample.fogFar) * weight }\n}\n\nexport type Fog = {\n /** Puts the weather's fog on the scene (the page's `fog.far` and `fog.near`, or the exponential-squared one) with the sky's colour. */\n update(sample: WeatherSample, sky: THREE_NS.Color, zone?: ZoneFog): void\n /** Takes the fog off the scene (a layer switched off). */\n clear(): void\n}\n\nexport function createFog(THREE: ThreeLib, scene: { fog: unknown }, options: { readonly expFrom?: number } = {}): Fog {\n // the fog the host had before: it comes back when the layer is switched off (the first update changes it in place, so a copy is kept)\n const original = scene.fog\n const kept = original && (original as { isFog?: boolean }).isFog ? (original as THREE_NS.Fog).clone() : original\n return {\n update(sample, sky, zone) {\n const values = fogOf(sample, zone, options.expFrom)\n const current = scene.fog as (THREE_NS.Fog & THREE_NS.FogExp2 & { isFog?: boolean; isFogExp2?: boolean }) | null | undefined\n if (values.mode === 'linear') {\n if (current?.isFog) {\n current.color.copy(sky)\n current.near = values.near\n current.far = values.far\n } else scene.fog = new THREE.Fog(sky.getHex(), values.near, values.far)\n } else if (current?.isFogExp2) {\n current.color.copy(sky)\n current.density = values.density\n } else scene.fog = new THREE.FogExp2(sky.getHex(), values.density)\n const fog = scene.fog as { color: THREE_NS.Color }\n fog.color.copy(sky)\n },\n clear() {\n scene.fog = kept && (kept as { isFog?: boolean }).isFog ? (kept as THREE_NS.Fog).clone() : (kept ?? null)\n },\n }\n}\n\n/** The Workshop's mist (W1073: low, slow, 3 to 5 m wide) and ash (fine, falling in a spiral), in a box that follows the camera. */\nexport const MIST = { box: { x: [-14, 10], y: [0.2, 1.1], z: [-3, 8] }, drift: [0.15, 0.35], life: [9, 13], size: [3, 5], grow: 1.4, color: 0x7d8aa0, alpha: 0.13, fadeIn: 0.35 } as const\nexport const ASH = { box: { x: [-10, 8], y: [4, 6], z: [-3, 7] }, fall: -0.35, life: [8, 12], size: [0.025, 0.04], color: 0xa09a90, alpha: 0.75, fadeIn: 0.1 } as const\n\n/**\n * Feeds the `normal` sprite pool of the Workshop with `mistPerSecond` puffs of mist and `ashPerSecond` flakes of ash a second (the page's `emit('fog', ...)`\n * and `emit('ash', ...)`, at the weather's rate instead of 5 and 14), around `camera`. The renderer of game-vfx-three draws them.\n */\nexport function emitAirborne(engine: WorkshopEngine, sample: WeatherSample, dt: number, camera: Vec3): void {\n const { random } = engine\n const around = (box: { readonly x: readonly number[]; readonly y: readonly number[]; readonly z: readonly number[] }): [number, number, number] => [\n camera[0] + random.between(box.x[0]!, box.x[1]!),\n random.between(box.y[0]!, box.y[1]!),\n camera[2] + random.between(box.z[0]!, box.z[1]!),\n ]\n if (sample.mistPerSecond > 0) {\n engine.emit('weather-mist', 'normal', sample.mistPerSecond, dt, () => ({\n p: around(MIST.box),\n v: [random.between(MIST.drift[0], MIST.drift[1]), 0, random.between(-0.05, 0.05)],\n sp: 0,\n life: MIST.life,\n size: MIST.size,\n grow: MIST.grow,\n c0: MIST.color,\n a: MIST.alpha,\n fi: MIST.fadeIn,\n }))\n }\n if (sample.ashPerSecond > 0) {\n engine.emit('weather-ash', 'normal', sample.ashPerSecond, dt, () => ({\n p: around(ASH.box),\n v: [random.between(0.1, 0.4), ASH.fall, random.between(-0.1, 0.1)],\n sp: [0.05, 0.15],\n life: ASH.life,\n size: ASH.size,\n c0: ASH.color,\n a: ASH.alpha,\n fi: ASH.fadeIn,\n gnd: 1,\n }))\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WorkshopEngine } from '@adatechnology/game-vfx'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib, Vec3 } from './types'\n\n/** The Workshop's car lamps (W101-103) and the rain that glows inside their beam (W1161-1170). */\nexport const HEADLIGHTS = {\n spot: { color: 0xfff1d0, intensity: 2.4, distance: 26, angle: 0.33, penumbra: 0.5, decay: 1.6 },\n /** Lamp position on the car (x is mirrored), where the spot points, and the cone drawn in the air. */\n lamp: [0.65, 0.74, 2.15],\n aim: [0.65, 0.2, 12],\n cone: { radius: 2.4, length: 9, segments: 18, color: 0xfff1d0, opacity: 0.06 },\n lens: { on: 0xfff1d0, off: 0x3a3a34 },\n /** Lit drops a second, thrown into the beam 1 to 13 m ahead (W1176). */\n lit: { rate: 600, depth: [1, 13], spread: 0.33, color: 0xcfdcf0, alpha: 0.9, life: 0.06, len: 0.035, velocity: [0.8, -14, 0] },\n /** Beyond this many metres a car keeps only the cone: no real light (W-b text of `farol`). */\n lightRange: 40,\n} as const\n\nexport type HeadlightRules = {\n /** Whether the lamps are lit in this weather and light (default: night, rain or fog). */\n readonly lit?: (sample: WeatherSample) => boolean\n readonly lightRange?: number\n}\n\n/** Night (the sun below the page's 0.3 night factor), rain or fog make a driver turn the lamps on. */\nexport const defaultHeadlightRule = (sample: WeatherSample): boolean => sample.nightFactor > 0.3 || sample.rain > 0 || sample.fogDensity > 0.02 || sample.visibility < 150\n\ntype Rig = { readonly car: THREE_NS.Object3D; readonly spots: THREE_NS.SpotLight[]; readonly cones: THREE_NS.Mesh[]; readonly lens: THREE_NS.MeshBasicMaterial | undefined; readonly targets: THREE_NS.Object3D[] }\n\nexport type Headlights = {\n /** Gives `car` its two spot lights and two beam cones (`lens`, when given, is the material of the lamp glass, lit with them). Returns the function that takes them off. */\n attach(car: THREE_NS.Object3D, lens?: THREE_NS.MeshBasicMaterial): () => void\n /** Lights the lamps of the cars attached, the real light only within range of `camera`; throws the lit drops of the beams into the Workshop's streak pool. */\n update(sample: WeatherSample, dt: number, camera: Vec3, engine?: WorkshopEngine, enabled?: boolean): void\n count(): number\n dispose(): void\n}\n\nexport function createHeadlights(THREE: ThreeLib, rules: HeadlightRules = {}): Headlights {\n const rigs = new Set<Rig>()\n const cone = HEADLIGHTS.cone\n const lampWorld = new THREE.Vector3()\n const aimWorld = new THREE.Vector3()\n const forward = new THREE.Vector3()\n const rule = rules.lit ?? defaultHeadlightRule\n const range = rules.lightRange ?? HEADLIGHTS.lightRange\n\n function attach(car: THREE_NS.Object3D, lens?: THREE_NS.MeshBasicMaterial): () => void {\n const spots: THREE_NS.SpotLight[] = []\n const cones: THREE_NS.Mesh[] = []\n const targets: THREE_NS.Object3D[] = []\n for (const side of [-1, 1]) {\n const spot = new THREE.SpotLight(HEADLIGHTS.spot.color, 0, HEADLIGHTS.spot.distance, HEADLIGHTS.spot.angle, HEADLIGHTS.spot.penumbra, HEADLIGHTS.spot.decay)\n spot.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2])\n const target = new THREE.Object3D()\n target.position.set(side * HEADLIGHTS.aim[0], HEADLIGHTS.aim[1], HEADLIGHTS.aim[2])\n car.add(spot, target)\n spot.target = target\n const geometry = new THREE.ConeGeometry(cone.radius, cone.length, cone.segments, 1, true)\n geometry.translate(0, -cone.length / 2, 0)\n geometry.rotateX(-Math.PI / 2)\n const material = new THREE.MeshBasicMaterial({ color: cone.color, transparent: true, opacity: cone.opacity, blending: THREE.AdditiveBlending, depthWrite: false, side: THREE.DoubleSide, fog: false })\n const beam = new THREE.Mesh(geometry, material)\n beam.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2])\n beam.visible = false\n car.add(beam)\n spots.push(spot)\n cones.push(beam)\n targets.push(target)\n }\n const rig: Rig = { car, spots, cones, lens, targets }\n rigs.add(rig)\n return () => {\n rigs.delete(rig)\n for (const object of [...spots, ...cones, ...targets]) car.remove(object)\n for (const beam of cones) {\n beam.geometry.dispose()\n ;(beam.material as THREE_NS.Material).dispose()\n }\n for (const spot of spots) spot.dispose()\n lens?.color.setHex(HEADLIGHTS.lens.off)\n }\n }\n\n return {\n attach,\n update(sample, dt, camera, engine, enabled = true) {\n const on = enabled && rule(sample)\n let index = 0\n for (const rig of rigs) {\n rig.car.updateWorldMatrix(true, false)\n lampWorld.set(0, HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2]).applyMatrix4(rig.car.matrixWorld)\n const near = Math.hypot(lampWorld.x - camera[0], lampWorld.z - camera[2]) <= range\n for (const spot of rig.spots) spot.intensity = on && near ? HEADLIGHTS.spot.intensity : 0\n for (const beam of rig.cones) beam.visible = on\n rig.lens?.color.setHex(on ? HEADLIGHTS.lens.on : HEADLIGHTS.lens.off)\n if (!on || !engine || sample.rain <= 0 || !near) {\n index++\n continue\n }\n aimWorld.set(0, HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2] + 1).applyMatrix4(rig.car.matrixWorld)\n forward.copy(aimWorld).sub(lampWorld).normalize()\n const side: [number, number] = [forward.z, -forward.x]\n const { random } = engine\n const lit = HEADLIGHTS.lit\n engine.emit(`weather-lit-${index}`, 'streak', lit.rate, dt, () => {\n const depth = random.between(lit.depth[0], lit.depth[1])\n const spread = depth * lit.spread * Math.sqrt(random.next())\n const turn = random.between(0, 6.283)\n return {\n p: [lampWorld.x + forward.x * depth + side[0] * Math.cos(turn) * spread, lampWorld.y + forward.y * depth + Math.sin(turn) * spread * 0.6, lampWorld.z + forward.z * depth + side[1] * Math.cos(turn) * spread],\n v: lit.velocity as unknown as [number, number, number],\n sp: 0,\n life: lit.life,\n len: lit.len,\n c0: lit.color,\n a: lit.alpha,\n }\n })\n index++\n }\n },\n count: () => rigs.size,\n dispose() {\n for (const rig of [...rigs]) {\n rigs.delete(rig)\n for (const object of [...rig.spots, ...rig.cones, ...rig.targets]) rig.car.remove(object)\n }\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib } from './types'\n\n/** Peak opacity of the shimmer at full haze, and how fast the bands rise (SDK-made: no team delivered heat haze, see the open question). */\nexport const HEAT_HAZE = { opacity: 0.09, bands: 38, rise: 1.4, color: [1, 0.93, 0.82] } as const\n\nexport const HEAT_HAZE_VERTEX = 'varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.); }'\nexport const HEAT_HAZE_FRAGMENT =\n 'uniform float uTime; uniform float uHaze; uniform vec3 uColor; varying vec2 vUv; void main(){ float low = 1. - smoothstep(0.15, 0.7, vUv.y); float wave = sin(vUv.y*38. - uTime*1.4 + sin(vUv.x*11. + uTime*.7)*2.2) * .5 + .5; gl_FragColor = vec4(uColor, uHaze*low*wave*.09); }'\n\nexport type HeatHaze = {\n readonly object: THREE_NS.Mesh\n update(sample: WeatherSample, time: number): void\n dispose(): void\n}\n\n/**\n * The heat shimmer of `extreme_heat` (`WeatherSample.haze`, 0..1): a screen-space layer of warm bands that rise over the lower half of the view. It is a layer, not a\n * distortion of the picture, because bending the picture needs a render target that only the host owns.\n */\nexport function createHeatHaze(THREE: ThreeLib): HeatHaze {\n const uniforms = { uTime: { value: 0 }, uHaze: { value: 0 }, uColor: { value: new THREE.Vector3(...HEAT_HAZE.color) } }\n const material = new THREE.ShaderMaterial({ uniforms, vertexShader: HEAT_HAZE_VERTEX, fragmentShader: HEAT_HAZE_FRAGMENT, transparent: true, depthTest: false, depthWrite: false })\n const object = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material)\n object.frustumCulled = false\n object.renderOrder = 999\n object.name = 'weather-heat-haze'\n object.visible = false\n return {\n object,\n update(sample, time) {\n uniforms.uHaze.value = sample.haze\n uniforms.uTime.value = time\n object.visible = sample.haze > 0\n },\n dispose() {\n object.geometry.dispose()\n material.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib } from './types'\n\n/**\n * What the Workshop's double flash does to the scene (W1072): the hemisphere light gains `I * 3.2`, the background gains `I * (.25, .27, .32)` and the screen goes\n * white by `I * .12`, where `I` is the flash the weather samples (1, then .2, then .8 for 0.26 s).\n */\nexport const LIGHTNING = { light: 3.2, background: [0.25, 0.27, 0.32], white: 0.12, skyColor: 0x3a4c6a, groundColor: 0x0b0b0c } as const\n\nexport type Lightning = {\n readonly light: THREE_NS.HemisphereLight\n /**\n * Lights the scene with the flash of `sample`. `background`, when given, is the sky just written for this frame (the renderer passes it only when it owns the sky),\n * and gains the flash; a background the host keeps for itself is left alone.\n */\n update(sample: WeatherSample, background?: THREE_NS.Color): void\n dispose(): void\n}\n\nexport function createLightning(THREE: ThreeLib, scene: { add(object: THREE_NS.Object3D): unknown; remove(object: THREE_NS.Object3D): unknown }, vfx?: VfxWorld): Lightning {\n const light = new THREE.HemisphereLight(LIGHTNING.skyColor, LIGHTNING.groundColor, 0)\n light.name = 'weather-lightning'\n scene.add(light)\n return {\n light,\n update(sample, background) {\n const flash = sample.flash\n light.intensity = flash * LIGHTNING.light\n if (flash <= 0) return\n if (background) {\n background.r += flash * LIGHTNING.background[0]!\n background.g += flash * LIGHTNING.background[1]!\n background.b += flash * LIGHTNING.background[2]!\n }\n const screen = vfx?.workshop().screen\n if (screen) screen.white = Math.max(screen.white, flash * LIGHTNING.white)\n },\n dispose() {\n scene.remove(light)\n light.dispose()\n },\n }\n}\n","import type { Puddle, VfxWorld } from '@adatechnology/game-vfx'\nimport { inPuddle } from '@adatechnology/game-vfx'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { Vec3 } from './types'\n\n/** The rain (mm/h) from which a drop that lands splashes (the Workshop's garoa, 2.5, does not; its chuva, 15, does). */\nexport const SPLASH_FROM_MM = 5\n\nexport type NearRainOptions = {\n /** Ground ellipses where a drop leaves a ring (the Workshop's four dark puddles; a game has its own). None by default. */\n readonly puddles?: readonly Puddle[]\n /** Replaces the puddle test. */\n readonly puddleAt?: (x: number, z: number) => boolean\n readonly splashFrom?: number\n}\n\nexport type NearRain = {\n update(sample: WeatherSample, dt: number, camera: Vec3): void\n /** Streaks alive. */\n count(): number\n clear(): void\n}\n\n/**\n * The Workshop's near rain (W313-331) driven by the weather: the streaks live in the world's Workshop engine (`engine.rain`), game-vfx-three draws them, and the\n * splashes and rings they leave go to the `normal` sprite pool and the rings. `drops` (900 garoa, 2 200 chuva, 4 000 temporal) and the wind along x are the Workshop's own\n * numbers for its three intensities.\n */\nexport function createNearRain(vfx: VfxWorld | undefined, options: NearRainOptions = {}): NearRain {\n const puddles = options.puddles ?? []\n return {\n update(sample, dt, camera) {\n const raining = sample.rain > 0\n const engine = raining ? vfx?.workshop() : vfx?.peekWorkshop()\n if (!engine) return\n const field = engine.rain\n if (!raining) {\n if (field.on) field.clear()\n return\n }\n field.puddleAt = options.puddleAt ?? ((x, z) => inPuddle(puddles, x, z))\n field.drive(sample.drops, sample.windX, camera[0], camera[2])\n field.update(dt, sample.rain >= (options.splashFrom ?? SPLASH_FROM_MM), camera)\n },\n count: () => vfx?.peekWorkshop()?.rain.count ?? 0,\n clear() {\n vfx?.peekWorkshop()?.rain.clear()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib, WeatherProfileName } from './types'\n\n/**\n * The game's rain curtain (jogo.js `const RAIN = 14000`): a box of points that follows the camera, 70 m wide and 25 m high, falling 13 m/s. The shader texts and the\n * numbers are the page's, character for character (a golden cuts them from the page and compares).\n */\nexport const RAIN_CURTAIN = { count: 14000, width: 70, height: 25, speed: 13, pointSize: 1.6 } as const\n\nexport const RAIN_CURTAIN_VERTEX =\n 'uniform float uTime; uniform vec3 uCam; void main(){ vec3 p = position; p.y = mod(p.y - uTime*13., 25.); p.xz = uCam.xz + mod(p.xz - uCam.xz + 35., 70.) - 35.; gl_Position = projectionMatrix*viewMatrix*vec4(p,1.); gl_PointSize = 1.6; }'\nexport const RAIN_CURTAIN_FRAGMENT = 'uniform float uDay; void main(){ gl_FragColor = vec4(vec3(.68,.72,.78)*(0.25+0.75*uDay), .22+.1*uDay); }'\n\n/** The share of the 14 000 points each quality draws. */\nexport const RAIN_CURTAIN_PROFILES: Readonly<Record<WeatherProfileName, number>> = { low: 0.35, medium: 0.7, high: 1 }\n/** The weather's `drops` at which the whole curtain is drawn (the storm's 4 000). */\nexport const RAIN_CURTAIN_FULL_AT = 4000\n\n/** The page's loop: x and z in -35..35, y in 0..25, three draws a point in that order, stored as Float32. */\nexport function rainCurtainPositions(random: () => number = Math.random, count: number = RAIN_CURTAIN.count): Float32Array {\n const positions = new Float32Array(count * 3)\n for (let index = 0; index < count; index++) {\n positions[index * 3] = (random() - 0.5) * RAIN_CURTAIN.width\n positions[index * 3 + 1] = random() * RAIN_CURTAIN.height\n positions[index * 3 + 2] = (random() - 0.5) * RAIN_CURTAIN.width\n }\n return positions\n}\n\nexport type RainCurtainOptions = {\n readonly random?: () => number\n readonly profile?: WeatherProfileName\n /** Drops (`WeatherSample.drops`) that draw the whole curtain. */\n readonly fullAt?: number\n readonly count?: number\n}\n\nexport type RainCurtain = {\n readonly object: THREE_NS.Points\n /** Draws `sample.drops` of the curtain around `camera`; `daylight` is the game's `s` (0 night, 1 day). */\n update(sample: WeatherSample, camera: { readonly x: number; readonly y: number; readonly z: number }, time: number, daylight: number): void\n setProfile(profile: WeatherProfileName): void\n /** How many points are drawn now. */\n drawn(): number\n dispose(): void\n}\n\nexport function createRainCurtain(THREE: ThreeLib, options: RainCurtainOptions = {}): RainCurtain {\n const count = options.count ?? RAIN_CURTAIN.count\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(rainCurtainPositions(options.random, count), 3))\n const uniforms = { uTime: { value: 0 }, uCam: { value: new THREE.Vector3() }, uDay: { value: 1 } }\n const material = new THREE.ShaderMaterial({ uniforms, transparent: true, depthWrite: false, vertexShader: RAIN_CURTAIN_VERTEX, fragmentShader: RAIN_CURTAIN_FRAGMENT })\n const object = new THREE.Points(geometry, material)\n object.frustumCulled = false\n object.name = 'weather-rain-curtain'\n object.visible = false\n let share = RAIN_CURTAIN_PROFILES[options.profile ?? 'high']\n let drawn = 0\n return {\n object,\n update(sample, camera, time, daylight) {\n const fullAt = options.fullAt ?? RAIN_CURTAIN_FULL_AT\n drawn = sample.rain > 0 ? Math.round(count * share * Math.min(1, sample.drops / fullAt)) : 0\n object.visible = drawn > 0\n geometry.setDrawRange(0, drawn)\n uniforms.uTime.value = time\n uniforms.uDay.value = daylight\n uniforms.uCam.value.set(camera.x, camera.y, camera.z)\n },\n setProfile(profile) {\n share = RAIN_CURTAIN_PROFILES[profile]\n },\n drawn: () => drawn,\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport type { Puddle } from '@adatechnology/game-vfx'\nimport { createFog, emitAirborne } from './fog'\nimport type { Fog } from './fog'\nimport { createHeadlights } from './headlights'\nimport type { HeadlightRules, Headlights } from './headlights'\nimport { createHeatHaze } from './heat-haze'\nimport type { HeatHaze } from './heat-haze'\nimport { createLightning } from './lightning'\nimport type { Lightning } from './lightning'\nimport { createNearRain } from './rain-near'\nimport type { NearRain } from './rain-near'\nimport { createRainCurtain } from './rain-curtain'\nimport type { RainCurtain } from './rain-curtain'\nimport { createSky } from './sky'\nimport type { Sky } from './sky'\nimport type { ThreeLib, Vec3, WeatherProfileName, WeatherSource, ZoneFog } from './types'\n\n/** The parts the renderer draws, each of which a layer switches. */\nexport const WEATHER_LAYERS = ['far_rain', 'near_rain', 'mist', 'fog', 'sky', 'lightning', 'headlights', 'haze'] as const\nexport type WeatherLayerId = (typeof WEATHER_LAYERS)[number]\n\nexport type WeatherRendererOptions = {\n readonly scene: THREE_NS.Scene\n readonly camera: THREE_NS.Camera\n readonly weather: WeatherSource\n /** The effects world: near rain, splashes, mist, ash, the white of lightning and the lit drops of headlights live in its Workshop pools (game-vfx-three draws them). */\n readonly vfx?: VfxWorld\n readonly profile?: WeatherProfileName\n /** Seeds the rain curtain (default `Math.random`). */\n readonly random?: () => number\n readonly zone?: ZoneFog\n readonly puddles?: readonly Puddle[]\n readonly puddleAt?: (x: number, z: number) => boolean\n readonly headlights?: HeadlightRules\n readonly layers?: Partial<Record<WeatherLayerId, boolean>>\n}\n\nexport type WeatherRenderer = {\n readonly curtain: RainCurtain\n readonly nearRain: NearRain\n readonly fog: Fog\n readonly sky: Sky\n readonly lightning: Lightning\n readonly headlights: Headlights\n readonly haze: HeatHaze\n /** Draws the weather of the source for a frame of `dt` seconds. Call once per frame, after the weather advanced. */\n update(dt: number): void\n setLayer(id: WeatherLayerId, on: boolean): void\n layer(id: WeatherLayerId): boolean\n setZoneFog(zone: ZoneFog | undefined): void\n setProfile(profile: WeatherProfileName): void\n stats(): { readonly rainCurtain: number; readonly rainNear: number; readonly cars: number }\n dispose(): void\n}\n\n/** The whole weather picture: rain curtain, near rain with splashes, mist and ash, fog, sky, lightning, headlights and heat haze, from one `WeatherSource`. */\nexport function createWeatherRenderer(THREE: ThreeLib, options: WeatherRendererOptions): WeatherRenderer {\n const { scene, camera, weather, vfx } = options\n const group = new THREE.Group()\n group.name = 'weather'\n scene.add(group)\n const curtain = createRainCurtain(THREE, { ...(options.random ? { random: options.random } : {}), ...(options.profile ? { profile: options.profile } : {}) })\n const haze = createHeatHaze(THREE)\n group.add(curtain.object, haze.object)\n const sky = createSky(THREE, scene)\n const fog = createFog(THREE, scene)\n const lightning = createLightning(THREE, scene, vfx)\n const headlights = createHeadlights(THREE, options.headlights)\n const nearRain = createNearRain(vfx, { ...(options.puddles ? { puddles: options.puddles } : {}), ...(options.puddleAt ? { puddleAt: options.puddleAt } : {}) })\n const on = new Map<WeatherLayerId, boolean>(WEATHER_LAYERS.map((id) => [id, options.layers?.[id] ?? true]))\n let zone = options.zone\n let time = 0\n const eye: { x: number; y: number; z: number } = { x: 0, y: 0, z: 0 }\n\n const switchedOff = (id: WeatherLayerId): void => {\n if (id === 'far_rain') curtain.object.visible = false\n else if (id === 'near_rain') nearRain.clear()\n else if (id === 'fog') fog.clear()\n else if (id === 'lightning') lightning.light.intensity = 0\n else if (id === 'haze') haze.object.visible = false\n }\n\n return {\n curtain,\n nearRain,\n fog,\n sky,\n lightning,\n headlights,\n haze,\n update(dt) {\n time += dt\n const sample = weather.sample()\n const position = camera.position\n eye.x = position.x\n eye.y = position.y\n eye.z = position.z\n const where: Vec3 = [eye.x, eye.y, eye.z]\n const background = (scene.background as THREE_NS.Color | null) ?? undefined\n const ownSky = on.get('sky') === true\n const color = ownSky ? sky.update(sample, zone) : background && (background as { isColor?: boolean }).isColor ? background : sky.color\n if (on.get('fog')) fog.update(sample, color, zone)\n if (on.get('lightning')) lightning.update(sample, ownSky ? (scene.background as THREE_NS.Color) : undefined)\n if (on.get('far_rain')) curtain.update(sample, eye, time, sample.sun)\n if (on.get('haze')) haze.update(sample, time)\n if (vfx) {\n if (on.get('near_rain')) nearRain.update(sample, dt, where)\n if (on.get('mist')) emitAirborne(vfx.workshop(), sample, dt, where)\n }\n headlights.update(sample, dt, where, vfx && sample.rain > 0 ? vfx.workshop() : undefined, on.get('headlights'))\n },\n setLayer(id, value) {\n on.set(id, value)\n if (!value) switchedOff(id)\n },\n layer: (id) => on.get(id) === true,\n setZoneFog(next) {\n zone = next\n },\n setProfile(profile) {\n curtain.setProfile(profile)\n },\n stats: () => ({ rainCurtain: curtain.drawn(), rainNear: nearRain.count(), cars: headlights.count() }),\n dispose() {\n scene.remove(group)\n curtain.dispose()\n haze.dispose()\n lightning.dispose()\n headlights.dispose()\n nearRain.clear()\n },\n }\n}\n","import type { WeatherLayerId } from '../renderer'\n\n/** The names of the visual layers in the bench; any other locale falls back to English. */\nexport type WeatherVisualText = { readonly layers: Readonly<Record<Exclude<WeatherLayerId, 'fog'>, string>> }\n\nconst TEXTS: Readonly<Record<string, WeatherVisualText>> = {\n en: { layers: { far_rain: 'Rain curtain', near_rain: 'Near rain and splashes', mist: 'Mist and ash', sky: 'Sky', lightning: 'Lightning', headlights: 'Headlights', haze: 'Heat haze' } },\n 'pt-BR': { layers: { far_rain: 'Cortina de chuva', near_rain: 'Chuva perto e respingos', mist: 'Névoa e cinza', sky: 'Céu', lightning: 'Relâmpago', headlights: 'Faróis', haze: 'Névoa de calor' } },\n}\n\nexport const weatherVisualTextOf = (locale: string): WeatherVisualText => TEXTS[locale] ?? TEXTS[locale.split('-')[0] ?? 'en'] ?? TEXTS.en!\n","import type { ModuleHost, ModuleLayer } from '@adatechnology/game-contracts'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport type { WeatherVisual, WeatherVisualContext, WeatherVisualFactory } from '@adatechnology/game-weather'\nimport type * as THREE_NS from 'three'\nimport { HEADLIGHTS } from '../headlights'\nimport { createWeatherRenderer } from '../renderer'\nimport type { WeatherLayerId, WeatherRenderer, WeatherRendererOptions } from '../renderer'\nimport type { ThreeLib } from '../types'\nimport { weatherVisualTextOf } from './text'\n\nexport type WeatherVisualOptions = Pick<WeatherRendererOptions, 'profile' | 'random' | 'zone' | 'puddles' | 'puddleAt' | 'headlights'> & {\n /** The effects world of the room (`room.vfx`); without it the near rain, mist, ash, white flash and lit drops are left out. */\n readonly vfx?: VfxWorld\n /** Where the lamp rig stands (the two headlights of the Workshop's car, to see the beams); `false` leaves it out. Default 2.5 m ahead of the test room camera, lamps toward it. */\n readonly rig?: readonly [x: number, z: number, turn: number] | false\n /** Which layers start on (all do by default); the room that is not about weather starts the sky and the fog off to keep its own look. */\n readonly layers?: Partial<Record<WeatherLayerId, boolean>>\n}\n\nconst LAYER_ORDER: readonly Exclude<WeatherLayerId, 'fog'>[] = ['far_rain', 'near_rain', 'mist', 'sky', 'lightning', 'headlights', 'haze']\nconst RIG_DEFAULT = [1.6, -2.5, 0] as const\n\n/** Two lamps, a body and the glass of the lamps (the Workshop's `hlMat`): what the headlights are attached to when the viewer has no car in the room. */\nfunction buildRig(THREE: ThreeLib): { readonly group: THREE_NS.Group; readonly lens: THREE_NS.MeshBasicMaterial; dispose(): void } {\n const group = new THREE.Group()\n group.name = 'weather-lamp-rig'\n const body = new THREE.Mesh(new THREE.BoxGeometry(1.8, 0.7, 4.2), new THREE.MeshBasicMaterial({ color: 0x1b1d20 }))\n body.position.set(0, 0.5, 0)\n const lens = new THREE.MeshBasicMaterial({ color: HEADLIGHTS.lens.off })\n const lampGeometry = new THREE.BoxGeometry(0.35, 0.15, 0.05)\n for (const side of [-1, 1]) {\n const lamp = new THREE.Mesh(lampGeometry, lens)\n lamp.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], 2.11)\n group.add(lamp)\n }\n group.add(body)\n return {\n group,\n lens,\n dispose() {\n body.geometry.dispose()\n ;(body.material as THREE_NS.Material).dispose()\n lampGeometry.dispose()\n lens.dispose()\n },\n }\n}\n\n/**\n * The picture of the weather for the weather bench: `createWeatherTestModule({ visual: createWeatherVisual({ vfx: room.vfx }) })`. It draws the weather the bench shows with\n * `createWeatherRenderer` on the room's scene and camera, switches each part with the bench layers and puts a lamp rig in front of the camera for the headlights.\n */\nexport function createWeatherVisual(options: WeatherVisualOptions = {}): WeatherVisualFactory {\n return {\n layers(locale): readonly ModuleLayer[] {\n const text = weatherVisualTextOf(locale)\n return LAYER_ORDER.map((id) => ({ id, name: text.layers[id], default: options.layers?.[id] ?? true }))\n },\n create({ host, weather }: WeatherVisualContext): WeatherVisual {\n const THREE = host.THREE as ThreeLib\n const renderer: WeatherRenderer = createWeatherRenderer(THREE, {\n scene: host.scene as THREE_NS.Scene,\n camera: host.camera as THREE_NS.Camera,\n weather,\n ...(options.vfx ? { vfx: options.vfx } : {}),\n ...(options.profile ? { profile: options.profile } : {}),\n ...(options.random ? { random: options.random } : {}),\n ...(options.zone ? { zone: options.zone } : {}),\n ...(options.puddles ? { puddles: options.puddles } : {}),\n ...(options.puddleAt ? { puddleAt: options.puddleAt } : {}),\n ...(options.headlights ? { headlights: options.headlights } : {}),\n ...(options.layers ? { layers: options.layers } : {}),\n })\n return attachRig(THREE, host, renderer, options.rig === undefined ? RIG_DEFAULT : options.rig)\n },\n }\n}\n\nfunction attachRig(THREE: ThreeLib, host: ModuleHost, renderer: WeatherRenderer, place: readonly [number, number, number] | false): WeatherVisual {\n const scene = host.scene as THREE_NS.Scene\n const rig = place === false ? undefined : buildRig(THREE)\n let detach: (() => void) | undefined\n if (rig && place) {\n rig.group.position.set(place[0], 0, place[1])\n rig.group.rotation.y = place[2]\n scene.add(rig.group)\n detach = renderer.headlights.attach(rig.group, rig.lens)\n }\n return {\n update: (dt) => renderer.update(dt),\n setLayer(id, on) {\n if ((WEATHER_IDS as readonly string[]).includes(id)) renderer.setLayer(id as WeatherLayerId, on)\n },\n dispose() {\n detach?.()\n if (rig) {\n scene.remove(rig.group)\n rig.dispose()\n }\n renderer.dispose()\n },\n }\n}\n\nconst WEATHER_IDS: readonly WeatherLayerId[] = ['far_rain', 'near_rain', 'mist', 'fog', 'sky', 'lightning', 'headlights', 'haze']\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/sky.ts","../src/fog.ts","../src/headlights.ts","../src/heat-haze.ts","../src/lightning.ts","../src/rain-near.ts","../src/rain-curtain.ts","../src/renderer.ts","../src/bench/text.ts","../src/bench/visual.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib, ZoneFog } from './types'\n\n/** The colours of the game's `skyUpdate` (jogo.js `_skyN` and `_skyD`): the sky goes from the night one to the day one with the sun height. */\nexport const SKY_NIGHT = 0x0b0f18\nexport const SKY_DAY = 0x8796a6\n/** The zone fog colour is lit by `0.35 + 0.65 s` (the page's `ZONA_NEBLINA` blend). */\nexport const ZONE_LIGHT = { base: 0.35, sun: 0.65 } as const\n/** The page's zone fog (`ZONA_NEBLINA`): colour and far distance; its weight is the game's to set. */\nexport const ZONE_FOG_DEFAULTS = { color: 0x3a4a3a, far: 60 } as const\n\nexport type Sky = {\n /** The sky colour for this weather: night to day by `sample.sun`, dimmed by `sample.skyScale` (the page's 0.8 in rain), pulled to the zone colour by its weight. */\n update(sample: WeatherSample, zone?: ZoneFog): THREE_NS.Color\n readonly color: THREE_NS.Color\n}\n\n/** Writes the sky into `scene.background` (a `Color`; made when the scene has none) and hands the colour to the fog. */\nexport function createSky(THREE: ThreeLib, scene: { background: unknown }): Sky {\n const night = new THREE.Color(SKY_NIGHT)\n const day = new THREE.Color(SKY_DAY)\n const zoneColor = new THREE.Color(ZONE_FOG_DEFAULTS.color)\n const tint = new THREE.Color()\n const color = new THREE.Color()\n return {\n color,\n update(sample, zone) {\n color.lerpColors(night, day, sample.sun)\n color.multiplyScalar(sample.skyScale)\n if (zone && zone.weight > 0) {\n zoneColor.setHex(zone.color ?? ZONE_FOG_DEFAULTS.color)\n color.lerp(tint.copy(zoneColor).multiplyScalar(ZONE_LIGHT.base + sample.sun * ZONE_LIGHT.sun), zone.weight)\n }\n const background = scene.background as THREE_NS.Color | null | undefined\n if (background && (background as { isColor?: boolean }).isColor) background.copy(color)\n else scene.background = color.clone()\n return color\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { WorkshopEngine } from '@adatechnology/game-vfx'\nimport { ZONE_FOG_DEFAULTS } from './sky'\nimport type { ThreeLib, Vec3, ZoneFog } from './types'\n\n/** The page's linear fog starts at 25 m and, in the zone, at 4 m (`scene.fog.near = lerp(25, 4, weight)`). */\nexport const FOG_NEAR = 25\nexport const FOG_ZONE_NEAR = 4\n/** Below this exponential-squared density the weather uses the linear fog (the clear weathers have 0). */\nexport const FOG_EXP_FROM = 0.0005\n/** exp2 density that sees as far as a linear fog of `far` metres (2 % left): used to blend the zone fog in the exponential case. */\nexport const densityForFar = (far: number): number => Math.sqrt(Math.log(50)) / far\n\nexport type FogValues = { readonly mode: 'linear'; readonly near: number; readonly far: number } | { readonly mode: 'exp2'; readonly density: number }\n\n/** The fog the weather and the zone ask for. Pure. */\nexport function fogOf(sample: WeatherSample, zone?: ZoneFog, expFrom: number = FOG_EXP_FROM): FogValues {\n const weight = zone?.weight ?? 0\n const zoneFar = zone?.far ?? ZONE_FOG_DEFAULTS.far\n if (sample.fogDensity >= expFrom) return { mode: 'exp2', density: sample.fogDensity + (densityForFar(zoneFar) - sample.fogDensity) * weight }\n return { mode: 'linear', near: FOG_NEAR + (FOG_ZONE_NEAR - FOG_NEAR) * weight, far: sample.fogFar + (zoneFar - sample.fogFar) * weight }\n}\n\nexport type Fog = {\n /** Puts the weather's fog on the scene (the page's `fog.far` and `fog.near`, or the exponential-squared one) with the sky's colour. */\n update(sample: WeatherSample, sky: THREE_NS.Color, zone?: ZoneFog): void\n /** Takes the fog off the scene (a layer switched off). */\n clear(): void\n}\n\nexport function createFog(THREE: ThreeLib, scene: { fog: unknown }, options: { readonly expFrom?: number } = {}): Fog {\n // the fog the host had before: it comes back when the layer is switched off (the first update changes it in place, so a copy is kept)\n const original = scene.fog\n const kept = original && (original as { isFog?: boolean }).isFog ? (original as THREE_NS.Fog).clone() : original\n return {\n update(sample, sky, zone) {\n const values = fogOf(sample, zone, options.expFrom)\n const current = scene.fog as (THREE_NS.Fog & THREE_NS.FogExp2 & { isFog?: boolean; isFogExp2?: boolean }) | null | undefined\n if (values.mode === 'linear') {\n if (current?.isFog) {\n current.color.copy(sky)\n current.near = values.near\n current.far = values.far\n } else scene.fog = new THREE.Fog(sky.getHex(), values.near, values.far)\n } else if (current?.isFogExp2) {\n current.color.copy(sky)\n current.density = values.density\n } else scene.fog = new THREE.FogExp2(sky.getHex(), values.density)\n const fog = scene.fog as { color: THREE_NS.Color }\n fog.color.copy(sky)\n },\n clear() {\n scene.fog = kept && (kept as { isFog?: boolean }).isFog ? (kept as THREE_NS.Fog).clone() : (kept ?? null)\n },\n }\n}\n\n/** The Workshop's mist (W1073: low, slow, 3 to 5 m wide) and ash (fine, falling in a spiral), in a box that follows the camera. */\nexport const MIST = { box: { x: [-14, 10], y: [0.2, 1.1], z: [-3, 8] }, drift: [0.15, 0.35], life: [9, 13], size: [3, 5], grow: 1.4, color: 0x7d8aa0, alpha: 0.13, fadeIn: 0.35 } as const\nexport const ASH = { box: { x: [-10, 8], y: [4, 6], z: [-3, 7] }, fall: -0.35, life: [8, 12], size: [0.025, 0.04], color: 0xa09a90, alpha: 0.75, fadeIn: 0.1 } as const\n\n/**\n * Feeds the `normal` sprite pool of the Workshop with `mistPerSecond` puffs of mist and `ashPerSecond` flakes of ash a second (the page's `emit('fog', ...)`\n * and `emit('ash', ...)`, at the weather's rate instead of 5 and 14), around `camera`. The renderer of game-vfx-three draws them.\n */\nexport function emitAirborne(engine: WorkshopEngine, sample: WeatherSample, dt: number, camera: Vec3): void {\n const { random } = engine\n const around = (box: { readonly x: readonly number[]; readonly y: readonly number[]; readonly z: readonly number[] }): [number, number, number] => [\n camera[0] + random.between(box.x[0]!, box.x[1]!),\n random.between(box.y[0]!, box.y[1]!),\n camera[2] + random.between(box.z[0]!, box.z[1]!),\n ]\n if (sample.mistPerSecond > 0) {\n engine.emit('weather-mist', 'normal', sample.mistPerSecond, dt, () => ({\n p: around(MIST.box),\n v: [random.between(MIST.drift[0], MIST.drift[1]), 0, random.between(-0.05, 0.05)],\n sp: 0,\n life: MIST.life,\n size: MIST.size,\n grow: MIST.grow,\n c0: MIST.color,\n a: MIST.alpha,\n fi: MIST.fadeIn,\n }))\n }\n if (sample.ashPerSecond > 0) {\n engine.emit('weather-ash', 'normal', sample.ashPerSecond, dt, () => ({\n p: around(ASH.box),\n v: [random.between(0.1, 0.4), ASH.fall, random.between(-0.1, 0.1)],\n sp: [0.05, 0.15],\n life: ASH.life,\n size: ASH.size,\n c0: ASH.color,\n a: ASH.alpha,\n fi: ASH.fadeIn,\n gnd: 1,\n }))\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WorkshopEngine } from '@adatechnology/game-vfx'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib, Vec3 } from './types'\n\n/** The Workshop's car lamps (W101-103) and the rain that glows inside their beam (W1161-1170). */\nexport const HEADLIGHTS = {\n spot: { color: 0xfff1d0, intensity: 2.4, distance: 26, angle: 0.33, penumbra: 0.5, decay: 1.6 },\n /** Lamp position on the car (x is mirrored), where the spot points, and the cone drawn in the air. */\n lamp: [0.65, 0.74, 2.15],\n aim: [0.65, 0.2, 12],\n cone: { radius: 2.4, length: 9, segments: 18, color: 0xfff1d0, opacity: 0.06 },\n lens: { on: 0xfff1d0, off: 0x3a3a34 },\n /** Lit drops a second, thrown into the beam 1 to 13 m ahead (W1176). */\n lit: { rate: 600, depth: [1, 13], spread: 0.33, color: 0xcfdcf0, alpha: 0.9, life: 0.06, len: 0.035, velocity: [0.8, -14, 0] },\n /** Beyond this many metres a car keeps only the cone: no real light (W-b text of `farol`). */\n lightRange: 40,\n} as const\n\nexport type HeadlightRules = {\n /** Whether the lamps are lit in this weather and light (default: night, rain or fog). */\n readonly lit?: (sample: WeatherSample) => boolean\n readonly lightRange?: number\n}\n\n/** Night (the sun below the page's 0.3 night factor), rain or fog make a driver turn the lamps on. */\nexport const defaultHeadlightRule = (sample: WeatherSample): boolean => sample.nightFactor > 0.3 || sample.rain > 0 || sample.fogDensity > 0.02 || sample.visibility < 150\n\ntype Rig = { readonly car: THREE_NS.Object3D; readonly spots: THREE_NS.SpotLight[]; readonly cones: THREE_NS.Mesh[]; readonly lens: THREE_NS.MeshBasicMaterial | undefined; readonly targets: THREE_NS.Object3D[] }\n\nexport type Headlights = {\n /** Gives `car` its two spot lights and two beam cones (`lens`, when given, is the material of the lamp glass, lit with them). Returns the function that takes them off. */\n attach(car: THREE_NS.Object3D, lens?: THREE_NS.MeshBasicMaterial): () => void\n /** Lights the lamps of the cars attached, the real light only within range of `camera`; throws the lit drops of the beams into the Workshop's streak pool. */\n update(sample: WeatherSample, dt: number, camera: Vec3, engine?: WorkshopEngine, enabled?: boolean): void\n count(): number\n dispose(): void\n}\n\nexport function createHeadlights(THREE: ThreeLib, rules: HeadlightRules = {}): Headlights {\n const rigs = new Set<Rig>()\n const cone = HEADLIGHTS.cone\n const lampWorld = new THREE.Vector3()\n const aimWorld = new THREE.Vector3()\n const forward = new THREE.Vector3()\n const rule = rules.lit ?? defaultHeadlightRule\n const range = rules.lightRange ?? HEADLIGHTS.lightRange\n\n function attach(car: THREE_NS.Object3D, lens?: THREE_NS.MeshBasicMaterial): () => void {\n const spots: THREE_NS.SpotLight[] = []\n const cones: THREE_NS.Mesh[] = []\n const targets: THREE_NS.Object3D[] = []\n for (const side of [-1, 1]) {\n const spot = new THREE.SpotLight(HEADLIGHTS.spot.color, 0, HEADLIGHTS.spot.distance, HEADLIGHTS.spot.angle, HEADLIGHTS.spot.penumbra, HEADLIGHTS.spot.decay)\n spot.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2])\n const target = new THREE.Object3D()\n target.position.set(side * HEADLIGHTS.aim[0], HEADLIGHTS.aim[1], HEADLIGHTS.aim[2])\n car.add(spot, target)\n spot.target = target\n const geometry = new THREE.ConeGeometry(cone.radius, cone.length, cone.segments, 1, true)\n geometry.translate(0, -cone.length / 2, 0)\n geometry.rotateX(-Math.PI / 2)\n const material = new THREE.MeshBasicMaterial({ color: cone.color, transparent: true, opacity: cone.opacity, blending: THREE.AdditiveBlending, depthWrite: false, side: THREE.DoubleSide, fog: false })\n const beam = new THREE.Mesh(geometry, material)\n beam.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2])\n beam.visible = false\n car.add(beam)\n spots.push(spot)\n cones.push(beam)\n targets.push(target)\n }\n const rig: Rig = { car, spots, cones, lens, targets }\n rigs.add(rig)\n return () => {\n rigs.delete(rig)\n for (const object of [...spots, ...cones, ...targets]) car.remove(object)\n for (const beam of cones) {\n beam.geometry.dispose()\n ;(beam.material as THREE_NS.Material).dispose()\n }\n for (const spot of spots) spot.dispose()\n lens?.color.setHex(HEADLIGHTS.lens.off)\n }\n }\n\n return {\n attach,\n update(sample, dt, camera, engine, enabled = true) {\n const on = enabled && rule(sample)\n let index = 0\n for (const rig of rigs) {\n rig.car.updateWorldMatrix(true, false)\n lampWorld.set(0, HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2]).applyMatrix4(rig.car.matrixWorld)\n const near = Math.hypot(lampWorld.x - camera[0], lampWorld.z - camera[2]) <= range\n for (const spot of rig.spots) spot.intensity = on && near ? HEADLIGHTS.spot.intensity : 0\n for (const beam of rig.cones) beam.visible = on\n rig.lens?.color.setHex(on ? HEADLIGHTS.lens.on : HEADLIGHTS.lens.off)\n if (!on || !engine || sample.rain <= 0 || !near) {\n index++\n continue\n }\n aimWorld.set(0, HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2] + 1).applyMatrix4(rig.car.matrixWorld)\n forward.copy(aimWorld).sub(lampWorld).normalize()\n const side: [number, number] = [forward.z, -forward.x]\n const { random } = engine\n const lit = HEADLIGHTS.lit\n engine.emit(`weather-lit-${index}`, 'streak', lit.rate, dt, () => {\n const depth = random.between(lit.depth[0], lit.depth[1])\n const spread = depth * lit.spread * Math.sqrt(random.next())\n const turn = random.between(0, 6.283)\n return {\n p: [lampWorld.x + forward.x * depth + side[0] * Math.cos(turn) * spread, lampWorld.y + forward.y * depth + Math.sin(turn) * spread * 0.6, lampWorld.z + forward.z * depth + side[1] * Math.cos(turn) * spread],\n v: lit.velocity as unknown as [number, number, number],\n sp: 0,\n life: lit.life,\n len: lit.len,\n c0: lit.color,\n a: lit.alpha,\n }\n })\n index++\n }\n },\n count: () => rigs.size,\n dispose() {\n for (const rig of [...rigs]) {\n rigs.delete(rig)\n for (const object of [...rig.spots, ...rig.cones, ...rig.targets]) rig.car.remove(object)\n }\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib } from './types'\n\n/** Peak opacity of the shimmer at full haze, and how fast the bands rise (SDK-made: no team delivered heat haze, see the open question). */\nexport const HEAT_HAZE = { opacity: 0.09, bands: 38, rise: 1.4, color: [1, 0.93, 0.82] } as const\n\nexport const HEAT_HAZE_VERTEX = 'varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.); }'\nexport const HEAT_HAZE_FRAGMENT =\n 'uniform float uTime; uniform float uHaze; uniform vec3 uColor; varying vec2 vUv; void main(){ float low = 1. - smoothstep(0.15, 0.7, vUv.y); float wave = sin(vUv.y*38. - uTime*1.4 + sin(vUv.x*11. + uTime*.7)*2.2) * .5 + .5; gl_FragColor = vec4(uColor, uHaze*low*wave*.09); }'\n\nexport type HeatHaze = {\n readonly object: THREE_NS.Mesh\n update(sample: WeatherSample, time: number): void\n dispose(): void\n}\n\n/**\n * The heat shimmer of `extreme_heat` (`WeatherSample.haze`, 0..1): a screen-space layer of warm bands that rise over the lower half of the view. It is a layer, not a\n * distortion of the picture, because bending the picture needs a render target that only the host owns.\n */\nexport function createHeatHaze(THREE: ThreeLib): HeatHaze {\n const uniforms = { uTime: { value: 0 }, uHaze: { value: 0 }, uColor: { value: new THREE.Vector3(...HEAT_HAZE.color) } }\n const material = new THREE.ShaderMaterial({ uniforms, vertexShader: HEAT_HAZE_VERTEX, fragmentShader: HEAT_HAZE_FRAGMENT, transparent: true, depthTest: false, depthWrite: false })\n const object = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material)\n object.frustumCulled = false\n object.renderOrder = 999\n object.name = 'weather-heat-haze'\n object.visible = false\n return {\n object,\n update(sample, time) {\n uniforms.uHaze.value = sample.haze\n uniforms.uTime.value = time\n object.visible = sample.haze > 0\n },\n dispose() {\n object.geometry.dispose()\n material.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib } from './types'\n\n/**\n * What the Workshop's double flash does to the scene (W1072): the hemisphere light gains `I * 3.2`, the background gains `I * (.25, .27, .32)` and the screen goes\n * white by `I * .12`, where `I` is the flash the weather samples (1, then .2, then .8 for 0.26 s).\n */\nexport const LIGHTNING = { light: 3.2, background: [0.25, 0.27, 0.32], white: 0.12, skyColor: 0x3a4c6a, groundColor: 0x0b0b0c } as const\n\nexport type Lightning = {\n readonly light: THREE_NS.HemisphereLight\n /**\n * Lights the scene with the flash of `sample`. `background`, when given, is the sky just written for this frame (the renderer passes it only when it owns the sky),\n * and gains the flash; a background the host keeps for itself is left alone.\n */\n update(sample: WeatherSample, background?: THREE_NS.Color): void\n dispose(): void\n}\n\nexport function createLightning(THREE: ThreeLib, scene: { add(object: THREE_NS.Object3D): unknown; remove(object: THREE_NS.Object3D): unknown }, vfx?: VfxWorld): Lightning {\n const light = new THREE.HemisphereLight(LIGHTNING.skyColor, LIGHTNING.groundColor, 0)\n light.name = 'weather-lightning'\n scene.add(light)\n return {\n light,\n update(sample, background) {\n const flash = sample.flash\n light.intensity = flash * LIGHTNING.light\n if (flash <= 0) return\n if (background) {\n background.r += flash * LIGHTNING.background[0]!\n background.g += flash * LIGHTNING.background[1]!\n background.b += flash * LIGHTNING.background[2]!\n }\n const screen = vfx?.workshop().screen\n if (screen) screen.white = Math.max(screen.white, flash * LIGHTNING.white)\n },\n dispose() {\n scene.remove(light)\n light.dispose()\n },\n }\n}\n","import type { Puddle, VfxWorld } from '@adatechnology/game-vfx'\nimport { inPuddle } from '@adatechnology/game-vfx'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { Vec3 } from './types'\n\n/** The rain (mm/h) from which a drop that lands splashes (the Workshop's garoa, 2.5, does not; its chuva, 15, does). */\nexport const SPLASH_FROM_MM = 5\n\nexport type NearRainOptions = {\n /** Ground ellipses where a drop leaves a ring (the Workshop's four dark puddles; a game has its own). None by default. */\n readonly puddles?: readonly Puddle[]\n /** Replaces the puddle test. */\n readonly puddleAt?: (x: number, z: number) => boolean\n readonly splashFrom?: number\n}\n\nexport type NearRain = {\n update(sample: WeatherSample, dt: number, camera: Vec3): void\n /** Streaks alive. */\n count(): number\n clear(): void\n}\n\n/**\n * The Workshop's near rain (W313-331) driven by the weather: the streaks live in the world's Workshop engine (`engine.rain`), game-vfx-three draws them, and the\n * splashes and rings they leave go to the `normal` sprite pool and the rings. `drops` (900 garoa, 2 200 chuva, 4 000 temporal) and the wind along x are the Workshop's own\n * numbers for its three intensities.\n */\nexport function createNearRain(vfx: VfxWorld | undefined, options: NearRainOptions = {}): NearRain {\n const puddles = options.puddles ?? []\n return {\n update(sample, dt, camera) {\n const raining = sample.rain > 0\n const engine = raining ? vfx?.workshop() : vfx?.peekWorkshop()\n if (!engine) return\n const field = engine.rain\n if (!raining) {\n if (field.on) field.clear()\n return\n }\n field.puddleAt = options.puddleAt ?? ((x, z) => inPuddle(puddles, x, z))\n field.drive(sample.drops, sample.windX, camera[0], camera[2])\n field.update(dt, sample.rain >= (options.splashFrom ?? SPLASH_FROM_MM), camera)\n },\n count: () => vfx?.peekWorkshop()?.rain.count ?? 0,\n clear() {\n vfx?.peekWorkshop()?.rain.clear()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeatherSample } from '@adatechnology/game-weather'\nimport type { ThreeLib, WeatherProfileName } from './types'\n\n/**\n * The game's rain curtain (jogo.js `const RAIN = 14000`): a box of points that follows the camera, 70 m wide and 25 m high, falling 13 m/s. The shader texts and the\n * numbers are the page's, character for character (a golden cuts them from the page and compares).\n */\nexport const RAIN_CURTAIN = { count: 14000, width: 70, height: 25, speed: 13, pointSize: 1.6 } as const\n\nexport const RAIN_CURTAIN_VERTEX =\n 'uniform float uTime; uniform vec3 uCam; void main(){ vec3 p = position; p.y = mod(p.y - uTime*13., 25.); p.xz = uCam.xz + mod(p.xz - uCam.xz + 35., 70.) - 35.; gl_Position = projectionMatrix*viewMatrix*vec4(p,1.); gl_PointSize = 1.6; }'\nexport const RAIN_CURTAIN_FRAGMENT = 'uniform float uDay; void main(){ gl_FragColor = vec4(vec3(.68,.72,.78)*(0.25+0.75*uDay), .22+.1*uDay); }'\n\n/** The share of the 14 000 points each quality draws. */\nexport const RAIN_CURTAIN_PROFILES: Readonly<Record<WeatherProfileName, number>> = { low: 0.35, medium: 0.7, high: 1 }\n/** The weather's `drops` at which the whole curtain is drawn (the storm's 4 000). */\nexport const RAIN_CURTAIN_FULL_AT = 4000\n\n/** The page's loop: x and z in -35..35, y in 0..25, three draws a point in that order, stored as Float32. */\nexport function rainCurtainPositions(random: () => number = Math.random, count: number = RAIN_CURTAIN.count): Float32Array {\n const positions = new Float32Array(count * 3)\n for (let index = 0; index < count; index++) {\n positions[index * 3] = (random() - 0.5) * RAIN_CURTAIN.width\n positions[index * 3 + 1] = random() * RAIN_CURTAIN.height\n positions[index * 3 + 2] = (random() - 0.5) * RAIN_CURTAIN.width\n }\n return positions\n}\n\nexport type RainCurtainOptions = {\n readonly random?: () => number\n readonly profile?: WeatherProfileName\n /** Drops (`WeatherSample.drops`) that draw the whole curtain. */\n readonly fullAt?: number\n readonly count?: number\n}\n\nexport type RainCurtain = {\n readonly object: THREE_NS.Points\n /** Draws `sample.drops` of the curtain around `camera`; `daylight` is the game's `s` (0 night, 1 day). */\n update(sample: WeatherSample, camera: { readonly x: number; readonly y: number; readonly z: number }, time: number, daylight: number): void\n setProfile(profile: WeatherProfileName): void\n /** How many points are drawn now. */\n drawn(): number\n dispose(): void\n}\n\nexport function createRainCurtain(THREE: ThreeLib, options: RainCurtainOptions = {}): RainCurtain {\n const count = options.count ?? RAIN_CURTAIN.count\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(rainCurtainPositions(options.random, count), 3))\n const uniforms = { uTime: { value: 0 }, uCam: { value: new THREE.Vector3() }, uDay: { value: 1 } }\n const material = new THREE.ShaderMaterial({ uniforms, transparent: true, depthWrite: false, vertexShader: RAIN_CURTAIN_VERTEX, fragmentShader: RAIN_CURTAIN_FRAGMENT })\n const object = new THREE.Points(geometry, material)\n object.frustumCulled = false\n object.name = 'weather-rain-curtain'\n object.visible = false\n let share = RAIN_CURTAIN_PROFILES[options.profile ?? 'high']\n let drawn = 0\n return {\n object,\n update(sample, camera, time, daylight) {\n const fullAt = options.fullAt ?? RAIN_CURTAIN_FULL_AT\n drawn = sample.rain > 0 ? Math.round(count * share * Math.min(1, sample.drops / fullAt)) : 0\n object.visible = drawn > 0\n geometry.setDrawRange(0, drawn)\n uniforms.uTime.value = time\n uniforms.uDay.value = daylight\n uniforms.uCam.value.set(camera.x, camera.y, camera.z)\n },\n setProfile(profile) {\n share = RAIN_CURTAIN_PROFILES[profile]\n },\n drawn: () => drawn,\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport type { Puddle } from '@adatechnology/game-vfx'\nimport { createFog, emitAirborne } from './fog'\nimport type { Fog } from './fog'\nimport { createHeadlights } from './headlights'\nimport type { HeadlightRules, Headlights } from './headlights'\nimport { createHeatHaze } from './heat-haze'\nimport type { HeatHaze } from './heat-haze'\nimport { createLightning } from './lightning'\nimport type { Lightning } from './lightning'\nimport { createNearRain } from './rain-near'\nimport type { NearRain } from './rain-near'\nimport { createRainCurtain } from './rain-curtain'\nimport type { RainCurtain } from './rain-curtain'\nimport { createSky } from './sky'\nimport type { Sky } from './sky'\nimport type { ThreeLib, Vec3, WeatherProfileName, WeatherSource, ZoneFog } from './types'\n\n/** The parts the renderer draws, each of which a layer switches. */\nexport const WEATHER_LAYERS = ['far_rain', 'near_rain', 'mist', 'fog', 'sky', 'lightning', 'headlights', 'haze'] as const\nexport type WeatherLayerId = (typeof WEATHER_LAYERS)[number]\n\nexport type WeatherRendererOptions = {\n readonly scene: THREE_NS.Scene\n readonly camera: THREE_NS.Camera\n readonly weather: WeatherSource\n /** The effects world: near rain, splashes, mist, ash, the white of lightning and the lit drops of headlights live in its Workshop pools (game-vfx-three draws them). */\n readonly vfx?: VfxWorld\n readonly profile?: WeatherProfileName\n /** Seeds the rain curtain (default `Math.random`). */\n readonly random?: () => number\n readonly zone?: ZoneFog\n readonly puddles?: readonly Puddle[]\n readonly puddleAt?: (x: number, z: number) => boolean\n readonly headlights?: HeadlightRules\n readonly layers?: Partial<Record<WeatherLayerId, boolean>>\n}\n\nexport type WeatherRenderer = {\n readonly curtain: RainCurtain\n readonly nearRain: NearRain\n readonly fog: Fog\n readonly sky: Sky\n readonly lightning: Lightning\n readonly headlights: Headlights\n readonly haze: HeatHaze\n /** Draws the weather of the source for a frame of `dt` seconds. Call once per frame, after the weather advanced. */\n update(dt: number): void\n setLayer(id: WeatherLayerId, on: boolean): void\n layer(id: WeatherLayerId): boolean\n setZoneFog(zone: ZoneFog | undefined): void\n setProfile(profile: WeatherProfileName): void\n stats(): { readonly rainCurtain: number; readonly rainNear: number; readonly cars: number }\n dispose(): void\n}\n\n/** The whole weather picture: rain curtain, near rain with splashes, mist and ash, fog, sky, lightning, headlights and heat haze, from one `WeatherSource`. */\nexport function createWeatherRenderer(THREE: ThreeLib, options: WeatherRendererOptions): WeatherRenderer {\n const { scene, camera, weather, vfx } = options\n const group = new THREE.Group()\n group.name = 'weather'\n scene.add(group)\n const curtain = createRainCurtain(THREE, { ...(options.random ? { random: options.random } : {}), ...(options.profile ? { profile: options.profile } : {}) })\n const haze = createHeatHaze(THREE)\n group.add(curtain.object, haze.object)\n const sky = createSky(THREE, scene)\n const fog = createFog(THREE, scene)\n const lightning = createLightning(THREE, scene, vfx)\n const headlights = createHeadlights(THREE, options.headlights)\n const nearRain = createNearRain(vfx, { ...(options.puddles ? { puddles: options.puddles } : {}), ...(options.puddleAt ? { puddleAt: options.puddleAt } : {}) })\n const on = new Map<WeatherLayerId, boolean>(WEATHER_LAYERS.map((id) => [id, options.layers?.[id] ?? true]))\n let zone = options.zone\n let time = 0\n const eye: { x: number; y: number; z: number } = { x: 0, y: 0, z: 0 }\n\n const switchedOff = (id: WeatherLayerId): void => {\n if (id === 'far_rain') curtain.object.visible = false\n else if (id === 'near_rain') nearRain.clear()\n else if (id === 'fog') fog.clear()\n else if (id === 'lightning') lightning.light.intensity = 0\n else if (id === 'haze') haze.object.visible = false\n }\n\n return {\n curtain,\n nearRain,\n fog,\n sky,\n lightning,\n headlights,\n haze,\n update(dt) {\n time += dt\n const sample = weather.sample()\n const position = camera.position\n eye.x = position.x\n eye.y = position.y\n eye.z = position.z\n const where: Vec3 = [eye.x, eye.y, eye.z]\n const background = (scene.background as THREE_NS.Color | null) ?? undefined\n const ownSky = on.get('sky') === true\n const color = ownSky ? sky.update(sample, zone) : background && (background as { isColor?: boolean }).isColor ? background : sky.color\n if (on.get('fog')) fog.update(sample, color, zone)\n if (on.get('lightning')) lightning.update(sample, ownSky ? (scene.background as THREE_NS.Color) : undefined)\n if (on.get('far_rain')) curtain.update(sample, eye, time, sample.sun)\n if (on.get('haze')) haze.update(sample, time)\n if (vfx) {\n if (on.get('near_rain')) nearRain.update(sample, dt, where)\n if (on.get('mist')) emitAirborne(vfx.workshop(), sample, dt, where)\n }\n headlights.update(sample, dt, where, vfx && sample.rain > 0 ? vfx.workshop() : undefined, on.get('headlights'))\n },\n setLayer(id, value) {\n on.set(id, value)\n if (!value) switchedOff(id)\n },\n layer: (id) => on.get(id) === true,\n setZoneFog(next) {\n zone = next\n },\n setProfile(profile) {\n curtain.setProfile(profile)\n },\n stats: () => ({ rainCurtain: curtain.drawn(), rainNear: nearRain.count(), cars: headlights.count() }),\n dispose() {\n scene.remove(group)\n curtain.dispose()\n haze.dispose()\n lightning.dispose()\n headlights.dispose()\n nearRain.clear()\n },\n }\n}\n","import type { WeatherLayerId } from '../renderer'\n\n/** The names of the visual layers in the bench; any other locale falls back to English. */\nexport type WeatherVisualText = { readonly layers: Readonly<Record<Exclude<WeatherLayerId, 'fog'>, string>> }\n\nconst TEXTS: Readonly<Record<string, WeatherVisualText>> = {\n en: { layers: { far_rain: 'Rain curtain', near_rain: 'Near rain and splashes', mist: 'Mist and ash', sky: 'Sky', lightning: 'Lightning', headlights: 'Headlights', haze: 'Heat haze' } },\n 'pt-BR': { layers: { far_rain: 'Cortina de chuva', near_rain: 'Chuva perto e respingos', mist: 'Névoa e cinza', sky: 'Céu', lightning: 'Relâmpago', headlights: 'Faróis', haze: 'Névoa de calor' } },\n}\n\nexport const weatherVisualTextOf = (locale: string): WeatherVisualText => TEXTS[locale] ?? TEXTS[locale.split('-')[0] ?? 'en'] ?? TEXTS.en!\n","import type { ModuleHost, ModuleLayer } from '@adatechnology/game-contracts'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport type { WeatherVisual, WeatherVisualContext, WeatherVisualFactory } from '@adatechnology/game-weather'\nimport type * as THREE_NS from 'three'\nimport { HEADLIGHTS } from '../headlights'\nimport { createWeatherRenderer } from '../renderer'\nimport type { WeatherLayerId, WeatherRenderer, WeatherRendererOptions } from '../renderer'\nimport type { ThreeLib } from '../types'\nimport { weatherVisualTextOf } from './text'\n\nexport type WeatherVisualOptions = Pick<WeatherRendererOptions, 'profile' | 'random' | 'zone' | 'puddles' | 'puddleAt' | 'headlights'> & {\n /** The effects world of the room (`room.vfx`); without it the near rain, mist, ash, white flash and lit drops are left out. */\n readonly vfx?: VfxWorld\n /** Where the lamp rig stands (the two headlights of the Workshop's car, to see the beams); `false` leaves it out. Default 2.5 m ahead of the test room camera, lamps toward it. */\n readonly rig?: readonly [x: number, z: number, turn: number] | false\n /**\n * The car the lamps are mounted on, built by the vehicles SDK for the host's three.js (`createVehiclesThree` of game-vehicles-three with the fleet installed), so the rig follows the fleet when it\n * changes. Without it the rig has only the lamps and their beams: no car drawn here.\n */\n readonly vehicles?: (THREE: ThreeLib) => RigVehicles\n /** Fleet id of the rig's car (default `midsize_sedan`). */\n readonly rigVehicle?: string\n /** Which layers start on (all do by default); the room that is not about weather starts the sky and the fog off to keep its own look. */\n readonly layers?: Partial<Record<WeatherLayerId, boolean>>\n}\n\n/** What the rig needs of the vehicles SDK (`VehiclesThree` of game-vehicles-three): a car in the game frame (front on +z, wheels on y = 0) and its length. */\nexport interface RigVehicles {\n build(key: string, options?: { quality?: 'high' | 'lite' }): { readonly group: THREE_NS.Object3D; readonly length: number; dispose(): void }\n}\n\nconst RIG_VEHICLE = 'midsize_sedan'\nconst LAYER_ORDER: readonly Exclude<WeatherLayerId, 'fog'>[] = ['far_rain', 'near_rain', 'mist', 'sky', 'lightning', 'headlights', 'haze']\nconst RIG_DEFAULT = [1.6, -2.5, 0] as const\n\n/**\n * The lamps of the Workshop's car and, when the vehicles SDK is lent, a car of the fleet under them, its nose just ahead of the lamps: what the headlights are attached to when the viewer has no\n * car in the room.\n */\nfunction buildRig(THREE: ThreeLib, vehicles: RigVehicles | undefined, key: string): { readonly group: THREE_NS.Group; dispose(): void } {\n const group = new THREE.Group()\n group.name = 'weather-lamp-rig'\n const car = vehicles?.build(key, { quality: 'lite' })\n if (car) {\n car.group.position.z = HEADLIGHTS.lamp[2] + 0.1 - car.length / 2\n group.add(car.group)\n }\n return {\n group,\n dispose() {\n car?.dispose()\n },\n }\n}\n\n/**\n * The picture of the weather for the weather bench: `createWeatherTestModule({ visual: createWeatherVisual({ vfx: room.vfx }) })`. It draws the weather the bench shows with\n * `createWeatherRenderer` on the room's scene and camera, switches each part with the bench layers and puts a lamp rig in front of the camera for the headlights.\n */\nexport function createWeatherVisual(options: WeatherVisualOptions = {}): WeatherVisualFactory {\n return {\n layers(locale): readonly ModuleLayer[] {\n const text = weatherVisualTextOf(locale)\n return LAYER_ORDER.map((id) => ({ id, name: text.layers[id], default: options.layers?.[id] ?? true }))\n },\n create({ host, weather }: WeatherVisualContext): WeatherVisual {\n const THREE = host.THREE as ThreeLib\n const renderer: WeatherRenderer = createWeatherRenderer(THREE, {\n scene: host.scene as THREE_NS.Scene,\n camera: host.camera as THREE_NS.Camera,\n weather,\n ...(options.vfx ? { vfx: options.vfx } : {}),\n ...(options.profile ? { profile: options.profile } : {}),\n ...(options.random ? { random: options.random } : {}),\n ...(options.zone ? { zone: options.zone } : {}),\n ...(options.puddles ? { puddles: options.puddles } : {}),\n ...(options.puddleAt ? { puddleAt: options.puddleAt } : {}),\n ...(options.headlights ? { headlights: options.headlights } : {}),\n ...(options.layers ? { layers: options.layers } : {}),\n })\n return attachRig(THREE, host, renderer, options.rig === undefined ? RIG_DEFAULT : options.rig, options.vehicles?.(THREE), options.rigVehicle ?? RIG_VEHICLE)\n },\n }\n}\n\nfunction attachRig(THREE: ThreeLib, host: ModuleHost, renderer: WeatherRenderer, place: readonly [number, number, number] | false, vehicles: RigVehicles | undefined, key: string): WeatherVisual {\n const scene = host.scene as THREE_NS.Scene\n const rig = place === false ? undefined : buildRig(THREE, vehicles, key)\n let detach: (() => void) | undefined\n if (rig && place) {\n rig.group.position.set(place[0], 0, place[1])\n rig.group.rotation.y = place[2]\n scene.add(rig.group)\n detach = renderer.headlights.attach(rig.group)\n }\n return {\n update: (dt) => renderer.update(dt),\n setLayer(id, on) {\n if ((WEATHER_IDS as readonly string[]).includes(id)) renderer.setLayer(id as WeatherLayerId, on)\n },\n dispose() {\n detach?.()\n if (rig) {\n scene.remove(rig.group)\n rig.dispose()\n }\n renderer.dispose()\n },\n }\n}\n\nconst WEATHER_IDS: readonly WeatherLayerId[] = ['far_rain', 'near_rain', 'mist', 'fog', 'sky', 'lightning', 'headlights', 'haze']\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adatechnology/game-weather-three",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "three.js renderer for @adatechnology/game-weather: the game's rain curtain (14 000 GPU points), the near rain and mist and ash on the game-vfx pools, linear and exponential fog with zone fog, the sky that dims in rain, lightning, headlights in rain and a heat haze.",
|
|
6
6
|
"keywords": [
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"dist"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@adatechnology/game-contracts": "0.
|
|
42
|
-
"@adatechnology/game-vfx": "0.3.0",
|
|
43
|
-
"@adatechnology/game-vfx
|
|
44
|
-
"@adatechnology/game-weather": "0.2.
|
|
41
|
+
"@adatechnology/game-contracts": "0.14.0",
|
|
42
|
+
"@adatechnology/game-vfx-three": "0.3.0",
|
|
43
|
+
"@adatechnology/game-vfx": "0.4.0",
|
|
44
|
+
"@adatechnology/game-weather": "0.2.1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"three": "^0.160.0"
|