1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-20 12:11:32 +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 "commands.hpp"
#include <QPointer>
#include <components/debug/debuglog.hpp>
#include <components/esm/loadland.hpp> #include <components/esm/loadland.hpp>
#include "editmode.hpp"
#include "terrainselection.hpp" #include "terrainselection.hpp"
#include "terrainshapemode.hpp"
#include "terraintexturemode.hpp"
#include "worldspacewidget.hpp"
CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent) CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent)
: mTerrainSelection(terrainSelection) : mWorldspaceWidget(worldspaceWidget)
{ } { }
void CSVRender::DrawTerrainSelectionCommand::redo() void CSVRender::DrawTerrainSelectionCommand::redo()
{ {
mTerrainSelection.update(); tryUpdate();
} }
void CSVRender::DrawTerrainSelectionCommand::undo() 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 #ifndef CSV_RENDER_COMMANDS_HPP
#define CSV_RENDER_COMMANDS_HPP #define CSV_RENDER_COMMANDS_HPP
#include <QPointer>
#include <QUndoCommand> #include <QUndoCommand>
#include "worldspacewidget.hpp"
namespace CSVRender namespace CSVRender
{ {
class TerrainSelection; class TerrainSelection;
@ -21,14 +25,17 @@ namespace CSVRender
*/ */
class DrawTerrainSelectionCommand : public QUndoCommand class DrawTerrainSelectionCommand : public QUndoCommand
{ {
private: private:
TerrainSelection& mTerrainSelection; QPointer<WorldspaceWidget> mWorldspaceWidget;
public: public:
DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent = nullptr); DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent = nullptr);
void redo() override; void redo() override;
void undo() override; void undo() override;
void tryUpdate();
}; };
} }

View file

@ -287,7 +287,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
undoStack.beginMacro ("Edit shape and normal records"); 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. // 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) for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
{ {
@ -358,7 +358,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId); pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId);
} }
// One command at the end of the macro for redrawing the terrain-selection grid when redoing the changes. // 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(); undoStack.endMacro();
clearTransientEdits(); clearTransientEdits();
@ -1444,6 +1444,11 @@ void CSVRender::TerrainShapeMode::mouseMoveEvent (QMouseEvent *event)
mBrushDraw->hide(); mBrushDraw->hide();
} }
std::shared_ptr<CSVRender::TerrainSelection> CSVRender::TerrainShapeMode::getTerrainSelection()
{
return mTerrainShapeSelection;
}
void CSVRender::TerrainShapeMode::setBrushSize(int brushSize) void CSVRender::TerrainShapeMode::setBrushSize(int brushSize)
{ {
mBrushSize = brushSize; mBrushSize = brushSize;

View file

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

View file

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

View file

@ -85,6 +85,8 @@ namespace CSVRender
void mouseMoveEvent (QMouseEvent *event) override; void mouseMoveEvent (QMouseEvent *event) override;
std::shared_ptr<TerrainSelection> getTerrainSelection();
private: 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);
@ -115,7 +117,7 @@ namespace CSVRender
int mDragMode; int mDragMode;
osg::Group* mParentNode; osg::Group* mParentNode;
bool mIsEditing; bool mIsEditing;
std::unique_ptr<TerrainSelection> mTerrainTextureSelection; std::shared_ptr<TerrainSelection> mTerrainTextureSelection;
const int cellSize {ESM::Land::REAL_SIZE}; const int cellSize {ESM::Land::REAL_SIZE};
const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE}; const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE};

View file

@ -452,6 +452,11 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo
return hit; return hit;
} }
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
}
void CSVRender::WorldspaceWidget::abortDrag() void CSVRender::WorldspaceWidget::abortDrag()
{ {
if (mDragging) if (mDragging)
@ -697,11 +702,6 @@ void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitRes
editMode.primaryOpenPressed (hit); editMode.primaryOpenPressed (hit);
} }
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
}
void CSVRender::WorldspaceWidget::primaryOpen(bool activate) void CSVRender::WorldspaceWidget::primaryOpen(bool activate)
{ {
handleInteraction(InteractionType_PrimaryOpen, 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. /// Erase all overrides and restore the visual representation to its true state.
virtual void reset (unsigned int elementMask) = 0; virtual void reset (unsigned int elementMask) = 0;
EditMode *getEditMode();
protected: protected:
/// Visual elements in a scene /// Visual elements in a scene
@ -215,8 +217,6 @@ namespace CSVRender
void settingChanged (const CSMPrefs::Setting *setting) override; void settingChanged (const CSMPrefs::Setting *setting) override;
EditMode *getEditMode();
bool getSpeedMode(); bool getSpeedMode();
private: private: