mirror of
https://github.com/minetest/minetest.git
synced 2025-03-06 20:48:40 +01: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`.
|
||||
* `calc_lighting([p1, p2], [propagate_shadow])`: Calculate lighting within the
|
||||
`VoxelManip`.
|
||||
* To be used only by a `VoxelManip` object from
|
||||
`minetest.get_mapgen_object`.
|
||||
* To be used only with a `VoxelManip` object from `minetest.get_mapgen_object`.
|
||||
* (`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
|
||||
or nil to use the default.
|
||||
|
@ -5019,9 +5018,11 @@ Methods
|
|||
generated mapchunk above are propagated down into the mapchunk, defaults
|
||||
to `true` if left out.
|
||||
* `update_liquids()`: Update liquid flow
|
||||
* `was_modified()`: Returns `true` or `false` if the data in the voxel
|
||||
manipulator had been modified since the last read from map, due to a call to
|
||||
`minetest.set_data()` on the loaded area elsewhere.
|
||||
* `was_modified()`: Returns `true` if the data in the voxel manipulator has been modified
|
||||
since it was last read from the map. This means you have to call `get_data` again.
|
||||
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.
|
||||
|
||||
`VoxelArea`
|
||||
|
|
16
src/map.cpp
16
src/map.cpp
|
@ -822,17 +822,9 @@ void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
|
|||
} else {
|
||||
flags |= VMANIP_BLOCK_DATA_INEXIST;
|
||||
|
||||
/*
|
||||
Mark area inexistent
|
||||
*/
|
||||
// Mark area inexistent
|
||||
VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
|
||||
// Fill with 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);
|
||||
}
|
||||
setFlags(a, VOXELFLAG_NO_DATA);
|
||||
}
|
||||
}
|
||||
/*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,
|
||||
bool overwrite_generated)
|
||||
bool overwrite_generated) const
|
||||
{
|
||||
if(m_area.getExtent() == v3s16(0,0,0))
|
||||
if (m_area.hasEmptyExtent())
|
||||
return;
|
||||
assert(m_map);
|
||||
|
||||
|
|
|
@ -333,7 +333,7 @@ public:
|
|||
|
||||
// This is much faster with big chunks of generated data
|
||||
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
|
||||
|
|
|
@ -178,13 +178,13 @@ void MapBlock::copyTo(VoxelManipulator &dst)
|
|||
getPosRelative(), data_size);
|
||||
}
|
||||
|
||||
void MapBlock::copyFrom(VoxelManipulator &dst)
|
||||
void MapBlock::copyFrom(const VoxelManipulator &src)
|
||||
{
|
||||
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
||||
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -307,8 +307,8 @@ public:
|
|||
// Copies data to VoxelManipulator to getPosRelative()
|
||||
void copyTo(VoxelManipulator &dst);
|
||||
|
||||
// Copies data from VoxelManipulator getPosRelative()
|
||||
void copyFrom(VoxelManipulator &dst);
|
||||
// Copies data from VoxelManipulator to getPosRelative()
|
||||
void copyFrom(const VoxelManipulator &src);
|
||||
|
||||
// Update is air flag.
|
||||
// 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);
|
||||
|
||||
// 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) {
|
||||
// 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);
|
||||
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);
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
void test_equal();
|
||||
void test_plus();
|
||||
void test_minor();
|
||||
void test_diff();
|
||||
void test_intersect();
|
||||
void test_index_xyz_all_pos();
|
||||
void test_index_xyz_x_neg();
|
||||
|
@ -75,6 +76,7 @@ void TestVoxelArea::runTests(IGameDef *gamedef)
|
|||
TEST(test_equal);
|
||||
TEST(test_plus);
|
||||
TEST(test_minor);
|
||||
TEST(test_diff);
|
||||
TEST(test_intersect);
|
||||
TEST(test_index_xyz_all_pos);
|
||||
TEST(test_index_xyz_x_neg);
|
||||
|
@ -100,21 +102,21 @@ void TestVoxelArea::runTests(IGameDef *gamedef)
|
|||
|
||||
void TestVoxelArea::test_addarea()
|
||||
{
|
||||
VoxelArea v1(v3s16(-1447, 8854, -875), v3s16(-147, -9547, 669));
|
||||
VoxelArea v2(v3s16(-887, 4445, -5478), v3s16(447, -8779, 4778));
|
||||
VoxelArea v1(v3s16(-1447, -9547, -875), v3s16(-147, 8854, 669));
|
||||
VoxelArea v2(v3s16(-887, -8779, -5478), v3s16(447, 4445, 4778));
|
||||
|
||||
v1.addArea(v2);
|
||||
UASSERT(v1.MinEdge == v3s16(-1447, 4445, -5478));
|
||||
UASSERT(v1.MaxEdge == v3s16(447, -8779, 4778));
|
||||
UASSERT(v1.MinEdge == v3s16(-1447, -9547, -5478));
|
||||
UASSERT(v1.MaxEdge == v3s16(447, 8854, 4778));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
UASSERT(v1.MinEdge == v3s16(-1547, 8654, -1175));
|
||||
UASSERT(v1.MaxEdge == v3s16(-47, -9347, 969));
|
||||
UASSERT(v1.MinEdge == v3s16(-1547, -9747, -1175));
|
||||
UASSERT(v1.MaxEdge == v3s16(-47, 9054, 969));
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_extent()
|
||||
|
@ -124,6 +126,9 @@ void TestVoxelArea::test_extent()
|
|||
|
||||
VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
|
||||
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()
|
||||
|
@ -133,6 +138,9 @@ void TestVoxelArea::test_volume()
|
|||
|
||||
VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
|
||||
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()
|
||||
|
@ -185,8 +193,7 @@ void TestVoxelArea::test_equal()
|
|||
VoxelArea v1(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669));
|
||||
UASSERTEQ(bool, v1 == VoxelArea(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)),
|
||||
true);
|
||||
UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(-147, 750, 669)), false);
|
||||
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(0, 0, 0)), false);
|
||||
}
|
||||
|
||||
|
@ -212,6 +219,30 @@ void TestVoxelArea::test_minor()
|
|||
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()
|
||||
{
|
||||
VoxelArea v1({-10, -10, -10}, {10, 10, 10});
|
||||
|
@ -231,8 +262,8 @@ void TestVoxelArea::test_index_xyz_all_pos()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(156, 25, 236), 155);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(156, 25, 236), 1267138774);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(156, 25, 236), 1310722495);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_xyz_x_neg()
|
||||
|
@ -240,8 +271,8 @@ void TestVoxelArea::test_index_xyz_x_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(-147, 25, 366), -148);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(-147, 25, 366), -870244825);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(-147, 25, 366), -821642064);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_xyz_y_neg()
|
||||
|
@ -249,8 +280,8 @@ void TestVoxelArea::test_index_xyz_y_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(247, -269, 100), 246);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(247, -269, 100), -989760747);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(247, -269, 100), -951958678);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_xyz_z_neg()
|
||||
|
@ -258,8 +289,8 @@ void TestVoxelArea::test_index_xyz_z_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(244, 336, -887), 243);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(244, 336, -887), -191478876);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(244, 336, -887), -190690273);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_xyz_xy_neg()
|
||||
|
@ -267,8 +298,8 @@ void TestVoxelArea::test_index_xyz_xy_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(-365, -47, 6978), -366);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(-365, -47, 6978), 1493679101);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(-365, -47, 6978), 1797427926);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_xyz_yz_neg()
|
||||
|
@ -276,8 +307,8 @@ void TestVoxelArea::test_index_xyz_yz_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(66, -58, -789), 65);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(66, -58, -789), 1435362734);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(66, -58, -789), 1439223357);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_xyz_xz_neg()
|
||||
|
@ -285,8 +316,8 @@ void TestVoxelArea::test_index_xyz_xz_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(-36, 589, -992), -37);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(-36, 589, -992), -1934371362);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(-36, 589, -992), -1937179681);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_xyz_all_neg()
|
||||
|
@ -294,8 +325,8 @@ void TestVoxelArea::test_index_xyz_all_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(-88, -99, -1474), -89);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(-88, -99, -1474), -1343473846);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(-88, -99, -1474), -1366133749);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_all_pos()
|
||||
|
@ -303,8 +334,8 @@ void TestVoxelArea::test_index_v3s16_all_pos()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(156, 25, 236)), 155);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(156, 25, 236)), 1267138774);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(156, 25, 236)), 1310722495);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_x_neg()
|
||||
|
@ -312,8 +343,8 @@ void TestVoxelArea::test_index_v3s16_x_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(-147, 25, 366)), -148);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-147, 25, 366)), -870244825);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-147, 25, 366)), -821642064);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_y_neg()
|
||||
|
@ -321,8 +352,8 @@ void TestVoxelArea::test_index_v3s16_y_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(247, -269, 100)), 246);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(247, -269, 100)), -989760747);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(247, -269, 100)), -951958678);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_z_neg()
|
||||
|
@ -330,8 +361,8 @@ void TestVoxelArea::test_index_v3s16_z_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(244, 336, -887)), 243);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(244, 336, -887)), -191478876);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(244, 336, -887)), -190690273);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_xy_neg()
|
||||
|
@ -339,8 +370,8 @@ void TestVoxelArea::test_index_v3s16_xy_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(-365, -47, 6978)), -366);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-365, -47, 6978)), 1493679101);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-365, -47, 6978)), 1797427926);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_yz_neg()
|
||||
|
@ -348,8 +379,8 @@ void TestVoxelArea::test_index_v3s16_yz_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(66, -58, -789)), 65);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(66, -58, -789)), 1435362734);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(66, -58, -789)), 1439223357);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_xz_neg()
|
||||
|
@ -357,8 +388,8 @@ void TestVoxelArea::test_index_v3s16_xz_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(-36, 589, -992)), -37);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-36, 589, -992)), -1934371362);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-36, 589, -992)), -1937179681);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_index_v3s16_all_neg()
|
||||
|
@ -366,8 +397,8 @@ void TestVoxelArea::test_index_v3s16_all_neg()
|
|||
VoxelArea v1;
|
||||
UASSERTEQ(s32, v1.index(v3s16(-88, -99, -1474)), -89);
|
||||
|
||||
VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-88, -99, -1474)), -1343473846);
|
||||
VoxelArea v2(v3s16(-147, -9547, -875), v3s16(756, 8854, 669));
|
||||
UASSERTEQ(s32, v2.index(v3s16(-88, -99, -1474)), -1366133749);
|
||||
}
|
||||
|
||||
void TestVoxelArea::test_add_x()
|
||||
|
|
|
@ -29,10 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
/*
|
||||
Debug stuff
|
||||
*/
|
||||
u64 addarea_time = 0;
|
||||
u64 emerge_time = 0;
|
||||
u64 emerge_load_time = 0;
|
||||
u64 clearflag_time = 0;
|
||||
|
||||
VoxelManipulator::~VoxelManipulator()
|
||||
{
|
||||
|
@ -53,7 +51,7 @@ void VoxelManipulator::clear()
|
|||
}
|
||||
|
||||
void VoxelManipulator::print(std::ostream &o, const NodeDefManager *ndef,
|
||||
VoxelPrintMode mode)
|
||||
VoxelPrintMode mode) const
|
||||
{
|
||||
const v3s16 &em = m_area.getExtent();
|
||||
v3s16 of = m_area.MinEdge;
|
||||
|
@ -140,8 +138,6 @@ void VoxelManipulator::addArea(const VoxelArea &area)
|
|||
if(m_area.contains(area))
|
||||
return;
|
||||
|
||||
TimeTaker timer("addArea", &addarea_time);
|
||||
|
||||
// Calculate new area
|
||||
VoxelArea new_area;
|
||||
// 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();
|
||||
|
||||
/*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
|
||||
MapNode *new_data = new MapNode[new_size];
|
||||
assert(new_data);
|
||||
|
@ -195,16 +182,11 @@ void VoxelManipulator::addArea(const VoxelArea &area)
|
|||
MapNode *old_data = m_data;
|
||||
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_flags = new_flags;
|
||||
|
||||
delete[] old_data;
|
||||
delete[] old_flags;
|
||||
|
||||
//dstream<<"addArea done"<<std::endl;
|
||||
}
|
||||
|
||||
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,
|
||||
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 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
|
||||
TimeTaker timer("clearFlag", &clearflag_time);
|
||||
if (a.hasEmptyExtent())
|
||||
return;
|
||||
|
||||
//v3s16 s = m_area.getExtent();
|
||||
assert(m_area.contains(a));
|
||||
|
||||
/*dstream<<"clearFlag clearing area of size "
|
||||
<<""<<s.X<<"x"<<s.Y<<"x"<<s.Z<<""
|
||||
<<std::endl;*/
|
||||
|
||||
//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++)
|
||||
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++)
|
||||
{
|
||||
u8 f = m_flags[m_area.index(x,y,z)];
|
||||
m_flags[m_area.index(x,y,z)] &= ~flags;
|
||||
if(m_flags[m_area.index(x,y,z)] != f)
|
||||
count++;
|
||||
}*/
|
||||
|
||||
s32 volume = m_area.getVolume();
|
||||
for(s32 i=0; i<volume; i++)
|
||||
{
|
||||
m_flags[i] &= ~flags;
|
||||
const s32 start = m_area.index(a.MinEdge.X, y, z);
|
||||
for (s32 i = start; i < start + stride; i++)
|
||||
m_flags[i] |= flags;
|
||||
}
|
||||
}
|
||||
|
||||
/*s32 volume = m_area.getVolume();
|
||||
for(s32 i=0; i<volume; i++)
|
||||
void VoxelManipulator::clearFlags(const VoxelArea &a, u8 flags)
|
||||
{
|
||||
if (a.hasEmptyExtent())
|
||||
return;
|
||||
|
||||
assert(m_area.contains(a));
|
||||
|
||||
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++)
|
||||
{
|
||||
u8 f = m_flags[i];
|
||||
m_flags[i] &= ~flags;
|
||||
if(m_flags[i] != f)
|
||||
count++;
|
||||
const s32 start = m_area.index(a.MinEdge.X, y, z);
|
||||
for (s32 i = start; i < start + stride; i++)
|
||||
m_flags[i] &= ~flags;
|
||||
}
|
||||
|
||||
dstream<<"clearFlag changed "<<count<<" flags out of "
|
||||
<<volume<<" nodes"<<std::endl;*/
|
||||
}
|
||||
|
||||
const MapNode VoxelManipulator::ContentIgnoreNode = MapNode(CONTENT_IGNORE);
|
||||
|
|
110
src/voxel.h
110
src/voxel.h
|
@ -59,7 +59,7 @@ class VoxelArea
|
|||
{
|
||||
public:
|
||||
// Starts as zero sized
|
||||
VoxelArea() = default;
|
||||
constexpr VoxelArea() = default;
|
||||
|
||||
VoxelArea(const v3s16 &min_edge, const v3s16 &max_edge):
|
||||
MinEdge(min_edge),
|
||||
|
@ -129,12 +129,11 @@ public:
|
|||
return m_cache_extent;
|
||||
}
|
||||
|
||||
/* Because MaxEdge and MinEdge are included in the voxel area an empty extent
|
||||
* is not represented by (0, 0, 0), but instead (-1, -1, -1)
|
||||
*/
|
||||
/// @note `getVolume() == 0` and `getEmptyExtent()` are not identical.
|
||||
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
|
||||
|
@ -208,83 +207,74 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
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.getExtent() == v3s16(0,0,0))
|
||||
if(a.hasEmptyExtent())
|
||||
{
|
||||
VoxelArea b = *this;
|
||||
if(b.getVolume() != 0)
|
||||
if (b.getVolume() != 0)
|
||||
result.push_back(b);
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1);
|
||||
v3s16 max(MaxEdge.X, MaxEdge.Y, MaxEdge.Z);
|
||||
VoxelArea b(min, max);
|
||||
if(b.getVolume() != 0)
|
||||
result.push_back(b);
|
||||
take(min, max);
|
||||
}
|
||||
|
||||
// Take front area, XY inclusive
|
||||
{
|
||||
v3s16 min(MinEdge.X, MinEdge.Y, MinEdge.Z);
|
||||
v3s16 max(MaxEdge.X, MaxEdge.Y, a.MinEdge.Z-1);
|
||||
VoxelArea b(min, max);
|
||||
if(b.getVolume() != 0)
|
||||
result.push_back(b);
|
||||
take(min, max);
|
||||
}
|
||||
|
||||
// Take top area, X inclusive
|
||||
{
|
||||
v3s16 min(MinEdge.X, a.MaxEdge.Y+1, a.MinEdge.Z);
|
||||
v3s16 max(MaxEdge.X, MaxEdge.Y, a.MaxEdge.Z);
|
||||
VoxelArea b(min, max);
|
||||
if(b.getVolume() != 0)
|
||||
result.push_back(b);
|
||||
take(min, max);
|
||||
}
|
||||
|
||||
// Take bottom area, X inclusive
|
||||
{
|
||||
v3s16 min(MinEdge.X, MinEdge.Y, a.MinEdge.Z);
|
||||
v3s16 max(MaxEdge.X, a.MinEdge.Y-1, a.MaxEdge.Z);
|
||||
VoxelArea b(min, max);
|
||||
if(b.getVolume() != 0)
|
||||
result.push_back(b);
|
||||
take(min, max);
|
||||
}
|
||||
|
||||
// Take left area, non-inclusive
|
||||
{
|
||||
v3s16 min(MinEdge.X, a.MinEdge.Y, a.MinEdge.Z);
|
||||
v3s16 max(a.MinEdge.X-1, a.MaxEdge.Y, a.MaxEdge.Z);
|
||||
VoxelArea b(min, max);
|
||||
if(b.getVolume() != 0)
|
||||
result.push_back(b);
|
||||
take(min, max);
|
||||
}
|
||||
|
||||
// Take right area, non-inclusive
|
||||
{
|
||||
v3s16 min(a.MaxEdge.X+1, a.MinEdge.Y, a.MinEdge.Z);
|
||||
v3s16 max(MaxEdge.X, a.MaxEdge.Y, a.MaxEdge.Z);
|
||||
VoxelArea b(min, max);
|
||||
if(b.getVolume() != 0)
|
||||
result.push_back(b);
|
||||
take(min, max);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -344,30 +334,34 @@ public:
|
|||
<< "=" << getVolume();
|
||||
}
|
||||
|
||||
// Edges are inclusive
|
||||
/// Minimum edge of the area (inclusive)
|
||||
/// @warning read-only!
|
||||
v3s16 MinEdge = v3s16(1,1,1);
|
||||
/// Maximum edge of the area (inclusive)
|
||||
/// @warning read-only!
|
||||
v3s16 MaxEdge;
|
||||
|
||||
private:
|
||||
void cacheExtent()
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
// unused
|
||||
#define VOXELFLAG_UNUSED (1 << 0)
|
||||
// no data about that node
|
||||
#define VOXELFLAG_NO_DATA (1 << 1)
|
||||
// Algorithm-dependent
|
||||
#define VOXELFLAG_CHECKED1 (1 << 2)
|
||||
// Algorithm-dependent
|
||||
#define VOXELFLAG_CHECKED2 (1 << 3)
|
||||
// Algorithm-dependent
|
||||
#define VOXELFLAG_CHECKED3 (1 << 4)
|
||||
// Algorithm-dependent
|
||||
#define VOXELFLAG_CHECKED4 (1 << 5)
|
||||
enum : u8 {
|
||||
VOXELFLAG_NO_DATA = 1 << 0, // no data about that node
|
||||
VOXELFLAG_CHECKED1 = 1 << 1, // Algorithm-dependent
|
||||
VOXELFLAG_CHECKED2 = 1 << 2, // Algorithm-dependent
|
||||
VOXELFLAG_CHECKED3 = 1 << 3, // Algorithm-dependent
|
||||
VOXELFLAG_CHECKED4 = 1 << 4, // Algorithm-dependent
|
||||
};
|
||||
|
||||
enum VoxelPrintMode
|
||||
{
|
||||
|
@ -414,7 +408,7 @@ public:
|
|||
|
||||
return m_data[index];
|
||||
}
|
||||
MapNode getNodeNoExNoEmerge(const v3s16 &p)
|
||||
MapNode getNodeNoExNoEmerge(const v3s16 &p) const
|
||||
{
|
||||
if (!m_area.contains(p))
|
||||
return {CONTENT_IGNORE};
|
||||
|
@ -430,7 +424,7 @@ public:
|
|||
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);
|
||||
|
||||
|
@ -483,10 +477,13 @@ public:
|
|||
virtual void clear();
|
||||
|
||||
void print(std::ostream &o, const NodeDefManager *nodemgr,
|
||||
VoxelPrintMode mode=VOXELPRINT_MATERIAL);
|
||||
VoxelPrintMode mode=VOXELPRINT_MATERIAL) const;
|
||||
|
||||
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
|
||||
dst_area.getExtent() <= src_area.getExtent()
|
||||
|
@ -496,13 +493,7 @@ public:
|
|||
|
||||
// Copy data
|
||||
void copyTo(MapNode *dst, const VoxelArea& dst_area,
|
||||
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size);
|
||||
|
||||
/*
|
||||
Algorithms
|
||||
*/
|
||||
|
||||
void clearFlag(u8 flag);
|
||||
v3s16 dst_pos, v3s16 from_pos, const v3s16 &size) const;
|
||||
|
||||
/*
|
||||
Member variables
|
||||
|
@ -510,13 +501,12 @@ public:
|
|||
|
||||
/*
|
||||
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;
|
||||
|
||||
/*
|
||||
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]
|
||||
*/
|
||||
MapNode *m_data = nullptr;
|
||||
|
|
|
@ -943,14 +943,18 @@ bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef,
|
|||
* The areas do not overlap.
|
||||
* Compatible with type 'direction'.
|
||||
*/
|
||||
const VoxelArea block_pad[] = {
|
||||
VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), //X+
|
||||
VoxelArea(v3s16(1, 15, 0), v3s16(14, 15, 15)), //Y+
|
||||
VoxelArea(v3s16(1, 1, 15), v3s16(14, 14, 15)), //Z+
|
||||
VoxelArea(v3s16(1, 1, 0), v3s16(14, 14, 0)), //Z-
|
||||
VoxelArea(v3s16(1, 0, 0), v3s16(14, 0, 15)), //Y-
|
||||
VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) //X-
|
||||
#define B_1 (MAP_BLOCKSIZE - 1)
|
||||
#define B_2 (MAP_BLOCKSIZE - 2)
|
||||
const static VoxelArea block_pad[] = {
|
||||
VoxelArea({B_1, 0, 0}, {B_1, B_1, B_1}), //X+
|
||||
VoxelArea({1, B_1, 0}, {B_2, B_1, B_1}), //Y+
|
||||
VoxelArea({1, 1, B_1}, {B_2, B_2, B_1}), //Z+
|
||||
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.
|
||||
|
|
Loading…
Add table
Reference in a new issue