Merge pull request #327 from thecelloman/smoothslope

Add a new Terrain brush action:  Smooth Slope.
This commit is contained in:
SilentMike 2013-04-10 14:47:09 -07:00
commit a9643a448d
8 changed files with 125 additions and 23 deletions

View file

@ -631,6 +631,52 @@ void SmoothHeightAction::process(Selection * sel, const Gui3DMouseEvent &, bool
}
}
void SmoothSlopeAction::process(Selection * sel, const Gui3DMouseEvent &, bool selChanged, Type)
{
if(!sel->size())
return;
if(selChanged)
{
// Perform simple 2d linear regression on x&z and y&z:
// b = (Avg(xz) - Avg(x)Avg(z))/(Avg(x^2) - Avg(x)^2)
Point2F prod(0.f, 0.f); // mean of product for covar
Point2F avgSqr(0.f, 0.f); // mean sqr of x, y for var
Point2F avgPos(0.f, 0.f);
F32 avgHeight = 0.f;
F32 z;
Point2F pos;
for(U32 k = 0; k < sel->size(); k++)
{
mTerrainEditor->getUndoSel()->add((*sel)[k]);
pos = Point2F((*sel)[k].mGridPoint.gridPos.x, (*sel)[k].mGridPoint.gridPos.y);
z = (*sel)[k].mHeight;
prod += pos * z;
avgSqr += pos * pos;
avgPos += pos;
avgHeight += z;
}
prod /= sel->size();
avgSqr /= sel->size();
avgPos /= sel->size();
avgHeight /= sel->size();
Point2F avgSlope = (prod - avgPos*avgHeight)/(avgSqr - avgPos*avgPos);
F32 goalHeight;
for(U32 i = 0; i < sel->size(); i++)
{
goalHeight = avgHeight + ((*sel)[i].mGridPoint.gridPos.x - avgPos.x)*avgSlope.x +
((*sel)[i].mGridPoint.gridPos.y - avgPos.y)*avgSlope.y;
(*sel)[i].mHeight += (goalHeight - (*sel)[i].mHeight) * (*sel)[i].mWeight;
mTerrainEditor->setGridInfo((*sel)[i]);
}
mTerrainEditor->scheduleGridUpdate();
}
}
void PaintNoiseAction::process(Selection * sel, const Gui3DMouseEvent &, bool selChanged, Type type)
{
// If this is the ending

View file

@ -258,6 +258,15 @@ class SmoothHeightAction : public TerrainAction
void process(Selection * sel, const Gui3DMouseEvent & event, bool selChanged, Type type);
};
class SmoothSlopeAction : public TerrainAction
{
public:
SmoothSlopeAction(TerrainEditor * editor) : TerrainAction(editor){}
StringTableEntry getName(){return("smoothSlope");}
void process(Selection * sel, const Gui3DMouseEvent & event, bool selChanged, Type type);
};
class PaintNoiseAction : public TerrainAction
{
public:

View file

@ -710,6 +710,7 @@ TerrainEditor::TerrainEditor() :
mActions.push_back(new AdjustHeightAction(this));
mActions.push_back(new FlattenHeightAction(this));
mActions.push_back(new SmoothHeightAction(this));
mActions.push_back(new SmoothSlopeAction(this));
mActions.push_back(new PaintNoiseAction(this));
//mActions.push_back(new ThermalErosionAction(this));