A Cauldron2D.Sectors.Map drawn while its sectors move: doors and lifts change
heights, lights flicker, switches and animated pictures change what sides and flats
show. Each sector is one mesh and one instance — its floors, ceilings and the walls
facing into it — and update/5 rebuilds only the sectors that changed and their
neighbours. Each sector's light level is held in a lightmap with a row per sector
(CauldronGPU.Sectors.Live.Lightmap), put again whenever a light changes, and turned
into light falling with distance by a light table
(CauldronGPU.Sectors.Live.LightTable) the caller puts in its environment with
light_space: :display:
{table, reach} = CauldronGPU.Sectors.Live.light_table(live)
%CauldronGPU.Environment{light_space: :display, light_table: {table, reach}, tone_map: :clamp}Sky ceilings and floors, and the upper walls left out between two sky ceilings, are
sky surfaces showing the environment's sky, so they hide what lies beyond them as
Doom's sky does; sky_box/4 gives the sky picture as a box laid out as Doom draws its
sky (CauldronGPU.Sectors.Live.SkyBox), for the environment's sky_picture:
{faces, live} = CauldronGPU.Sectors.Live.sky_box(live, target, 1.2, nil)
%CauldronGPU.Environment{sky_picture: {:box, faces}}
live = CauldronGPU.Sectors.Live.new(map, pictures, palette, sky: sky, sky_flats: [f_sky1], first_id: 1)
{changes, live} = CauldronGPU.Sectors.Live.update(live, target, sectors, sides, shown: %{}, stretch: 1.2)
CauldronGPU.Target.submit(target, changes)
CauldronGPU.Target.submit(target, CauldronGPU.Sectors.Live.close(live, target))map carries a BSP; pictures is the Cauldron2D.Sectors.Pictures set its picture
ids index, made with native: false; palette is 768 bytes. sectors and sides are
the map's as they are now, with the shapes Cauldron2D.Sectors.Map gives them.
Instances take the ids from :first_id up, one a sector in sector order (ids/1).
Options of new/4:
:sky— picture id of the sky, default none:sky_flats— picture ids that mark a sky ceiling, default[]:first_id— the first instance id, default1:scale— metres per map unit, default1 / 32:light— the options ofCauldron2D.Sectors.Lightthe light table follows, default[]
Options of update/5, as Cauldron2D.Sectors.View takes them:
:shown—%{picture => picture}, the picture drawn in place of another this tick, for animated pictures; default%{}:extra_light— light added to every level, default0:fixed— a light table every picture is drawn through at full light, defaultnil:stretch— how many times taller than wide a map unit is drawn, default1.0
Pictures are uploaded the first time they are drawn.
Summary
Functions
Removes every instance placed and releases every handle uploaded; gives the removing changes.
A camera far distance, in the renderer's units, that keeps the level and its sky in view.
The instance ids the live map uses.
The light table and its reach in metres, for the environment's light_table; nil
before the first update/5.
A material kept as key (a tuple whose second and third elements are a picture and a
light table), made the first time by make from that picture's texture.
A live map ready for its first update/5; nothing is uploaded yet.
A map point {x, y, height} in the renderer's frame, heights times stretch.
The sky picture as the six faces of an environment's {:box, faces} sky, for heights
drawn stretch times taller than wide and pictures through light table table
(nil for none); made the first time for each, nil for a map with no sky picture.
The texture of picture through light table table (nil for none), uploaded the first time.
The transform that places map coordinates in the renderer's frame, heights times stretch.
The changes that draw the map with sectors and sides as they are now, and the
live map to update next time. Meshes, textures and materials it needs are uploaded
through target.
Types
@type t() :: %CauldronGPU.Sectors.Live{ count: pos_integer(), first_id: pos_integer(), geometry: CauldronGPU.Sectors.Live.Geometry.t(), light: term(), light_options: keyword(), light_table: {CauldronGPU.Handle.t(), float()} | nil, lightmap: CauldronGPU.Handle.t() | nil, meshes: %{ required(non_neg_integer()) => %{ mesh: CauldronGPU.Handle.t(), keys: [term()] } }, pictures: CauldronGPU.Sectors.Live.Pictures.t(), placed: %{required(non_neg_integer()) => term()}, reach: float(), scale: number(), sectors: tuple() | nil, sides: tuple() | nil, sky: non_neg_integer() | nil, sky_boxes: %{ required({number(), non_neg_integer() | nil}) => %{ required(atom()) => CauldronGPU.Handle.t() } }, sky_flats: MapSet.t(), sky_material: CauldronGPU.Handle.t() | nil }
Functions
@spec close(t(), CauldronGPU.Target.t()) :: [CauldronGPU.Stream.change()]
Removes every instance placed and releases every handle uploaded; gives the removing changes.
A camera far distance, in the renderer's units, that keeps the level and its sky in view.
The instance ids the live map uses.
@spec light_table(t()) :: {CauldronGPU.Handle.t(), float()} | nil
The light table and its reach in metres, for the environment's light_table; nil
before the first update/5.
@spec material( t(), CauldronGPU.Target.t(), tuple(), (CauldronGPU.Sectors.Live.Pictures.texture() -> CauldronGPU.Material.t()) ) :: {CauldronGPU.Handle.t(), t()}
A material kept as key (a tuple whose second and third elements are a picture and a
light table), made the first time by make from that picture's texture.
@spec new( Cauldron2D.Sectors.Map.t(), Cauldron2D.Sectors.Pictures.t(), binary(), keyword() ) :: t()
A live map ready for its first update/5; nothing is uploaded yet.
A map point {x, y, height} in the renderer's frame, heights times stretch.
@spec sky_box(t(), CauldronGPU.Target.t(), number(), non_neg_integer() | nil) :: {%{required(atom()) => CauldronGPU.Handle.t()} | nil, t()}
The sky picture as the six faces of an environment's {:box, faces} sky, for heights
drawn stretch times taller than wide and pictures through light table table
(nil for none); made the first time for each, nil for a map with no sky picture.
@spec texture(t(), CauldronGPU.Target.t(), non_neg_integer(), non_neg_integer() | nil) :: {CauldronGPU.Sectors.Live.Pictures.texture(), t()}
The texture of picture through light table table (nil for none), uploaded the first time.
@spec transform(t(), number()) :: CauldronGPU.Transform.t()
The transform that places map coordinates in the renderer's frame, heights times stretch.
@spec update(t(), CauldronGPU.Target.t(), tuple(), tuple(), keyword()) :: {[CauldronGPU.Stream.change()], t()}
The changes that draw the map with sectors and sides as they are now, and the
live map to update next time. Meshes, textures and materials it needs are uploaded
through target.