Log inGet started
Package

Wind.component

Newest version

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" blows velocity.
    • "grid" blows a velocity per texel over the size box (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. columns texels along X, rows along Z and layers along Y (each default 1; one layer is a map, read the same at every height of the box); velocities lists 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). Or texture names 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 = true repeats 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 of radius metres (default 5), whose edge turns at speed m/s (default 10, by the right-hand rule about the axis, negative the other way; the core turns at speed / radius rad/s), slowing as radius / distance outside it; inflow (m/s, default 0) draws the air in toward the axis and updraft (m/s, default 0) lifts it on the axis, fading to nothing at updraftRadius metres from it (default 0: 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 at speed m/s at radius metres (negative draws the air in), rising from nothing at the centre: out in every direction with spread = "point" (the default, slowing by the square of the distance: a blast), or out across its up axis with spread = "line" (slowing by the distance: a rotor's downwash).
  • velocity (m/s, default {5, 0, 0}) in space, 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, default 0): how far the speed rises and falls along the wind's direction, over gustPeriod seconds (default 4), the gusts travelling downwind and differing across the wind over gustSize metres (default 20).
  • size (m, default all 0): 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, default 0): 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 least falloff below 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 } })