From 8acfa2600f30d04f948fd6607711ca5babad3c91 Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Mon, 7 Oct 2019 02:57:09 +0300 Subject: [PATCH] Terrain shape editing related fixes --- CHANGELOG_PR.md | 2 + apps/opencs/model/world/columnimp.cpp | 4 +- apps/opencs/view/render/terrainshapemode.cpp | 121 +++++++++++------- apps/opencs/view/render/terrainshapemode.hpp | 27 ++-- apps/opencs/view/render/terrainstorage.cpp | 8 +- apps/opencs/view/render/terrainstorage.hpp | 4 +- apps/opencs/view/widget/brushshapes.hpp | 14 ++ .../view/widget/scenetoolshapebrush.cpp | 15 ++- .../view/widget/scenetoolshapebrush.hpp | 17 +-- 9 files changed, 126 insertions(+), 86 deletions(-) create mode 100644 apps/opencs/view/widget/brushshapes.hpp diff --git a/CHANGELOG_PR.md b/CHANGELOG_PR.md index 8862a8448..71677af50 100644 --- a/CHANGELOG_PR.md +++ b/CHANGELOG_PR.md @@ -40,6 +40,8 @@ New Features: New Editor Features: - "Faction Ranks" table for "Faction" records (#4209) +- Changes to height editing can be cancelled without changes to data (press esc to cancel) (#4840) +- Land heightmap/shape editing and vertex selection (#5170) Bug Fixes: - Scripted Items cannot be stacked anymore to avoid multiple script execution (#2969) diff --git a/apps/opencs/model/world/columnimp.cpp b/apps/opencs/model/world/columnimp.cpp index b202a97d9..e610ef223 100644 --- a/apps/opencs/model/world/columnimp.cpp +++ b/apps/opencs/model/world/columnimp.cpp @@ -89,10 +89,12 @@ namespace CSMWorld DataType values(Size, 0); - if (land.isDataLoaded(Land::DATA_WNAM)) + if (land.mDataTypes & Land::DATA_WNAM) { for (int i = 0; i < Size; ++i) + { values[i] = land.mWnam[i]; + } } QVariant variant; diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index 382bf186c..171ad5a27 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -18,6 +18,7 @@ #include #include +#include "../widget/brushshapes.hpp" #include "../widget/modebutton.hpp" #include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolshapebrush.hpp" @@ -44,14 +45,14 @@ CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent) : EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain | Mask_Reference, "Terrain land editing", parent), - mBrushSize(0), - mBrushShape(BrushShape_Point), + mBrushSize(1), + mBrushShape(CSVWidget::BrushShape_Point), mShapeBrushScenetool(0), mDragMode(InteractionType_None), mParentNode(parentNode), mIsEditing(false), mTotalDiffY(0), - mShapeEditTool(0), + mShapeEditTool(ShapeEditTool_Drag), mShapeEditToolStrength(8), mTargetHeight(0) { @@ -69,7 +70,7 @@ void CSVRender::TerrainShapeMode::activate(CSVWidget::SceneToolbar* toolbar) mShapeBrushScenetool = new CSVWidget::SceneToolShapeBrush (toolbar, "scenetoolshapebrush", getWorldspaceWidget().getDocument()); connect(mShapeBrushScenetool, SIGNAL (clicked()), mShapeBrushScenetool, SLOT (activate())); connect(mShapeBrushScenetool->mShapeBrushWindow, SIGNAL(passBrushSize(int)), this, SLOT(setBrushSize(int))); - connect(mShapeBrushScenetool->mShapeBrushWindow, SIGNAL(passBrushShape(int)), this, SLOT(setBrushShape(int))); + connect(mShapeBrushScenetool->mShapeBrushWindow, SIGNAL(passBrushShape(CSVWidget::BrushShape)), this, SLOT(setBrushShape(CSVWidget::BrushShape))); connect(mShapeBrushScenetool->mShapeBrushWindow->mSizeSliders->mBrushSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(setBrushSize(int))); connect(mShapeBrushScenetool->mShapeBrushWindow->mToolSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setShapeEditTool(int))); connect(mShapeBrushScenetool->mShapeBrushWindow->mToolStrengthSlider, SIGNAL(valueChanged(int)), this, SLOT(setShapeEditToolStrength(int))); @@ -94,12 +95,12 @@ void CSVRender::TerrainShapeMode::primaryEditPressed(const WorldspaceHitResult& if (hit.hit && hit.tag == 0) { - if (mShapeEditTool == 4) + if (mShapeEditTool == ShapeEditTool_Flatten) setFlattenToolTargetHeight(hit); - if (mDragMode == InteractionType_PrimaryEdit && mShapeEditTool > 0) + if (mDragMode == InteractionType_PrimaryEdit && mShapeEditTool != ShapeEditTool_Drag) { std::string cellId = getWorldspaceWidget().getCellId (hit.worldPos); - if (mShapeEditTool > 0) editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true); + editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true); applyTerrainEditChanges(); } @@ -149,7 +150,7 @@ bool CSVRender::TerrainShapeMode::primaryEditStartDrag (const QPoint& pos) { mEditingPos = hit.worldPos; mIsEditing = true; - if (mShapeEditTool == 4) + if (mShapeEditTool == ShapeEditTool_Flatten) setFlattenToolTargetHeight(hit); } @@ -194,8 +195,8 @@ void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY, WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); std::string cellId = getWorldspaceWidget().getCellId (hit.worldPos); mTotalDiffY += diffY; - if (mIsEditing == true && mShapeEditTool == 0) editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(mEditingPos), true); - if (mIsEditing == true && mShapeEditTool > 0) editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true); + if (mIsEditing == true && mShapeEditTool == ShapeEditTool_Drag) editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(mEditingPos), true); + if (mIsEditing == true && mShapeEditTool != ShapeEditTool_Drag) editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true); } if (mDragMode == InteractionType_PrimarySelect) @@ -256,6 +257,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); + int landMapLodColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandMapLodIndex); int landnormalsColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex); QUndoStack& undoStack = document.getUndoStack(); @@ -296,7 +298,9 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY()); undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); const CSMWorld::LandHeightsColumn::DataType landShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandMapLodColumn::DataType landMapLodPointer = landTable.data(landTable.getModelIndex(cellId, landMapLodColumn)).value(); CSMWorld::LandHeightsColumn::DataType landShapeNew(landShapePointer); + CSMWorld::LandMapLodColumn::DataType mapLodShapeNew(landMapLodPointer); for(int i = 0; i < ESM::Land::LAND_SIZE; ++i) { for(int j = 0; j < ESM::Land::LAND_SIZE; ++j) @@ -311,7 +315,15 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() } } } - if (allowLandShapeEditing(cellId) == true) pushEditToCommand(landShapeNew, document, landTable, cellId); + for(int i = 0; i < ESM::Land::LAND_GLOBAL_MAP_LOD_SIZE; ++i) + { + mapLodShapeNew[i] = landMapLodPointer[i]; //TO-DO: generate a new mWnam based on new heights + } + if (allowLandShapeEditing(cellId) == true) + { + pushEditToCommand(landShapeNew, document, landTable, cellId); + pushLodToCommand(mapLodShapeNew, document, landTable, cellId); + } } for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) @@ -358,9 +370,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() v2.z() = 0; } - normal.y() = v1.z()*v2.x() - v1.x()*v2.z(); - normal.x() = v1.y()*v2.z() - v1.z()*v2.y(); - normal.z() = v1.x()*v2.y() - v1.y()*v2.x(); + normal = v1 ^ v2; hyp = normal.length() / 127.0f; @@ -388,22 +398,22 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair if (CSVRender::PagedWorldspaceWidget *paged = dynamic_cast (&getWorldspaceWidget())) { - if (mShapeEditTool == 0) paged->resetAllAlteredHeights(); + if (mShapeEditTool == ShapeEditTool_Drag) paged->resetAllAlteredHeights(); } if(allowLandShapeEditing(cellId)==true) { - if (mBrushShape == BrushShape_Point) + if (mBrushShape == CSVWidget::BrushShape_Point) { int x = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.first); int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.second); - if (mShapeEditTool == 0) alterHeight(cellCoords, x, y, mTotalDiffY); - if (mShapeEditTool == 1 || mShapeEditTool == 2) alterHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == 3) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == 4) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, mTotalDiffY); + if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) alterHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } - if (mBrushShape == BrushShape_Square) + if (mBrushShape == CSVWidget::BrushShape_Square) { for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { @@ -413,15 +423,15 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair cellCoords = CSMWorld::CellCoordinates::fromId(cellId).first; int x = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(i); int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(j); - if (mShapeEditTool == 0) alterHeight(cellCoords, x, y, mTotalDiffY); - if (mShapeEditTool == 1 || mShapeEditTool == 2) alterHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == 3) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == 4) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, mTotalDiffY); + if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) alterHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } } } - if (mBrushShape == BrushShape_Circle) + if (mBrushShape == CSVWidget::BrushShape_Circle) { for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { @@ -436,18 +446,19 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(j); float distancePerRadius = 1.0f * distance / r; float smoothedByDistance = 0.0f; - if (mShapeEditTool == 0) smoothedByDistance = mTotalDiffY - mTotalDiffY * (3 * distancePerRadius * distancePerRadius - 2 * distancePerRadius * distancePerRadius * distancePerRadius); - if (mShapeEditTool == 1 || mShapeEditTool == 2) smoothedByDistance = (r + mShapeEditToolStrength) - (r + mShapeEditToolStrength) * (3 * distancePerRadius * distancePerRadius - 2 * distancePerRadius * distancePerRadius * distancePerRadius); + if (mShapeEditTool == ShapeEditTool_Drag) smoothedByDistance = mTotalDiffY - mTotalDiffY * (3 * distancePerRadius * distancePerRadius - 2 * distancePerRadius * distancePerRadius * distancePerRadius); + if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) smoothedByDistance = (r + mShapeEditToolStrength) - (r + mShapeEditToolStrength) * (3 * distancePerRadius * distancePerRadius - 2 * distancePerRadius * distancePerRadius * distancePerRadius); if (distance <= r) { - if (mShapeEditTool >= 0 && mShapeEditTool < 3) alterHeight(cellCoords, x, y, smoothedByDistance); - if (mShapeEditTool == 3) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == 4) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Drag || mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) + alterHeight(cellCoords, x, y, smoothedByDistance); + if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } } } } - if (mBrushShape == BrushShape_Custom) + if (mBrushShape == CSVWidget::BrushShape_Custom) { if(!mCustomBrushShape.empty()) { @@ -457,10 +468,10 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair cellCoords = CSMWorld::CellCoordinates::fromId(cellId).first; int x = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.first + value.first); int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.second + value.second); - if (mShapeEditTool == 0) alterHeight(cellCoords, x, y, mTotalDiffY); - if (mShapeEditTool == 1 || mShapeEditTool == 2) alterHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == 3) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == 4) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, mTotalDiffY); + if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) alterHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } } } @@ -506,7 +517,7 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c if (useTool) { mAlteredCells.emplace_back(cellCoords); - if (mShapeEditTool == 0) + if (mShapeEditTool == ShapeEditTool_Drag) { // Get distance from modified land, alter land change based on zoom osg::Vec3d eye, center, up; @@ -514,9 +525,9 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c osg::Vec3d distance = eye - mEditingPos; alteredHeight = alteredHeight * (distance.length() / 500); } - if (mShapeEditTool == 1) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; - if (mShapeEditTool == 2) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) - alteredHeight; - if (mShapeEditTool == 3) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; + if (mShapeEditTool == ShapeEditTool_PaintToRaise) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; + if (mShapeEditTool == ShapeEditTool_PaintToLower) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) - alteredHeight; + if (mShapeEditTool == ShapeEditTool_Smooth) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; } if (inCellX != 0 && inCellY != 0 && inCellX != ESM::Land::LAND_SIZE - 1 && inCellY != ESM::Land::LAND_SIZE - 1) @@ -1037,12 +1048,12 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& int r = mBrushSize / 2; std::vector> selections; - if (mBrushShape == BrushShape_Point) + if (mBrushShape == CSVWidget::BrushShape_Point) { selections.emplace_back(vertexCoords); } - if (mBrushShape == BrushShape_Square) + if (mBrushShape == CSVWidget::BrushShape_Square) { for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { @@ -1053,7 +1064,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& } } - if (mBrushShape == BrushShape_Circle) + if (mBrushShape == CSVWidget::BrushShape_Circle) { for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { @@ -1067,7 +1078,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& } } - if (mBrushShape == BrushShape_Custom) + if (mBrushShape == CSVWidget::BrushShape_Custom) { if(!mCustomBrushShape.empty()) { @@ -1084,7 +1095,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& } void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, std::string cellId) + CSMWorld::IdTable& landTable, const std::string& cellId) { QVariant changedLand; changedLand.setValue(newLandGrid); @@ -1096,7 +1107,7 @@ void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsC } void CSVRender::TerrainShapeMode::pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, std::string cellId) + CSMWorld::IdTable& landTable, const std::string& cellId) { QVariant changedLand; changedLand.setValue(newLandGrid); @@ -1107,7 +1118,19 @@ void CSVRender::TerrainShapeMode::pushNormalsEditToCommand(const CSMWorld::LandN undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLand)); } -bool CSVRender::TerrainShapeMode::allowLandShapeEditing(std::string cellId) +void CSVRender::TerrainShapeMode::pushLodToCommand(const CSMWorld::LandMapLodColumn::DataType& newLandMapLod, CSMDoc::Document& document, + CSMWorld::IdTable& landTable, const std::string& cellId) +{ + QVariant changedLod; + changedLod.setValue(newLandMapLod); + + QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandMapLodIndex))); + + QUndoStack& undoStack = document.getUndoStack(); + undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLod)); +} + +bool CSVRender::TerrainShapeMode::allowLandShapeEditing(const std::string& cellId) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); CSMWorld::IdTable& landTable = dynamic_cast ( @@ -1191,12 +1214,12 @@ void CSVRender::TerrainShapeMode::setBrushSize(int brushSize) mBrushSize = brushSize; } -void CSVRender::TerrainShapeMode::setBrushShape(int brushShape) +void CSVRender::TerrainShapeMode::setBrushShape(CSVWidget::BrushShape brushShape) { mBrushShape = brushShape; //Set custom brush shape - if (mBrushShape == BrushShape_Custom && !mTerrainShapeSelection->getTerrainSelection().empty()) + if (mBrushShape == CSVWidget::BrushShape_Custom && !mTerrainShapeSelection->getTerrainSelection().empty()) { auto terrainSelection = mTerrainShapeSelection->getTerrainSelection(); int selectionCenterX = 0; diff --git a/apps/opencs/view/render/terrainshapemode.hpp b/apps/opencs/view/render/terrainshapemode.hpp index b6d2ffde1..912aec2ce 100644 --- a/apps/opencs/view/render/terrainshapemode.hpp +++ b/apps/opencs/view/render/terrainshapemode.hpp @@ -12,11 +12,11 @@ #ifndef Q_MOC_RUN #include "../../model/world/data.hpp" #include "../../model/world/land.hpp" - #include "../../model/doc/document.hpp" #include "../../model/world/commands.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/landtexture.hpp" +#include "../widget/brushshapes.hpp" #endif #include "terrainselection.hpp" @@ -46,12 +46,13 @@ namespace CSVRender InteractionType_None }; - enum BrushShape + enum ShapeEditTool { - BrushShape_Point = 0, - BrushShape_Square = 1, - BrushShape_Circle = 2, - BrushShape_Custom = 3 + ShapeEditTool_Drag = 0, + ShapeEditTool_PaintToRaise = 1, + ShapeEditTool_PaintToLower = 2, + ShapeEditTool_Smooth = 3, + ShapeEditTool_Flatten = 4 }; /// Editmode for terrain shape grid @@ -124,20 +125,24 @@ namespace CSVRender /// Push terrain shape edits to command macro void pushEditToCommand (const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, std::string cellId); + CSMWorld::IdTable& landTable, const std::string& cellId); /// Push land normals edits to command macro void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, std::string cellId); + CSMWorld::IdTable& landTable, const std::string& cellId); + + /// Generate new land map LOD + void pushLodToCommand(const CSMWorld::LandMapLodColumn::DataType& newLandMapLod, CSMDoc::Document& document, + CSMWorld::IdTable& landTable, const std::string& cellId); /// Create new cell and land if needed - bool allowLandShapeEditing(std::string textureFileName); + bool allowLandShapeEditing(const std::string& textureFileName); private: std::string mCellId; std::string mBrushTexture; int mBrushSize; - int mBrushShape; + CSVWidget::BrushShape mBrushShape; std::vector> mCustomBrushShape; CSVWidget::SceneToolShapeBrush *mShapeBrushScenetool; int mDragMode; @@ -158,7 +163,7 @@ namespace CSVRender public slots: void setBrushSize(int brushSize); - void setBrushShape(int brushShape); + void setBrushShape(CSVWidget::BrushShape brushShape); void setShapeEditTool(int shapeEditTool); void setShapeEditToolStrength(int shapeEditToolStrength); }; diff --git a/apps/opencs/view/render/terrainstorage.cpp b/apps/opencs/view/render/terrainstorage.cpp index 8938866e3..7f5dc1208 100644 --- a/apps/opencs/view/render/terrainstorage.cpp +++ b/apps/opencs/view/render/terrainstorage.cpp @@ -128,13 +128,13 @@ namespace CSVRender return abs(getThisHeight(col, row, heightData) - getDownHeight(col, row, heightData)); } - bool TerrainStorage::LeftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const + bool TerrainStorage::leftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const { return getHeightDifferenceToLeft(col, row, heightData) >= heightWarningLimit || getHeightDifferenceToUp(col, row, heightData) >= heightWarningLimit; } - bool TerrainStorage::RightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const + bool TerrainStorage::rightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const { return getHeightDifferenceToRight(col, row, heightData) >= heightWarningLimit || getHeightDifferenceToDown(col, row, heightData) >= heightWarningLimit; @@ -144,8 +144,8 @@ namespace CSVRender { // Highlight broken height changes int heightWarningLimit = 1024; - if (((col > 0 && row > 0) && LeftOrUpIsOverTheLimit(col, row, heightWarningLimit, heightData)) || - ((col < ESM::Land::LAND_SIZE - 1 && row < ESM::Land::LAND_SIZE - 1) && RightOrDownIsOverTheLimit(col, row, heightWarningLimit, heightData))) + if (((col > 0 && row > 0) && leftOrUpIsOverTheLimit(col, row, heightWarningLimit, heightData)) || + ((col < ESM::Land::LAND_SIZE - 1 && row < ESM::Land::LAND_SIZE - 1) && rightOrDownIsOverTheLimit(col, row, heightWarningLimit, heightData))) { color.r() = 255; color.g() = 0; diff --git a/apps/opencs/view/render/terrainstorage.hpp b/apps/opencs/view/render/terrainstorage.hpp index 703cd9be2..9e5226d5f 100644 --- a/apps/opencs/view/render/terrainstorage.hpp +++ b/apps/opencs/view/render/terrainstorage.hpp @@ -39,8 +39,8 @@ namespace CSVRender int getHeightDifferenceToRight(int col, int row, const ESM::Land::LandData *heightData) const; int getHeightDifferenceToUp(int col, int row, const ESM::Land::LandData *heightData) const; int getHeightDifferenceToDown(int col, int row, const ESM::Land::LandData *heightData) const; - bool LeftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; - bool RightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; + bool leftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; + bool rightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const override; float getAlteredHeight(int col, int row) const override; diff --git a/apps/opencs/view/widget/brushshapes.hpp b/apps/opencs/view/widget/brushshapes.hpp new file mode 100644 index 000000000..2e931157c --- /dev/null +++ b/apps/opencs/view/widget/brushshapes.hpp @@ -0,0 +1,14 @@ +#ifndef CSV_WIDGET_BRUSHSHAPES_H +#define CSV_WIDGET_BRUSHSHAPES_H + +namespace CSVWidget +{ + enum BrushShape + { + BrushShape_Point, + BrushShape_Square, + BrushShape_Circle, + BrushShape_Custom + }; +} +#endif diff --git a/apps/opencs/view/widget/scenetoolshapebrush.cpp b/apps/opencs/view/widget/scenetoolshapebrush.cpp index bc7b04c73..3b9d908ac 100644 --- a/apps/opencs/view/widget/scenetoolshapebrush.cpp +++ b/apps/opencs/view/widget/scenetoolshapebrush.cpp @@ -21,6 +21,7 @@ #include #include +#include "brushshapes.hpp" #include "scenetool.hpp" #include "../../model/doc/document.hpp" @@ -58,7 +59,7 @@ CSVWidget::ShapeBrushSizeControls::ShapeBrushSizeControls(const QString &title, CSVWidget::ShapeBrushWindow::ShapeBrushWindow(CSMDoc::Document& document, QWidget *parent) : QFrame(parent, Qt::Popup), - mBrushShape(BrushShape_Point), + mBrushShape(CSVWidget::BrushShape_Point), mBrushSize(1), mDocument(document) { @@ -169,7 +170,7 @@ CSVWidget::SceneToolShapeBrush::SceneToolShapeBrush (SceneToolbar *parent, const mShapeBrushWindow(new ShapeBrushWindow(document, this)) { setAcceptDrops(true); - connect(mShapeBrushWindow, SIGNAL(passBrushShape(int)), this, SLOT(setButtonIcon(int))); + connect(mShapeBrushWindow, SIGNAL(passBrushShape(CSVWidget::BrushShape)), this, SLOT(setButtonIcon(CSVWidget::BrushShape))); setButtonIcon(mShapeBrushWindow->mBrushShape); mPanel = new QFrame (this, Qt::Popup); @@ -199,31 +200,31 @@ CSVWidget::SceneToolShapeBrush::SceneToolShapeBrush (SceneToolbar *parent, const } -void CSVWidget::SceneToolShapeBrush::setButtonIcon (int brushShape) +void CSVWidget::SceneToolShapeBrush::setButtonIcon (CSVWidget::BrushShape brushShape) { QString tooltip = "Change brush settings

Currently selected: "; switch (brushShape) { - case 0: + case BrushShape_Point: setIcon (QIcon (QPixmap (":scenetoolbar/brush-point"))); tooltip += mShapeBrushWindow->toolTipPoint; break; - case 1: + case BrushShape_Square: setIcon (QIcon (QPixmap (":scenetoolbar/brush-square"))); tooltip += mShapeBrushWindow->toolTipSquare; break; - case 2: + case BrushShape_Circle: setIcon (QIcon (QPixmap (":scenetoolbar/brush-circle"))); tooltip += mShapeBrushWindow->toolTipCircle; break; - case 3: + case BrushShape_Custom: setIcon (QIcon (QPixmap (":scenetoolbar/brush-custom"))); tooltip += mShapeBrushWindow->toolTipCustom; diff --git a/apps/opencs/view/widget/scenetoolshapebrush.hpp b/apps/opencs/view/widget/scenetoolshapebrush.hpp index 44fd66df1..19d24111d 100644 --- a/apps/opencs/view/widget/scenetoolshapebrush.hpp +++ b/apps/opencs/view/widget/scenetoolshapebrush.hpp @@ -16,6 +16,7 @@ #include #ifndef Q_MOC_RUN +#include "brushshapes.hpp" #include "scenetool.hpp" #include "../../model/doc/document.hpp" @@ -54,24 +55,16 @@ namespace CSVWidget public: - enum BrushShape - { - BrushShape_Point = 0, - BrushShape_Square = 1, - BrushShape_Circle = 2, - BrushShape_Custom = 3 - }; - ShapeBrushWindow(CSMDoc::Document& document, QWidget *parent = 0); void configureButtonInitialSettings(QPushButton *button); const QString toolTipPoint = "Paint single point"; const QString toolTipSquare = "Paint with square brush"; const QString toolTipCircle = "Paint with circle brush"; - const QString toolTipCustom = "Paint custom selection (not implemented yet)"; + const QString toolTipCustom = "Paint with custom brush, defined by terrain selection"; private: - int mBrushShape; + CSVWidget::BrushShape mBrushShape; int mBrushSize; CSMDoc::Document& mDocument; QGroupBox *mHorizontalGroupBox; @@ -92,7 +85,7 @@ namespace CSVWidget signals: void passBrushSize (int brushSize); - void passBrushShape(int brushShape); + void passBrushShape(CSVWidget::BrushShape brushShape); }; class SceneToolShapeBrush : public SceneTool @@ -122,7 +115,7 @@ namespace CSVWidget friend class CSVRender::TerrainShapeMode; public slots: - void setButtonIcon(int brushShape); + void setButtonIcon(CSVWidget::BrushShape brushShape); void clicked (const QModelIndex& index); virtual void activate();