add erosion brushes

todo: sort why noise... isn't.
This commit is contained in:
AzaezelX 2025-02-17 05:48:15 -06:00
parent 818d76d481
commit 2eb2cbc302
5 changed files with 113 additions and 36 deletions

View file

@ -746,51 +746,57 @@ void PaintNoiseAction::process(Selection * sel, const Gui3DMouseEvent &, bool se
mTerrainEditor->scheduleGridUpdate();
}
}
/*
void ThermalErosionAction::process(Selection * sel, const Gui3DMouseEvent &, bool selChanged, Type)
void ThermalErosionAction::process(Selection * sel, const Gui3DMouseEvent &, bool selChanged, Type type)
{
if( selChanged )
if (selChanged)
{
TerrainBlock *tblock = mTerrainEditor->getActiveTerrain();
if ( !tblock )
TerrainBlock* tblock = mTerrainEditor->getActiveTerrain();
if (!tblock)
return;
U32 size = tblock->getBlockSize();
F32 height = 0;
F32 maxHeight = 0;
U32 shift = getBinLog2( TerrainBlock::BlockSize );
U32 shift = getBinLog2(size);
for ( U32 x = 0; x < TerrainBlock::BlockSize; x++ )
mNoiseData.setSize(size * size);
mTerrainHeights.setSize(size * size);
mNoise.fBm(&mNoiseData, size, 12, 1.0f, 5.0f);
Vector<F32> scratch = mNoiseData;
mNoise.rigidMultiFractal( &mNoiseData, &scratch, size, 12, 1.0f, 5.0f );
for (U32 x = 0; x < size; x++)
{
for ( U32 y = 0; y < TerrainBlock::BlockSize; y++ )
for (U32 y = 0; y < size; y++)
{
height = fixedToFloat( tblock->getHeight( x, y ) );
mTerrainHeights[ x + (y << 8)] = height;
height = fixedToFloat(tblock->getHeight(Point2I(x, y)));
mTerrainHeights[x + (y << 8)] = height * mNoiseData[x + (y << 8)];
if ( height > maxHeight )
if (height > maxHeight)
maxHeight = height;
}
}
//mNoise.erodeThermal( &mTerrainHeights, &mNoiseData, 30.0f, 5.0f, 5, TerrainBlock::BlockSize, tblock->getSquareSize(), maxHeight );
mNoise.erodeHydraulic( &mTerrainHeights, &mNoiseData, 1, TerrainBlock::BlockSize );
mNoise.erodeThermal( &mTerrainHeights, &mNoiseData, 45.0f, 0.5f, 12, size, tblock->getSquareSize(), maxHeight );
//mNoise.erodeHydraulic(&mTerrainHeights, &mNoiseData, 1, tblock->getBlockSize());
F32 heightDiff = 0;
for( U32 i = 0; i < sel->size(); i++ )
for (U32 i = 0; i < sel->size(); i++)
{
mTerrainEditor->getUndoSel()->add((*sel)[i]);
const Point2I &gridPos = (*sel)[i].mGridPoint.gridPos;
const Point2I& gridPos = (*sel)[i].mGridPoint.gridPos;
// Need to get the height difference
// between the current height and the
// erosion height to properly apply the
// softness and pressure settings of the brush
// for this selection.
heightDiff = (*sel)[i].mHeight - mNoiseData[ gridPos.x + (gridPos.y << shift)];
heightDiff = (*sel)[i].mHeight - mNoiseData[gridPos.x + (gridPos.y << shift)];
(*sel)[i].mHeight -= (heightDiff * (*sel)[i].mWeight);
(*sel)[i].mHeight -= (heightDiff * (*sel)[i].mWeight) / maxHeight;
mTerrainEditor->setGridInfo((*sel)[i]);
}
@ -798,8 +804,60 @@ void ThermalErosionAction::process(Selection * sel, const Gui3DMouseEvent &, boo
mTerrainEditor->gridUpdateComplete();
}
}
*/
void HydraulicErosionAction::process(Selection* sel, const Gui3DMouseEvent&, bool selChanged, Type type)
{
if (selChanged)
{
TerrainBlock* tblock = mTerrainEditor->getActiveTerrain();
if (!tblock)
return;
U32 size = tblock->getBlockSize();
F32 height = 0;
F32 maxHeight = 0;
U32 shift = getBinLog2(size);
mNoiseData.setSize(size * size);
mTerrainHeights.setSize(size * size);
mNoise.fBm(&mNoiseData, size, 12, 1.0f, 5.0f);
for (U32 x = 0; x < size; x++)
{
for (U32 y = 0; y < size; y++)
{
height = fixedToFloat(tblock->getHeight(Point2I(x, y)));
mTerrainHeights[x + (y << 8)] = height * mNoiseData[x + (y << 8)];
if (height > maxHeight)
maxHeight = height;
}
}
mNoise.erodeHydraulic(&mTerrainHeights, &mNoiseData, 1, size);
F32 heightDiff = 0;
for (U32 i = 0; i < sel->size(); i++)
{
mTerrainEditor->getUndoSel()->add((*sel)[i]);
const Point2I& gridPos = (*sel)[i].mGridPoint.gridPos;
// Need to get the height difference
// between the current height and the
// erosion height to properly apply the
// softness and pressure settings of the brush
// for this selection.
heightDiff = (*sel)[i].mHeight - mNoiseData[gridPos.x + (gridPos.y << shift)];
(*sel)[i].mHeight -= (heightDiff * (*sel)[i].mWeight) / maxHeight;
mTerrainEditor->setGridInfo((*sel)[i]);
}
mTerrainEditor->gridUpdateComplete();
}
}
IMPLEMENT_CONOBJECT( TerrainSmoothAction );

View file

@ -302,7 +302,7 @@ class PaintNoiseAction : public TerrainAction
F32 mScale;
};
/*
class ThermalErosionAction : public TerrainAction
{
public:
@ -310,8 +310,6 @@ class ThermalErosionAction : public TerrainAction
: TerrainAction(editor)
{
mNoise.setSeed( 1 );//Sim::getCurrentTime() );
mNoiseData.setSize( TerrainBlock::BlockSize * TerrainBlock::BlockSize );
mTerrainHeights.setSize( TerrainBlock::BlockSize * TerrainBlock::BlockSize );
}
StringTableEntry getName(){return("thermalErode");}
@ -322,7 +320,23 @@ class ThermalErosionAction : public TerrainAction
Vector<F32> mNoiseData;
Vector<F32> mTerrainHeights;
};
*/
class HydraulicErosionAction : public TerrainAction
{
public:
HydraulicErosionAction(TerrainEditor* editor)
: TerrainAction(editor)
{
mNoise.setSeed(1);//Sim::getCurrentTime() );
}
StringTableEntry getName() { return("hydraulicErode"); }
void process(Selection* sel, const Gui3DMouseEvent& event, bool selChanged, Type type);
Noise2D mNoise;
Vector<F32> mNoiseData;
Vector<F32> mTerrainHeights;
};
/// An undo action used to perform terrain wide smoothing.
class TerrainSmoothAction : public UndoAction

View file

@ -712,7 +712,8 @@ TerrainEditor::TerrainEditor() :
mActions.push_back(new SmoothHeightAction(this));
mActions.push_back(new SmoothSlopeAction(this));
mActions.push_back(new PaintNoiseAction(this));
//mActions.push_back(new ThermalErosionAction(this));
mActions.push_back(new ThermalErosionAction(this));
mActions.push_back(new HydraulicErosionAction(this));
// set the default action

View file

