From aeb0ccff90bbb6655dab2ad08b1a70d859dc25f8 Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Mon, 4 Nov 2019 12:16:08 +0200 Subject: [PATCH 1/3] Allow selecting cell edges everywhere --- apps/opencs/view/render/terrainshapemode.cpp | 23 ++++++++++++++++---- apps/opencs/view/render/terrainshapemode.hpp | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index af97e4d8f7..d7b4684d6b 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -1038,6 +1038,21 @@ bool CSVRender::TerrainShapeMode::isInCellSelection(int globalSelectionX, int gl return false; } +void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int globalSelectionY, std::vector>* selections) +{ + if (isInCellSelection(globalSelectionX, globalSelectionY)) selections->emplace_back(globalSelectionX, globalSelectionY); + else + { + int moduloX = globalSelectionX % (ESM::Land::LAND_SIZE - 1); + int moduloY = globalSelectionY % (ESM::Land::LAND_SIZE - 1); + bool xIsAtCellBorder = moduloX == 0; + bool yIsAtCellBorder = moduloY == 0; + if (isInCellSelection(globalSelectionX - 1, globalSelectionY) && xIsAtCellBorder && !yIsAtCellBorder) selections->emplace_back(globalSelectionX, globalSelectionY); + if (isInCellSelection(globalSelectionX, globalSelectionY - 1) && !xIsAtCellBorder && yIsAtCellBorder) selections->emplace_back(globalSelectionX, globalSelectionY); + if (isInCellSelection(globalSelectionX - 1, globalSelectionY - 1) && xIsAtCellBorder && yIsAtCellBorder) selections->emplace_back(globalSelectionX, globalSelectionY); + } +} + void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& vertexCoords, unsigned char selectMode, bool dragOperation) { int r = mBrushSize / 2; @@ -1045,7 +1060,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& if (mBrushShape == CSVWidget::BrushShape_Point) { - if (isInCellSelection(vertexCoords.first, vertexCoords.second)) selections.emplace_back(vertexCoords.first, vertexCoords.second); + handleSelection(vertexCoords.first, vertexCoords.second, &selections); } if (mBrushShape == CSVWidget::BrushShape_Square) @@ -1054,7 +1069,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& { for(int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) { - if (isInCellSelection(i, j)) selections.emplace_back(i, j); + handleSelection(i, j, &selections); } } } @@ -1068,7 +1083,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& int distanceX = abs(i - vertexCoords.first); int distanceY = abs(j - vertexCoords.second); int distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); - if (isInCellSelection(i, j) && distance <= r) selections.emplace_back(i, j); + if (distance <= r) handleSelection(i, j, &selections); } } } @@ -1081,7 +1096,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& { std::pair localVertexCoords (vertexCoords.first + value.first, vertexCoords.second + value.second); std::string cellId (CSMWorld::CellCoordinates::vertexGlobalToCellId(localVertexCoords)); - if (isInCellSelection(localVertexCoords.first, localVertexCoords.second)) selections.emplace_back(localVertexCoords); + handleSelection(localVertexCoords.first, localVertexCoords.second, &selections); } } } diff --git a/apps/opencs/view/render/terrainshapemode.hpp b/apps/opencs/view/render/terrainshapemode.hpp index 605827c9e4..ce2ea5465e 100644 --- a/apps/opencs/view/render/terrainshapemode.hpp +++ b/apps/opencs/view/render/terrainshapemode.hpp @@ -134,6 +134,9 @@ namespace CSVRender /// Check if global selection coordinate belongs to cell in view bool isInCellSelection(int globalSelectionX, int globalSelectionY); + /// Select vertex at global selection coordinate + void handleSelection(int globalSelectionX, int globalSelectionY, std::vector>* selections); + /// Handle brush mechanics for terrain shape selection void selectTerrainShapes (const std::pair& vertexCoords, unsigned char selectMode, bool dragOperation); From 45d43045eb0032c970e620bdaa3f882378f158c2 Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Mon, 4 Nov 2019 12:29:37 +0200 Subject: [PATCH 2/3] Remove unused std::string --- apps/opencs/view/render/terrainshapemode.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index d7b4684d6b..ee6492a87d 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -1095,7 +1095,6 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& for(auto const& value: mCustomBrushShape) { std::pair localVertexCoords (vertexCoords.first + value.first, vertexCoords.second + value.second); - std::string cellId (CSMWorld::CellCoordinates::vertexGlobalToCellId(localVertexCoords)); handleSelection(localVertexCoords.first, localVertexCoords.second, &selections); } } From 120583f443f5cec487f235dd2c07b0892d2ecf27 Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Thu, 14 Nov 2019 11:28:49 +0200 Subject: [PATCH 3/3] optimize isInCellSelection calls --- apps/opencs/view/render/terrainshapemode.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index ee6492a87d..e73887615c 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -1047,9 +1047,16 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob int moduloY = globalSelectionY % (ESM::Land::LAND_SIZE - 1); bool xIsAtCellBorder = moduloX == 0; bool yIsAtCellBorder = moduloY == 0; - if (isInCellSelection(globalSelectionX - 1, globalSelectionY) && xIsAtCellBorder && !yIsAtCellBorder) selections->emplace_back(globalSelectionX, globalSelectionY); - if (isInCellSelection(globalSelectionX, globalSelectionY - 1) && !xIsAtCellBorder && yIsAtCellBorder) selections->emplace_back(globalSelectionX, globalSelectionY); - if (isInCellSelection(globalSelectionX - 1, globalSelectionY - 1) && xIsAtCellBorder && yIsAtCellBorder) selections->emplace_back(globalSelectionX, globalSelectionY); + if (!xIsAtCellBorder && !yIsAtCellBorder) + return; + int selectionX = globalSelectionX; + int selectionY = globalSelectionY; + if (xIsAtCellBorder) + selectionX--; + if (yIsAtCellBorder) + selectionY--; + if (isInCellSelection(selectionX, selectionY)) + selections->emplace_back(globalSelectionX, globalSelectionY); } }