mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 16:23:52 +00:00
716eebe616
Fix terrain selection crash See merge request OpenMW/openmw!1165 (cherry picked from commitec4e3b04a7
)b84e41bd
Avoid storing ref, dynamic cast worldspacewidget for safetyd62ddc00
Use QPointer to detect object existence, less verbose debug messagescb42b528
Remove friend, make getEditMode public to allow editmode testing.4b148180
Restucture code08f7c73e
Fix text
200 lines
8.4 KiB
C++
200 lines
8.4 KiB
C++
#ifndef CSV_RENDER_TERRAINSHAPEMODE_H
|
|
#define CSV_RENDER_TERRAINSHAPEMODE_H
|
|
|
|
#include "editmode.hpp"
|
|
|
|
#include <string>
|
|
#include <memory>
|
|
|
|
#include <QWidget>
|
|
#include <QEvent>
|
|
|
|
#ifndef Q_MOC_RUN
|
|
#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"
|
|
#include "../widget/brushshapes.hpp"
|
|
#endif
|
|
|
|
#include "brushdraw.hpp"
|
|
#include "terrainselection.hpp"
|
|
|
|
namespace CSVWidget
|
|
{
|
|
class SceneToolShapeBrush;
|
|
}
|
|
|
|
namespace CSVRender
|
|
{
|
|
class PagedWorldspaceWidget;
|
|
|
|
/// \brief EditMode for handling the terrain shape editing
|
|
class TerrainShapeMode : public EditMode
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
enum InteractionType
|
|
{
|
|
InteractionType_PrimaryEdit,
|
|
InteractionType_PrimarySelect,
|
|
InteractionType_SecondaryEdit,
|
|
InteractionType_SecondarySelect,
|
|
InteractionType_None
|
|
};
|
|
|
|
enum ShapeEditTool
|
|
{
|
|
ShapeEditTool_Drag = 0,
|
|
ShapeEditTool_PaintToRaise = 1,
|
|
ShapeEditTool_PaintToLower = 2,
|
|
ShapeEditTool_Smooth = 3,
|
|
ShapeEditTool_Flatten = 4
|
|
};
|
|
|
|
/// Editmode for terrain shape grid
|
|
TerrainShapeMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr);
|
|
|
|
void primaryOpenPressed (const WorldspaceHitResult& hit) override;
|
|
|
|
/// Create single command for one-click shape editing
|
|
void primaryEditPressed (const WorldspaceHitResult& hit) override;
|
|
|
|
/// Open brush settings window
|
|
void primarySelectPressed(const WorldspaceHitResult&) override;
|
|
|
|
void secondarySelectPressed(const WorldspaceHitResult&) override;
|
|
|
|
void activate(CSVWidget::SceneToolbar*) override;
|
|
void deactivate(CSVWidget::SceneToolbar*) override;
|
|
|
|
/// Start shape editing command macro
|
|
bool primaryEditStartDrag (const QPoint& pos) override;
|
|
|
|
bool secondaryEditStartDrag (const QPoint& pos) override;
|
|
bool primarySelectStartDrag (const QPoint& pos) override;
|
|
bool secondarySelectStartDrag (const QPoint& pos) override;
|
|
|
|
/// Handle shape edit behavior during dragging
|
|
void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override;
|
|
|
|
/// End shape editing command macro
|
|
void dragCompleted(const QPoint& pos) override;
|
|
|
|
/// Cancel shape editing, and reset all pending changes
|
|
void dragAborted() override;
|
|
|
|
void dragWheel (int diff, double speedFactor) override;
|
|
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
|
|
void sortAndLimitAlteredCells();
|
|
|
|
/// Reset everything in the current edit
|
|
void clearTransientEdits();
|
|
|
|
/// Move pending alteredHeights changes to omwgame/omwaddon -data
|
|
void applyTerrainEditChanges();
|
|
|
|
/// Handle brush mechanics for shape editing
|
|
void editTerrainShapeGrid (const std::pair<int, int>& vertexCoords, bool dragOperation);
|
|
|
|
/// Calculate height, when aiming for bump-shaped terrain change
|
|
float calculateBumpShape(float distance, int radius, float height);
|
|
|
|
/// set the target height for flatten tool
|
|
void setFlattenToolTargetHeight(const WorldspaceHitResult& hit);
|
|
|
|
/// Do a single height alteration for transient shape edit map
|
|
void alterHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float alteredHeight, bool useTool = true);
|
|
|
|
/// Do a single smoothing height alteration for transient shape edit map
|
|
void smoothHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength);
|
|
|
|
/// Do a single flattening height alteration for transient shape edit map
|
|
void flattenHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength, int targetHeight);
|
|
|
|
/// Get altered height values around one vertex
|
|
void updateKeyHeightValues(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float* thisHeight,
|
|
float* thisAlteredHeight, float* leftHeight, float* leftAlteredHeight, float* upHeight, float* upAlteredHeight,
|
|
float* rightHeight, float* rightAlteredHeight, float* downHeight, float* downAlteredHeight);
|
|
|
|
///Limit steepness based on either X or Y and return false if steepness is limited
|
|
void compareAndLimit(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float* limitedAlteredHeightXAxis,
|
|
float* limitedAlteredHeightYAxis, bool* steepnessIsWithinLimits);
|
|
|
|
/// Check that the edit doesn't break save format limits, fix if necessary, return true if slope steepness is within limits
|
|
bool limitAlteredHeights(const CSMWorld::CellCoordinates& cellCoords, bool reverseMode = false);
|
|
|
|
/// Check if global selection coordinate belongs to cell in view
|
|
bool isInCellSelection(int globalSelectionX, int globalSelectionY);
|
|
|
|
/// Select vertex at global selection coordinate
|
|
void handleSelection(int globalSelectionX, int globalSelectionY, std::vector<std::pair<int, int>>* selections);
|
|
|
|
/// Handle brush mechanics for terrain shape selection
|
|
void selectTerrainShapes (const std::pair<int, int>& vertexCoords, unsigned char selectMode, bool dragOperation);
|
|
|
|
/// Push terrain shape edits to command macro
|
|
void pushEditToCommand (const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
|
CSMWorld::IdTable& landTable, const std::string& cellId);
|
|
|
|
/// Push land normals edits to command macro
|
|
void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
|
CSMWorld::IdTable& landTable, const std::string& cellId);
|
|
|
|
bool noCell(const std::string& cellId);
|
|
|
|
bool noLand(const std::string& cellId);
|
|
|
|
bool noLandLoaded(const std::string& cellId);
|
|
|
|
bool isLandLoaded(const std::string& cellId);
|
|
|
|
/// Create new blank height record and new normals, if there are valid adjancent cell, take sample points and set the average height based on that
|
|
void createNewLandData(const CSMWorld::CellCoordinates& cellCoords);
|
|
|
|
/// Create new cell and land if needed, only user tools may ask for opening new cells (useTool == false is for automated land changes)
|
|
bool allowLandShapeEditing(const std::string& textureFileName, bool useTool = true);
|
|
|
|
/// Bind the edging vertice to the values of the adjancent cells
|
|
void fixEdges(CSMWorld::CellCoordinates cellCoords);
|
|
|
|
std::string mBrushTexture;
|
|
int mBrushSize = 1;
|
|
CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point;
|
|
std::unique_ptr<BrushDraw> mBrushDraw;
|
|
std::vector<std::pair<int, int>> mCustomBrushShape;
|
|
CSVWidget::SceneToolShapeBrush *mShapeBrushScenetool = nullptr;
|
|
int mDragMode = InteractionType_None;
|
|
osg::Group* mParentNode;
|
|
bool mIsEditing = false;
|
|
std::shared_ptr<TerrainSelection> mTerrainShapeSelection;
|
|
int mTotalDiffY = 0;
|
|
std::vector<CSMWorld::CellCoordinates> mAlteredCells;
|
|
osg::Vec3d mEditingPos;
|
|
int mShapeEditTool = ShapeEditTool_Drag;
|
|
int mShapeEditToolStrength = 8;
|
|
int mTargetHeight = 0;
|
|
|
|
PagedWorldspaceWidget& getPagedWorldspaceWidget();
|
|
|
|
public slots:
|
|
void setBrushSize(int brushSize);
|
|
void setBrushShape(CSVWidget::BrushShape brushShape);
|
|
void setShapeEditTool(int shapeEditTool);
|
|
void setShapeEditToolStrength(int shapeEditToolStrength);
|
|
};
|
|
}
|
|
|
|
|
|
#endif
|