Brush affects adjancent cells

0.6.3
Nelsson Huotari 7 years ago
parent 1ca2710a2a
commit 9f742d5b1f

@ -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<CSMWorld::CellCoordinates, bool> 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<CSMWorld::IdTable&> (
@ -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>();
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>();
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<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)
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>();
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>();
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));
}

@ -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;

Loading…
Cancel
Save