Wind.component
This package holds more than this page lists. See all of its files in its world.
README.md
Wind
Air moving through the world, placed as an entity and saved with its scene: a breeze over the whole map, a gale on a cliff top, a fan, an updraft over a vent, a wind tunnel, the gap between two buildings. Every body carrying FluidForces or a LiftSurface feels it inside each physics step, and Physics.wind(point) reads it, so a flag, a tree or a particle system that bends to it matches what the bodies feel.
Public fields:
kind(default"steady"): what the wind blows."steady"blowsvelocity."grid"blows a velocity per texel over thesizebox (above 0 along every axis), read smoothly between the texels' centres: air flowing around a building, a valley channelling it, a storm front painted over a map.columnstexels along X,rowsalong Z andlayersalong Y (each default1; one layer is a map, read the same at every height of the box);velocitieslists x, y, z per texel in m/s, in the world's frame, along X first, then Z, then Y (the texel at column c, row r, layer y, counted from 0, starts at number 3 * ((y * rows + r) * columns + c) + 1). Ortexturenames a float (rgba32f) texture asset whose texels are the velocities: red, green and blue are x, y and z in m/s, its width the columns and its height the rows, its first row at the box's -Z face; it is read when the component starts, is enabled or has a field changed (moving the entity carries the texels already read), and an 8-bit texture is refused with the format it holds.scroll(m/s, default{0, 0, 0}) moves the pattern through its box, wrapping around it;wrap = truerepeats the grid past its box, where otherwise it blows within its box alone."vortex"turns the air about this entity's up axis through its position, like a solid body inside a core ofradiusmetres (default5), whose edge turns atspeedm/s (default10, by the right-hand rule about the axis, negative the other way; the core turns atspeed / radiusrad/s), slowing asradius / distanceoutside it;inflow(m/s, default0) draws the air in toward the axis andupdraft(m/s, default0) lifts it on the axis, fading to nothing atupdraftRadiusmetres from it (default0: the core's edge; wider, a column that carries up what the vortex swings around outside its core): a tornado, a dust devil."radial"blows out of this entity's position atspeedm/s atradiusmetres (negative draws the air in), rising from nothing at the centre: out in every direction withspread = "point"(the default, slowing by the square of the distance: a blast), or out across its up axis withspread = "line"(slowing by the distance: a rotor's downwash).
velocity(m/s, default{5, 0, 0}) inspace, added on top of every kind (set it to{0, 0, 0}for a vortex or a radial wind standing still in the air):"local"(default: this entity's own frame, so a fan blows along its own axis however it is turned, and a vortex turns about its own up) or"world".gust(m/s, default0): how far the speed rises and falls along the wind's direction, overgustPeriodseconds (default4), the gusts travelling downwind and differing across the wind overgustSizemetres (default20).size(m, default all0): with all 0 the wind blows everywhere; otherwise within a world-aligned box of that size centred on the entity, which follows the entity as it moves.falloff(m, default0): how far inside the box's faces the wind reaches full strength. Every face fades it, the floor and the top included, so a wind meant to blow at full strength along the ground puts the box's floor at leastfalloffbelow it.
Several winds covering a point add up. Disabling the component stills its wind. A wind is the field Physics.defineWind defines, kept in step with the component: Physics.winds() lists it, and a script defines a wind of its own the same way, including a field stated in an entity's own space (space = "entity").
-- a gusting breeze over the whole level
level.component.add("Wind", { velocity = { 6, 0, 2 }, gust = 3, space = "world" })
-- an updraft 6 m across and 20 m high over a vent, soft at its edges
vent.component.add("Wind", { velocity = { 0, 9, 0 }, size = { 6, 20, 6 }, falloff = 1 })
-- a fan blowing along its own +Z, turning with it
fan.component.add("Wind", { velocity = { 0, 0, 12 }, size = { 3, 3, 10 }, falloff = 0.5 })
-- a tornado 40 m across, drawing the air in and lifting it over a column 12 m from its axis, that goes where its entity goes
twister.component.add("Wind", { kind = "vortex", velocity = { 0, 0, 0 }, radius = 5, speed = 30, inflow = 4, updraft = 10, updraftRadius = 12, size = { 40, 60, 40 }, falloff = 8 })
-- a 40 m square map of 2 x 2 texels: calm in one corner, 4 m/s along +X in the next two and 8 m/s in the far one
pass.component.add("Wind", { kind = "grid", velocity = { 0, 0, 0 }, size = { 40, 20, 40 }, columns = 2, rows = 2,
velocities = { 0, 0, 0, 4, 0, 0, 4, 0, 0, 8, 0, 0 } })
-- the same kind of map baked into a float texture: red, green, blue are the wind's x, y, z
local map = asset.create("texture", "valleyWind", { rgba = texels, width = 64, height = 64, settings = { compression = "rgba32f" } })
valley.component.add("Wind", { kind = "grid", velocity = { 0, 0, 0 }, size = { 400, 60, 400 }, texture = map })
-- a blast pushing everything out of a 20 m box
bomb.component.add("Wind", { kind = "radial", velocity = { 0, 0, 0 }, radius = 2, speed = 40, size = { 20, 20, 20 } })