@ -345,7 +345,7 @@ bool Noise2D::erodeThermal(Vector<F32> *src, Vector<F32> *dst, F32 slope, F32 ma
//dMemset( r.address(), 0, r.memSize() );
F32 conservation = 1.0f - mClampF(materialLoss, 0.0f, 100.0f)/100.0f;
slope = mClampF(conservation, 0.0f, 89.0f); // clamp to 0-89 degrees
slope = mMin(slope, mClampF(conservation, 0.0f, 89.0f)); // clamp to 0-89 degrees
F32 talusConst = mTan(mDegToRad(slope)) * squareSize; // in world units
talusConst = talusConst * (fmax-fmin) / maxHeight; // scale to current height units

View file

@ -1205,10 +1205,12 @@ function TerrainEditorPlugin::onWorldEditorStartup( %this )
%map.bindCmd( keyboard, "4", "ToolsPaletteArray->smoothHeight.performClick();", "" ); // Average Height
%map.bindCmd( keyboard, "5", "ToolsPaletteArray->smoothSlope.performClick();", "" ); // Smooth Slope
%map.bindCmd( keyboard, "6", "ToolsPaletteArray->paintNoise.performClick();", "" ); // Noise
%map.bindCmd( keyboard, "7", "ToolsPaletteArray->flattenHeight.performClick();", "" ); // Flatten
%map.bindCmd( keyboard, "8", "ToolsPaletteArray->setHeight.performClick();", "" ); // Set Height
%map.bindCmd( keyboard, "9", "ToolsPaletteArray->setEmpty.performClick();", "" ); // Clear Terrain
%map.bindCmd( keyboard, "0", "ToolsPaletteArray->clearEmpty.performClick();", "" ); // Restore Terrain
%map.bindCmd( keyboard, "6", "ToolsPaletteArray->thermalErode.performClick();", "" ); // Noise
%map.bindCmd( keyboard, "7", "ToolsPaletteArray->hydraulicErode.performClick();", "" ); // Noise
%map.bindCmd( keyboard, "8", "ToolsPaletteArray->flattenHeight.performClick();", "" ); // Flatten
%map.bindCmd( keyboard, "9", "ToolsPaletteArray->setHeight.performClick();", "" ); // Set Height
%map.bindCmd( keyboard, "0", "ToolsPaletteArray->setEmpty.performClick();", "" ); // Clear Terrain
%map.bindCmd( keyboard, "shift 0", "ToolsPaletteArray->clearEmpty.performClick();", "" ); // Restore Terrain
%map.bindCmd( keyboard, "v", "EWTerrainEditToolbarBrushType->ellipse.performClick();", "" );// Circle Brush
%map.bindCmd( keyboard, "b", "EWTerrainEditToolbarBrushType->box.performClick();", "" );// Box Brush
%map.bindCmd( keyboard, "=", "TerrainEditorPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size
@ -1248,11 +1250,13 @@ function EditorGui::SetTerrainPalletBar()
EWToolsPaletteWindow.addButton("LowerHeight", "ToolsModule:lowerHeight_n_image", "ETerrainEditor.switchAction( lowerHeight );", "", "Lower Height", "3");
EWToolsPaletteWindow.addButton("SmoothHeight", "ToolsModule:smoothHeight_n_image", "ETerrainEditor.switchAction( smoothHeight );", "", "Smooth Height", "4");
EWToolsPaletteWindow.addButton("SmoothSlope", "ToolsModule:softCurve_n_image", "ETerrainEditor.switchAction( smoothSlope );", "", "Smooth Slope", "5");
EWToolsPaletteWindow.addButton("PaintNoise", "ToolsModule:brushPaintNoise_n_image", "ETerrainEditor.switchAction( paintNoise );", "", "Paint Noise", "6");
EWToolsPaletteWindow.addButton("FlattenHeight", "ToolsModule:flattenHeight_n_image", "ETerrainEditor.switchAction( flattenHeight );", "", "Flatten Height", "7");
EWToolsPaletteWindow.addButton("SetHeight", "ToolsModule:setHeight_n_image", "ETerrainEditor.switchAction( setHeight );", "", "Set Height", "8");
EWToolsPaletteWindow.addButton("SetEmpty", "ToolsModule:setEmpty_n_image", "ETerrainEditor.switchAction( setEmpty );", "", "Set Empty", "9");
EWToolsPaletteWindow.addButton("ClearEmpty", "ToolsModule:clearEmpty_n_image", "ETerrainEditor.switchAction( clearEmpty );", "", "Clear Empty", "0");
EWToolsPaletteWindow.addButton("PaintNoise", "ToolsModule:brushPaintNoise_n_image", "ETerrainEditor.switchAction( paintNoise );", "", "Paint Noise", "6");
EWToolsPaletteWindow.addButton("thermalErode", "ToolsModule:brushPaintNoise_n_image", "ETerrainEditor.switchAction( thermalErode );", "", "thermal Erode", "7");
EWToolsPaletteWindow.addButton("hydraulicErode", "ToolsModule:brushPaintNoise_n_image", "ETerrainEditor.switchAction( hydraulicErode );", "", "hydraulic Erode", "8");
EWToolsPaletteWindow.addButton("FlattenHeight", "ToolsModule:flattenHeight_n_image", "ETerrainEditor.switchAction( flattenHeight );", "", "Flatten Height", "9");
EWToolsPaletteWindow.addButton("SetHeight", "ToolsModule:setHeight_n_image", "ETerrainEditor.switchAction( setHeight );", "", "Set Height", "0");
EWToolsPaletteWindow.addButton("SetEmpty", "ToolsModule:setEmpty_n_image", "ETerrainEditor.switchAction( setEmpty );", "", "Set Empty", "0");
EWToolsPaletteWindow.addButton("ClearEmpty", "ToolsModule:clearEmpty_n_image", "ETerrainEditor.switchAction( clearEmpty );", "", "Clear Empty", "shift 0");
EWToolsPaletteWindow.refresh();
}