VoxelManip cleanups (const ref, const move) + function removal (#6169)

* VoxelManip cleanups (const ref, const move) permitting to improve a little bit performance

* VoxelArea: precalculate extent (performance enhancement)

This permits to reduce extend high cost to zero and drop many v3s16 object creation/removal to calculate extent
It rebalance the client thread update to updateFastFaceRow instead of MapBlockMesh generation
This will also benefits to mapgen
This commit is contained in:
Loïc Blot 2017-07-26 07:35:09 +02:00 committed by GitHub
parent 0c99da4255
commit 9a17b65f26
13 changed files with 85 additions and 198 deletions

View File

@ -73,7 +73,7 @@ void CavesNoiseIntersection::generateCaves(MMVManip *vm,
noise_cave1->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z);
noise_cave2->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 index2d = 0; // Biomemap index
for (s16 z = nmin.Z; z <= nmax.Z; z++)
@ -208,7 +208,7 @@ bool CavernsNoise::generateCaverns(MMVManip *vm, v3s16 nmin, v3s16 nmax)
//// Place nodes
bool near_cavern = false;
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 index2d = 0;
for (s16 z = nmin.Z; z <= nmax.Z; z++)

View File

@ -151,7 +151,7 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax)
void DungeonGen::makeDungeon(v3s16 start_padding)
{
v3s16 areasize = vm->m_area.getExtent();
const v3s16 &areasize = vm->m_area.getExtent();
v3s16 roomsize;
v3s16 roomplace;

View File

@ -202,7 +202,7 @@ u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef)
Calculate smooth lighting at the XYZ- corner of p.
Both light banks
*/
static u16 getSmoothLightCombined(v3s16 p, MeshMakeData *data)
static u16 getSmoothLightCombined(const v3s16 &p, MeshMakeData *data)
{
static const v3s16 dirs8[8] = {
v3s16(0,0,0),
@ -855,11 +855,10 @@ static void getTileInfo(
*/
static void updateFastFaceRow(
MeshMakeData *data,
v3s16 startpos,
const v3s16 &&startpos,
v3s16 translate_dir,
v3f translate_dir_f,
v3s16 face_dir,
v3f face_dir_f,
const v3f &&translate_dir_f,
const v3s16 &&face_dir,
std::vector<FastFace> &dest)
{
v3s16 p = startpos;
@ -966,7 +965,6 @@ static void updateAllFastFaceRows(MeshMakeData *data,
v3s16(1,0,0), //dir
v3f (1,0,0),
v3s16(0,1,0), //face dir
v3f (0,1,0),
dest);
}
}
@ -981,7 +979,6 @@ static void updateAllFastFaceRows(MeshMakeData *data,
v3s16(0,0,1), //dir
v3f (0,0,1),
v3s16(1,0,0), //face dir
v3f (1,0,0),
dest);
}
}
@ -996,7 +993,6 @@ static void updateAllFastFaceRows(MeshMakeData *data,
v3s16(1,0,0), //dir
v3f (1,0,0),
v3s16(0,0,1), //face dir
v3f (0,0,1),
dest);
}
}
@ -1525,14 +1521,12 @@ void MeshCollector::applyTileColors()
{
if (m_use_tangent_vertices)
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
std::vector<PreMeshBuffer> *p = &prebuffers[layer];
for (std::vector<PreMeshBuffer>::iterator it = p->begin();
it != p->end(); ++it) {
video::SColor tc = it->layer.color;
for (auto &pmb : prebuffers[layer]) {
video::SColor tc = pmb.layer.color;
if (tc == video::SColor(0xFFFFFFFF))
continue;
for (u32 index = 0; index < it->tangent_vertices.size(); index++) {
video::SColor *c = &it->tangent_vertices[index].Color;
for (auto &tangent_vertice : pmb.tangent_vertices) {
video::SColor *c = &tangent_vertice.Color;
c->set(c->getAlpha(), c->getRed() * tc.getRed() / 255,
c->getGreen() * tc.getGreen() / 255,
c->getBlue() * tc.getBlue() / 255);
@ -1541,14 +1535,12 @@ void MeshCollector::applyTileColors()
}
else
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
std::vector<PreMeshBuffer> *p = &prebuffers[layer];
for (std::vector<PreMeshBuffer>::iterator it = p->begin();
it != p->end(); ++it) {
video::SColor tc = it->layer.color;
for (auto &pmb : prebuffers[layer]) {
video::SColor tc = pmb.layer.color;
if (tc == video::SColor(0xFFFFFFFF))
continue;
for (u32 index = 0; index < it->vertices.size(); index++) {
video::SColor *c = &it->vertices[index].Color;
for (auto &vertice : pmb.vertices) {
video::SColor *c = &vertice.Color;
c->set(c->getAlpha(), c->getRed() * tc.getRed() / 255,
c->getGreen() * tc.getGreen() / 255,
c->getBlue() * tc.getBlue() / 255);

View File

@ -237,7 +237,7 @@ u32 Mapgen::getBlockSeed2(v3s16 p, s32 seed)
// Returns Y one under area minimum if not found
s16 Mapgen::findGroundLevelFull(v2s16 p2d)
{
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
s16 y_nodes_max = vm->m_area.MaxEdge.Y;
s16 y_nodes_min = vm->m_area.MinEdge.Y;
u32 i = vm->m_area.index(p2d.X, y_nodes_max, p2d.Y);
@ -257,7 +257,7 @@ s16 Mapgen::findGroundLevelFull(v2s16 p2d)
// Returns -MAX_MAP_GENERATION_LIMIT if not found
s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax)
{
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y);
s16 y;
@ -275,7 +275,7 @@ s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax)
// Returns -MAX_MAP_GENERATION_LIMIT if not found or if ground is found first
s16 Mapgen::findLiquidSurface(v2s16 p2d, s16 ymin, s16 ymax)
{
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y);
s16 y;
@ -344,7 +344,7 @@ inline bool Mapgen::isLiquidHorizontallyFlowable(u32 vi, v3s16 em)
void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax)
{
bool isignored, isliquid, wasignored, wasliquid, waschecked, waspushed;
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
for (s16 z = nmin.Z + 1; z <= nmax.Z - 1; z++)
for (s16 x = nmin.X + 1; x <= nmax.X - 1; x++) {
@ -467,7 +467,7 @@ void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow)
//TimeTaker t("propagateSunlight");
VoxelArea a(nmin, nmax);
bool block_is_underground = (water_level >= nmax.Y);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
// NOTE: Direct access to the low 4 bits of param1 is okay here because,
// by definition, sunlight will never be in the night lightbank.
@ -627,7 +627,7 @@ MgStoneType MapgenBasic::generateBiomes(s16 biome_zero_level)
assert(biomegen);
assert(biomemap);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 index = 0;
MgStoneType stone_type = MGSTONE_STONE;
@ -764,7 +764,7 @@ void MapgenBasic::dustTopNodes()
if (node_max.Y < water_level)
return;
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 index = 0;
for (s16 z = node_min.Z; z <= node_max.Z; z++)

View File

@ -230,7 +230,7 @@ s16 MapgenFlat::generateTerrain()
MapNode n_stone(c_stone);
MapNode n_water(c_water_source);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
u32 ni2d = 0;

View File

@ -206,7 +206,7 @@ void MapgenV6Params::writeParams(Settings *settings) const
// Returns Y one under area minimum if not found
s16 MapgenV6::find_stone_level(v2s16 p2d)
{
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
s16 y_nodes_max = vm->m_area.MaxEdge.Y;
s16 y_nodes_min = vm->m_area.MinEdge.Y;
u32 i = vm->m_area.index(p2d.X, y_nodes_max, p2d.Y);
@ -681,7 +681,7 @@ int MapgenV6::generateGround()
BiomeV6Type bt = getBiome(v2s16(x, z));
// Fill ground with stone
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 i = vm->m_area.index(x, node_min.Y, z);
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
@ -750,7 +750,7 @@ void MapgenV6::addMud()
// Add mud on ground
s16 mudcount = 0;
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
s16 y_start = surface_y + 1;
u32 i = vm->m_area.index(x, y_start, z);
for (s16 y = y_start; y <= node_max.Y; y++) {
@ -784,7 +784,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
// Node position in 2d
v2s16 p2d = v2s16(node_min.X, node_min.Z) + v2s16(x, z);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 i = vm->m_area.index(p2d.X, node_max.Y, p2d.Y);
s16 y = node_max.Y;
@ -947,7 +947,7 @@ void MapgenV6::placeTreesAndJungleGrass()
if (c_junglegrass == CONTENT_IGNORE)
c_junglegrass = CONTENT_AIR;
MapNode n_junglegrass(c_junglegrass);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
// Divide area into parts
s16 div = 8;
@ -1055,7 +1055,7 @@ void MapgenV6::growGrass() // Add surface nodes
MapNode n_dirt_with_snow(c_dirt_with_snow);
MapNode n_snowblock(c_snowblock);
MapNode n_snow(c_snow);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 index = 0;
for (s16 z = full_node_min.Z; z <= full_node_max.Z; z++)

View File

@ -489,7 +489,7 @@ int MapgenV7::generateTerrain()
}
//// Place nodes
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
u32 index2d = 0;

View File

@ -475,7 +475,7 @@ int MapgenValleys::generateTerrain()
MapNode n_stone(c_stone);
MapNode n_water(c_water_source);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT;
u32 index_2d = 0;
@ -597,7 +597,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth)
MapNode n_lava(c_lava_source);
MapNode n_water(c_river_water_source);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
// Cave blend distance near YMIN, YMAX
const float massive_cave_blend = 128.f;

View File

@ -299,7 +299,7 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
bool force_placement = (flags & DECO_FORCE_PLACEMENT);
v3s16 em = vm->m_area.getExtent();
const v3s16 &em = vm->m_area.getExtent();
u32 vi = vm->m_area.index(p);
for (int i = 0; i < height; i++) {
vm->m_area.add_y(em, vi, 1);

View File

@ -606,7 +606,7 @@ void Minimap::updateActiveMarkers()
//// MinimapMapblock
////
void MinimapMapblock::getMinimapNodes(VoxelManipulator *vmanip, v3s16 pos)
void MinimapMapblock::getMinimapNodes(VoxelManipulator *vmanip, const v3s16 &pos)
{
for (s16 x = 0; x < MAP_BLOCKSIZE; x++)

View File

@ -63,7 +63,7 @@ struct MinimapPixel {
};
struct MinimapMapblock {
void getMinimapNodes(VoxelManipulator *vmanip, v3s16 pos);
void getMinimapNodes(VoxelManipulator *vmanip, const v3s16 &pos);
MinimapPixel data[MAP_BLOCKSIZE * MAP_BLOCKSIZE];
};

View File

@ -55,7 +55,7 @@ void VoxelManipulator::clear()
void VoxelManipulator::print(std::ostream &o, INodeDefManager *ndef,
VoxelPrintMode mode)
{
v3s16 em = m_area.getExtent();
const v3s16 &em = m_area.getExtent();
v3s16 of = m_area.MinEdge;
o<<"size: "<<em.X<<"x"<<em.Y<<"x"<<em.Z
<<" offset: ("<<of.X<<","<<of.Y<<","<<of.Z<<")"<<std::endl;
@ -208,7 +208,7 @@ void VoxelManipulator::addArea(const VoxelArea &area)
}
void VoxelManipulator::copyFrom(MapNode *src, const VoxelArea& src_area,
v3s16 from_pos, v3s16 to_pos, v3s16 size)
v3s16 from_pos, v3s16 to_pos, const v3s16 &size)
{
/* The reason for this optimised code is that we're a member function
* and the data type/layout of m_data is know to us: it's stored as
@ -256,7 +256,7 @@ void VoxelManipulator::copyFrom(MapNode *src, const VoxelArea& src_area,
}
void VoxelManipulator::copyTo(MapNode *dst, const VoxelArea& dst_area,
v3s16 dst_pos, v3s16 from_pos, v3s16 size)
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size)
{
for(s16 z=0; z<size.Z; z++)
for(s16 y=0; y<size.Y; y++)
@ -384,37 +384,6 @@ void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
}
}
/*
Goes recursively through the neighbours of the node.
Alters only transparent nodes.
If the lighting of the neighbour is lower than the lighting of
the node was (before changing it to 0 at the step before), the
lighting of the neighbour is set to 0 and then the same stuff
repeats for the neighbour.
The ending nodes of the routine are stored in light_sources.
This is useful when a light is removed. In such case, this
routine can be called for the light node and then again for
light_sources to re-light the area without the removed light.
values of from_nodes are lighting values.
*/
void VoxelManipulator::unspreadLight(enum LightBank bank,
std::map<v3s16, u8> & from_nodes,
std::set<v3s16> & light_sources, INodeDefManager *nodemgr)
{
if(from_nodes.empty())
return;
for(std::map<v3s16, u8>::iterator j = from_nodes.begin();
j != from_nodes.end(); ++j)
{
unspreadLight(bank, j->first, j->second, light_sources, nodemgr);
}
}
void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p,
INodeDefManager *nodemgr)
{

View File

@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h"
#include <set>
#include <list>
#include <map>
#include "util/basic_macros.h"
class INodeDefManager;
@ -62,15 +62,18 @@ public:
// Starts as zero sized
VoxelArea() {}
VoxelArea(v3s16 min_edge, v3s16 max_edge):
VoxelArea(const v3s16 &min_edge, const v3s16 &max_edge):
MinEdge(min_edge),
MaxEdge(max_edge)
{
cacheExtent();
}
VoxelArea(v3s16 p):
VoxelArea(const v3s16 &p):
MinEdge(p),
MaxEdge(p)
{
cacheExtent();
}
/*
@ -90,13 +93,16 @@ public:
if(a.MaxEdge.X > MaxEdge.X) MaxEdge.X = a.MaxEdge.X;
if(a.MaxEdge.Y > MaxEdge.Y) MaxEdge.Y = a.MaxEdge.Y;
if(a.MaxEdge.Z > MaxEdge.Z) MaxEdge.Z = a.MaxEdge.Z;
cacheExtent();
}
void addPoint(const v3s16 &p)
{
if(hasEmptyExtent())
{
MinEdge = p;
MaxEdge = p;
cacheExtent();
return;
}
if(p.X < MinEdge.X) MinEdge.X = p.X;
@ -105,6 +111,7 @@ public:
if(p.X > MaxEdge.X) MaxEdge.X = p.X;
if(p.Y > MaxEdge.Y) MaxEdge.Y = p.Y;
if(p.Z > MaxEdge.Z) MaxEdge.Z = p.Z;
cacheExtent();
}
// Pad with d nodes
@ -114,25 +121,13 @@ public:
MaxEdge += d;
}
/*void operator+=(v3s16 off)
{
MinEdge += off;
MaxEdge += off;
}
void operator-=(v3s16 off)
{
MinEdge -= off;
MaxEdge -= off;
}*/
/*
const methods
*/
v3s16 getExtent() const
const v3s16 &getExtent() const
{
return MaxEdge - MinEdge + v3s16(1,1,1);
return m_cache_extent;
}
/* Because MaxEdge and MinEdge are included in the voxel area an empty extent
@ -145,9 +140,9 @@ public:
s32 getVolume() const
{
v3s16 e = getExtent();
return (s32)e.X * (s32)e.Y * (s32)e.Z;
return (s32)m_cache_extent.X * (s32)m_cache_extent.Y * (s32)m_cache_extent.Z;
}
bool contains(const VoxelArea &a) const
{
// No area contains an empty area
@ -179,12 +174,12 @@ public:
&& MaxEdge == other.MaxEdge);
}
VoxelArea operator+(v3s16 off) const
VoxelArea operator+(const v3s16 &off) const
{
return VoxelArea(MinEdge+off, MaxEdge+off);
}
VoxelArea operator-(v3s16 off) const
VoxelArea operator-(const v3s16 &off) const
{
return VoxelArea(MinEdge-off, MaxEdge-off);
}
@ -273,10 +268,9 @@ public:
*/
s32 index(s16 x, s16 y, s16 z) const
{
v3s16 em = getExtent();
v3s16 off = MinEdge;
s32 i = (s32)(z-off.Z)*em.Y*em.X + (y-off.Y)*em.X + (x-off.X);
//dstream<<" i("<<x<<","<<y<<","<<z<<")="<<i<<" ";
s32 i = (s32)(z - MinEdge.Z) * m_cache_extent.Y * m_cache_extent.X
+ (y - MinEdge.Y) * m_cache_extent.X
+ (x - MinEdge.X);
return i;
}
s32 index(v3s16 p) const
@ -310,20 +304,21 @@ public:
*/
void print(std::ostream &o) const
{
v3s16 e = getExtent();
o<<"("<<MinEdge.X
<<","<<MinEdge.Y
<<","<<MinEdge.Z
<<")("<<MaxEdge.X
<<","<<MaxEdge.Y
<<","<<MaxEdge.Z
<<")"
<<"="<<e.X<<"x"<<e.Y<<"x"<<e.Z<<"="<<getVolume();
o << PP(MinEdge) << PP(MaxEdge) << "="
<< m_cache_extent.X << "x" << m_cache_extent.Y << "x" << m_cache_extent.Z
<< "=" << getVolume();
}
// Edges are inclusive
v3s16 MinEdge = v3s16(1,1,1);
v3s16 MaxEdge;
private:
void cacheExtent()
{
m_cache_extent = MaxEdge - MinEdge + v3s16(1,1,1);
}
v3s16 m_cache_extent = v3s16(0,0,0);
};
// unused
@ -347,36 +342,22 @@ enum VoxelPrintMode
VOXELPRINT_LIGHT_DAY,
};
class VoxelManipulator /*: public NodeContainer*/
class VoxelManipulator
{
public:
VoxelManipulator();
virtual ~VoxelManipulator();
/*
Virtuals from NodeContainer
*/
/*virtual u16 nodeContainerId() const
{
return NODECONTAINER_ID_VOXELMANIPULATOR;
}
bool isValidPosition(v3s16 p)
{
addArea(p);
return !(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA);
}*/
/*
These are a bit slow and shouldn't be used internally.
Use m_data[m_area.index(p)] instead.
*/
MapNode getNode(v3s16 p)
MapNode getNode(const v3s16 &p)
{
VoxelArea voxel_area(p);
addArea(voxel_area);
if(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA)
{
if (m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) {
/*dstream<<"EXCEPT: VoxelManipulator::getNode(): "
<<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<", index="<<m_area.index(p)
@ -388,23 +369,22 @@ public:
return m_data[m_area.index(p)];
}
MapNode getNodeNoEx(v3s16 p)
MapNode getNodeNoEx(const v3s16 &p)
{
VoxelArea voxel_area(p);
addArea(voxel_area);
if(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA)
{
if (m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) {
return MapNode(CONTENT_IGNORE);
}
return m_data[m_area.index(p)];
}
MapNode getNodeNoExNoEmerge(v3s16 p)
MapNode getNodeNoExNoEmerge(const v3s16 &p)
{
if(m_area.contains(p) == false)
if (!m_area.contains(p))
return MapNode(CONTENT_IGNORE);
if(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA)
if (m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA)
return MapNode(CONTENT_IGNORE);
return m_data[m_area.index(p)];
}
@ -425,32 +405,18 @@ public:
return m_data[index];
}
u8 & getFlagsRefUnsafe(v3s16 p)
u8 & getFlagsRefUnsafe(const v3s16 &p)
{
return m_flags[m_area.index(p)];
}
bool exists(v3s16 p)
bool exists(const v3s16 &p)
{
return m_area.contains(p) &&
!(getFlagsRefUnsafe(p) & VOXELFLAG_NO_DATA);
}
MapNode & getNodeRef(v3s16 p)
{
VoxelArea voxel_area(p);
addArea(voxel_area);
if(getFlagsRefUnsafe(p) & VOXELFLAG_NO_DATA)
{
/*dstream<<"EXCEPT: VoxelManipulator::getNode(): "
<<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<", index="<<m_area.index(p)
<<", flags="<<(int)getFlagsRefUnsafe(p)
<<" is inexistent"<<std::endl;*/
throw InvalidPositionException
("VoxelManipulator: getNode: inexistent");
}
return getNodeRefUnsafe(p);
}
void setNode(v3s16 p, const MapNode &n)
void setNode(const v3s16 &p, const MapNode &n)
{
VoxelArea voxel_area(p);
addArea(voxel_area);
@ -459,57 +425,24 @@ public:
m_flags[m_area.index(p)] &= ~VOXELFLAG_NO_DATA;
}
// TODO: Should be removed and replaced with setNode
void setNodeNoRef(v3s16 p, const MapNode &n)
void setNodeNoRef(const v3s16 &p, const MapNode &n)
{
setNode(p, n);
}
/*void setExists(VoxelArea a)
{
addArea(a);
for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++)
for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++)
{
m_flags[m_area.index(x,y,z)] &= ~VOXELFLAG_NO_DATA;
}
}*/
/*MapNode & operator[](v3s16 p)
{
//dstream<<"operator[] p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;
if(isValidPosition(p) == false)
addArea(VoxelArea(p));
return m_data[m_area.index(p)];
}*/
/*
Set stuff if available without an emerge.
Return false if failed.
This is convenient but slower than playing around directly
with the m_data table with indices.
*/
bool setNodeNoEmerge(v3s16 p, MapNode n)
bool setNodeNoEmerge(const v3s16 &p, MapNode n)
{
if(m_area.contains(p) == false)
if(!m_area.contains(p))
return false;
m_data[m_area.index(p)] = n;
return true;
}
bool setNodeNoEmerge(s32 i, MapNode n)
{
if(m_area.contains(i) == false)
return false;
m_data[i] = n;
return true;
}
/*bool setContentNoEmerge(v3s16 p, u8 c)
{
if(isValidPosition(p) == false)
return false;
m_data[m_area.index(p)].d = c;
}*/
/*
Control
@ -527,11 +460,11 @@ public:
dst_area.getExtent() <= src_area.getExtent()
*/
void copyFrom(MapNode *src, const VoxelArea& src_area,
v3s16 from_pos, v3s16 to_pos, v3s16 size);
v3s16 from_pos, v3s16 to_pos, const v3s16 &size);
// Copy data
void copyTo(MapNode *dst, const VoxelArea& dst_area,
v3s16 dst_pos, v3s16 from_pos, v3s16 size);
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size);
/*
Algorithms
@ -543,18 +476,11 @@ public:
void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
std::set<v3s16> & light_sources, INodeDefManager *nodemgr);
void unspreadLight(enum LightBank bank,
std::map<v3s16, u8> & from_nodes,
std::set<v3s16> & light_sources, INodeDefManager *nodemgr);
void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr);
void spreadLight(enum LightBank bank,
std::set<v3s16> & from_nodes, INodeDefManager *nodemgr);
/*
Virtual functions
*/
/*
Member variables
*/