QtCraft API C++ classes QML types Handbook

QcLightEngine Class

Block and sky light of all loaded chunks per section, kept up to date incrementally (decisions E-049 and E-389); the server and the client use the same engine. More...

Header: #include <common/light/QcLightEngine.h>

Public Types

struct Memory
struct Options
class Prepared
enum class Channel { Block, Sky }

Public Functions

void addChunk(const QcChunk &chunk)
void addChunk(std::shared_ptr<const QcChunk> chunk)
void addChunk(const QcChunk &chunk, const std::shared_ptr<QcLightEngine::Prepared> &prepared)
int blockLight(QcBlockPos pos) const
void changeBlock(QcBlockPos pos, std::shared_ptr<const QcChunk> chunk)
void changeBlock(QcBlockPos pos, QcBlockId before, const QcChunk &chunk)
void compact(QcLightEngine::Channel channel, QcChunkPos pos, int index)
bool hasChunk(QcChunkPos pos) const
bool hasSky() const
int level(QcLightEngine::Channel channel, QcBlockPos pos) const
QcLightEngine::Memory memory() const
std::shared_ptr<QcLightEngine::Prepared> prepare(const QcChunk &chunk) const
void rebind(const QcChunk &chunk)
void removeChunk(QcChunkPos pos)
const QcLightNibbles *section(QcLightEngine::Channel channel, QcChunkPos pos, int index) const
const std::shared_ptr<const QcLightTable> &sharedTable() const
int skyLight(QcBlockPos pos) const
int skyTop(QcBlockPos column) const
const QcLightTable &table() const
QList<QcSectionAddress> takeTouched(QcLightEngine::Channel channel)
int uniformLevel(QcLightEngine::Channel channel, QcChunkPos pos, int index) const
quint64 visitedCells() const

Static Public Members

const int channelCount
const int maxLevel

Detailed Description

Block light shines from the blocks that give off light. Sky light shines with 15 into every cell above the highest cell of its column that keeps sky light coming straight down out (QcLightPassage::skyStop) and spreads from there like block light. Every step into a cell costs max(1, opacity) levels, opacity 15 stops light, no step crosses a face a partial shape covers, and unloaded chunks are dark walls. The result of each channel is the unique fixpoint "brightest source minus cheapest path", so it equals one full flood fill of the loaded chunks, whatever the order of the changes: a new chunk floods its own sources and the light flowing in over its borders; a changed block clears the light that depended on it (breadth-first removal) and refills the cleared cells from their lit boundary and from sources; an unloaded chunk takes away the light that came from it.

Levels are kept as nibbles per section; a section whose cells all have the same level (all dark, or all lit by the open sky) holds no cells. Not thread-safe: one thread uses it.

Member Type Documentation

enum class QcLightEngine::Channel

The two kinds of light.

ConstantValueDescription
QcLightEngine::Channel::Block0Light of the blocks that give off light.
QcLightEngine::Channel::Sky1Light of the sky.

Member Function Documentation

void QcLightEngine::addChunk(const QcChunk &chunk)

The caller keeps chunk alive and in place until it hands over another copy (changeBlock, rebind) or removes it.

void QcLightEngine::addChunk(std::shared_ptr<const QcChunk> chunk)

The engine keeps a snapshot of the chunk.

void QcLightEngine::addChunk(const QcChunk &chunk, const std::shared_ptr<QcLightEngine::Prepared> &prepared)

As above with the light prepare() computed for the same blocks (null or another chunk's: computed here).

int QcLightEngine::blockLight(QcBlockPos pos) const

Returns the block light at pos.

void QcLightEngine::changeBlock(QcBlockPos pos, std::shared_ptr<const QcChunk> chunk)

chunk holds the blocks of the chunk at pos after the change (same ownership rules as addChunk); the block before the change is read from the snapshot kept so far.

void QcLightEngine::changeBlock(QcBlockPos pos, QcBlockId before, const QcChunk &chunk)

The block at pos was before and chunk (changed in place or a new copy) holds the new one.

void QcLightEngine::compact(QcLightEngine::Channel channel, QcChunkPos pos, int index)

Lets section index of the chunk at pos in channel go without cells when they all have the same level.

bool QcLightEngine::hasChunk(QcChunkPos pos) const

Returns whether the chunk at pos is held.

bool QcLightEngine::hasSky() const

Returns whether the engine keeps sky light (Options::sky).

int QcLightEngine::level(QcLightEngine::Channel channel, QcBlockPos pos) const

Returns the current level of channel at pos; 0 in unloaded chunks and without the channel. Above the world the sky is 15.

QcLightEngine::Memory QcLightEngine::memory() const

Returns the memory the levels take.

std::shared_ptr<QcLightEngine::Prepared> QcLightEngine::prepare(const QcChunk &chunk) const

Returns the light of chunk alone, for addChunk(); thread-safe (reads only the table).

void QcLightEngine::rebind(const QcChunk &chunk)

The blocks of chunk moved to another, equal copy (copy on write); its light stays.

void QcLightEngine::removeChunk(QcChunkPos pos)

Removes the chunk at pos and the light that came from it.

const QcLightNibbles *QcLightEngine::section(QcLightEngine::Channel channel, QcChunkPos pos, int index) const

Returns the cells of section index of the chunk at pos in channel; null when they all have the level uniformLevel() (or it is not loaded).

const std::shared_ptr<const QcLightTable> &QcLightEngine::sharedTable() const

Returns the shared table.

int QcLightEngine::skyLight(QcBlockPos pos) const

Returns the sky light at pos.

int QcLightEngine::skyTop(QcBlockPos column) const

Returns the highest cell of the block column column that sky light coming straight down does not reach (-1: none; QcWorld::worldHeight in a chunk that is not held).

const QcLightTable &QcLightEngine::table() const

Returns the table of the blocks' light properties.

QList<QcSectionAddress> QcLightEngine::takeTouched(QcLightEngine::Channel channel)

Returns the sections of channel whose levels were written since the last call (Options::trackChanges).

int QcLightEngine::uniformLevel(QcLightEngine::Channel channel, QcChunkPos pos, int index) const

Returns the level of every cell of section index of the chunk at pos in channel while it holds no cells; 0 for a chunk that is not held.

quint64 QcLightEngine::visitedCells() const

Returns the cells visited by the propagation steps so far (work measure for benchmarks).

Member Variable Documentation

const int QcLightEngine::channelCount

The number of channels.

const int QcLightEngine::maxLevel

The highest level.