WeatherField

from acron.atmosphere import WeatherField
class WeatherField

Bases:

Bases: TypedReferenceCount

Inheritance diagram

digraph inheritancee8cef33582 { bgcolor=transparent; rankdir=BT; size="8.0, 12.0"; "DTOOL_SUPER_BASE" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style=""]; "ReferenceCount" [URL="acron.core.ReferenceCount.html#acron.core.ReferenceCount",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "DTOOL_SUPER_BASE" -> "ReferenceCount" [arrowsize=0.75,style=""]; "TypedObject" [URL="acron.core.TypedObject.html#acron.core.TypedObject",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "DTOOL_SUPER_BASE" -> "TypedObject" [arrowsize=0.75,style=""]; "TypedReferenceCount" [URL="acron.core.TypedReferenceCount.html#acron.core.TypedReferenceCount",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "TypedObject" -> "TypedReferenceCount" [arrowsize=0.75,style=""]; "ReferenceCount" -> "TypedReferenceCount" [arrowsize=0.75,style=""]; "WeatherField" [URL="acron.atmosphere.WeatherField.html#acron.atmosphere.WeatherField",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top"]; "TypedReferenceCount" -> "WeatherField" [arrowsize=0.75,style=""]; }
__init__()

A field for the seed, packing maps of map_size^2 texels, starting on the “fair” preset.

add_front()

A front crossing the tile: cold (a narrow line of strong uplift, cooler drier air behind) or warm (broad, gentle uplift ahead: stratiform cloud and rain; warmer moister air behind). It moves towards heading_deg (0 north, 90 east) at speed m/s relative to the air, from distance metres before the focus, with the given strength (0..2), for lifetime seconds (fading in and out). A front that leaves the tile comes round again (the tile repeats). Returns how many fronts there are.

add_volume()

Voxel volumes.

A game’s own voxel cloud (in the air frame: it drifts with the wind). density_at() and the sun’s column count it.

air_to_world()

An air-frame point in the world: the image (the tile repeats) nearest the focus.

property blend → float

How far the last set_preset() blend has got, 0..1.

clear_bolts()
clear_fronts()
clear_override()

Ends set_override().

clear_terrain()
clear_volumes()

Removes the game’s volumes (the hero volumes stay; set_hero_count(0) ends those).

property cloud_base → float

Where cumulus bases sit (m): 1800 in dry air down to 650 in humid air.

property convection → float
cover_at()

The cloud cover (0..1) over the world point p, straight from the field.

density_at()

The cloud density (0..1, before extinction) at a world point (metres), as the shader’s base density computes it from the last packed weather map and the base noise.

property extinction → float

The clouds’ extinction per metre at density 1 (higher in storms).

fill_map()

Writes the weather map into tex (set up as map_size^2 RGBA8, repeating, linear, if it isn’t already): r cover, g type / 2 (0 stratus, 0.5 cumulus, 1 cumulonimbus), b base / 12 km, a top / 12 km. Texel (i, j) holds the air point ((i + 0.5), (j + 0.5)) x tile / map_size, so the shader samples it at air.xy / tile.

fill_precipitation()

Writes the precipitation map into tex (like fill_map): r precipitation 0..1 at the ground (widened a texel round showers), g the share falling as snow, a 1.

fill_sim_map()

The simulation’s fields into tex (set up as sim_size^2 RGBA32F, repeating, linear, like the weather map: texel (i, j) the air point ((i + 0.5), (j + 0.5)) x tile / sim_size): r relative humidity, g the temperature’s anomaly (K), b the uplift (m/s), a the stratiform and anvil cloud water. For debug views.

property focus → LPoint2f

Where the forced looks of the clear, rain, snow and storm presets are exactly the preset’s (the player), world metres. Also where the storm level and the lightning are measured.

property fog → float
get_base_noise_size()
get_blend()

How far the last set_preset() blend has got, 0..1.

get_bolt()

A lightning bolt since the last clear_bolts(): (x, y, z world metres, strength 0..1). At most 64 are kept.

get_cell()

Cell n: (x, y world metres, the image nearest the focus; its base and top metres above the sea).

get_cell_id()

Cell n’s id (stable over its life; the hero volumes are keyed by it).

get_cell_state()

Cell n’s state: (updraught m/s, how much of it exists 0..1, its anvil 0..1, its rain 0..1).

static get_class_type()
get_cloud_base()

Where cumulus bases sit (m): 1800 in dry air down to 650 in humid air.

get_convection()
get_extinction()

The clouds’ extinction per metre at density 1 (higher in storms).

get_focus()
get_fog()
get_hero_count()
get_hero_radius()
get_hero_resolution()
get_humidity()

The boundary layer’s relative humidity (0..1, a little more where it is supersaturated) under the world point.

get_last_march_samples()
get_layer_base()
get_layer_offset()

The layers’ stretch compensation (metres), for the shader’s sxy = ap + lay * ((M - I) * ap + layer_offset), where ap = world.xy - get_offset() and M stretches 0.6 along get_wind_dir() and 1.3 across it. It is (0, 0) until the offset first wraps, so with it the formula is castaway’s mix(ap, M ap, lay); each wrap adds what keeps the layers from jumping. It is not wrapped (it grows by ~7 km a wrap).

get_layer_top()
get_light_dir()
get_map_size()
static get_max_height()
get_moisture()
get_noise_offset()

The base noise’s scroll (metres; the shader adds it to the sample point before dividing by the base tile): the noise rises 1.6 m/s, so the puffs boil.

get_num_bolts()
get_num_cells()

The convective cells (simulated, or the lattice’s).

How many convective cells there are now (the simulation’s, alive or fading; or the lattice’s live ones).

get_num_fronts()
get_num_volumes()
get_offset()

The field’s drift (metres, wrapped into [0, tile)): air = world - offset.

get_preset()
get_seed()
get_sim_size()
get_sim_sources()
get_sim_speed()
static get_sim_step()
get_sim_steps()

How many fixed steps the simulation has taken since it started over.

get_snow()
get_storm()
get_stratus()
get_temperature()

The air’s temperature (C) at the world point: the surface’s (the climate’s and the simulation’s anomaly) less the environment’s lapse rate with height.

get_terrain_height()

The terrain’s height (m) at world (x, y) as set_terrain() gave it.

static get_tile()
get_tile_m()
get_time()
get_uplift()

The vertical wind (m/s) at the world point: the boundary layer’s uplift (convergence, slopes, fronts) fading with height, and inside a cell’s updraught its speed.

get_volume()
get_volume_cell()

The id of the cell hero volume n was grown from (0 for a game’s).

get_volume_weight()

How much volume n counts, 0..1 (a hero fades in as its cell leaves the map, and out again).

get_water_source()

The water the climate has added (less taken) since the simulation started over: get_water_total() minus it is what the processes conserve.

get_water_total()

All the simulation’s water (water units: g/kg summed over its grid cells): vapour, cloud, rain, anvil ice, the ground’s, the cells’.

get_wind()

The wind at the clouds, m/s in world space (x east, y north, z up); the field drifts with it.

get_wind_dir()

The wind’s direction (unit, xy): layers are drawn out along it.

static has_preset()

Whether a preset of this name exists: clear, fair, overcast, rain, storm, fog, snow, convective (scattered thunderstorms, nothing forced).

property hero_count → int

How many of the deepest cells near the focus become hero volumes (voxelised cumulonimbus; 0, the default: none). Needs the simulation.

property hero_radius → float

How far from the focus (m) a cell may be to become a hero volume.

is_hero_volume()
is_simulated()
property layer_base → float
property layer_offset → LVecBase2f

The layers’ stretch compensation (metres), for the shader’s sxy = ap + lay * ((M - I) * ap + layer_offset), where ap = world.xy - get_offset() and M stretches 0.6 along get_wind_dir() and 1.3 across it. It is (0, 0) until the offset first wraps, so with it the formula is castaway’s mix(ap, M ap, lay); each wrap adds what keeps the layers from jumping. It is not wrapped (it grows by ~7 km a wrap).

property layer_top → float
property light_dir → LVector3f

Towards the key light: the hero volumes’ self-shadow is swept for it (a few slices each step()).

property map_size → int
march_density()

The integral of density_at() (density x metres, before extinction) along the segment from world point p, length metres along dir, sampled every step metres (at the steps’ middles). With skip the volumes’ signed distances skip the samples that lie provably outside every cloud (outside the layer’s slab and more than a voxel from every volume’s envelope): the march the renderer makes; without, every sample (brute force). get_last_march_samples() says how many were taken.

property moisture → float
property noise_offset → LVecBase3f

The base noise’s scroll (metres; the shader adds it to the sample point before dividing by the base tile): the noise rises 1.6 m/s, so the puffs boil.

property offset → LVecBase2f

The field’s drift (metres, wrapped into [0, tile)): air = world - offset.

optical_depth()

The optical depth of the cloud layer between the world point p and the light in the direction to_light: a 12-step march of density_at() from p (or the layer’s base, whichever is higher) to the layer’s top, times the extinction. The light’s elevation is taken as at least asin(0.12) (~7 degrees); 0 above the layer or for a zero direction.

precipitation_at()

The precipitation (0..1 at the ground: 0.1 drizzle, 0.4 a shower, 1 a downpour) under the world point p, straight from the field.

property preset → string
remove_volume()
sample()

The field over the world point (x, y): (cover 0..1, type 0..2, base m, top m).

property seed → int
set_base_noise()

Shares the base noise volume the renderer samples (CloudNoise::make_base, any size, RGBA16 with its RAM image), so density_at() reads the very same texels. Without one, a 64^3 base of the field’s seed is baked on first use (the same noise as a larger base of that seed, down-sampled).

set_focus()

Where the forced looks of the clear, rain, snow and storm presets are exactly the preset’s (the player), world metres. Also where the storm level and the lightning are measured.

set_hero_count()

How many of the deepest cells near the focus become hero volumes (voxelised cumulonimbus; 0, the default: none). Needs the simulation.

set_hero_radius()

How far from the focus (m) a cell may be to become a hero volume.

set_hero_resolution()

The hero volumes’ voxels (each 8..256; default 64^3).

set_light_dir()

Towards the key light: the hero volumes’ self-shadow is swept for it (a few slices each step()).

set_override()

Forces parts of the field everywhere (the debug view, tests, a scripted sky): each value < 0 leaves that part alone. Heights are metres.

set_preset()

Takes the weather towards a preset over seconds of step() time (0: at once). The blend starts from wherever the weather is now, so a new preset in the middle of a blend never jumps. Returns false for an unknown name.

set_sim_size()

The simulation’s grid: n x n cells over the tile (8..256, default 64: 256 m). Starts it over.

set_sim_sources()

Whether the climate feeds the boundary layer (vapour and warmth towards the preset’s targets: the sources and sinks). Off, the water is only moved about: get_water_total() stays (the budget the tests check).

set_sim_speed()

The simulation’s time scale: physics seconds per second of step() (1: the real atmosphere’s pace, a storm towering in ~20 minutes; the default 6 tells a cell’s life in a few minutes, like the lattice’s).

set_simulated()

The simulation.

The simulation.

Simulates the weather (the default) or, off, draws it from the lattice of scripted cells (castaway’s model, cheaper and fully procedural). On starts the simulation over in the current weather.

set_terrain()

The ground’s heights for the uplift over slopes: a grey image (white scale metres) over the world rectangle (x0, y0, x1, y1; the image’s top row the north edge). Outside it the ground is flat.

property sim_size → int

The simulation’s grid: n x n cells over the tile (8..256, default 64: 256 m). Starts it over.

property sim_sources → bool

Whether the climate feeds the boundary layer (vapour and warmth towards the preset’s targets: the sources and sinks). Off, the water is only moved about: get_water_total() stays (the budget the tests check).

property sim_speed → float

The simulation’s time scale: physics seconds per second of step() (1: the real atmosphere’s pace, a storm towering in ~20 minutes; the default 6 tells a cell’s life in a few minutes, like the lattice’s).

property simulated → bool

The simulation.

The simulation.

Simulates the weather (the default) or, off, draws it from the lattice of scripted cells (castaway’s model, cheaper and fully procedural). On starts the simulation over in the current weather.

property snow → float
step()

Advances the weather by dt seconds: the cells’ lives, the blend towards the preset, the wind (it veers slowly about the seed’s prevailing direction) and the drift of the field with it. The packed maps are refreshed by the next fill_map() / update_map(). A dt that is negative or not finite does nothing; one longer than an hour advances an hour (with a warning).

property storm → float
property stratus → float
sun_column()

The transmittance (0..1) of light from the direction to_light reaching the world point p through the cloud layer: exp(-optical_depth()), but thick cloud keeps a little diffuse light (multiple scattering): max(exp(-od), 0.35 exp(-0.2 od)).

property tile_m → float
property time → float
update_map()

Packs the field into the internal maps when it has changed since they were last packed. fill_map() and fill_precipitation() do this themselves; call it when only density_at() / sun_column() are used.

volume_density()

The voxel volumes’ part of density_at() at a world point.

property wind → LVecBase3f

The wind at the clouds, m/s in world space (x east, y north, z up); the field drifts with it.

property wind_dir → LVecBase2f

The wind’s direction (unit, xy): layers are drawn out along it.

world_to_air()

A world point in the drifting frame: (x, y) - get_offset(), z kept.