1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-21 13:09:42 +00:00

Merge branch 'terrainselectioncrashfix' into 'openmw-47'

Fix terrain selection crash

See merge request OpenMW/openmw!1165

(cherry picked from commit ec4e3b04a7)

b84e41bd Avoid storing ref, dynamic cast worldspacewidget for safety
d62ddc00 Use QPointer to detect object existence, less verbose debug messages
cb42b528 Remove friend, make getEditMode public to allow editmode testing.
4b148180 Restucture code
08f7c73e Fix text
This commit is contained in:
psi29a 2021-08-22 19:22:13 +00:00
parent 855f491196
commit 716eebe616
8 changed files with 65 additions and 19 deletions

View file

@ -1,19 +1,44 @@
#include "commands.hpp"
#include <QPointer>
#include <components/debug/debuglog.hpp>
#include <components/esm/loadland.hpp>
#include "editmode.hpp"
#include "terrainselection.hpp"
#include "terrainshapemode.hpp"
#include "terraintexturemode.hpp"
#include "worldspacewidget.hpp"
CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent)
: mTerrainSelection(terrainSelection)
CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent)
: mWorldspaceWidget(worldspaceWidget)
{ }
void CSVRender::DrawTerrainSelectionCommand::redo()
{
mTerrainSelection.update();
tryUpdate();
}
void CSVRender::DrawTerrainSelectionCommand::undo()
{
mTerrainSelection.update();
tryUpdate();
}
void CSVRender::DrawTerrainSelectionCommand::tryUpdate()
{
if (!mWorldspaceWidget)
{
Log(Debug::Verbose) << "Can't update terrain selection, no WorldspaceWidget found!";
return;
}
auto terrainMode = dynamic_cast<CSVRender::TerrainShapeMode*>(mWorldspaceWidget->getEditMode());
if (!terrainMode)
{
Log(Debug::Verbose) << "Can't update terrain selection in current EditMode";
return;
}
terrainMode->getTerrainSelection()->update();
}

View file

@ -1,8 +1,12 @@
#ifndef CSV_RENDER_COMMANDS_HPP
#define CSV_RENDER_COMMANDS_HPP
#include <QPointer>
#include <QUndoCommand>
#include "worldspacewidget.hpp"
namespace CSVRender
{
class TerrainSelection;
@ -21,14 +25,17 @@ namespace CSVRender
*/
class DrawTerrainSelectionCommand : public QUndoCommand
{
private:
TerrainSelection& mTerrainSelection;
QPointer<WorldspaceWidget> mWorldspaceWidget;
public:
DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent = nullptr);
DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent = nullptr);
void redo() override;
void undo() override;
void tryUpdate();
};
}

View file

@ -287,7 +287,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
undoStack.beginMacro ("Edit shape and normal records");
// One command at the beginning of the macro for redrawing the terrain-selection grid when undoing the changes.
undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection));
undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget()));
for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
{
@ -358,7 +358,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId);
}
// One command at the end of the macro for redrawing the terrain-selection grid when redoing the changes.
undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection));
undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget()));
undoStack.endMacro();
clearTransientEdits();
@ -1049,7 +1049,7 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob
*/
if (xIsAtCellBorder && yIsAtCellBorder)
{
/*
/*
Handle the NW, NE, and SE corner vertices.
NW corner: (+1, -1) offset to reach current cell.
NE corner: (-1, -1) offset to reach current cell.
@ -1132,7 +1132,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
selectAction = CSMPrefs::get()["3D Scene Editing"]["primary-select-action"].toString();
else
selectAction = CSMPrefs::get()["3D Scene Editing"]["secondary-select-action"].toString();
if (selectAction == "Select only")
mTerrainShapeSelection->onlySelect(selections);
else if (selectAction == "Add to selection")
@ -1444,6 +1444,11 @@ void CSVRender::TerrainShapeMode::mouseMoveEvent (QMouseEvent *event)
mBrushDraw->hide();
}
std::shared_ptr<CSVRender::TerrainSelection> CSVRender::TerrainShapeMode::getTerrainSelection()
{
return mTerrainShapeSelection;
}
void CSVRender::TerrainShapeMode::setBrushSize(int brushSize)
{
mBrushSize = brushSize;

View file

@ -92,6 +92,8 @@ namespace CSVRender
void dragMoveEvent (QDragMoveEvent *event) override;
void mouseMoveEvent (QMouseEvent *event) override;
std::shared_ptr<TerrainSelection> getTerrainSelection();
private:
/// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse
@ -176,7 +178,7 @@ namespace CSVRender
int mDragMode = InteractionType_None;
osg::Group* mParentNode;
bool mIsEditing = false;
std::unique_ptr<TerrainSelection> mTerrainShapeSelection;
std::shared_ptr<TerrainSelection> mTerrainShapeSelection;
int mTotalDiffY = 0;
std::vector<CSMWorld::CellCoordinates> mAlteredCells;
osg::Vec3d mEditingPos;

View file

@ -712,6 +712,11 @@ void CSVRender::TerrainTextureMode::mouseMoveEvent (QMouseEvent *event)
mBrushDraw->hide();
}
std::shared_ptr<CSVRender::TerrainSelection> CSVRender::TerrainTextureMode::getTerrainSelection()
{
return mTerrainTextureSelection;
}
void CSVRender::TerrainTextureMode::setBrushSize(int brushSize)
{

View file

@ -85,6 +85,8 @@ namespace CSVRender
void mouseMoveEvent (QMouseEvent *event) override;
std::shared_ptr<TerrainSelection> getTerrainSelection();
private:
/// \brief Handle brush mechanics, maths regarding worldspace hit etc.
void editTerrainTextureGrid (const WorldspaceHitResult& hit);
@ -115,7 +117,7 @@ namespace CSVRender
int mDragMode;
osg::Group* mParentNode;
bool mIsEditing;
std::unique_ptr<TerrainSelection> mTerrainTextureSelection;
std::shared_ptr<TerrainSelection> mTerrainTextureSelection;
const int cellSize {ESM::Land::REAL_SIZE};
const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE};

View file

@ -452,6 +452,11 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo
return hit;
}
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
}
void CSVRender::WorldspaceWidget::abortDrag()
{
if (mDragging)
@ -697,11 +702,6 @@ void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitRes
editMode.primaryOpenPressed (hit);
}
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
}
void CSVRender::WorldspaceWidget::primaryOpen(bool activate)
{
handleInteraction(InteractionType_PrimaryOpen, activate);

View file

@ -189,6 +189,8 @@ namespace CSVRender
/// Erase all overrides and restore the visual representation to its true state.
virtual void reset (unsigned int elementMask) = 0;
EditMode *getEditMode();
protected:
/// Visual elements in a scene
@ -215,8 +217,6 @@ namespace CSVRender
void settingChanged (const CSMPrefs::Setting *setting) override;
EditMode *getEditMode();
bool getSpeedMode();
private: