From 4649d1258c03dcc9f653e011e69859855409157b Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Sun, 15 Apr 2018 18:49:33 +0300 Subject: [PATCH] Direct data terrain editing --- .../opencs/view/render/terraintexturemode.cpp | 146 ++++++++++++++++-- .../opencs/view/render/terraintexturemode.hpp | 33 +++- 2 files changed, 166 insertions(+), 13 deletions(-) diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp index 346ba3136..3d3175b8d 100644 --- a/apps/opencs/view/render/terraintexturemode.cpp +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -25,10 +25,35 @@ #include "../../model/world/universalid.hpp" #include "../../model/world/tablemimedata.hpp" +#include "../../model/world/idtable.hpp" #include "pagedworldspacewidget.hpp" +#include "../../model/doc/document.hpp" +#include "../../model/world/land.hpp" +#include "../../model/world/landtexture.hpp" +//#include "../../model/world/universalid.hpp" +//#include "../../model/world/tablemimedata.hpp" +//#include "../../model/world/idtable.hpp" + +#include "../../model/world/columnbase.hpp" +#include "../../model/world/resourcetable.hpp" +#include "../../model/world/commandmacro.hpp" +#include "../../model/world/data.hpp" +#include "../../model/world/commands.hpp" + +//#include +//#include + +//#include +#include +//#include +//#include +//#include + + + CSVRender::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *parent) : QGroupBox(title, parent) { @@ -62,16 +87,6 @@ CSVRender::TextureBrushWindow::TextureBrushWindow(WorldspaceWidget *worldspaceWi mBrushTextureLabel = "Brush: " + mBrushTexture; selectedBrush = new QLabel(QString::fromUtf8(mBrushTextureLabel.c_str()), this); - const std::string& iconPoint = ":scenetoolbar/brush-point"; - const std::string& iconSquare = ":scenetoolbar/brush-square"; - const std::string& iconCircle = ":scenetoolbar/brush-circle"; - const std::string& iconCustom = ":scenetoolbar/brush-custom"; - - TextureBrushButton *buttonPoint = new TextureBrushButton(QIcon (QPixmap (iconPoint.c_str())), "", this); - TextureBrushButton *buttonSquare = new TextureBrushButton(QIcon (QPixmap (iconSquare.c_str())), "", this); - TextureBrushButton *buttonCircle = new TextureBrushButton(QIcon (QPixmap (iconCircle.c_str())), "", this); - TextureBrushButton *buttonCustom = new TextureBrushButton(QIcon (QPixmap (iconCustom.c_str())), "", this); - QVBoxLayout *layoutMain = new QVBoxLayout; layoutMain->setSpacing(0); @@ -108,6 +123,13 @@ CSVRender::TextureBrushWindow::TextureBrushWindow(WorldspaceWidget *worldspaceWi setLayout(layoutMain); + connect(buttonPoint, SIGNAL(clicked()), this, SLOT(setBrushShape())); + connect(buttonSquare, SIGNAL(clicked()), this, SLOT(setBrushShape())); + connect(buttonCircle, SIGNAL(clicked()), this, SLOT(setBrushShape())); + connect(buttonCustom, SIGNAL(clicked()), this, SLOT(setBrushShape())); + + connect(sizeSliders->brushSizeSlider, SIGNAL(valueChanged(int)), parent, SLOT(setBrushSize(int))); + connect(parent, SIGNAL(passBrushTexture(std::string)), this, SLOT(getBrushTexture(std::string))); } @@ -128,12 +150,29 @@ void CSVRender::TextureBrushWindow::getBrushTexture(std::string brushTexture) selectedBrush->setText(QString::fromUtf8(mBrushTextureLabel.c_str())); } +void CSVRender::TextureBrushWindow::setBrushSize(int brushSize) +{ + mBrushSize = brushSize; + emit passBrushSize(mBrushSize); +} + +void CSVRender::TextureBrushWindow::setBrushShape() +{ + if(buttonPoint->isChecked()) mBrushShape = 0; + if(buttonSquare->isChecked()) mBrushShape = 1; + if(buttonCircle->isChecked()) mBrushShape = 2; + if(buttonCustom->isChecked()) mBrushShape = 3; + emit passBrushShape(mBrushShape); +} + CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) : EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, Mask_Terrain | Mask_Reference, "Terrain texture editing", parent) , textureBrushWindow(new TextureBrushWindow(worldspaceWidget, this)) { connect(parent, SIGNAL(passEvent(QDragEnterEvent*)), this, SLOT(handleDragEnterEvent(QDragEnterEvent*))); connect(parent, SIGNAL(passEvent(QDropEvent*)), this, SLOT(handleDropEvent(QDropEvent*))); + connect(textureBrushWindow, SIGNAL(passBrushSize(int)), this, SLOT(setBrushSize(int))); + connect(textureBrushWindow, SIGNAL(passBrushShape(int)), this, SLOT(setBrushShape(int))); } void CSVRender::TerrainTextureMode::activate(CSVWidget::SceneToolbar* toolbar) @@ -146,6 +185,83 @@ void CSVRender::TerrainTextureMode::deactivate(CSVWidget::SceneToolbar* toolbar) EditMode::deactivate(toolbar); } +void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult& hit) // Apply changes here +{ + cellId = getWorldspaceWidget().getCellId (hit.worldPos); + std::string hash = "#"; + std::string space = " "; + std::size_t hashlocation = cellId.find(hash); + std::size_t spacelocation = cellId.find(space); + std::string slicedX = cellId.substr (hashlocation+1, spacelocation-hashlocation); + std::string slicedY = cellId.substr (spacelocation+1); + CSMWorld::CellCoordinates mCoordinates(stoi(slicedX), stoi(slicedY)); + + CSMDoc::Document& document = getWorldspaceWidget().getDocument(); + CSMWorld::IdTable& landTable = dynamic_cast ( +*document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); + /*CSMWorld::IdTable& ltexTable = dynamic_cast ( +*document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures));*/ + + int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex); + CSMWorld::LandTexturesColumn::DataType mPointer = landTable.data(landTable.getModelIndex(cellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType mNew(mPointer); + + int xInCell {(hit.worldPos.x() - (stoi(slicedX)* cellSize)) * landTextureSize / cellSize}; + int yInCell {(hit.worldPos.y() - (stoi(slicedY)* cellSize)) * landTextureSize / cellSize}; + + hashlocation = mBrushTexture.find(hash); + std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1); + int brushInt = stoi(mBrushTexture.substr (hashlocation+1)); + + if (mBrushShape == 0) mNew[yInCell*landTextureSize+xInCell] = brushInt; + if (mBrushShape == 1) + { + for(int i=-mBrushSize/2;i= 0 && yInCell+j >= 0 && xInCell+i <= 15 && yInCell+j <= 15) + mNew[(yInCell+j)*landTextureSize+(xInCell+i)] = brushInt; + } + } + } + float distance = 0; + if (mBrushShape == 2) + { + float rf = mBrushSize/2; + int r = (mBrushSize/2)+1; + int r2 = r * r; + for(int i = -r; i < r; i++) + { + for(int j = -r; j < r; j++) + { + distance = std::round(sqrt(pow((xInCell+i)-xInCell, 2) + pow((yInCell+j)-yInCell, 2))); + if (xInCell+i >= 0 && yInCell+j >= 0 && xInCell+i <= 15 && yInCell+j <= 15 && distance <= rf) + mNew[(yInCell+j)*landTextureSize+(xInCell+i)] = brushInt; + } + } + } + if (mBrushShape == 3) + { + // Not implemented + } + + // Modify data, this should be done via command system! + QVariant variant; + variant.setValue(mNew); + landTable.setData(landTable.getModelIndex(cellId, textureColumn), variant); + + // Reference + /*CSMWorld::ModifyLandTexturesCommand::ModifyLandTexturesCommand(IdTable& landTable, + IdTable& ltexTable, QUndoCommand* parent)*/ + + // Reference + /*CSMWorld::DeleteCommand* command = new CSMWorld::DeleteCommand(referencesTable, + static_cast(iter->get())->mObject->getReferenceId()); + + getWorldspaceWidget().getDocument().getUndoStack().push(command);*/ +} + void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResult& hit) { QPoint position = QCursor::pos(); @@ -212,3 +328,13 @@ void CSVRender::TerrainTextureMode::handleDropEvent (QDropEvent *event) { void CSVRender::TerrainTextureMode::dragMoveEvent (QDragMoveEvent *event) { } + +void CSVRender::TerrainTextureMode::setBrushSize(int brushSize) +{ + mBrushSize = brushSize; +} + +void CSVRender::TerrainTextureMode::setBrushShape(int brushShape) +{ + mBrushShape = brushShape; +} diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index 809816047..fff5b7dae 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -16,6 +16,9 @@ #include #include +#include "../../model/world/data.hpp" +#include "../../model/world/land.hpp" + namespace CSVWidget { class SceneToolMode; @@ -29,9 +32,9 @@ namespace CSVRender public: BrushSizeControls(const QString &title, QWidget *parent); + QSlider *brushSizeSlider; private: - QSlider *brushSizeSlider; QSpinBox *brushSizeSpinBox; QHBoxLayout *layoutSliderSize; }; @@ -53,10 +56,17 @@ namespace CSVRender TextureBrushWindow(WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); void configureButtonInitialSettings(TextureBrushButton *button); + TextureBrushButton *buttonPoint = new TextureBrushButton(QIcon (QPixmap (":scenetoolbar/brush-point")), "", this); + TextureBrushButton *buttonSquare = new TextureBrushButton(QIcon (QPixmap (":scenetoolbar/brush-square")), "", this); + TextureBrushButton *buttonCircle = new TextureBrushButton(QIcon (QPixmap (":scenetoolbar/brush-circle")), "", this); + TextureBrushButton *buttonCustom = new TextureBrushButton(QIcon (QPixmap (":scenetoolbar/brush-custom")), "", this); + private: QLabel *selectedBrush; QGroupBox *horizontalGroupBox; int mButtonSize; + int mBrushSize = 0; + int mBrushShape = 0; int mIconSize; WorldspaceWidget *mWorldspaceWidget; std::string mBrushTexture; @@ -64,6 +74,12 @@ namespace CSVRender public slots: void getBrushTexture(std::string brushTexture); + void setBrushShape(); + void setBrushSize(int brushSize); + + signals: + void passBrushSize (int brushSize); + void passBrushShape(int brushShape); }; class TerrainTextureMode : public EditMode @@ -71,10 +87,11 @@ namespace CSVRender Q_OBJECT public: - std::string mBrushTexture; TerrainTextureMode(WorldspaceWidget*, QWidget* parent = nullptr); + void primaryEditPressed (const WorldspaceHitResult& hit); + void primarySelectPressed(const WorldspaceHitResult&); void secondarySelectPressed(const WorldspaceHitResult&); @@ -93,14 +110,24 @@ namespace CSVRender private: TextureBrushWindow *textureBrushWindow; + std::string cellId; + std::string mBrushTexture = "#0"; + int mBrushSize = 0; + int mBrushShape = 0; - signals: + const int cellSize {ESM::Land::REAL_SIZE}; + const int landSize {ESM::Land::LAND_SIZE}; + const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE}; + signals: void passBrushTexture(std::string brushTexture); public slots: void handleDragEnterEvent (QDragEnterEvent *event); void handleDropEvent(QDropEvent *event); + void setBrushSize(int brushSize); + void setBrushShape(int brushShape); + }; }