1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 19:53:54 +00:00
openmw/apps/opencs/view/render/terrainshapemode.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

226 lines
8.1 KiB
C++
Raw Normal View History

2019-09-11 09:59:15 +00:00
#ifndef CSV_RENDER_TERRAINSHAPEMODE_H
#define CSV_RENDER_TERRAINSHAPEMODE_H
#include "editmode.hpp"
#include <memory>
#include <string>
2022-10-19 17:02:00 +00:00
#include <utility>
#include <vector>
2019-09-11 09:59:15 +00:00
2022-10-19 17:02:00 +00:00
#include <apps/opencs/model/world/cellcoordinates.hpp>
#include <osg/Vec3d>
2019-09-11 09:59:15 +00:00
#ifndef Q_MOC_RUN
2022-08-19 17:19:42 +00:00
#include "../../model/world/columnimp.hpp"
2019-10-06 23:57:09 +00:00
#include "../widget/brushshapes.hpp"
2019-09-11 09:59:15 +00:00
#endif
#include "brushdraw.hpp"
2022-10-19 17:02:00 +00:00
class QDragMoveEvent;
class QMouseEvent;
class QObject;
class QPoint;
class QWidget;
namespace osg
{
class Group;
}
namespace CSMDoc
{
class Document;
}
2019-09-11 09:59:15 +00:00
namespace CSVWidget
{
class SceneToolShapeBrush;
}
2022-08-19 17:19:42 +00:00
namespace CSMWorld
{
2022-10-19 17:02:00 +00:00
class IdTable;
2022-08-19 17:19:42 +00:00
}
2019-09-11 09:59:15 +00:00
namespace CSVRender
{
class PagedWorldspaceWidget;
2022-10-19 17:02:00 +00:00
class TerrainSelection;
class WorldspaceWidget;
struct WorldspaceHitResult;
class SceneToolbar;
2019-09-11 09:59:15 +00:00
/// \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
};
2019-10-06 23:57:09 +00:00
enum ShapeEditTool
2019-10-04 09:07:47 +00:00
{
2019-10-06 23:57:09 +00:00
ShapeEditTool_Drag = 0,
ShapeEditTool_PaintToRaise = 1,
ShapeEditTool_PaintToLower = 2,
ShapeEditTool_Smooth = 3,
ShapeEditTool_Flatten = 4
2019-10-04 09:07:47 +00:00
};
2019-09-11 09:59:15 +00:00
/// Editmode for terrain shape grid
TerrainShapeMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr);
void primaryOpenPressed(const WorldspaceHitResult& hit) override;
2019-09-11 09:59:15 +00:00
/// Create single command for one-click shape editing
void primaryEditPressed(const WorldspaceHitResult& hit) override;
2019-09-11 09:59:15 +00:00
/// Open brush settings window
void primarySelectPressed(const WorldspaceHitResult&) override;
2019-09-11 09:59:15 +00:00
void secondarySelectPressed(const WorldspaceHitResult&) override;
2019-09-11 09:59:15 +00:00
void activate(CSVWidget::SceneToolbar*) override;
void deactivate(CSVWidget::SceneToolbar*) override;
2019-09-11 09:59:15 +00:00
/// Start shape editing command macro
bool primaryEditStartDrag(const QPoint& pos) override;
2019-09-11 09:59:15 +00:00
bool secondaryEditStartDrag(const QPoint& pos) override;
bool primarySelectStartDrag(const QPoint& pos) override;
bool secondarySelectStartDrag(const QPoint& pos) override;
2019-09-11 09:59:15 +00:00
/// Handle shape edit behavior during dragging
void drag(const QPoint& pos, int diffX, int diffY, double speedFactor) override;
2019-09-11 09:59:15 +00:00
/// End shape editing command macro
void dragCompleted(const QPoint& pos) override;
2019-09-11 09:59:15 +00:00
/// Cancel shape editing, and reset all pending changes
void dragAborted() override;
2019-09-11 09:59:15 +00:00
void dragWheel(int diff, double speedFactor) override;
void dragMoveEvent(QDragMoveEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
2019-09-11 09:59:15 +00:00
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);
2019-09-11 09:59:15 +00:00
/// Calculate height, when aiming for bump-shaped terrain change
float calculateBumpShape(float distance, int radius, float height);
2019-10-22 17:58:23 +00:00
/// set the target height for flatten tool
2019-10-22 21:02:24 +00:00
void setFlattenToolTargetHeight(const WorldspaceHitResult& hit);
2019-10-22 17:58:23 +00:00
/// 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);
2019-09-11 09:59:15 +00:00
/// 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);
2019-09-19 09:38:15 +00:00
/// Limit steepness based on either X or Y and return false if steepness is limited
2019-09-11 09:59:15 +00:00
void compareAndLimit(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY,
2019-09-19 09:38:15 +00:00
float* limitedAlteredHeightXAxis, float* limitedAlteredHeightYAxis, bool* steepnessIsWithinLimits);
2019-09-11 09:59:15 +00:00
/// 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);
2019-09-11 09:59:15 +00:00
/// Select vertex at global selection coordinate
void handleSelection(int globalSelectionX, int globalSelectionY, std::vector<std::pair<int, int>>* selections);
2019-11-04 10:16:08 +00:00
/// Handle brush mechanics for terrain shape selection
void selectTerrainShapes(const std::pair<int, int>& vertexCoords, unsigned char selectMode);
2019-09-11 09:59:15 +00:00
/// Push terrain shape edits to command macro
void pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,
CSMWorld::IdTable& landTable, const std::string& cellId);
2019-09-11 09:59:15 +00:00
/// Push land normals edits to command macro
void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid,
2019-10-06 23:57:09 +00:00
CSMDoc::Document& document, CSMWorld::IdTable& landTable, const std::string& cellId);
2019-09-11 09:59:15 +00:00
2019-10-06 23:57:09 +00:00
bool noCell(const std::string& cellId);
2019-09-11 09:59:15 +00:00
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;
2019-09-11 09:59:15 +00:00
PagedWorldspaceWidget& getPagedWorldspaceWidget();
2019-09-11 09:59:15 +00:00
public slots:
void setBrushSize(int brushSize);
2019-10-06 23:57:09 +00:00
void setBrushShape(CSVWidget::BrushShape brushShape);
2019-09-11 09:59:15 +00:00
void setShapeEditTool(int shapeEditTool);
void setShapeEditToolStrength(int shapeEditToolStrength);
};
}
#endif