From 9f742d5b1fe68a340db13b128c393645d18df542 Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Thu, 19 Apr 2018 18:00:47 +0300 Subject: [PATCH] Brush affects adjancent cells --- .../opencs/view/render/terraintexturemode.cpp | 147 ++++++++++++++---- .../opencs/view/render/terraintexturemode.hpp | 7 + 2 files changed, 127 insertions(+), 27 deletions(-) diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp index 0ce0bcd9b..baaae55be 100644 --- a/apps/opencs/view/render/terraintexturemode.cpp +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -252,11 +252,16 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe { mCellId = getWorldspaceWidget().getCellId (hit.worldPos); - std::istringstream streamCoord (mCellId); - char ignore; - int cellX = 0; - int cellY = 0; - streamCoord >> ignore >> cellX >> cellY; + std::pair cellCoordinates_pair = CSMWorld::CellCoordinates::fromId (mCellId); + + int cellX = cellCoordinates_pair.first.getX(); + int cellY = cellCoordinates_pair.first.getY(); + + // The coordinates of hit in mCellId + int xHitInCell ((hit.worldPos.x() - (cellX* cellSize)) * landTextureSize / cellSize); + int yHitInCell ((hit.worldPos.y() - (cellY* cellSize)) * landTextureSize / cellSize); + + std::string iteratedCellId; CSMDoc::Document& document = getWorldspaceWidget().getDocument(); CSMWorld::IdTable& landTable = dynamic_cast ( @@ -265,40 +270,123 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex); - CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value(); - CSMWorld::LandTexturesColumn::DataType mNew(mPointer); - - int xInCell ((hit.worldPos.x() - (cellX* cellSize)) * landTextureSize / cellSize); - int yInCell ((hit.worldPos.y() - (cellY* cellSize)) * landTextureSize / cellSize); std::size_t hashlocation = mBrushTexture.find("#"); std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1); int brushInt = stoi(mBrushTexture.substr (hashlocation+1))+1; // All indices are offset by +1 - if (mBrushShape == 0) mNew[yInCell*landTextureSize+xInCell] = brushInt; + float rf = mBrushSize/2; + int r = (mBrushSize/2)+1; + float distance = 0; + + if (mBrushShape == 0) + { + CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType mNew(mPointer); + mNew[yHitInCell*landTextureSize+xHitInCell] = brushInt; + pushEditToCommand(mNew, document, landTable, ltexTable, mCellId); + } + if (mBrushShape == 1) { - for(int i=-mBrushSize/2;i landTextureSize - 1) lowerrightCellX++; + if (yHitInCell + (r % landTextureSize) > landTextureSize - 1) lowerrightCellY++; + + for(int i_cell = upperLeftCellX; i_cell <= lowerrightCellX; i_cell++) { - for(int j=-mBrushSize/2;j= 0 && yInCell+j >= 0 && xInCell+i <= landTextureSize - 1 && yInCell+j <= landTextureSize - 1) - mNew[(yInCell+j)*landTextureSize+(xInCell+i)] = brushInt; + iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell); + CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType mNew(mPointer); + for(int i = 0; i < landTextureSize; i++) + { + for(int j = 0; j < landTextureSize; j++) + { + + if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r) + { + mNew[j*landTextureSize+i] = brushInt; + } + else + { + int distanceX(0); + int distanceY(0); + if (i_cell < cellX) distanceX = xHitInCell + landTextureSize - i; + if (j_cell < cellY) distanceY = yHitInCell + landTextureSize - j; + if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize + i - 1; + if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize + j - 1; + if (i_cell == cellX) distanceX = abs(i-xHitInCell); + if (j_cell == cellY) distanceY = abs(j-yHitInCell); + if (distanceX < r && distanceY < r) mNew[j*landTextureSize+i] = brushInt; + } + } + } + pushEditToCommand(mNew, document, landTable, ltexTable, iteratedCellId); } } } - float distance = 0; + if (mBrushShape == 2) { - float rf = mBrushSize/2; - int r = (mBrushSize/2)+1; - for(int i = -r; i < r; i++) + int upperLeftCellX = cellX - std::floor(r / landTextureSize); + int upperLeftCellY = cellY - std::floor(r / landTextureSize); + if (xHitInCell - (r % landTextureSize) < 0) upperLeftCellX--; + if (yHitInCell - (r % landTextureSize) < 0) upperLeftCellY--; + + int lowerrightCellX = cellX + std::floor(r / landTextureSize); + int lowerrightCellY = cellY + std::floor(r / landTextureSize); + if (xHitInCell + (r % landTextureSize) > landTextureSize - 1) lowerrightCellX++; + if (yHitInCell + (r % landTextureSize) > landTextureSize - 1) lowerrightCellY++; + + for(int i_cell = upperLeftCellX; i_cell <= lowerrightCellX; i_cell++) { - for(int j = -r; j < r; j++) + for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++) { - distance = std::round(sqrt(pow((xInCell+i)-xInCell, 2) + pow((yInCell+j)-yInCell, 2))); - if (xInCell+i >= 0 && yInCell+j >= 0 && xInCell+i <= landTextureSize - 1 && yInCell+j <= landTextureSize - 1 && distance <= rf) - mNew[(yInCell+j)*landTextureSize+(xInCell+i)] = brushInt; + iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell); + CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType mNew(mPointer); + for(int i = 0; i < landTextureSize; i++) + { + for(int j = 0; j < landTextureSize; j++) + { + + if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r) + { + int distanceX(0); + int distanceY(0); + if (i_cell < cellX) distanceX = xHitInCell + landTextureSize - i; + if (j_cell < cellY) distanceY = yHitInCell + landTextureSize - j; + if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize + i - 1; + if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize + j - 1; + if (i_cell == cellX) distanceX = abs(i-xHitInCell); + if (j_cell == cellY) distanceY = abs(j-yHitInCell); + distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); + if (distance < rf) mNew[j*landTextureSize+i] = brushInt; + } + else + { + int distanceX(0); + int distanceY(0); + if (i_cell < cellX) distanceX = xHitInCell + landTextureSize - i; + if (j_cell < cellY) distanceY = yHitInCell + landTextureSize - j; + if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize + i - 1; + if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize + j - 1; + if (i_cell == cellX) distanceX = abs(i-xHitInCell); + if (j_cell == cellY) distanceY = abs(j-yHitInCell); + distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); + if (distance < rf) mNew[j*landTextureSize+i] = brushInt; + } + } + } + pushEditToCommand(mNew, document, landTable, ltexTable, iteratedCellId); } } } @@ -307,13 +395,18 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe // Not implemented } +} + +void CSVRender::TerrainTextureMode::pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document, + CSMWorld::IdTable& landTable, CSMWorld::IdTable& ltexTable, std::string cellId) +{ QVariant changedLand; - changedLand.setValue(mNew); + changedLand.setValue(newLandGrid); CSMWorld::CommandMacro macro (document.getUndoStack(), "Edit texture records"); - QModelIndex index(landTable.getModelIndex (mCellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandTexturesIndex))); - - macro.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); + QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandTexturesIndex))); + + macro.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); macro.push (new CSMWorld::ModifyCommand(landTable, index, changedLand)); } diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index 7e991a8f0..48b9aeb59 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -19,6 +19,11 @@ #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" + namespace CSVWidget { class SceneToolMode; @@ -107,6 +112,8 @@ namespace CSVRender virtual void dragMoveEvent (QDragMoveEvent *event); void editTerrainTextureGrid (const WorldspaceHitResult& hit); + void pushEditToCommand (CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document, + CSMWorld::IdTable& landTable, CSMWorld::IdTable& ltexTable, std::string cellId); private: TextureBrushWindow *textureBrushWindow;