From 46960825ef8c3ba1d722e92353f5c08cbdf2c5f8 Mon Sep 17 00:00:00 2001 From: unelsson Date: Mon, 4 Oct 2021 00:20:39 +0300 Subject: [PATCH] Various terrain selection and editmode dragging fixes --- apps/opencs/view/render/terrainselection.cpp | 79 +++++-------------- apps/opencs/view/render/terrainselection.hpp | 10 +-- apps/opencs/view/render/terrainshapemode.cpp | 39 ++++----- apps/opencs/view/render/terrainshapemode.hpp | 2 +- .../opencs/view/render/terraintexturemode.cpp | 37 ++++++--- .../opencs/view/render/terraintexturemode.hpp | 2 +- 6 files changed, 68 insertions(+), 101 deletions(-) diff --git a/apps/opencs/view/render/terrainselection.cpp b/apps/opencs/view/render/terrainselection.cpp index 8b855fc91b..03009e8701 100644 --- a/apps/opencs/view/render/terrainselection.cpp +++ b/apps/opencs/view/render/terrainselection.cpp @@ -8,7 +8,6 @@ #include #include -#include #include "../../model/world/cellcoordinates.hpp" #include "../../model/world/columnimp.hpp" @@ -18,7 +17,7 @@ #include "worldspacewidget.hpp" CSVRender::TerrainSelection::TerrainSelection(osg::Group* parentNode, WorldspaceWidget *worldspaceWidget, TerrainSelectionType type): -mParentNode(parentNode), mWorldspaceWidget (worldspaceWidget), mDraggedOperationFlag(false), mSelectionType(type) +mParentNode(parentNode), mWorldspaceWidget (worldspaceWidget), mSelectionType(type) { mGeometry = new osg::Geometry(); @@ -47,19 +46,25 @@ void CSVRender::TerrainSelection::onlySelect(const std::vector>& localPositions, bool toggleInProgress) +void CSVRender::TerrainSelection::addSelect(const std::vector>& localPositions) { - handleSelection(localPositions, toggleInProgress, SelectionMethod::AddSelect); + handleSelection(localPositions, SelectionMethod::AddSelect); } -void CSVRender::TerrainSelection::removeSelect(const std::vector>& localPositions, bool toggleInProgress) +void CSVRender::TerrainSelection::removeSelect(const std::vector>& localPositions) { - handleSelection(localPositions, toggleInProgress, SelectionMethod::RemoveSelect); + handleSelection(localPositions, SelectionMethod::RemoveSelect); } -void CSVRender::TerrainSelection::toggleSelect(const std::vector>& localPositions, bool toggleInProgress) +void CSVRender::TerrainSelection::toggleSelect(const std::vector>& localPositions) { - handleSelection(localPositions, toggleInProgress, SelectionMethod::ToggleSelect); + handleSelection(localPositions, SelectionMethod::ToggleSelect); +} + +void CSVRender::TerrainSelection::clearTemporarySelection() +{ + mTemporarySelection.clear(); + update(); } void CSVRender::TerrainSelection::activate() @@ -202,56 +207,13 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod) +void CSVRender::TerrainSelection::handleSelection(const std::vector>& localPositions, SelectionMethod selectionMethod) { - if (toggleInProgress) + for (auto const& localPos : localPositions) { - for (auto const& localPos : localPositions) - { - auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos); - mDraggedOperationFlag = true; + auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos); - if (iterTemp == mTemporarySelection.end()) - { - auto iter = std::find(mSelection.begin(), mSelection.end(), localPos); - - switch (selectionMethod) - { - case SelectionMethod::AddSelect: - if (iter == mSelection.end()) - { - mSelection.emplace_back(localPos); - } - - break; - case SelectionMethod::RemoveSelect: - if (iter != mSelection.end()) - { - mSelection.erase(iter); - } - - break; - case SelectionMethod::ToggleSelect: - if (iter == mSelection.end()) - { - mSelection.emplace_back(localPos); - } - else - { - mSelection.erase(iter); - } - - break; - default: break; - } - } - - mTemporarySelection.push_back(localPos); - } - } - else if (mDraggedOperationFlag == false) - { - for (auto const& localPos : localPositions) + if (iterTemp == mTemporarySelection.end()) { const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos); @@ -285,14 +247,9 @@ void CSVRender::TerrainSelection::handleSelection(const std::vector> &localPositions); - void addSelect(const std::vector>& localPositions, bool toggleInProgress); - void removeSelect(const std::vector>& localPositions, bool toggleInProgress); - void toggleSelect(const std::vector> &localPositions, bool toggleInProgress); + void addSelect(const std::vector>& localPositions); + void removeSelect(const std::vector>& localPositions); + void toggleSelect(const std::vector> &localPositions); + void clearTemporarySelection(); void activate(); void deactivate(); @@ -64,7 +65,7 @@ namespace CSVRender private: - void handleSelection(const std::vector>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod); + void handleSelection(const std::vector>& localPositions, SelectionMethod selectionMethod); bool noCell(const std::string& cellId); @@ -81,7 +82,6 @@ namespace CSVRender osg::ref_ptr mSelectionNode; std::vector> mSelection; // Global terrain selection coordinate in either vertex or texture units std::vector> mTemporarySelection; // Used during toggle to compare the most recent drag operation - bool mDraggedOperationFlag; //true during drag operation, false when click-operation TerrainSelectionType mSelectionType; }; } diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index 0504944954..21359a8684 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -106,16 +106,6 @@ void CSVRender::TerrainShapeMode::primaryEditPressed(const WorldspaceHitResult& editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true); applyTerrainEditChanges(); } - - if (mDragMode == InteractionType_PrimarySelect) - { - selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true); - } - - if (mDragMode == InteractionType_SecondarySelect) - { - selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true); - } } clearTransientEdits(); } @@ -124,7 +114,7 @@ void CSVRender::TerrainShapeMode::primarySelectPressed(const WorldspaceHitResult { if(hit.hit && hit.tag == nullptr) { - selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, false); + selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0); } } @@ -132,7 +122,7 @@ void CSVRender::TerrainShapeMode::secondarySelectPressed(const WorldspaceHitResu { if(hit.hit && hit.tag == nullptr) { - selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, false); + selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1); } } @@ -167,8 +157,8 @@ bool CSVRender::TerrainShapeMode::primarySelectStartDrag (const QPoint& pos) mDragMode = InteractionType_None; return false; } - selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true); - return false; + selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0); + return true; } bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos) @@ -180,8 +170,8 @@ bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos) mDragMode = InteractionType_None; return false; } - selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true); - return false; + selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1); + return true; } void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) @@ -200,13 +190,13 @@ void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY, if (mDragMode == InteractionType_PrimarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true); + if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0); } if (mDragMode == InteractionType_SecondarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true); + if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1); } } @@ -217,12 +207,17 @@ void CSVRender::TerrainShapeMode::dragCompleted(const QPoint& pos) applyTerrainEditChanges(); clearTransientEdits(); } + if (mDragMode == InteractionType_PrimarySelect || mDragMode == InteractionType_SecondarySelect) + { + mTerrainShapeSelection->clearTemporarySelection(); + } } void CSVRender::TerrainShapeMode::dragAborted() { clearTransientEdits(); + mDragMode = InteractionType_None; } void CSVRender::TerrainShapeMode::dragWheel (int diff, double speedFactor) @@ -1076,7 +1071,7 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob } } -void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& vertexCoords, unsigned char selectMode, bool dragOperation) +void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& vertexCoords, unsigned char selectMode) { int r = mBrushSize / 2; std::vector> selections; @@ -1136,11 +1131,11 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& if (selectAction == "Select only") mTerrainShapeSelection->onlySelect(selections); else if (selectAction == "Add to selection") - mTerrainShapeSelection->addSelect(selections, dragOperation); + mTerrainShapeSelection->addSelect(selections); else if (selectAction == "Remove from selection") - mTerrainShapeSelection->removeSelect(selections, dragOperation); + mTerrainShapeSelection->removeSelect(selections); else if (selectAction == "Invert selection") - mTerrainShapeSelection->toggleSelect(selections, dragOperation); + mTerrainShapeSelection->toggleSelect(selections); } void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, diff --git a/apps/opencs/view/render/terrainshapemode.hpp b/apps/opencs/view/render/terrainshapemode.hpp index abc4b8aba8..8b40483be4 100644 --- a/apps/opencs/view/render/terrainshapemode.hpp +++ b/apps/opencs/view/render/terrainshapemode.hpp @@ -142,7 +142,7 @@ namespace CSVRender 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); + void selectTerrainShapes (const std::pair& vertexCoords, unsigned char selectMode); /// Push terrain shape edits to command macro void pushEditToCommand (const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp index dfcc29ae01..5f1cc354f6 100644 --- a/apps/opencs/view/render/terraintexturemode.cpp +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -129,7 +129,7 @@ void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResu { if(hit.hit && hit.tag == nullptr) { - selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, false); + selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0); } } @@ -137,7 +137,7 @@ void CSVRender::TerrainTextureMode::secondarySelectPressed(const WorldspaceHitRe { if(hit.hit && hit.tag == nullptr) { - selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, false); + selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1); } } @@ -188,8 +188,8 @@ bool CSVRender::TerrainTextureMode::primarySelectStartDrag (const QPoint& pos) mDragMode = InteractionType_None; return false; } - selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, true); - return false; + selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0); + return true; } bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos) @@ -201,8 +201,8 @@ bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos) mDragMode = InteractionType_None; return false; } - selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, true); - return false; + selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1); + return true; } void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) @@ -225,13 +225,13 @@ void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diff if (mDragMode == InteractionType_PrimarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, true); + if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0); } if (mDragMode == InteractionType_SecondarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, true); + if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1); } } @@ -251,6 +251,8 @@ void CSVRender::TerrainTextureMode::dragCompleted(const QPoint& pos) mIsEditing = false; } } + + mTerrainTextureSelection->clearTemporarySelection(); } void CSVRender::TerrainTextureMode::dragAborted() @@ -496,7 +498,7 @@ bool CSVRender::TerrainTextureMode::isInCellSelection(int globalSelectionX, int } -void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair& texCoords, unsigned char selectMode, bool dragOperation) +void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair& texCoords, unsigned char selectMode) { int r = mBrushSize / 2; std::vector> selections; @@ -559,8 +561,21 @@ void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::paironlySelect(selections); - if(selectMode == 1) mTerrainTextureSelection->toggleSelect(selections, dragOperation); + std::string selectAction; + + if (selectMode == 0) + selectAction = CSMPrefs::get()["3D Scene Editing"]["primary-select-action"].toString(); + else + selectAction = CSMPrefs::get()["3D Scene Editing"]["secondary-select-action"].toString(); + + if (selectAction == "Select only") + mTerrainTextureSelection->onlySelect(selections); + else if (selectAction == "Add to selection") + mTerrainTextureSelection->addSelect(selections); + else if (selectAction == "Remove from selection") + mTerrainTextureSelection->removeSelect(selections); + else if (selectAction == "Invert selection") + mTerrainTextureSelection->toggleSelect(selections); } void CSVRender::TerrainTextureMode::pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document, diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index e0c6e4b40f..06c95e3d79 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -95,7 +95,7 @@ namespace CSVRender bool isInCellSelection(int globalSelectionX, int globalSelectionY); /// \brief Handle brush mechanics for texture selection - void selectTerrainTextures (const std::pair& texCoords, unsigned char selectMode, bool dragOperation); + void selectTerrainTextures (const std::pair& texCoords, unsigned char selectMode); /// \brief Push texture edits to command macro void pushEditToCommand (CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document,