@adatechnology/game-weather-three 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-SOEOSGSU.js +621 -0
- package/dist/chunk-SOEOSGSU.js.map +1 -0
- package/dist/index.d.ts +6 -354
- package/dist/index.global.js +209 -27
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +38 -537
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +379 -0
- package/dist/testing.js +9 -0
- package/dist/testing.js.map +1 -0
- package/package.json +10 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bench/visual.ts","../src/headlights.ts","../src/fog.ts","../src/sky.ts","../src/heat-haze.ts","../src/lightning.ts","../src/rain-near.ts","../src/rain-curtain.ts","../src/renderer.ts","../src/bench/text.ts"],"sourcesContent":["import { isLightBudget } from '@adatechnology/game-render-three'\nimport { footprintBlocker } from '@adatechnology/game-contracts'\nimport type { Footprint, ModuleHost, ModuleLayer } from '@adatechnology/game-contracts'\nimport type { VfxWorld } from '@adatechnology/game-vfx'\nimport type { WeatherVisual, WeatherVisualContext, WeatherVisualFactory } from '@adatechnology/game-weather/testing'\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 /**\n * The rig's car as an item of the host's catalogue (`sedan` of the vehicles test module): the host puts it in its world (`ModuleHost.addObject`), so shots, blows, blasts and fire damage it, it\n * blocks the player and its doors open, and the lamps go on its nose. Wins over `vehicles` when the host can place it; until a loaded module has the item the rig has only the lamps.\n */\n readonly rigItem?: 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; readonly width?: 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; readonly footprint?: Footprint; 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 // the car is solid: the walking player stops at its body (its length and width, measured by the vehicles SDK) instead of walking through it\n const footprint = car ? footprintOf(car) : undefined\n return {\n group,\n ...(footprint ? { footprint } : {}),\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 ...(isLightBudget(host.lights) ? { lights: host.lights } : {}),\n })\n const item = options.rigItem && host.addObject ? options.rigItem : undefined\n return attachRig(THREE, host, renderer, options.rig === undefined ? RIG_DEFAULT : options.rig, item ? undefined : options.vehicles?.(THREE), options.rigVehicle ?? RIG_VEHICLE, item)\n },\n }\n}\n\nfunction footprintOf(car: { readonly group: THREE_NS.Object3D; readonly length: number; readonly width?: number }): Footprint | undefined {\n if (!car.width) return undefined\n const z = car.group.position.z\n return { minX: -car.width / 2, maxX: car.width / 2, minZ: z - car.length / 2, maxZ: z + car.length / 2 }\n}\n\n/** Length (m, along its own z) of what an object draws, measured in its own space. */\nfunction lengthOf(THREE: ThreeLib, root: THREE_NS.Object3D): number {\n root.updateMatrixWorld(true)\n const inverse = new THREE.Matrix4().copy(root.matrixWorld).invert()\n const box = new THREE.Box3()\n const piece = new THREE.Box3()\n const matrix = new THREE.Matrix4()\n root.traverse((mesh) => {\n const m = mesh as THREE_NS.Mesh\n if (!m.isMesh || !m.geometry) return\n if (!m.geometry.boundingBox) m.geometry.computeBoundingBox()\n piece.copy(m.geometry.boundingBox!).applyMatrix4(matrix.multiplyMatrices(inverse, m.matrixWorld))\n box.union(piece)\n })\n return box.isEmpty() ? 0 : box.max.z - box.min.z\n}\n\nfunction attachRig(\n THREE: ThreeLib,\n host: ModuleHost,\n renderer: WeatherRenderer,\n place: readonly [number, number, number] | false,\n vehicles: RigVehicles | undefined,\n key: string,\n item?: string,\n): 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 let unblock: (() => 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 if (rig.footprint) unblock = host.addBlocker?.(footprintBlocker(rig.group, rig.footprint))\n }\n // the car as a real object of the host: placed as soon as a loaded module has the item (the vehicles module may load after this one), centred on the rig's place, and the lamps then\n // move to its nose (the car's centre is where the rig's car stood, the lamps just behind its front)\n let car: { remove(): void } | null = null\n let stopWaiting: (() => void) | undefined\n if (item && place) {\n const tryPlace = (): void => {\n if (car || !host.addObject) return\n const placed = host.addObject(item, { position: [place[0], 0, place[1]], rotationY: place[2] })\n if (!placed) return\n car = placed\n stopWaiting?.()\n stopWaiting = undefined\n const ahead = lengthOf(THREE, placed.root as THREE_NS.Object3D) / 2 - HEADLIGHTS.lamp[2] - 0.1\n rig!.group.position.set(place[0] + Math.sin(place[2]) * ahead, 0, place[1] + Math.cos(place[2]) * ahead)\n }\n tryPlace()\n if (!car) stopWaiting = host.onFrame(tryPlace)\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 unblock?.()\n stopWaiting?.()\n car?.remove()\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","import type * as THREE_NS from 'three'\nimport { LIGHT_PRIORITY } from '@adatechnology/game-render-three'\nimport type { LightBudget, SourceHandle } from '@adatechnology/game-render-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 * The host's light budget: each lamp is a source of it (it competes for a spot slot by distance) instead of a `SpotLight` on the car. Without it the lamps create their own spots (deprecated,\n * removed in the next major).\n */\n readonly lights?: LightBudget\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 sources: SourceHandle[]; 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 const lights = rules.lights\n const forwardAxis = new THREE.Vector3(0, 0, -1)\n\n /** A lamp the budget lights: a node on the car whose -z points where the spot aims, followed by the source. */\n function lampSource(side: number, car: THREE_NS.Object3D, targets: THREE_NS.Object3D[]): SourceHandle {\n const lamp = new THREE.Object3D()\n lamp.position.set(side * HEADLIGHTS.lamp[0], HEADLIGHTS.lamp[1], HEADLIGHTS.lamp[2])\n const aim = new THREE.Vector3(side * HEADLIGHTS.aim[0], HEADLIGHTS.aim[1], HEADLIGHTS.aim[2]).sub(lamp.position).normalize()\n lamp.quaternion.setFromUnitVectors(forwardAxis, aim)\n car.add(lamp)\n targets.push(lamp)\n const spot = HEADLIGHTS.spot\n return lights!.addSource({ owner: 'weather.headlight', kind: 'spot', priority: LIGHT_PRIORITY.headlight, color: spot.color, intensity: 0, distance: spot.distance, decay: spot.decay, angle: spot.angle, penumbra: spot.penumbra, position: [0, 0, 0], follow: lamp })\n }\n\n function legacySpot(side: number, car: THREE_NS.Object3D, targets: THREE_NS.Object3D[]): THREE_NS.SpotLight {\n // eslint-disable-next-line no-restricted-syntax -- D2: legacy path without LightBudget, removed in the next major\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 targets.push(target)\n return spot\n }\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 const sources: SourceHandle[] = []\n for (const side of [-1, 1]) {\n if (lights) sources.push(lampSource(side, car, targets))\n else spots.push(legacySpot(side, car, targets))\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 cones.push(beam)\n }\n const rig: Rig = { car, spots, sources, 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 for (const source of sources) source.remove()\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 source of rig.sources) source.update({ 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 for (const source of rig.sources) source.remove()\n }\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport { createFog as createStableFog } from '@adatechnology/game-render-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 type FogOptions = {\n readonly expFrom?: number\n /**\n * The scene's fog never goes back to `null` (the layer switched off leaves the host's own linear fog or a neutral one that fogs nothing), so its presence and type, which are part of every\n * lit material's program key, never change. Needs a real `Scene`. Default false: the host's fog (or none) comes back, as before.\n */\n readonly stable?: boolean\n}\n\nexport function createFog(THREE: ThreeLib, scene: { fog: unknown }, options: FogOptions = {}): Fog {\n if (options.stable) return stableFog(THREE, scene as THREE_NS.Scene, options)\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\nfunction stableFog(THREE: ThreeLib, scene: THREE_NS.Scene, options: FogOptions): Fog {\n const controller = createStableFog(THREE, scene, { stable: true })\n return {\n update(sample, sky, zone) {\n const values = fogOf(sample, zone, options.expFrom)\n if (values.mode === 'linear') controller.useLinear(sky.getHex(), values.near, values.far)\n else controller.useExp2(sky.getHex(), values.density)\n ;(scene.fog as { color: THREE_NS.Color }).color.copy(sky)\n },\n clear: () => controller.clear(),\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 { 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 { 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 { LightBudget } from '@adatechnology/game-render-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 type LightningOptions = {\n /**\n * The host's light budget: the flash uses one of its hemisphere slots (leased for good) instead of a light of its own, so the weather coming up in the middle of the game does not\n * change the number of lights. Without it the light is created here (deprecated, removed in the next major).\n */\n readonly lights?: LightBudget\n}\n\nexport function createLightning(THREE: ThreeLib, scene: { add(object: THREE_NS.Object3D): unknown; remove(object: THREE_NS.Object3D): unknown }, vfx?: VfxWorld, options: LightningOptions = {}): Lightning {\n const leased = options.lights?.leaseHemisphere('weather.lightning') ?? null\n // eslint-disable-next-line no-restricted-syntax -- D2: legacy path without LightBudget (or a budget with no hemisphere slot left: then it stays out of the scene), removed in the next major\n const light = leased ?? new THREE.HemisphereLight(LIGHTNING.skyColor, LIGHTNING.groundColor, 0)\n light.name = 'weather-lightning'\n light.color.setHex(LIGHTNING.skyColor)\n light.groundColor.setHex(LIGHTNING.groundColor)\n if (!options.lights) 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 light.intensity = 0\n if (options.lights) return\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 { LightBudget } from '@adatechnology/game-render-three'\nimport 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 /**\n * The host's light budget: the headlights are sources of it and the lightning flash leases one of its hemisphere slots. With it the fog is also stable (never `null`), because the budget seals\n * the fog state of the scene. Without it the lights are created here, as before (deprecated, removed in the next major).\n */\n readonly lights?: LightBudget\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, { stable: options.lights !== undefined })\n const lightning = createLightning(THREE, scene, vfx, options.lights ? { lights: options.lights } : {})\n const headlights = createHeadlights(THREE, options.lights ? { ...options.headlights, lights: options.lights } : 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"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,354 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/** What the renderer reads of a weather world: its sample. A `createWeather` world fits. */
|
|
8
|
-
type WeatherSource = {
|
|
9
|
-
sample(): WeatherSample;
|
|
10
|
-
};
|
|
11
|
-
/** The quality names of game-vfx; they size the rain curtain. */
|
|
12
|
-
type WeatherProfileName = 'low' | 'medium' | 'high';
|
|
13
|
-
/** Zone fog (the game's `ZONA_NEBLINA`): colour, far distance in metres and weight 0..1. */
|
|
14
|
-
type ZoneFog = {
|
|
15
|
-
readonly color?: number;
|
|
16
|
-
readonly far?: number;
|
|
17
|
-
readonly weight: number;
|
|
18
|
-
};
|
|
19
|
-
type Vec3 = readonly [number, number, number];
|
|
20
|
-
|
|
21
|
-
/** The page's linear fog starts at 25 m and, in the zone, at 4 m (`scene.fog.near = lerp(25, 4, weight)`). */
|
|
22
|
-
declare const FOG_NEAR = 25;
|
|
23
|
-
declare const FOG_ZONE_NEAR = 4;
|
|
24
|
-
/** Below this exponential-squared density the weather uses the linear fog (the clear weathers have 0). */
|
|
25
|
-
declare const FOG_EXP_FROM = 0.0005;
|
|
26
|
-
/** 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. */
|
|
27
|
-
declare const densityForFar: (far: number) => number;
|
|
28
|
-
type FogValues = {
|
|
29
|
-
readonly mode: 'linear';
|
|
30
|
-
readonly near: number;
|
|
31
|
-
readonly far: number;
|
|
32
|
-
} | {
|
|
33
|
-
readonly mode: 'exp2';
|
|
34
|
-
readonly density: number;
|
|
35
|
-
};
|
|
36
|
-
/** The fog the weather and the zone ask for. Pure. */
|
|
37
|
-
declare function fogOf(sample: WeatherSample, zone?: ZoneFog, expFrom?: number): FogValues;
|
|
38
|
-
type Fog = {
|
|
39
|
-
/** 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. */
|
|
40
|
-
update(sample: WeatherSample, sky: THREE_NS.Color, zone?: ZoneFog): void;
|
|
41
|
-
/** Takes the fog off the scene (a layer switched off). */
|
|
42
|
-
clear(): void;
|
|
43
|
-
};
|
|
44
|
-
declare function createFog(THREE: ThreeLib, scene: {
|
|
45
|
-
fog: unknown;
|
|
46
|
-
}, options?: {
|
|
47
|
-
readonly expFrom?: number;
|
|
48
|
-
}): Fog;
|
|
49
|
-
/** 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. */
|
|
50
|
-
declare const MIST: {
|
|
51
|
-
readonly box: {
|
|
52
|
-
readonly x: readonly [-14, 10];
|
|
53
|
-
readonly y: readonly [0.2, 1.1];
|
|
54
|
-
readonly z: readonly [-3, 8];
|
|
55
|
-
};
|
|
56
|
-
readonly drift: readonly [0.15, 0.35];
|
|
57
|
-
readonly life: readonly [9, 13];
|
|
58
|
-
readonly size: readonly [3, 5];
|
|
59
|
-
readonly grow: 1.4;
|
|
60
|
-
readonly color: 8227488;
|
|
61
|
-
readonly alpha: 0.13;
|
|
62
|
-
readonly fadeIn: 0.35;
|
|
63
|
-
};
|
|
64
|
-
declare const ASH: {
|
|
65
|
-
readonly box: {
|
|
66
|
-
readonly x: readonly [-10, 8];
|
|
67
|
-
readonly y: readonly [4, 6];
|
|
68
|
-
readonly z: readonly [-3, 7];
|
|
69
|
-
};
|
|
70
|
-
readonly fall: -0.35;
|
|
71
|
-
readonly life: readonly [8, 12];
|
|
72
|
-
readonly size: readonly [0.025, 0.04];
|
|
73
|
-
readonly color: 10525328;
|
|
74
|
-
readonly alpha: 0.75;
|
|
75
|
-
readonly fadeIn: 0.1;
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* 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', ...)`
|
|
79
|
-
* and `emit('ash', ...)`, at the weather's rate instead of 5 and 14), around `camera`. The renderer of game-vfx-three draws them.
|
|
80
|
-
*/
|
|
81
|
-
declare function emitAirborne(engine: WorkshopEngine, sample: WeatherSample, dt: number, camera: Vec3): void;
|
|
82
|
-
|
|
83
|
-
/** The Workshop's car lamps (W101-103) and the rain that glows inside their beam (W1161-1170). */
|
|
84
|
-
declare const HEADLIGHTS: {
|
|
85
|
-
readonly spot: {
|
|
86
|
-
readonly color: 16773584;
|
|
87
|
-
readonly intensity: 2.4;
|
|
88
|
-
readonly distance: 26;
|
|
89
|
-
readonly angle: 0.33;
|
|
90
|
-
readonly penumbra: 0.5;
|
|
91
|
-
readonly decay: 1.6;
|
|
92
|
-
};
|
|
93
|
-
/** Lamp position on the car (x is mirrored), where the spot points, and the cone drawn in the air. */
|
|
94
|
-
readonly lamp: readonly [0.65, 0.74, 2.15];
|
|
95
|
-
readonly aim: readonly [0.65, 0.2, 12];
|
|
96
|
-
readonly cone: {
|
|
97
|
-
readonly radius: 2.4;
|
|
98
|
-
readonly length: 9;
|
|
99
|
-
readonly segments: 18;
|
|
100
|
-
readonly color: 16773584;
|
|
101
|
-
readonly opacity: 0.06;
|
|
102
|
-
};
|
|
103
|
-
readonly lens: {
|
|
104
|
-
readonly on: 16773584;
|
|
105
|
-
readonly off: 3815988;
|
|
106
|
-
};
|
|
107
|
-
/** Lit drops a second, thrown into the beam 1 to 13 m ahead (W1176). */
|
|
108
|
-
readonly lit: {
|
|
109
|
-
readonly rate: 600;
|
|
110
|
-
readonly depth: readonly [1, 13];
|
|
111
|
-
readonly spread: 0.33;
|
|
112
|
-
readonly color: 13622512;
|
|
113
|
-
readonly alpha: 0.9;
|
|
114
|
-
readonly life: 0.06;
|
|
115
|
-
readonly len: 0.035;
|
|
116
|
-
readonly velocity: readonly [0.8, -14, 0];
|
|
117
|
-
};
|
|
118
|
-
/** Beyond this many metres a car keeps only the cone: no real light (W-b text of `farol`). */
|
|
119
|
-
readonly lightRange: 40;
|
|
120
|
-
};
|
|
121
|
-
type HeadlightRules = {
|
|
122
|
-
/** Whether the lamps are lit in this weather and light (default: night, rain or fog). */
|
|
123
|
-
readonly lit?: (sample: WeatherSample) => boolean;
|
|
124
|
-
readonly lightRange?: number;
|
|
125
|
-
};
|
|
126
|
-
/** Night (the sun below the page's 0.3 night factor), rain or fog make a driver turn the lamps on. */
|
|
127
|
-
declare const defaultHeadlightRule: (sample: WeatherSample) => boolean;
|
|
128
|
-
type Headlights = {
|
|
129
|
-
/** 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. */
|
|
130
|
-
attach(car: THREE_NS.Object3D, lens?: THREE_NS.MeshBasicMaterial): () => void;
|
|
131
|
-
/** 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. */
|
|
132
|
-
update(sample: WeatherSample, dt: number, camera: Vec3, engine?: WorkshopEngine, enabled?: boolean): void;
|
|
133
|
-
count(): number;
|
|
134
|
-
dispose(): void;
|
|
135
|
-
};
|
|
136
|
-
declare function createHeadlights(THREE: ThreeLib, rules?: HeadlightRules): Headlights;
|
|
137
|
-
|
|
138
|
-
/** 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). */
|
|
139
|
-
declare const HEAT_HAZE: {
|
|
140
|
-
readonly opacity: 0.09;
|
|
141
|
-
readonly bands: 38;
|
|
142
|
-
readonly rise: 1.4;
|
|
143
|
-
readonly color: readonly [1, 0.93, 0.82];
|
|
144
|
-
};
|
|
145
|
-
declare const HEAT_HAZE_VERTEX = "varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.); }";
|
|
146
|
-
declare const HEAT_HAZE_FRAGMENT = "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); }";
|
|
147
|
-
type HeatHaze = {
|
|
148
|
-
readonly object: THREE_NS.Mesh;
|
|
149
|
-
update(sample: WeatherSample, time: number): void;
|
|
150
|
-
dispose(): void;
|
|
151
|
-
};
|
|
152
|
-
/**
|
|
153
|
-
* 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
|
|
154
|
-
* distortion of the picture, because bending the picture needs a render target that only the host owns.
|
|
155
|
-
*/
|
|
156
|
-
declare function createHeatHaze(THREE: ThreeLib): HeatHaze;
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* 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
|
|
160
|
-
* white by `I * .12`, where `I` is the flash the weather samples (1, then .2, then .8 for 0.26 s).
|
|
161
|
-
*/
|
|
162
|
-
declare const LIGHTNING: {
|
|
163
|
-
readonly light: 3.2;
|
|
164
|
-
readonly background: readonly [0.25, 0.27, 0.32];
|
|
165
|
-
readonly white: 0.12;
|
|
166
|
-
readonly skyColor: 3820650;
|
|
167
|
-
readonly groundColor: 723724;
|
|
168
|
-
};
|
|
169
|
-
type Lightning = {
|
|
170
|
-
readonly light: THREE_NS.HemisphereLight;
|
|
171
|
-
/**
|
|
172
|
-
* 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),
|
|
173
|
-
* and gains the flash; a background the host keeps for itself is left alone.
|
|
174
|
-
*/
|
|
175
|
-
update(sample: WeatherSample, background?: THREE_NS.Color): void;
|
|
176
|
-
dispose(): void;
|
|
177
|
-
};
|
|
178
|
-
declare function createLightning(THREE: ThreeLib, scene: {
|
|
179
|
-
add(object: THREE_NS.Object3D): unknown;
|
|
180
|
-
remove(object: THREE_NS.Object3D): unknown;
|
|
181
|
-
}, vfx?: VfxWorld): Lightning;
|
|
182
|
-
|
|
183
|
-
/** The rain (mm/h) from which a drop that lands splashes (the Workshop's garoa, 2.5, does not; its chuva, 15, does). */
|
|
184
|
-
declare const SPLASH_FROM_MM = 5;
|
|
185
|
-
type NearRainOptions = {
|
|
186
|
-
/** Ground ellipses where a drop leaves a ring (the Workshop's four dark puddles; a game has its own). None by default. */
|
|
187
|
-
readonly puddles?: readonly Puddle[];
|
|
188
|
-
/** Replaces the puddle test. */
|
|
189
|
-
readonly puddleAt?: (x: number, z: number) => boolean;
|
|
190
|
-
readonly splashFrom?: number;
|
|
191
|
-
};
|
|
192
|
-
type NearRain = {
|
|
193
|
-
update(sample: WeatherSample, dt: number, camera: Vec3): void;
|
|
194
|
-
/** Streaks alive. */
|
|
195
|
-
count(): number;
|
|
196
|
-
clear(): void;
|
|
197
|
-
};
|
|
198
|
-
/**
|
|
199
|
-
* 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
|
|
200
|
-
* 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
|
|
201
|
-
* numbers for its three intensities.
|
|
202
|
-
*/
|
|
203
|
-
declare function createNearRain(vfx: VfxWorld | undefined, options?: NearRainOptions): NearRain;
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* 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
|
|
207
|
-
* numbers are the page's, character for character (a golden cuts them from the page and compares).
|
|
208
|
-
*/
|
|
209
|
-
declare const RAIN_CURTAIN: {
|
|
210
|
-
readonly count: 14000;
|
|
211
|
-
readonly width: 70;
|
|
212
|
-
readonly height: 25;
|
|
213
|
-
readonly speed: 13;
|
|
214
|
-
readonly pointSize: 1.6;
|
|
215
|
-
};
|
|
216
|
-
declare const RAIN_CURTAIN_VERTEX = "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; }";
|
|
217
|
-
declare const RAIN_CURTAIN_FRAGMENT = "uniform float uDay; void main(){ gl_FragColor = vec4(vec3(.68,.72,.78)*(0.25+0.75*uDay), .22+.1*uDay); }";
|
|
218
|
-
/** The share of the 14 000 points each quality draws. */
|
|
219
|
-
declare const RAIN_CURTAIN_PROFILES: Readonly<Record<WeatherProfileName, number>>;
|
|
220
|
-
/** The weather's `drops` at which the whole curtain is drawn (the storm's 4 000). */
|
|
221
|
-
declare const RAIN_CURTAIN_FULL_AT = 4000;
|
|
222
|
-
/** The page's loop: x and z in -35..35, y in 0..25, three draws a point in that order, stored as Float32. */
|
|
223
|
-
declare function rainCurtainPositions(random?: () => number, count?: number): Float32Array;
|
|
224
|
-
type RainCurtainOptions = {
|
|
225
|
-
readonly random?: () => number;
|
|
226
|
-
readonly profile?: WeatherProfileName;
|
|
227
|
-
/** Drops (`WeatherSample.drops`) that draw the whole curtain. */
|
|
228
|
-
readonly fullAt?: number;
|
|
229
|
-
readonly count?: number;
|
|
230
|
-
};
|
|
231
|
-
type RainCurtain = {
|
|
232
|
-
readonly object: THREE_NS.Points;
|
|
233
|
-
/** Draws `sample.drops` of the curtain around `camera`; `daylight` is the game's `s` (0 night, 1 day). */
|
|
234
|
-
update(sample: WeatherSample, camera: {
|
|
235
|
-
readonly x: number;
|
|
236
|
-
readonly y: number;
|
|
237
|
-
readonly z: number;
|
|
238
|
-
}, time: number, daylight: number): void;
|
|
239
|
-
setProfile(profile: WeatherProfileName): void;
|
|
240
|
-
/** How many points are drawn now. */
|
|
241
|
-
drawn(): number;
|
|
242
|
-
dispose(): void;
|
|
243
|
-
};
|
|
244
|
-
declare function createRainCurtain(THREE: ThreeLib, options?: RainCurtainOptions): RainCurtain;
|
|
245
|
-
|
|
246
|
-
/** 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. */
|
|
247
|
-
declare const SKY_NIGHT = 724760;
|
|
248
|
-
declare const SKY_DAY = 8885926;
|
|
249
|
-
/** The zone fog colour is lit by `0.35 + 0.65 s` (the page's `ZONA_NEBLINA` blend). */
|
|
250
|
-
declare const ZONE_LIGHT: {
|
|
251
|
-
readonly base: 0.35;
|
|
252
|
-
readonly sun: 0.65;
|
|
253
|
-
};
|
|
254
|
-
/** The page's zone fog (`ZONA_NEBLINA`): colour and far distance; its weight is the game's to set. */
|
|
255
|
-
declare const ZONE_FOG_DEFAULTS: {
|
|
256
|
-
readonly color: 3820090;
|
|
257
|
-
readonly far: 60;
|
|
258
|
-
};
|
|
259
|
-
type Sky = {
|
|
260
|
-
/** 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. */
|
|
261
|
-
update(sample: WeatherSample, zone?: ZoneFog): THREE_NS.Color;
|
|
262
|
-
readonly color: THREE_NS.Color;
|
|
263
|
-
};
|
|
264
|
-
/** Writes the sky into `scene.background` (a `Color`; made when the scene has none) and hands the colour to the fog. */
|
|
265
|
-
declare function createSky(THREE: ThreeLib, scene: {
|
|
266
|
-
background: unknown;
|
|
267
|
-
}): Sky;
|
|
268
|
-
|
|
269
|
-
/** The parts the renderer draws, each of which a layer switches. */
|
|
270
|
-
declare const WEATHER_LAYERS: readonly ["far_rain", "near_rain", "mist", "fog", "sky", "lightning", "headlights", "haze"];
|
|
271
|
-
type WeatherLayerId = (typeof WEATHER_LAYERS)[number];
|
|
272
|
-
type WeatherRendererOptions = {
|
|
273
|
-
readonly scene: THREE_NS.Scene;
|
|
274
|
-
readonly camera: THREE_NS.Camera;
|
|
275
|
-
readonly weather: WeatherSource;
|
|
276
|
-
/** 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). */
|
|
277
|
-
readonly vfx?: VfxWorld;
|
|
278
|
-
readonly profile?: WeatherProfileName;
|
|
279
|
-
/** Seeds the rain curtain (default `Math.random`). */
|
|
280
|
-
readonly random?: () => number;
|
|
281
|
-
readonly zone?: ZoneFog;
|
|
282
|
-
readonly puddles?: readonly Puddle[];
|
|
283
|
-
readonly puddleAt?: (x: number, z: number) => boolean;
|
|
284
|
-
readonly headlights?: HeadlightRules;
|
|
285
|
-
readonly layers?: Partial<Record<WeatherLayerId, boolean>>;
|
|
286
|
-
};
|
|
287
|
-
type WeatherRenderer = {
|
|
288
|
-
readonly curtain: RainCurtain;
|
|
289
|
-
readonly nearRain: NearRain;
|
|
290
|
-
readonly fog: Fog;
|
|
291
|
-
readonly sky: Sky;
|
|
292
|
-
readonly lightning: Lightning;
|
|
293
|
-
readonly headlights: Headlights;
|
|
294
|
-
readonly haze: HeatHaze;
|
|
295
|
-
/** Draws the weather of the source for a frame of `dt` seconds. Call once per frame, after the weather advanced. */
|
|
296
|
-
update(dt: number): void;
|
|
297
|
-
setLayer(id: WeatherLayerId, on: boolean): void;
|
|
298
|
-
layer(id: WeatherLayerId): boolean;
|
|
299
|
-
setZoneFog(zone: ZoneFog | undefined): void;
|
|
300
|
-
setProfile(profile: WeatherProfileName): void;
|
|
301
|
-
stats(): {
|
|
302
|
-
readonly rainCurtain: number;
|
|
303
|
-
readonly rainNear: number;
|
|
304
|
-
readonly cars: number;
|
|
305
|
-
};
|
|
306
|
-
dispose(): void;
|
|
307
|
-
};
|
|
308
|
-
/** The whole weather picture: rain curtain, near rain with splashes, mist and ash, fog, sky, lightning, headlights and heat haze, from one `WeatherSource`. */
|
|
309
|
-
declare function createWeatherRenderer(THREE: ThreeLib, options: WeatherRendererOptions): WeatherRenderer;
|
|
310
|
-
|
|
311
|
-
type WeatherVisualOptions = Pick<WeatherRendererOptions, 'profile' | 'random' | 'zone' | 'puddles' | 'puddleAt' | 'headlights'> & {
|
|
312
|
-
/** The effects world of the room (`room.vfx`); without it the near rain, mist, ash, white flash and lit drops are left out. */
|
|
313
|
-
readonly vfx?: VfxWorld;
|
|
314
|
-
/** 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. */
|
|
315
|
-
readonly rig?: readonly [x: number, z: number, turn: number] | false;
|
|
316
|
-
/**
|
|
317
|
-
* 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
|
|
318
|
-
* changes. Without it the rig has only the lamps and their beams: no car drawn here.
|
|
319
|
-
*/
|
|
320
|
-
readonly vehicles?: (THREE: ThreeLib) => RigVehicles;
|
|
321
|
-
/** Fleet id of the rig's car (default `midsize_sedan`). */
|
|
322
|
-
readonly rigVehicle?: string;
|
|
323
|
-
/**
|
|
324
|
-
* The rig's car as an item of the host's catalogue (`sedan` of the vehicles test module): the host puts it in its world (`ModuleHost.addObject`), so shots, blows, blasts and fire damage it, it
|
|
325
|
-
* blocks the player and its doors open, and the lamps go on its nose. Wins over `vehicles` when the host can place it; until a loaded module has the item the rig has only the lamps.
|
|
326
|
-
*/
|
|
327
|
-
readonly rigItem?: string;
|
|
328
|
-
/** 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. */
|
|
329
|
-
readonly layers?: Partial<Record<WeatherLayerId, boolean>>;
|
|
330
|
-
};
|
|
331
|
-
/** 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. */
|
|
332
|
-
interface RigVehicles {
|
|
333
|
-
build(key: string, options?: {
|
|
334
|
-
quality?: 'high' | 'lite';
|
|
335
|
-
}): {
|
|
336
|
-
readonly group: THREE_NS.Object3D;
|
|
337
|
-
readonly length: number;
|
|
338
|
-
readonly width?: number;
|
|
339
|
-
dispose(): void;
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* The picture of the weather for the weather bench: `createWeatherTestModule({ visual: createWeatherVisual({ vfx: room.vfx }) })`. It draws the weather the bench shows with
|
|
344
|
-
* `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.
|
|
345
|
-
*/
|
|
346
|
-
declare function createWeatherVisual(options?: WeatherVisualOptions): WeatherVisualFactory;
|
|
347
|
-
|
|
348
|
-
/** The names of the visual layers in the bench; any other locale falls back to English. */
|
|
349
|
-
type WeatherVisualText = {
|
|
350
|
-
readonly layers: Readonly<Record<Exclude<WeatherLayerId, 'fog'>, string>>;
|
|
351
|
-
};
|
|
352
|
-
declare const weatherVisualTextOf: (locale: string) => WeatherVisualText;
|
|
353
|
-
|
|
354
|
-
export { ASH, FOG_EXP_FROM, FOG_NEAR, FOG_ZONE_NEAR, type Fog, type FogValues, HEADLIGHTS, HEAT_HAZE, HEAT_HAZE_FRAGMENT, HEAT_HAZE_VERTEX, type HeadlightRules, type Headlights, type HeatHaze, LIGHTNING, type Lightning, MIST, type NearRain, type NearRainOptions, RAIN_CURTAIN, RAIN_CURTAIN_FRAGMENT, RAIN_CURTAIN_FULL_AT, RAIN_CURTAIN_PROFILES, RAIN_CURTAIN_VERTEX, type RainCurtain, type RainCurtainOptions, type RigVehicles, SKY_DAY, SKY_NIGHT, SPLASH_FROM_MM, type Sky, type ThreeLib, type Vec3, WEATHER_LAYERS, type WeatherLayerId, type WeatherProfileName, type WeatherRenderer, type WeatherRendererOptions, type WeatherSource, type WeatherVisualOptions, type WeatherVisualText, ZONE_FOG_DEFAULTS, ZONE_LIGHT, type ZoneFog, createFog, createHeadlights, createHeatHaze, createLightning, createNearRain, createRainCurtain, createSky, createWeatherRenderer, createWeatherVisual, defaultHeadlightRule, densityForFar, emitAirborne, fogOf, rainCurtainPositions, weatherVisualTextOf };
|
|
1
|
+
export { A as ASH, F as FOG_EXP_FROM, a as FOG_NEAR, b as FOG_ZONE_NEAR, c as Fog, d as FogValues, H as HEADLIGHTS, e as HEAT_HAZE, f as HEAT_HAZE_FRAGMENT, g as HEAT_HAZE_VERTEX, h as HeadlightRules, i as Headlights, j as HeatHaze, L as LIGHTNING, k as Lightning, l as LightningOptions, M as MIST, N as NearRain, m as NearRainOptions, R as RAIN_CURTAIN, n as RAIN_CURTAIN_FRAGMENT, o as RAIN_CURTAIN_FULL_AT, p as RAIN_CURTAIN_PROFILES, q as RAIN_CURTAIN_VERTEX, r as RainCurtain, s as RainCurtainOptions, RigVehicles, S as SKY_DAY, t as SKY_NIGHT, u as SPLASH_FROM_MM, v as Sky, T as ThreeLib, V as Vec3, W as WEATHER_LAYERS, w as WeatherLayerId, x as WeatherProfileName, y as WeatherRenderer, z as WeatherRendererOptions, B as WeatherSource, WeatherVisualOptions, WeatherVisualText, Z as ZONE_FOG_DEFAULTS, C as ZONE_LIGHT, D as ZoneFog, E as createFog, G as createHeadlights, I as createHeatHaze, J as createLightning, K as createNearRain, O as createRainCurtain, P as createSky, Q as createWeatherRenderer, createWeatherVisual, U as defaultHeadlightRule, X as densityForFar, Y as emitAirborne, _ as fogOf, $ as rainCurtainPositions, weatherVisualTextOf } from './testing.js';
|
|
2
|
+
import '@adatechnology/game-render-three';
|
|
3
|
+
import 'three';
|
|
4
|
+
import '@adatechnology/game-vfx';
|
|
5
|
+
import '@adatechnology/game-weather';
|
|
6
|
+
import '@adatechnology/game-weather/testing';
|