You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
8.4 KiB
C++
201 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
|