Merge pull request #2553 from unelsson/terraintexturemode_codeupdates

Editor: Code improvements for Terrain Texture mode (also fix for 4904)
This commit is contained in:
Alexei Dobrohotov 2019-10-10 16:53:14 +03:00 committed by GitHub
commit c891d8ce62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 54 deletions

View file

@ -79,6 +79,7 @@
Bug #4888: Global variable stray explicit reference calls break script compilation Bug #4888: Global variable stray explicit reference calls break script compilation
Bug #4896: Title screen music doesn't loop Bug #4896: Title screen music doesn't loop
Bug #4902: Using scrollbars in settings causes resolution to change Bug #4902: Using scrollbars in settings causes resolution to change
Bug #4904: Editor: Texture painting with duplicate of a base-version texture
Bug #4911: Editor: QOpenGLContext::swapBuffers() warning with Qt5 Bug #4911: Editor: QOpenGLContext::swapBuffers() warning with Qt5
Bug #4916: Specular power (shininess) material parameter is ignored when shaders are used. Bug #4916: Specular power (shininess) material parameter is ignored when shaders are used.
Bug #4918: Abilities don't play looping VFX when they're initially applied Bug #4918: Abilities don't play looping VFX when they're initially applied

View file

@ -101,6 +101,7 @@ Editor Bug Fixes:
- Colour fields in interior-cell records now also use the colour picker widget (#4745) - Colour fields in interior-cell records now also use the colour picker widget (#4745)
- Cloned, added, or moved instances no longer disappear at load-time (#4748) - Cloned, added, or moved instances no longer disappear at load-time (#4748)
- "Clear" function in the content selector no longer tries to execute a "Remove" action on an empty file list (#4757) - "Clear" function in the content selector no longer tries to execute a "Remove" action on an empty file list (#4757)
- Terrain texture editing for plugins now correctly handles drags from base file (#4904)
- Engine no longer tries to swap buffers of windows which weren't exposed to Qt's window management system (#4911) - Engine no longer tries to swap buffers of windows which weren't exposed to Qt's window management system (#4911)
- Minimap doesn't get corrupted, when editing new omwgame (#5177) - Minimap doesn't get corrupted, when editing new omwgame (#5177)

View file

@ -41,9 +41,9 @@
CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent) CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, Mask_Terrain | Mask_Reference, "Terrain texture editing", parent), : EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, Mask_Terrain | Mask_Reference, "Terrain texture editing", parent),
mBrushTexture("L0#0"), mBrushTexture("L0#0"),
mBrushSize(0), mBrushSize(1),
mBrushShape(0), mBrushShape(0),
mTextureBrushScenetool(0), mTextureBrushScenetool(nullptr),
mDragMode(InteractionType_None), mDragMode(InteractionType_None),
mParentNode(parentNode), mParentNode(parentNode),
mIsEditing(false) mIsEditing(false)
@ -82,7 +82,7 @@ void CSVRender::TerrainTextureMode::deactivate(CSVWidget::SceneToolbar* toolbar)
{ {
toolbar->removeTool (mTextureBrushScenetool); toolbar->removeTool (mTextureBrushScenetool);
delete mTextureBrushScenetool; delete mTextureBrushScenetool;
mTextureBrushScenetool = 0; mTextureBrushScenetool = nullptr;
} }
if (mTerrainTextureSelection) if (mTerrainTextureSelection)

View file

@ -51,36 +51,37 @@ namespace CSVRender
/// \brief Editmode for terrain texture grid /// \brief Editmode for terrain texture grid
TerrainTextureMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr); TerrainTextureMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr);
void primaryOpenPressed (const WorldspaceHitResult& hit); void primaryOpenPressed (const WorldspaceHitResult& hit) final;
/// \brief Create single command for one-click texture editing /// \brief Create single command for one-click texture editing
void primaryEditPressed (const WorldspaceHitResult& hit); void primaryEditPressed (const WorldspaceHitResult& hit) final;
/// \brief Open brush settings window /// \brief Open brush settings window
void primarySelectPressed(const WorldspaceHitResult&); void primarySelectPressed(const WorldspaceHitResult&) final;
void secondarySelectPressed(const WorldspaceHitResult&); void secondarySelectPressed(const WorldspaceHitResult&) final;
void activate(CSVWidget::SceneToolbar*); void activate(CSVWidget::SceneToolbar*) final;
void deactivate(CSVWidget::SceneToolbar*); void deactivate(CSVWidget::SceneToolbar*) final;
/// \brief Start texture editing command macro /// \brief Start texture editing command macro
virtual bool primaryEditStartDrag (const QPoint& pos); bool primaryEditStartDrag (const QPoint& pos) final;
virtual bool secondaryEditStartDrag (const QPoint& pos); bool secondaryEditStartDrag (const QPoint& pos) final;
virtual bool primarySelectStartDrag (const QPoint& pos); bool primarySelectStartDrag (const QPoint& pos) final;
virtual bool secondarySelectStartDrag (const QPoint& pos); bool secondarySelectStartDrag (const QPoint& pos) final;
/// \brief Handle texture edit behavior during dragging /// \brief Handle texture edit behavior during dragging
virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor); void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) final;
/// \brief End texture editing command macro /// \brief End texture editing command macro
virtual void dragCompleted(const QPoint& pos); void dragCompleted(const QPoint& pos) final;
virtual void dragAborted(); void dragAborted() final;
virtual void dragWheel (int diff, double speedFactor); void dragWheel (int diff, double speedFactor) final;
virtual void dragMoveEvent (QDragMoveEvent *event); void dragMoveEvent (QDragMoveEvent *event) final;
private:
/// \brief Handle brush mechanics, maths regarding worldspace hit etc. /// \brief Handle brush mechanics, maths regarding worldspace hit etc.
void editTerrainTextureGrid (const WorldspaceHitResult& hit); void editTerrainTextureGrid (const WorldspaceHitResult& hit);
@ -100,7 +101,6 @@ namespace CSVRender
/// \brief Create new cell and land if needed /// \brief Create new cell and land if needed
bool allowLandTextureEditing(std::string textureFileName); bool allowLandTextureEditing(std::string textureFileName);
private:
std::string mCellId; std::string mCellId;
std::string mBrushTexture; std::string mBrushTexture;
int mBrushSize; int mBrushSize;
@ -113,7 +113,6 @@ namespace CSVRender
std::unique_ptr<TerrainSelection> mTerrainTextureSelection; std::unique_ptr<TerrainSelection> mTerrainTextureSelection;
const int cellSize {ESM::Land::REAL_SIZE}; const int cellSize {ESM::Land::REAL_SIZE};
const int landSize {ESM::Land::LAND_SIZE};
const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE}; const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE};
signals: signals:

