CauldronGPU.Sectors.Live (CauldronGPU v0.3.3)

Copy Markdown View Source

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, default 1
  • :scale — metres per map unit, default 1 / 32
  • :light — the options of Cauldron2D.Sectors.Light the 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, default 0
  • :fixed — a light table every picture is drawn through at full light, default nil
  • :stretch — how many times taller than wide a map unit is drawn, default 1.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

t()

@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

close(live, target)

Removes every instance placed and releases every handle uploaded; gives the removing changes.

far(live, stretch)

@spec far(t(), number()) :: float()

A camera far distance, in the renderer's units, that keeps the level and its sky in view.

ids(live)

@spec ids(t()) :: Range.t()

The instance ids the live map uses.

light_table(live)

@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.

material(live, target, key, make)

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.

new(map, pictures, palette, opts \\ [])

A live map ready for its first update/5; nothing is uploaded yet.

point(live, arg, stretch)

@spec point(t(), {number(), number(), number()}, number()) ::
  {float(), float(), float()}

A map point {x, y, height} in the renderer's frame, heights times stretch.

sky_box(live, target, stretch, table)

@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.

texture(live, target, picture, table)

The texture of picture through light table table (nil for none), uploaded the first time.

transform(live, stretch)

@spec transform(t(), number()) :: CauldronGPU.Transform.t()

The transform that places map coordinates in the renderer's frame, heights times stretch.

update(live, target, sectors, sides, opts \\ [])

@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.