From 84fb663d6cce83805a93132b591f4627c3505f39 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 17 Jun 2023 18:05:54 +0200 Subject: [PATCH] Add VoxelArea::intersect() --- src/unittest/test_voxelarea.cpp | 16 ++++++++++++++++ src/voxel.h | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/unittest/test_voxelarea.cpp b/src/unittest/test_voxelarea.cpp index a79c9778e..386fe499c 100644 --- a/src/unittest/test_voxelarea.cpp +++ b/src/unittest/test_voxelarea.cpp @@ -38,6 +38,7 @@ public: void test_equal(); void test_plus(); void test_minor(); + void test_intersect(); void test_index_xyz_all_pos(); void test_index_xyz_x_neg(); void test_index_xyz_y_neg(); @@ -74,6 +75,7 @@ void TestVoxelArea::runTests(IGameDef *gamedef) TEST(test_equal); TEST(test_plus); TEST(test_minor); + TEST(test_intersect); TEST(test_index_xyz_all_pos); TEST(test_index_xyz_x_neg); TEST(test_index_xyz_y_neg); @@ -210,6 +212,20 @@ void TestVoxelArea::test_minor() VoxelArea(v3s16(-10, -10, -45), v3s16(100, 100, 65))); } +void TestVoxelArea::test_intersect() +{ + VoxelArea v1({-10, -10, -10}, {10, 10, 10}); + VoxelArea v2({1, 2, 3}, {4, 5, 6}); + VoxelArea v3({11, 11, 11}, {11, 11, 11}); + VoxelArea v4({-11, -2, -10}, {10, 2, 11}); + UASSERT(v2.intersect(v1) == v2); + UASSERT(v1.intersect(v2) == v2.intersect(v1)); + UASSERT(v1.intersect(v3).hasEmptyExtent()); + UASSERT(v3.intersect(v1) == v1.intersect(v3)); + UASSERT(v1.intersect(v4) == + VoxelArea({-10, -2, -10}, {10, 2, 10})); +} + void TestVoxelArea::test_index_xyz_all_pos() { VoxelArea v1; diff --git a/src/voxel.h b/src/voxel.h index 16540e595..7a36b10bf 100644 --- a/src/voxel.h +++ b/src/voxel.h @@ -183,6 +183,31 @@ public: return {MinEdge-off, MaxEdge-off}; } + /* + Returns the intersection of this area and `a`. + */ + VoxelArea intersect(const VoxelArea &a) const + { + // This is an example of an operation that would be simpler with + // non-inclusive edges, but oh well. + VoxelArea ret; + + if (a.MaxEdge.X < MinEdge.X || a.MinEdge.X > MaxEdge.X) + return VoxelArea(); + if (a.MaxEdge.Y < MinEdge.Y || a.MinEdge.Y > MaxEdge.Y) + return VoxelArea(); + if (a.MaxEdge.Z < MinEdge.Z || a.MinEdge.Z > MaxEdge.Z) + return VoxelArea(); + ret.MinEdge.X = std::max(a.MinEdge.X, MinEdge.X); + ret.MaxEdge.X = std::min(a.MaxEdge.X, MaxEdge.X); + ret.MinEdge.Y = std::max(a.MinEdge.Y, MinEdge.Y); + ret.MaxEdge.Y = std::min(a.MaxEdge.Y, MaxEdge.Y); + ret.MinEdge.Z = std::max(a.MinEdge.Z, MinEdge.Z); + ret.MaxEdge.Z = std::min(a.MaxEdge.Z, MaxEdge.Z); + + return ret; + } + /* Returns 0-6 non-overlapping areas that can be added to a to make up this area.