diff --git a/apps/opencs/model/world/cellcoordinates.cpp b/apps/opencs/model/world/cellcoordinates.cpp index dbe90b906..1e545e38d 100644 --- a/apps/opencs/model/world/cellcoordinates.cpp +++ b/apps/opencs/model/world/cellcoordinates.cpp @@ -5,8 +5,16 @@ #include #include +#include #include +namespace +{ + const int cellSize {ESM::Land::REAL_SIZE}; + const int landSize {ESM::Land::LAND_SIZE}; + const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE}; +} + CSMWorld::CellCoordinates::CellCoordinates() : mX (0), mY (0) {} CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {} @@ -32,11 +40,13 @@ CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move (int x, int y) const std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) const { // we ignore the worldspace for now, since there is only one (will change in 1.1) - std::ostringstream stream; + return generateId(mX, mY); +} - stream << "#" << mX << " " << mY; - - return stream.str(); +std::string CSMWorld::CellCoordinates::generateId (int x, int y) +{ + std::string cellId = "#" + std::to_string(x) + " " + std::to_string(y); + return cellId; } bool CSMWorld::CellCoordinates::isExteriorCell (const std::string& id) @@ -66,6 +76,50 @@ std::pair CSMWorld::CellCoordinates::coordinatesToCellIndex (float x, return std::make_pair (std::floor (x / Constants::CellSizeInUnits), std::floor (y / Constants::CellSizeInUnits)); } +std::pair CSMWorld::CellCoordinates::toTextureCoords(osg::Vec3d worldPos) +{ + const auto xd = static_cast(worldPos.x() * landTextureSize / cellSize - 0.25f); + const auto yd = static_cast(worldPos.y() * landTextureSize / cellSize + 0.25f); + + const auto x = static_cast(std::floor(xd)); + const auto y = static_cast(std::floor(yd)); + + return std::make_pair(x, y); +} + +std::pair CSMWorld::CellCoordinates::toVertexCoords(osg::Vec3d worldPos) +{ + const auto xd = static_cast(worldPos.x() * (landSize - 1) / cellSize + 0.5f); + const auto yd = static_cast(worldPos.y() * (landSize - 1) / cellSize + 0.5f); + + const auto x = static_cast(std::floor(xd)); + const auto y = static_cast(std::floor(yd)); + + return std::make_pair(x, y); +} + +float CSMWorld::CellCoordinates::textureSelectionToWorldCoords(int pos) +{ + return cellSize * static_cast(pos) / landTextureSize; +} + +float CSMWorld::CellCoordinates::vertexSelectionToWorldCoords(int pos) +{ + return cellSize * static_cast(pos) / (landSize - 1); +} + +int CSMWorld::CellCoordinates::vertexSelectionToInCellCoords(int pos) +{ + return static_cast(pos - std::floor(static_cast(pos) / (landSize - 1)) * (landSize - 1)); +} + +std::string CSMWorld::CellCoordinates::vertexGlobalToCellId(std::pair vertexGlobal) +{ + int x = std::floor(static_cast(vertexGlobal.first) / (landSize - 1)); + int y = std::floor(static_cast(vertexGlobal.second) / (landSize - 1)); + return generateId(x, y); +} + bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right) { return left.getX()==right.getX() && left.getY()==right.getY(); diff --git a/apps/opencs/model/world/cellcoordinates.hpp b/apps/opencs/model/world/cellcoordinates.hpp index 9207aede5..2bd4840be 100644 --- a/apps/opencs/model/world/cellcoordinates.hpp +++ b/apps/opencs/model/world/cellcoordinates.hpp @@ -7,6 +7,8 @@ #include +#include + namespace CSMWorld { class CellCoordinates @@ -29,6 +31,9 @@ namespace CSMWorld CellCoordinates move (int x, int y) const; ///< Return a copy of *this, moved by the given offset. + ///Generate cell id string from x and y coordinates + static std::string generateId (int x, int y); + std::string getId (const std::string& worldspace) const; ///< Return the ID for the cell at these coordinates. @@ -42,6 +47,24 @@ namespace CSMWorld /// \return cell coordinates such that given world coordinates are in it. static std::pair coordinatesToCellIndex (float x, float y); + + ///Converts worldspace coordinates to global texture selection, taking in account the texture offset. + static std::pair toTextureCoords(osg::Vec3d worldPos); + + ///Converts worldspace coordinates to global vertex selection. + static std::pair toVertexCoords(osg::Vec3d worldPos); + + ///Converts global texture coordinate to worldspace coordinate that is at the upper left corner of the selected texture. + static float textureSelectionToWorldCoords(int); + + ///Converts global vertex coordinate to worldspace coordinate + static float vertexSelectionToWorldCoords(int); + + ///Converts local cell's heightmap coordinates from the global vertex coordinate + static int vertexSelectionToInCellCoords(int); + + ///Converts global vertex coordinates to cell id + static std::string vertexGlobalToCellId(std::pair); }; bool operator== (const CellCoordinates& left, const CellCoordinates& right);