mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Some refactoring and fixes to VoxelArea and VoxelManip
In particular this validates the edges of VoxelArea and fixes all the nonsense tests uncovered by it.
This commit is contained in:
parent
5532248cd7
commit
6d5103900f
11 changed files with 178 additions and 183 deletions
|
@ -5010,8 +5010,7 @@ Methods
|
||||||
the `VoxelManip`.
|
the `VoxelManip`.
|
||||||
* `calc_lighting([p1, p2], [propagate_shadow])`: Calculate lighting within the
|
* `calc_lighting([p1, p2], [propagate_shadow])`: Calculate lighting within the
|
||||||
`VoxelManip`.
|
`VoxelManip`.
|
||||||
* To be used only by a `VoxelManip` object from
|
* To be used only with a `VoxelManip` object from `minetest.get_mapgen_object`.
|
||||||
`minetest.get_mapgen_object`.
|
|
||||||
* (`p1`, `p2`) is the area in which lighting is set, defaults to the whole
|
* (`p1`, `p2`) is the area in which lighting is set, defaults to the whole
|
||||||
area if left out or nil. For almost all uses these should be left out
|
area if left out or nil. For almost all uses these should be left out
|
||||||
or nil to use the default.
|
or nil to use the default.
|
||||||
|
@ -5019,9 +5018,11 @@ Methods
|
||||||
generated mapchunk above are propagated down into the mapchunk, defaults
|
generated mapchunk above are propagated down into the mapchunk, defaults
|
||||||
to `true` if left out.
|
to `true` if left out.
|
||||||
* `update_liquids()`: Update liquid flow
|
* `update_liquids()`: Update liquid flow
|
||||||
* `was_modified()`: Returns `true` or `false` if the data in the voxel
|
* `was_modified()`: Returns `true` if the data in the voxel manipulator has been modified
|
||||||
manipulator had been modified since the last read from map, due to a call to
|
since it was last read from the map. This means you have to call `get_data` again.
|
||||||
`minetest.set_data()` on the loaded area elsewhere.
|
This only applies to a `VoxelManip` object from `minetest.get_mapgen_object`,
|
||||||
|
where the engine will keep the map and the VM in sync automatically.
|
||||||
|
* Note: this doesn't do what you think it does and is subject to removal. Don't use it!
|
||||||
* `get_emerged_area()`: Returns actual emerged minimum and maximum positions.
|
* `get_emerged_area()`: Returns actual emerged minimum and maximum positions.
|
||||||
|
|
||||||
`VoxelArea`
|
`VoxelArea`
|
||||||
|
|
16
src/map.cpp
16
src/map.cpp
|
@ -822,17 +822,9 @@ void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
|
||||||
} else {
|
} else {
|
||||||
flags |= VMANIP_BLOCK_DATA_INEXIST;
|
flags |= VMANIP_BLOCK_DATA_INEXIST;
|
||||||
|
|
||||||
/*
|
// Mark area inexistent
|
||||||
Mark area inexistent
|
|
||||||
*/
|
|
||||||
VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
|
VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
|
||||||
// Fill with VOXELFLAG_NO_DATA
|
setFlags(a, VOXELFLAG_NO_DATA);
|
||||||
for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
|
|
||||||
for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++)
|
|
||||||
{
|
|
||||||
s32 i = m_area.index(a.MinEdge.X,y,z);
|
|
||||||
memset(&m_flags[i], VOXELFLAG_NO_DATA, MAP_BLOCKSIZE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE)
|
/*else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE)
|
||||||
|
@ -848,9 +840,9 @@ void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
|
void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
|
||||||
bool overwrite_generated)
|
bool overwrite_generated) const
|
||||||
{
|
{
|
||||||
if(m_area.getExtent() == v3s16(0,0,0))
|
if (m_area.hasEmptyExtent())
|
||||||
return;
|
return;
|
||||||
assert(m_map);
|
assert(m_map);
|
||||||
|
|
||||||
|
|
|
@ -333,7 +333,7 @@ public:
|
||||||
|
|
||||||
// This is much faster with big chunks of generated data
|
// This is much faster with big chunks of generated data
|
||||||
void blitBackAll(std::map<v3s16, MapBlock*> * modified_blocks,
|
void blitBackAll(std::map<v3s16, MapBlock*> * modified_blocks,
|
||||||
bool overwrite_generated = true);
|
bool overwrite_generated = true) const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates a copy of this VManip including contents, the copy will not be
|
Creates a copy of this VManip including contents, the copy will not be
|
||||||
|
|
|
@ -178,13 +178,13 @@ void MapBlock::copyTo(VoxelManipulator &dst)
|
||||||
getPosRelative(), data_size);
|
getPosRelative(), data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapBlock::copyFrom(VoxelManipulator &dst)
|
void MapBlock::copyFrom(const VoxelManipulator &src)
|
||||||
{
|
{
|
||||||
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
||||||
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
|
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
|
||||||
|
|
||||||
// Copy from VoxelManipulator to data
|
// Copy from VoxelManipulator to data
|
||||||
dst.copyTo(data, data_area, v3s16(0,0,0),
|
src.copyTo(data, data_area, v3s16(0,0,0),
|
||||||
getPosRelative(), data_size);
|
getPosRelative(), data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -307,8 +307,8 @@ public:
|
||||||
// Copies data to VoxelManipulator to getPosRelative()
|
// Copies data to VoxelManipulator to getPosRelative()
|
||||||
void copyTo(VoxelManipulator &dst);
|
void copyTo(VoxelManipulator &dst);
|
||||||
|
|
||||||
// Copies data from VoxelManipulator getPosRelative()
|
// Copies data from VoxelManipulator to getPosRelative()
|
||||||
void copyFrom(VoxelManipulator &dst);
|
void copyFrom(const VoxelManipulator &src);
|
||||||
|
|
||||||
// Update is air flag.
|
// Update is air flag.
|
||||||
// Sets m_is_air to appropriate value.
|
// Sets m_is_air to appropriate value.
|
||||||
|
|
|
@ -91,7 +91,7 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax)
|
||||||
random.seed(bseed + 2);
|
random.seed(bseed + 2);
|
||||||
|
|
||||||
// Dungeon generator doesn't modify places which have this set
|
// Dungeon generator doesn't modify places which have this set
|
||||||
vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
|
vm->clearFlags(vm->m_area, VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
|
||||||
|
|
||||||
if (dp.only_in_ground) {
|
if (dp.only_in_ground) {
|
||||||
// Set all air and liquid drawtypes to be untouchable to make dungeons generate
|
// Set all air and liquid drawtypes to be untouchable to make dungeons generate
|
||||||
|
|
|
@ -333,6 +333,9 @@ int LuaVoxelManip::l_was_modified(lua_State *L)
|
||||||
LuaVoxelManip *o = checkObject<LuaVoxelManip>(L, 1);
|
LuaVoxelManip *o = checkObject<LuaVoxelManip>(L, 1);
|
||||||
MMVManip *vm = o->vm;
|
MMVManip *vm = o->vm;
|
||||||
|
|
||||||
|
if (!o->is_mapgen_vm)
|
||||||
|
log_deprecated(L, "was_modified called for a non-mapgen VoxelManip object");
|
||||||
|
|
||||||
lua_pushboolean(L, vm->m_is_dirty);
|
lua_pushboolean(L, vm->m_is_dirty);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
void test_equal();
|
void test_equal();
|
||||||
void test_plus();
|
void test_plus();
|
||||||
void test_minor();
|
void test_minor();
|
||||||
|
void test_diff();
|
||||||
void test_intersect();
|
void test_intersect();
|
||||||
void test_index_xyz_all_pos();
|
void test_index_xyz_all_pos();
|
||||||
void test_index_xyz_x_neg();
|
void test_index_xyz_x_neg();
|
||||||
|
@ -75,6 +76,7 @@ void TestVoxelArea::runTests(IGameDef *gamedef)
|
||||||
TEST(test_equal);
|
TEST(test_equal);
|
||||||
TEST(test_plus);
|
TEST(test_plus);
|
||||||
TEST(test_minor);
|
TEST(test_minor);
|
||||||
|
TEST(test_diff);
|
||||||
TEST(test_intersect);
|
TEST(test_intersect);
|
||||||
TEST(test_index_xyz_all_pos);
|
TEST(test_index_xyz_all_pos);
|
||||||
TEST(test_index_xyz_x_neg);
|
TEST(test_index_xyz_x_neg);
|
||||||
|
@ -100,21 +102,21 @@ void TestVoxelArea::runTests(IGameDef *gamedef)
|
||||||
|
|
||||||
void TestVoxelArea::test_addarea()
|
void TestVoxelArea::test_addarea()
|
||||||
{
|
{
|
||||||
VoxelArea v1(v3s16(-1447, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v1(v3s16(-1447, -9547, -875), v3s16(-147, 8854, 669));
|
||||||
VoxelArea v2(v3s16(-887, 4445, -5478), v3s16(447, -8779, 4778));
|
VoxelArea v2(v3s16(-887, -8779, -5478), v3s16(447, 4445, 4778));
|
||||||
|
|
||||||
v1.addArea(v2);
|
v1.addArea(v2);
|
||||||
UASSERT(v1.MinEdge == v3s16(-1447, 4445, -5478));
|
UASSERT(v1.MinEdge == v3s16(-1447, -9547, -5478));
|
||||||
UASSERT(v1.MaxEdge == v3s16(447, -8779, 4778));
|
UASSERT(v1.MaxEdge == v3s16(447, 8854, 4778));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_pad()
|
void TestVoxelArea::test_pad()
|
||||||
{
|
{
|
||||||
VoxelArea v1(v3s16(-1447, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v1(v3s16(-1447, -9547, -875), v3s16(-147, 8854, 669));
|
||||||
v1.pad(v3s16(100, 200, 300));
|
v1.pad(v3s16(100, 200, 300));
|
||||||
|
|
||||||
UASSERT(v1.MinEdge == v3s16(-1547, 8654, -1175));
|
UASSERT(v1.MinEdge == v3s16(-1547, -9747, -1175));
|
||||||
UASSERT(v1.MaxEdge == v3s16(-47, -9347, 969));
|
UASSERT(v1.MaxEdge == v3s16(-47, 9054, 969));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_extent()
|
void TestVoxelArea::test_extent()
|
||||||
|
@ -124,6 +126,9 @@ void TestVoxelArea::test_extent()
|
||||||
|
|
||||||
VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
|
VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
|
||||||
UASSERT(v2.getExtent() == v3s16(16, 16, 16));
|
UASSERT(v2.getExtent() == v3s16(16, 16, 16));
|
||||||
|
|
||||||
|
UASSERT(VoxelArea({2,3,4}, {1,2,3}).hasEmptyExtent());
|
||||||
|
UASSERT(VoxelArea({2,3,4}, {2,2,3}).hasEmptyExtent() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_volume()
|
void TestVoxelArea::test_volume()
|
||||||
|
@ -133,6 +138,9 @@ void TestVoxelArea::test_volume()
|
||||||
|
|
||||||
VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
|
VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
|
||||||
UASSERTEQ(s32, v2.getVolume(), 4096);
|
UASSERTEQ(s32, v2.getVolume(), 4096);
|
||||||
|
|
||||||
|
UASSERTEQ(s32, VoxelArea({2,3,4}, {1,2,3}).getVolume(), 0);
|
||||||
|
UASSERTEQ(s32, VoxelArea({2,3,4}, {2,2,3}).getVolume(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_contains_voxelarea()
|
void TestVoxelArea::test_contains_voxelarea()
|
||||||
|
@ -185,8 +193,7 @@ void TestVoxelArea::test_equal()
|
||||||
VoxelArea v1(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669));
|
VoxelArea v1(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669));
|
||||||
UASSERTEQ(bool, v1 == VoxelArea(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)),
|
UASSERTEQ(bool, v1 == VoxelArea(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)),
|
||||||
true);
|
true);
|
||||||
UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(-147, 750, 669)), false);
|
UASSERTEQ(bool, v1 == VoxelArea(v3s16(-147, 0, 0), v3s16(0, 750, 669)), false);
|
||||||
UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(-147, 750, 669)), false);
|
|
||||||
UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(0, 0, 0)), false);
|
UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(0, 0, 0)), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +219,30 @@ void TestVoxelArea::test_minor()
|
||||||
VoxelArea(v3s16(-10, -10, -45), v3s16(100, 100, 65)));
|
VoxelArea(v3s16(-10, -10, -45), v3s16(100, 100, 65)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestVoxelArea::test_diff()
|
||||||
|
{
|
||||||
|
const VoxelArea v1({-10, -10, -10}, {100, 100, 100});
|
||||||
|
std::vector<VoxelArea> res;
|
||||||
|
|
||||||
|
v1.diff(VoxelArea({-10, -10, -10}, {99, 100, 100}), res);
|
||||||
|
UASSERTEQ(auto, res.size(), 1U);
|
||||||
|
UASSERT(res[0] == VoxelArea({100, -10, -10}, {100, 100, 100}));
|
||||||
|
res.clear();
|
||||||
|
|
||||||
|
v1.diff(VoxelArea({-10, -10, -10}, {100, 50, 80}), res);
|
||||||
|
UASSERTEQ(auto, res.size(), 2U);
|
||||||
|
UASSERT(res[0] == VoxelArea({-10, -10, 81}, {100, 100, 100}));
|
||||||
|
UASSERT(res[1] == VoxelArea({-10, 51, -10}, {100, 100, 80}));
|
||||||
|
res.clear();
|
||||||
|
|
||||||
|
// edge cases
|
||||||
|
v1.diff(v1, res);
|
||||||
|
UASSERT(res.empty());
|
||||||
|
v1.diff(VoxelArea(), res);
|
||||||
|
UASSERTEQ(auto, res.size(), 1U);
|
||||||
|
UASSERT(res[0] == v1);
|
||||||
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_intersect()
|
void TestVoxelArea::test_intersect()
|
||||||
{
|
{
|
||||||
VoxelArea v1({-10, -10, -10}, {10, 10, 10});
|
VoxelArea v1({-10, -10, -10}, {10, 10, 10});
|
||||||
|
@ -231,8 +262,8 @@ void TestVoxelArea::test_index_xyz_all_pos()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(156, 25, 236), 155);
|
UASSERTEQ(s32, v1.index(156, 25, 236), 155);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(156, 25, 236), 1267138774);
|
UASSERTEQ(s32, v2.index(156, 25, 236), 1310722495);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_xyz_x_neg()
|
void TestVoxelArea::test_index_xyz_x_neg()
|
||||||
|
@ -240,8 +271,8 @@ void TestVoxelArea::test_index_xyz_x_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(-147, 25, 366), -148);
|
UASSERTEQ(s32, v1.index(-147, 25, 366), -148);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(-147, 25, 366), -870244825);
|
UASSERTEQ(s32, v2.index(-147, 25, 366), -821642064);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_xyz_y_neg()
|
void TestVoxelArea::test_index_xyz_y_neg()
|
||||||
|
@ -249,8 +280,8 @@ void TestVoxelArea::test_index_xyz_y_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(247, -269, 100), 246);
|
UASSERTEQ(s32, v1.index(247, -269, 100), 246);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(247, -269, 100), -989760747);
|
UASSERTEQ(s32, v2.index(247, -269, 100), -951958678);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_xyz_z_neg()
|
void TestVoxelArea::test_index_xyz_z_neg()
|
||||||
|
@ -258,8 +289,8 @@ void TestVoxelArea::test_index_xyz_z_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(244, 336, -887), 243);
|
UASSERTEQ(s32, v1.index(244, 336, -887), 243);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(244, 336, -887), -191478876);
|
UASSERTEQ(s32, v2.index(244, 336, -887), -190690273);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_xyz_xy_neg()
|
void TestVoxelArea::test_index_xyz_xy_neg()
|
||||||
|
@ -267,8 +298,8 @@ void TestVoxelArea::test_index_xyz_xy_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(-365, -47, 6978), -366);
|
UASSERTEQ(s32, v1.index(-365, -47, 6978), -366);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(-365, -47, 6978), 1493679101);
|
UASSERTEQ(s32, v2.index(-365, -47, 6978), 1797427926);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_xyz_yz_neg()
|
void TestVoxelArea::test_index_xyz_yz_neg()
|
||||||
|
@ -276,8 +307,8 @@ void TestVoxelArea::test_index_xyz_yz_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(66, -58, -789), 65);
|
UASSERTEQ(s32, v1.index(66, -58, -789), 65);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(66, -58, -789), 1435362734);
|
UASSERTEQ(s32, v2.index(66, -58, -789), 1439223357);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_xyz_xz_neg()
|
void TestVoxelArea::test_index_xyz_xz_neg()
|
||||||
|
@ -285,8 +316,8 @@ void TestVoxelArea::test_index_xyz_xz_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(-36, 589, -992), -37);
|
UASSERTEQ(s32, v1.index(-36, 589, -992), -37);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(-36, 589, -992), -1934371362);
|
UASSERTEQ(s32, v2.index(-36, 589, -992), -1937179681);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_xyz_all_neg()
|
void TestVoxelArea::test_index_xyz_all_neg()
|
||||||
|
@ -294,8 +325,8 @@ void TestVoxelArea::test_index_xyz_all_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(-88, -99, -1474), -89);
|
UASSERTEQ(s32, v1.index(-88, -99, -1474), -89);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(-88, -99, -1474), -1343473846);
|
UASSERTEQ(s32, v2.index(-88, -99, -1474), -1366133749);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_all_pos()
|
void TestVoxelArea::test_index_v3s16_all_pos()
|
||||||
|
@ -303,8 +334,8 @@ void TestVoxelArea::test_index_v3s16_all_pos()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(156, 25, 236)), 155);
|
UASSERTEQ(s32, v1.index(v3s16(156, 25, 236)), 155);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(156, 25, 236)), 1267138774);
|
UASSERTEQ(s32, v2.index(v3s16(156, 25, 236)), 1310722495);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_x_neg()
|
void TestVoxelArea::test_index_v3s16_x_neg()
|
||||||
|
@ -312,8 +343,8 @@ void TestVoxelArea::test_index_v3s16_x_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(-147, 25, 366)), -148);
|
UASSERTEQ(s32, v1.index(v3s16(-147, 25, 366)), -148);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(-147, 25, 366)), -870244825);
|
UASSERTEQ(s32, v2.index(v3s16(-147, 25, 366)), -821642064);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_y_neg()
|
void TestVoxelArea::test_index_v3s16_y_neg()
|
||||||
|
@ -321,8 +352,8 @@ void TestVoxelArea::test_index_v3s16_y_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(247, -269, 100)), 246);
|
UASSERTEQ(s32, v1.index(v3s16(247, -269, 100)), 246);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(247, -269, 100)), -989760747);
|
UASSERTEQ(s32, v2.index(v3s16(247, -269, 100)), -951958678);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_z_neg()
|
void TestVoxelArea::test_index_v3s16_z_neg()
|
||||||
|
@ -330,8 +361,8 @@ void TestVoxelArea::test_index_v3s16_z_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(244, 336, -887)), 243);
|
UASSERTEQ(s32, v1.index(v3s16(244, 336, -887)), 243);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(244, 336, -887)), -191478876);
|
UASSERTEQ(s32, v2.index(v3s16(244, 336, -887)), -190690273);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_xy_neg()
|
void TestVoxelArea::test_index_v3s16_xy_neg()
|
||||||
|
@ -339,8 +370,8 @@ void TestVoxelArea::test_index_v3s16_xy_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(-365, -47, 6978)), -366);
|
UASSERTEQ(s32, v1.index(v3s16(-365, -47, 6978)), -366);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(-365, -47, 6978)), 1493679101);
|
UASSERTEQ(s32, v2.index(v3s16(-365, -47, 6978)), 1797427926);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_yz_neg()
|
void TestVoxelArea::test_index_v3s16_yz_neg()
|
||||||
|
@ -348,8 +379,8 @@ void TestVoxelArea::test_index_v3s16_yz_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(66, -58, -789)), 65);
|
UASSERTEQ(s32, v1.index(v3s16(66, -58, -789)), 65);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(66, -58, -789)), 1435362734);
|
UASSERTEQ(s32, v2.index(v3s16(66, -58, -789)), 1439223357);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_xz_neg()
|
void TestVoxelArea::test_index_v3s16_xz_neg()
|
||||||
|
@ -357,8 +388,8 @@ void TestVoxelArea::test_index_v3s16_xz_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(-36, 589, -992)), -37);
|
UASSERTEQ(s32, v1.index(v3s16(-36, 589, -992)), -37);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(-36, 589, -992)), -1934371362);
|
UASSERTEQ(s32, v2.index(v3s16(-36, 589, -992)), -1937179681);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_index_v3s16_all_neg()
|
void TestVoxelArea::test_index_v3s16_all_neg()
|
||||||
|
@ -366,8 +397,8 @@ void TestVoxelArea::test_index_v3s16_all_neg()
|
||||||
VoxelArea v1;
|
VoxelArea v1;
|
||||||
UASSERTEQ(s32, v1.index(v3s16(-88, -99, -1474)), -89);
|
UASSERTEQ(s32, v1.index(v3s16(-88, -99, -1474)), -89);
|
||||||
|
|
||||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||||
UASSERTEQ(s32, v2.index(v3s16(-88, -99, -1474)), -1343473846);
|
UASSERTEQ(s32, v2.index(v3s16(-88, -99, -1474)), -1366133749);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestVoxelArea::test_add_x()
|
void TestVoxelArea::test_add_x()
|
||||||
|
|
|
@ -29,10 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
/*
|
/*
|
||||||
Debug stuff
|
Debug stuff
|
||||||
*/
|
*/
|
||||||
u64 addarea_time = 0;
|
|
||||||
u64 emerge_time = 0;
|
u64 emerge_time = 0;
|
||||||
u64 emerge_load_time = 0;
|
u64 emerge_load_time = 0;
|
||||||
u64 clearflag_time = 0;
|
|
||||||
|
|
||||||
VoxelManipulator::~VoxelManipulator()
|
VoxelManipulator::~VoxelManipulator()
|
||||||
{
|
{
|
||||||
|
@ -53,7 +51,7 @@ void VoxelManipulator::clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelManipulator::print(std::ostream &o, const NodeDefManager *ndef,
|
void VoxelManipulator::print(std::ostream &o, const NodeDefManager *ndef,
|
||||||
VoxelPrintMode mode)
|
VoxelPrintMode mode) const
|
||||||
{
|
{
|
||||||
const v3s16 &em = m_area.getExtent();
|
const v3s16 &em = m_area.getExtent();
|
||||||
v3s16 of = m_area.MinEdge;
|
v3s16 of = m_area.MinEdge;
|
||||||
|
@ -140,8 +138,6 @@ void VoxelManipulator::addArea(const VoxelArea &area)
|
||||||
if(m_area.contains(area))
|
if(m_area.contains(area))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TimeTaker timer("addArea", &addarea_time);
|
|
||||||
|
|
||||||
// Calculate new area
|
// Calculate new area
|
||||||
VoxelArea new_area;
|
VoxelArea new_area;
|
||||||
// New area is the requested area if m_area has zero volume
|
// New area is the requested area if m_area has zero volume
|
||||||
|
@ -158,15 +154,6 @@ void VoxelManipulator::addArea(const VoxelArea &area)
|
||||||
|
|
||||||
s32 new_size = new_area.getVolume();
|
s32 new_size = new_area.getVolume();
|
||||||
|
|
||||||
/*dstream<<"adding area ";
|
|
||||||
area.print(dstream);
|
|
||||||
dstream<<", old area ";
|
|
||||||
m_area.print(dstream);
|
|
||||||
dstream<<", new area ";
|
|
||||||
new_area.print(dstream);
|
|
||||||
dstream<<", new_size="<<new_size;
|
|
||||||
dstream<<std::endl;*/
|
|
||||||
|
|
||||||
// Allocate new data and clear flags
|
// Allocate new data and clear flags
|
||||||
MapNode *new_data = new MapNode[new_size];
|
MapNode *new_data = new MapNode[new_size];
|
||||||
assert(new_data);
|
assert(new_data);
|
||||||
|
@ -195,16 +182,11 @@ void VoxelManipulator::addArea(const VoxelArea &area)
|
||||||
MapNode *old_data = m_data;
|
MapNode *old_data = m_data;
|
||||||
u8 *old_flags = m_flags;
|
u8 *old_flags = m_flags;
|
||||||
|
|
||||||
/*dstream<<"old_data="<<(int)old_data<<", new_data="<<(int)new_data
|
|
||||||
<<", old_flags="<<(int)m_flags<<", new_flags="<<(int)new_flags<<std::endl;*/
|
|
||||||
|
|
||||||
m_data = new_data;
|
m_data = new_data;
|
||||||
m_flags = new_flags;
|
m_flags = new_flags;
|
||||||
|
|
||||||
delete[] old_data;
|
delete[] old_data;
|
||||||
delete[] old_flags;
|
delete[] old_flags;
|
||||||
|
|
||||||
//dstream<<"addArea done"<<std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelManipulator::copyFrom(MapNode *src, const VoxelArea& src_area,
|
void VoxelManipulator::copyFrom(MapNode *src, const VoxelArea& src_area,
|
||||||
|
@ -256,7 +238,7 @@ void VoxelManipulator::copyFrom(MapNode *src, const VoxelArea& src_area,
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelManipulator::copyTo(MapNode *dst, const VoxelArea& dst_area,
|
void VoxelManipulator::copyTo(MapNode *dst, const VoxelArea& dst_area,
|
||||||
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size)
|
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size) const
|
||||||
{
|
{
|
||||||
for(s16 z=0; z<size.Z; z++)
|
for(s16 z=0; z<size.Z; z++)
|
||||||
for(s16 y=0; y<size.Y; y++)
|
for(s16 y=0; y<size.Y; y++)
|
||||||
|
@ -277,46 +259,38 @@ void VoxelManipulator::copyTo(MapNode *dst, const VoxelArea& dst_area,
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void VoxelManipulator::clearFlag(u8 flags)
|
void VoxelManipulator::setFlags(const VoxelArea &a, u8 flags)
|
||||||
{
|
{
|
||||||
// 0-1ms on moderate area
|
if (a.hasEmptyExtent())
|
||||||
TimeTaker timer("clearFlag", &clearflag_time);
|
return;
|
||||||
|
|
||||||
//v3s16 s = m_area.getExtent();
|
assert(m_area.contains(a));
|
||||||
|
|
||||||
/*dstream<<"clearFlag clearing area of size "
|
const s32 stride = a.getExtent().X;
|
||||||
<<""<<s.X<<"x"<<s.Y<<"x"<<s.Z<<""
|
for (s32 z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++)
|
||||||
<<std::endl;*/
|
for (s32 y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++)
|
||||||
|
|
||||||
//s32 count = 0;
|
|
||||||
|
|
||||||
/*for(s32 z=m_area.MinEdge.Z; z<=m_area.MaxEdge.Z; z++)
|
|
||||||
for(s32 y=m_area.MinEdge.Y; y<=m_area.MaxEdge.Y; y++)
|
|
||||||
for(s32 x=m_area.MinEdge.X; x<=m_area.MaxEdge.X; x++)
|
|
||||||
{
|
{
|
||||||
u8 f = m_flags[m_area.index(x,y,z)];
|
const s32 start = m_area.index(a.MinEdge.X, y, z);
|
||||||
m_flags[m_area.index(x,y,z)] &= ~flags;
|
for (s32 i = start; i < start + stride; i++)
|
||||||
if(m_flags[m_area.index(x,y,z)] != f)
|
m_flags[i] |= flags;
|
||||||
count++;
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
s32 volume = m_area.getVolume();
|
|
||||||
for(s32 i=0; i<volume; i++)
|
|
||||||
{
|
|
||||||
m_flags[i] &= ~flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*s32 volume = m_area.getVolume();
|
void VoxelManipulator::clearFlags(const VoxelArea &a, u8 flags)
|
||||||
for(s32 i=0; i<volume; i++)
|
|
||||||
{
|
{
|
||||||
u8 f = m_flags[i];
|
if (a.hasEmptyExtent())
|
||||||
m_flags[i] &= ~flags;
|
return;
|
||||||
if(m_flags[i] != f)
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
dstream<<"clearFlag changed "<<count<<" flags out of "
|
assert(m_area.contains(a));
|
||||||
<<volume<<" nodes"<<std::endl;*/
|
|
||||||
|
const s32 stride = a.getExtent().X;
|
||||||
|
for (s32 z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++)
|
||||||
|
for (s32 y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++)
|
||||||
|
{
|
||||||
|
const s32 start = m_area.index(a.MinEdge.X, y, z);
|
||||||
|
for (s32 i = start; i < start + stride; i++)
|
||||||
|
m_flags[i] &= ~flags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapNode VoxelManipulator::ContentIgnoreNode = MapNode(CONTENT_IGNORE);
|
const MapNode VoxelManipulator::ContentIgnoreNode = MapNode(CONTENT_IGNORE);
|
||||||
|
|
108
src/voxel.h
108
src/voxel.h
|
@ -59,7 +59,7 @@ class VoxelArea
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Starts as zero sized
|
// Starts as zero sized
|
||||||
VoxelArea() = default;
|
constexpr VoxelArea() = default;
|
||||||
|
|
||||||
VoxelArea(const v3s16 &min_edge, const v3s16 &max_edge):
|
VoxelArea(const v3s16 &min_edge, const v3s16 &max_edge):
|
||||||
MinEdge(min_edge),
|
MinEdge(min_edge),
|
||||||
|
@ -129,12 +129,11 @@ public:
|
||||||
return m_cache_extent;
|
return m_cache_extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Because MaxEdge and MinEdge are included in the voxel area an empty extent
|
/// @note `getVolume() == 0` and `getEmptyExtent()` are not identical.
|
||||||
* is not represented by (0, 0, 0), but instead (-1, -1, -1)
|
|
||||||
*/
|
|
||||||
bool hasEmptyExtent() const
|
bool hasEmptyExtent() const
|
||||||
{
|
{
|
||||||
return MaxEdge - MinEdge == v3s16(-1, -1, -1);
|
// FIXME: shouldn't this actually be a component-wise check?
|
||||||
|
return m_cache_extent == v3s16(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 getVolume() const
|
s32 getVolume() const
|
||||||
|
@ -208,20 +207,18 @@ public:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Returns 0-6 non-overlapping areas that can be added to
|
Returns 0-6 non-overlapping areas that can be added to
|
||||||
a to make up this area.
|
`a` to make up this area.
|
||||||
|
|
||||||
a: area inside *this
|
@tparam C container that has push_back
|
||||||
|
@param a area inside *this
|
||||||
*/
|
*/
|
||||||
void diff(const VoxelArea &a, std::list<VoxelArea> &result)
|
template <typename C>
|
||||||
|
void diff(const VoxelArea &a, C &result) const
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
This can result in a maximum of 6 areas
|
|
||||||
*/
|
|
||||||
|
|
||||||
// If a is an empty area, return the current area as a whole
|
// If a is an empty area, return the current area as a whole
|
||||||
if(a.getExtent() == v3s16(0,0,0))
|
if(a.hasEmptyExtent())
|
||||||
{
|
{
|
||||||
VoxelArea b = *this;
|
VoxelArea b = *this;
|
||||||
if (b.getVolume() != 0)
|
if (b.getVolume() != 0)
|
||||||
|
@ -231,60 +228,53 @@ public:
|
||||||
|
|
||||||
assert(contains(a)); // pre-condition
|
assert(contains(a)); // pre-condition
|
||||||
|
|
||||||
|
const auto &take = [&result] (v3s16 min, v3s16 max) {
|
||||||
|
VoxelArea b(min, max);
|
||||||
|
if (b.getVolume() != 0)
|
||||||
|
result.push_back(b);
|
||||||
|
};
|
||||||
|
|
||||||
// Take back area, XY inclusive
|
// Take back area, XY inclusive
|
||||||
{
|
{
|
||||||
v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1);
|
v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1);
|
||||||
v3s16 max(MaxEdge.X, MaxEdge.Y, MaxEdge.Z);
|
v3s16 max(MaxEdge.X, MaxEdge.Y, MaxEdge.Z);
|
||||||
VoxelArea b(min, max);
|
take(min, max);
|
||||||
if(b.getVolume() != 0)
|
|
||||||
result.push_back(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take front area, XY inclusive
|
// Take front area, XY inclusive
|
||||||
{
|
{
|
||||||
v3s16 min(MinEdge.X, MinEdge.Y, MinEdge.Z);
|
v3s16 min(MinEdge.X, MinEdge.Y, MinEdge.Z);
|
||||||
v3s16 max(MaxEdge.X, MaxEdge.Y, a.MinEdge.Z-1);
|
v3s16 max(MaxEdge.X, MaxEdge.Y, a.MinEdge.Z-1);
|
||||||
VoxelArea b(min, max);
|
take(min, max);
|
||||||
if(b.getVolume() != 0)
|
|
||||||
result.push_back(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take top area, X inclusive
|
// Take top area, X inclusive
|
||||||
{
|
{
|
||||||
v3s16 min(MinEdge.X, a.MaxEdge.Y+1, a.MinEdge.Z);
|
v3s16 min(MinEdge.X, a.MaxEdge.Y+1, a.MinEdge.Z);
|
||||||
v3s16 max(MaxEdge.X, MaxEdge.Y, a.MaxEdge.Z);
|
v3s16 max(MaxEdge.X, MaxEdge.Y, a.MaxEdge.Z);
|
||||||
VoxelArea b(min, max);
|
take(min, max);
|
||||||
if(b.getVolume() != 0)
|
|
||||||
result.push_back(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take bottom area, X inclusive
|
// Take bottom area, X inclusive
|
||||||
{
|
{
|
||||||
v3s16 min(MinEdge.X, MinEdge.Y, a.MinEdge.Z);
|
v3s16 min(MinEdge.X, MinEdge.Y, a.MinEdge.Z);
|
||||||
v3s16 max(MaxEdge.X, a.MinEdge.Y-1, a.MaxEdge.Z);
|
v3s16 max(MaxEdge.X, a.MinEdge.Y-1, a.MaxEdge.Z);
|
||||||
VoxelArea b(min, max);
|
take(min, max);
|
||||||
if(b.getVolume() != 0)
|
|
||||||
result.push_back(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take left area, non-inclusive
|
// Take left area, non-inclusive
|
||||||
{
|
{
|
||||||
v3s16 min(MinEdge.X, a.MinEdge.Y, a.MinEdge.Z);
|
v3s16 min(MinEdge.X, a.MinEdge.Y, a.MinEdge.Z);
|
||||||
v3s16 max(a.MinEdge.X-1, a.MaxEdge.Y, a.MaxEdge.Z);
|
v3s16 max(a.MinEdge.X-1, a.MaxEdge.Y, a.MaxEdge.Z);
|
||||||
VoxelArea b(min, max);
|
take(min, max);
|
||||||
if(b.getVolume() != 0)
|
|
||||||
result.push_back(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take right area, non-inclusive
|
// Take right area, non-inclusive
|
||||||
{
|
{
|
||||||
v3s16 min(a.MaxEdge.X+1, a.MinEdge.Y, a.MinEdge.Z);
|
v3s16 min(a.MaxEdge.X+1, a.MinEdge.Y, a.MinEdge.Z);
|
||||||
v3s16 max(MaxEdge.X, a.MaxEdge.Y, a.MaxEdge.Z);
|
v3s16 max(MaxEdge.X, a.MaxEdge.Y, a.MaxEdge.Z);
|
||||||
VoxelArea b(min, max);
|
take(min, max);
|
||||||
if(b.getVolume() != 0)
|
|
||||||
result.push_back(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -344,30 +334,34 @@ public:
|
||||||
<< "=" << getVolume();
|
<< "=" << getVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edges are inclusive
|
/// Minimum edge of the area (inclusive)
|
||||||
|
/// @warning read-only!
|
||||||
v3s16 MinEdge = v3s16(1,1,1);
|
v3s16 MinEdge = v3s16(1,1,1);
|
||||||
|
/// Maximum edge of the area (inclusive)
|
||||||
|
/// @warning read-only!
|
||||||
v3s16 MaxEdge;
|
v3s16 MaxEdge;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cacheExtent()
|
void cacheExtent()
|
||||||
{
|
{
|
||||||
m_cache_extent = MaxEdge - MinEdge + v3s16(1,1,1);
|
m_cache_extent = MaxEdge - MinEdge + v3s16(1,1,1);
|
||||||
|
// If positions were sorted correctly this must always hold.
|
||||||
|
// Note that this still permits empty areas (where MinEdge = MaxEdge + 1).
|
||||||
|
assert(m_cache_extent.X >= 0);
|
||||||
|
assert(m_cache_extent.Y >= 0);
|
||||||
|
assert(m_cache_extent.Z >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
v3s16 m_cache_extent = v3s16(0,0,0);
|
v3s16 m_cache_extent = v3s16(0,0,0);
|
||||||
};
|
};
|
||||||
|
|
||||||
// unused
|
enum : u8 {
|
||||||
#define VOXELFLAG_UNUSED (1 << 0)
|
VOXELFLAG_NO_DATA = 1 << 0, // no data about that node
|
||||||
// no data about that node
|
VOXELFLAG_CHECKED1 = 1 << 1, // Algorithm-dependent
|
||||||
#define VOXELFLAG_NO_DATA (1 << 1)
|
VOXELFLAG_CHECKED2 = 1 << 2, // Algorithm-dependent
|
||||||
// Algorithm-dependent
|
VOXELFLAG_CHECKED3 = 1 << 3, // Algorithm-dependent
|
||||||
#define VOXELFLAG_CHECKED1 (1 << 2)
|
VOXELFLAG_CHECKED4 = 1 << 4, // Algorithm-dependent
|
||||||
// Algorithm-dependent
|
};
|
||||||
#define VOXELFLAG_CHECKED2 (1 << 3)
|
|
||||||
// Algorithm-dependent
|
|
||||||
#define VOXELFLAG_CHECKED3 (1 << 4)
|
|
||||||
// Algorithm-dependent
|
|
||||||
#define VOXELFLAG_CHECKED4 (1 << 5)
|
|
||||||
|
|
||||||
enum VoxelPrintMode
|
enum VoxelPrintMode
|
||||||
{
|
{
|
||||||
|
@ -414,7 +408,7 @@ public:
|
||||||
|
|
||||||
return m_data[index];
|
return m_data[index];
|
||||||
}
|
}
|
||||||
MapNode getNodeNoExNoEmerge(const v3s16 &p)
|
MapNode getNodeNoExNoEmerge(const v3s16 &p) const
|
||||||
{
|
{
|
||||||
if (!m_area.contains(p))
|
if (!m_area.contains(p))
|
||||||
return {CONTENT_IGNORE};
|
return {CONTENT_IGNORE};
|
||||||
|
@ -430,7 +424,7 @@ public:
|
||||||
return m_data[m_area.index(p)];
|
return m_data[m_area.index(p)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapNode & getNodeRefUnsafeCheckFlags(const v3s16 &p)
|
const MapNode & getNodeRefUnsafeCheckFlags(const v3s16 &p) const
|
||||||
{
|
{
|
||||||
s32 index = m_area.index(p);
|
s32 index = m_area.index(p);
|
||||||
|
|
||||||
|
@ -483,10 +477,13 @@ public:
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
void print(std::ostream &o, const NodeDefManager *nodemgr,
|
void print(std::ostream &o, const NodeDefManager *nodemgr,
|
||||||
VoxelPrintMode mode=VOXELPRINT_MATERIAL);
|
VoxelPrintMode mode=VOXELPRINT_MATERIAL) const;
|
||||||
|
|
||||||
void addArea(const VoxelArea &area);
|
void addArea(const VoxelArea &area);
|
||||||
|
|
||||||
|
void setFlags(const VoxelArea &area, u8 flag);
|
||||||
|
void clearFlags(const VoxelArea &area, u8 flag);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copy data and set flags to 0
|
Copy data and set flags to 0
|
||||||
dst_area.getExtent() <= src_area.getExtent()
|
dst_area.getExtent() <= src_area.getExtent()
|
||||||
|
@ -496,13 +493,7 @@ public:
|
||||||
|
|
||||||
// Copy data
|
// Copy data
|
||||||
void copyTo(MapNode *dst, const VoxelArea& dst_area,
|
void copyTo(MapNode *dst, const VoxelArea& dst_area,
|
||||||
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size);
|
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size) const;
|
||||||
|
|
||||||
/*
|
|
||||||
Algorithms
|
|
||||||
*/
|
|
||||||
|
|
||||||
void clearFlag(u8 flag);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Member variables
|
Member variables
|
||||||
|
@ -510,13 +501,12 @@ public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The area that is stored in m_data.
|
The area that is stored in m_data.
|
||||||
addInternalBox should not be used if getExtent() == v3s16(0,0,0)
|
MaxEdge is 1 higher than maximum allowed position.
|
||||||
MaxEdge is 1 higher than maximum allowed position
|
|
||||||
*/
|
*/
|
||||||
VoxelArea m_area;
|
VoxelArea m_area;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
nullptr if data size is 0 (extent (0,0,0))
|
nullptr if data size is 0 (empty extent)
|
||||||
Data is stored as [z*h*w + y*h + x]
|
Data is stored as [z*h*w + y*h + x]
|
||||||
*/
|
*/
|
||||||
MapNode *m_data = nullptr;
|
MapNode *m_data = nullptr;
|
||||||
|
|
|
@ -943,14 +943,18 @@ bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef,
|
||||||
* The areas do not overlap.
|
* The areas do not overlap.
|
||||||
* Compatible with type 'direction'.
|
* Compatible with type 'direction'.
|
||||||
*/
|
*/
|
||||||
const VoxelArea block_pad[] = {
|
#define B_1 (MAP_BLOCKSIZE - 1)
|
||||||
VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), //X+
|
#define B_2 (MAP_BLOCKSIZE - 2)
|
||||||
VoxelArea(v3s16(1, 15, 0), v3s16(14, 15, 15)), //Y+
|
const static VoxelArea block_pad[] = {
|
||||||
VoxelArea(v3s16(1, 1, 15), v3s16(14, 14, 15)), //Z+
|
VoxelArea({B_1, 0, 0}, {B_1, B_1, B_1}), //X+
|
||||||
VoxelArea(v3s16(1, 1, 0), v3s16(14, 14, 0)), //Z-
|
VoxelArea({1, B_1, 0}, {B_2, B_1, B_1}), //Y+
|
||||||
VoxelArea(v3s16(1, 0, 0), v3s16(14, 0, 15)), //Y-
|
VoxelArea({1, 1, B_1}, {B_2, B_2, B_1}), //Z+
|
||||||
VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) //X-
|
VoxelArea({1, 1, 0}, {B_2, B_2, 0}), //Z-
|
||||||
|
VoxelArea({1, 0, 0}, {B_2, 0, B_1}), //Y-
|
||||||
|
VoxelArea({0, 0, 0}, {0, B_1, B_1}) //X-
|
||||||
};
|
};
|
||||||
|
#undef B_1
|
||||||
|
#undef B_2
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* The common part of bulk light updates - it is always executed.
|
* The common part of bulk light updates - it is always executed.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue