diff --git a/include/doorkeeper/components/tilecoords.hpp b/include/doorkeeper/components/tilecoords.hpp index 1126f50..b5f87a2 100644 --- a/include/doorkeeper/components/tilecoords.hpp +++ b/include/doorkeeper/components/tilecoords.hpp @@ -48,6 +48,12 @@ namespace dk { CoordinateScalarType sub_mod ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure; CoordinateScalarType sub_div ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure; } //namespace implem + + template + CoordinateDistType to_index ( const Vector& parPos, const Vector& parUpper ) a_pure; + + template + CoordinateDistType to_index ( const TileCoords& parTC ) a_pure; } //namespace dk #include "doorkeeper/implem/tilecoords.inl" diff --git a/include/doorkeeper/implem/tilecoords.inl b/include/doorkeeper/implem/tilecoords.inl index 6b19bef..214634e 100644 --- a/include/doorkeeper/implem/tilecoords.inl +++ b/include/doorkeeper/implem/tilecoords.inl @@ -40,6 +40,32 @@ namespace dk { } } //namespace implem + template + inline CoordinateDistType to_index (const Vector& parPos, const Vector& parUpper) { + CoordinateDistType index = 0; + for (CoordinateDistType d = 0; d < D; ++d) { + auto pos = static_cast(parPos[D - 1 - d]); + for (CoordinateDistType p = 0; p < D - 1 - d; ++p) { + pos *= static_cast(parUpper[p] + 1); + } + + index += pos; + } + return index; + } + +#if defined(NDEBUG) + template <> + inline CoordinateDistType to_index<2> (const Vector<2>& parPos, const Vector<2>& parUpper) { + return parPos.y() * (parUpper.x() + 1) + parPos.x(); + } +#endif + + template + inline CoordinateDistType to_index (const TileCoords& parTC) { + return to_index(parTC.position(), parTC.upper()); + } + template TileCoords::TileCoords (const coords& parSize) : m_pos(CoordinateScalarType(0)), diff --git a/test/unit/tilecoords.cpp b/test/unit/tilecoords.cpp index 55c94ea..c496da3 100644 --- a/test/unit/tilecoords.cpp +++ b/test/unit/tilecoords.cpp @@ -140,3 +140,30 @@ TEST(back_forward, tilecoords) { EXPECT_EQ(coords4(69, 1934, 3, 0), test.position()); } } + +TEST(to_index, tilecoords) { + typedef dk::TileCoords<2> tcoords2; + typedef dk::TileCoords<2>::coords coords2; + + { + const coords2 max_coords(1000); + tcoords2 test(max_coords); + + EXPECT_EQ(0, dk::to_index(test)); + + ++test; + EXPECT_EQ(1, dk::to_index(test)); + + --test; + EXPECT_EQ(0, dk::to_index(test)); + + test += 1; + EXPECT_EQ(1, dk::to_index(test)); + + test += 1; + EXPECT_EQ(2, dk::to_index(test)); + + test += 1501; + EXPECT_EQ(1503, dk::to_index(test)); + } +}