/*
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "voxelalgorithms.h"
#include "nodedef.h"
#include "mapblock.h"
#include "map.h"
namespace voxalgo
{
/*!
* A direction.
* 0=X+
* 1=Y+
* 2=Z+
* 3=Z-
* 4=Y-
* 5=X-
* 6=no direction
* Two directions are opposite only if their sum is 5.
*/
typedef u8 direction;
/*!
* Relative node position.
* This represents a node's position in its map block.
* All coordinates must be between 0 and 15.
*/
typedef v3s16 relative_v3;
/*!
* Position of a map block (block coordinates).
* One block_pos unit is as long as 16 node position units.
*/
typedef v3s16 mapblock_v3;
//! Contains information about a node whose light is about to change.
struct ChangingLight {
//! Relative position of the node in its map block.
relative_v3 rel_position;
//! Position of the node's block.
mapblock_v3 block_position;
//! Pointer to the node's block.
MapBlock *block = NULL;
/*!
* Direction from the node that caused this node's changing
* to this node.
*/
direction source_direction = 6;
ChangingLight() = default;
ChangingLight(const relative_v3 &rel_pos, const mapblock_v3 &block_pos,
MapBlock *b, direction source_dir) :
rel_position(rel_pos),
block_position(block_pos),
block(b),
source_direction(source_dir)
{}
};
/*!
* A fast, priority queue-like container to contain ChangingLights.
* The ChangingLights are ordered by the given light levels.
* The brightest ChangingLight is returned first.
*/
struct LightQueue {
//! For each light level there is a vector.
std::vector<ChangingLight> lights[LIGHT_SUN + 1];
//! Light of the brightest ChangingLight in the queue.
u8 max_light;
/*!
* Creates a LightQueue.
* \param reserve for each light level that many slots are reserved.
*/
LightQueue(size_t reserve)
{
max_light = LIGHT_SUN;
for (u8 i = 0; i <= LIGHT_SUN; i++) {
lights[i].reserve(reserve);
}
}
/*!
* Returns the next brightest ChangingLight and
* removes it from the queue.
* If there were no elements in the queue, the given parameters
* remain unmodified.
* \param light light level of the popped ChangingLight
* \param data the ChangingLight that was popped
* \returns true if there was a ChangingLight in the queue.
*/
bool next(u8 &light, ChangingLight &data)
{
while (lights[max_light].empty()) {
if (max_light == 0) {
return false;
}
max_light--;
}
light = max_light;
data = lights[max_light].back();
lights[max_light].pop_back();
return true;
}
/*!
* Adds an element to the queue.
* The parameters are the same as in ChangingLight's constructor.
* \param light light level of the ChangingLight
*/
|