Brush affects adjancent cells

pull/440/head
Nelsson Huotari 7 years ago
parent 1ca2710a2a
commit 9f742d5b1f

@ -252,11 +252,16 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
{ {
mCellId = getWorldspaceWidget().getCellId (hit.worldPos); mCellId = getWorldspaceWidget().getCellId (hit.worldPos);
std::istringstream streamCoord (mCellId); std::pair<CSMWorld::CellCoordinates, bool> cellCoordinates_pair = CSMWorld::CellCoordinates::fromId (mCellId);
char ignore;
int cellX = 0; int cellX = cellCoordinates_pair.first.getX();
int cellY = 0; int cellY = cellCoordinates_pair.first.getY();
streamCoord >> ignore >> cellX >> cellY;
// 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(); CSMDoc::Document& document = getWorldspaceWidget().getDocument();
CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&> ( CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&> (
@ -265,40 +270,123 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
*document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures));
int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex); int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex);
CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
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::size_t hashlocation = mBrushTexture.find("#");
std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1); std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1);
int brushInt = stoi(mBrushTexture.substr (hashlocation+1))+1; // All indices are offset by +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>();
CSMWorld::LandTexturesColumn::DataType mNew(mPointer);
mNew[yHitInCell*landTextureSize+xHitInCell] = brushInt;
pushEditToCommand(mNew, document, landTable, ltexTable, mCellId);
}
if (mBrushShape == 1) if (mBrushShape == 1)
{ {
for(int i=-mBrushSize/2;i<mBrushSize/2;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=-mBrushSize/2;j<mBrushSize/2;j++) for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++)
{ {
if (xInCell+i >= 0 && yInCell+j >= 0 && xInCell+i <= landTextureSize - 1 && yInCell+j <= landTextureSize - 1) iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell);
mNew[(yInCell+j)*landTextureSize+(xInCell+i)] = brushInt; CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
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) if (mBrushShape == 2)
{ {
float rf = mBrushSize/2; int upperLeftCellX = cellX - std::floor(r / landTextureSize);
int r = (mBrushSize/2)+1; int upperLeftCellY = cellY - std::floor(r / landTextureSize);
for(int i = -r; i < r; i++) 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))); iteratedCellId = "#" + std::to_string(i_cell) + " " + std::to_string(j_cell);
if (xInCell+i >= 0 && yInCell+j >= 0 && xInCell+i <= landTextureSize - 1 && yInCell+j <= landTextureSize - 1 && distance <= rf) CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
mNew[(yInCell+j)*landTextureSize+(xInCell+i)] = brushInt; 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 // Not implemented
} }
}
void CSVRender::TerrainTextureMode::pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document,
CSMWorld::IdTable& landTable, CSMWorld::IdTable& ltexTable, std::string cellId)
{
QVariant changedLand; QVariant changedLand;
changedLand.setValue(mNew); changedLand.setValue(newLandGrid);
CSMWorld::CommandMacro macro (document.getUndoStack(), "Edit texture records"); CSMWorld::CommandMacro macro (document.getUndoStack(), "Edit texture records");
QModelIndex index(landTable.getModelIndex (mCellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandTexturesIndex))); QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandTexturesIndex)));
macro.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); macro.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId));
macro.push (new CSMWorld::ModifyCommand(landTable, index, changedLand)); macro.push (new CSMWorld::ModifyCommand(landTable, index, changedLand));
} }

@ -19,6 +19,11 @@
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/land.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 namespace CSVWidget
{ {
class SceneToolMode; class SceneToolMode;
@ -107,6 +112,8 @@ namespace CSVRender
virtual void dragMoveEvent (QDragMoveEvent *event); virtual void dragMoveEvent (QDragMoveEvent *event);
void editTerrainTextureGrid (const WorldspaceHitResult& hit); void editTerrainTextureGrid (const WorldspaceHitResult& hit);
void pushEditToCommand (CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document,
CSMWorld::IdTable& landTable, CSMWorld::IdTable& ltexTable, std::string cellId);
private: private:
TextureBrushWindow *textureBrushWindow; TextureBrushWindow *textureBrushWindow;

Loading…
Cancel
Save