#include "cellcoordinates.hpp" #include #include #include #include #include #include #include CSMWorld::CellCoordinates::CellCoordinates() : mX(0) , mY(0) { } CSMWorld::CellCoordinates::CellCoordinates(int x, int y) : mX(x) , mY(y) { } CSMWorld::CellCoordinates::CellCoordinates(const std::pair& coordinates) : mX(coordinates.first) , mY(coordinates.second) { } int CSMWorld::CellCoordinates::getX() const { return mX; } int CSMWorld::CellCoordinates::getY() const { return mY; } CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move(int x, int y) const { return CellCoordinates(mX + x, mY + y); } 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) return generateId(mX, mY); } 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) { return (!id.empty() && id[0] == '#'); } bool CSMWorld::CellCoordinates::isExteriorCell(const ESM::RefId& id) { return id.startsWith("#"); } std::pair CSMWorld::CellCoordinates::fromId(const std::string& id) { // no worldspace for now, needs to be changed for 1.1 if (isExteriorCell(id)) { int x, y; char ignore; std::istringstream stream(id); if (stream >> ignore >> x >> y) return std::make_pair(CellCoordinates(x, y), true); } return std::make_pair(CellCoordinates(), false); } std::pair CSMWorld::CellCoordinates::coordinatesToCellIndex(float x, float y) { return std::make_pair(std::floor(x / Constants::CellSizeInUnits), std::floor(y / Constants::CellSizeInUnits)); } std::pair CSMWorld::CellCoordinates::toTextureCoords(const osg::Vec3d& worldPos) { const auto xd = static_cast(worldPos.x() * ESM::Land::LAND_TEXTURE_SIZE / ESM::Land::REAL_SIZE - 0.25f); const auto yd = static_cast(worldPos.y() * ESM::Land::LAND_TEXTURE_SIZE / ESM::Land::REAL_SIZE + 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(const osg::Vec3d& worldPos) { const auto xd = static_cast(worldPos.x() * (ESM::Land::LAND_SIZE - 1) / ESM::Land::REAL_SIZE + 0.5f); const auto yd = static_cast(worldPos.y() * (ESM::Land::LAND_SIZE - 1) / ESM::Land::REAL_SIZE + 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::textureGlobalXToWorldCoords(int textureGlobal) { return ESM::Land::REAL_SIZE * (static_cast(textureGlobal) + 0.25f) / ESM::Land::LAND_TEXTURE_SIZE; } float CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(int textureGlobal) { return ESM::Land::REAL_SIZE * (static_cast(textureGlobal) - 0.25f) / ESM::Land::LAND_TEXTURE_SIZE; } float CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(int vertexGlobal) { return ESM::Land::REAL_SIZE * static_cast(vertexGlobal) / (ESM::Land::LAND_SIZE - 1); } int CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(int vertexGlobal) { return static_cast(vertexGlobal - std::floor(static_cast(vertexGlobal) / (ESM::Land::LAND_SIZE - 1)) * (ESM::Land::LAND_SIZE - 1)); } std::string CSMWorld::CellCoordinates::textureGlobalToCellId(const std::pair& textureGlobal) { int x = std::floor(static_cast(textureGlobal.first) / ESM::Land::LAND_TEXTURE_SIZE); int y = std::floor(static_cast(textureGlobal.second) / ESM::Land::LAND_TEXTURE_SIZE); return generateId(x, y); } std::string CSMWorld::CellCoordinates::vertexGlobalToCellId(const std::pair& vertexGlobal) { int x = std::floor(static_cast(vertexGlobal.first) / (ESM::Land::LAND_SIZE - 1)); int y = std::floor(static_cast(vertexGlobal.second) / (ESM::Land::LAND_SIZE - 1)); return generateId(x, y); } bool CSMWorld::operator==(const CellCoordinates& left, const CellCoordinates& right) { return left.getX() == right.getX() && left.getY() == right.getY(); } bool CSMWorld::operator!=(const CellCoordinates& left, const CellCoordinates& right) { return !(left == right); } bool CSMWorld::operator<(const CellCoordinates& left, const CellCoordinates& right) { if (left.getX() < right.getX()) return true; if (left.getX() > right.getX()) return false; return left.getY() < right.getY(); } std::ostream& CSMWorld::operator<<(std::ostream& stream, const CellCoordinates& coordiantes) { return stream << coordiantes.getX() << ", " << coordiantes.getY(); }