View file

@ -33,19 +33,19 @@
CSVWidget::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *parent) CSVWidget::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *parent)
: QGroupBox(title, parent) : QGroupBox(title, parent),
mLayoutSliderSize(new QHBoxLayout),
mBrushSizeSlider(new QSlider(Qt::Horizontal)),
mBrushSizeSpinBox(new QSpinBox)
{ {
mBrushSizeSlider = new QSlider(Qt::Horizontal);
mBrushSizeSlider->setTickPosition(QSlider::TicksBothSides); mBrushSizeSlider->setTickPosition(QSlider::TicksBothSides);
mBrushSizeSlider->setTickInterval(10); mBrushSizeSlider->setTickInterval(10);
mBrushSizeSlider->setRange(1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt()); mBrushSizeSlider->setRange(1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt());
mBrushSizeSlider->setSingleStep(1); mBrushSizeSlider->setSingleStep(1);
mBrushSizeSpinBox = new QSpinBox;
mBrushSizeSpinBox->setRange(1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt()); mBrushSizeSpinBox->setRange(1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt());
mBrushSizeSpinBox->setSingleStep(1); mBrushSizeSpinBox->setSingleStep(1);
mLayoutSliderSize = new QHBoxLayout;
mLayoutSliderSize->addWidget(mBrushSizeSlider); mLayoutSliderSize->addWidget(mBrushSizeSlider);
mLayoutSliderSize->addWidget(mBrushSizeSpinBox); mLayoutSliderSize->addWidget(mBrushSizeSpinBox);
@ -58,7 +58,7 @@ CSVWidget::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *p
CSVWidget::TextureBrushWindow::TextureBrushWindow(CSMDoc::Document& document, QWidget *parent) CSVWidget::TextureBrushWindow::TextureBrushWindow(CSMDoc::Document& document, QWidget *parent)
: QFrame(parent, Qt::Popup), : QFrame(parent, Qt::Popup),
mBrushShape(0), mBrushShape(0),
mBrushSize(0), mBrushSize(1),
mBrushTexture("L0#0"), mBrushTexture("L0#0"),
mDocument(document) mDocument(document)
{ {
@ -142,60 +142,61 @@ void CSVWidget::TextureBrushWindow::configureButtonInitialSettings(QPushButton *
void CSVWidget::TextureBrushWindow::setBrushTexture(std::string brushTexture) void CSVWidget::TextureBrushWindow::setBrushTexture(std::string brushTexture)
{ {
mBrushTexture = brushTexture; CSMWorld::IdTable& ltexTable = dynamic_cast<CSMWorld::IdTable&> (
*mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures));
QUndoStack& undoStack = mDocument.getUndoStack();
CSMWorld::IdCollection<CSMWorld::LandTexture>& landtexturesCollection = mDocument.getData().getLandTextures(); CSMWorld::IdCollection<CSMWorld::LandTexture>& landtexturesCollection = mDocument.getData().getLandTextures();
int landTextureFilename = landtexturesCollection.findColumnIndex(CSMWorld::Columns::ColumnId_Texture); int landTextureFilename = landtexturesCollection.findColumnIndex(CSMWorld::Columns::ColumnId_Texture);
int columnModification = landtexturesCollection.findColumnIndex(CSMWorld::Columns::ColumnId_Modification);
int index = landtexturesCollection.searchId(mBrushTexture);
// Check if texture exists in current plugin int index = 0;
if(landtexturesCollection.getData(index, columnModification).value<int>() == 0) int pluginInDragged = 0;
CSMWorld::LandTexture::parseUniqueRecordId(brushTexture, pluginInDragged, index);
std::string newBrushTextureId = CSMWorld::LandTexture::createUniqueRecordId(0, index);
int rowInBase = landtexturesCollection.searchId(brushTexture);
int rowInNew = landtexturesCollection.searchId(newBrushTextureId);
// Check if texture exists in current plugin, and clone if id found in base, otherwise reindex the texture
// TO-DO: Handle case when texture is not found in neither base or plugin properly (finding new index is not enough)
// TO-DO: Handle conflicting plugins properly
if (rowInNew == -1)
{ {
CSMWorld::IdTable& ltexTable = dynamic_cast<CSMWorld::IdTable&> ( if (rowInBase == -1)
*mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures));
QUndoStack& undoStack = mDocument.getUndoStack();
QVariant textureFileNameVariant;
textureFileNameVariant.setValue(landtexturesCollection.getData(index, landTextureFilename).value<QString>());
std::size_t hashlocation = mBrushTexture.find("#");
std::string mBrushTexturePlugin = "L0#" + mBrushTexture.substr (hashlocation+1);
int indexPlugin = landtexturesCollection.searchId(mBrushTexturePlugin);
// Reindex texture if needed
if (indexPlugin != -1 && !landtexturesCollection.getRecord(indexPlugin).isDeleted())
{ {
int counter=0; int counter=0;
bool freeIndexFound = false; bool freeIndexFound = false;
const int maxCounter = std::numeric_limits<uint16_t>::max() - 1;
do { do {
const size_t maxCounter = std::numeric_limits<uint16_t>::max() - 1; newBrushTextureId = CSMWorld::LandTexture::createUniqueRecordId(0, counter);
mBrushTexturePlugin = CSMWorld::LandTexture::createUniqueRecordId(0, counter); if (landtexturesCollection.searchId(brushTexture) != -1 &&
if (landtexturesCollection.searchId(mBrushTexturePlugin) != -1 && landtexturesCollection.getRecord(mBrushTexturePlugin).isDeleted() == 0) counter = (counter + 1) % maxCounter; landtexturesCollection.getRecord(brushTexture).isDeleted() == 0 &&
landtexturesCollection.searchId(newBrushTextureId) != -1 &&
landtexturesCollection.getRecord(newBrushTextureId).isDeleted() == 0)
counter = (counter + 1) % maxCounter;
else freeIndexFound = true; else freeIndexFound = true;
} while (freeIndexFound == false); } while (freeIndexFound == false || counter < maxCounter);
} }
undoStack.beginMacro ("Add land texture record"); undoStack.beginMacro ("Add land texture record");
undoStack.push (new CSMWorld::CloneCommand (ltexTable, mBrushTexture, mBrushTexturePlugin, CSMWorld::UniversalId::Type_LandTexture)); undoStack.push (new CSMWorld::CloneCommand (ltexTable, brushTexture, newBrushTextureId, CSMWorld::UniversalId::Type_LandTexture));
undoStack.endMacro(); undoStack.endMacro();
mBrushTexture = mBrushTexturePlugin;
emit passTextureId(mBrushTexture);
} }
if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted()) if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted())
{ {
mBrushTextureLabel = "Selected texture: " + mBrushTexture + " "; mBrushTextureLabel = "Selected texture: " + newBrushTextureId + " ";
mSelectedBrush->setText(QString::fromStdString(mBrushTextureLabel) + landtexturesCollection.getData(index, landTextureFilename).value<QString>()); mSelectedBrush->setText(QString::fromStdString(mBrushTextureLabel) + landtexturesCollection.getData(index, landTextureFilename).value<QString>());
} else } else
{ {
newBrushTextureId = "";
mBrushTextureLabel = "No selected texture or invalid texture"; mBrushTextureLabel = "No selected texture or invalid texture";
mSelectedBrush->setText(QString::fromStdString(mBrushTextureLabel)); mSelectedBrush->setText(QString::fromStdString(mBrushTextureLabel));
} }
emit passBrushShape(mBrushShape); // update icon mBrushTexture = newBrushTextureId;
emit passTextureId(mBrushTexture);
emit passBrushShape(mBrushShape); // updates the icon tooltip
} }
void CSVWidget::TextureBrushWindow::setBrushSize(int brushSize) void CSVWidget::TextureBrushWindow::setBrushSize(int brushSize)