diff --git a/Engine/source/gui/worldEditor/terrainActions.cpp b/Engine/source/gui/worldEditor/terrainActions.cpp index 2552a4d78..630aed26c 100644 --- a/Engine/source/gui/worldEditor/terrainActions.cpp +++ b/Engine/source/gui/worldEditor/terrainActions.cpp @@ -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 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 ); diff --git a/Engine/source/gui/worldEditor/terrainActions.h b/Engine/source/gui/worldEditor/terrainActions.h index c59451717..d04c1658e 100644 --- a/Engine/source/gui/worldEditor/terrainActions.h +++ b/Engine/source/gui/worldEditor/terrainActions.h @@ -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 mNoiseData; Vector 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 mNoiseData; + Vector mTerrainHeights; +}; + /// An undo action used to perform terrain wide smoothing. class TerrainSmoothAction : public UndoAction diff --git a/Engine/source/gui/worldEditor/terrainEditor.cpp b/Engine/source/gui/worldEditor/terrainEditor.cpp index ff3ee9e30..30ac24d28 100644 --- a/Engine/source/gui/worldEditor/terrainEditor.cpp +++ b/Engine/source/gui/worldEditor/terrainEditor.cpp @@ -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 diff --git a/Engine/source/util/noise2d.cpp b/Engine/source/util/noise2d.cpp index 24c1579dd..34405bd56 100644 --- a/Engine/source/util/noise2d.cpp +++ b/Engine/source/util/noise2d.cpp @@ -345,7 +345,7 @@ bool Noise2D::erodeThermal(Vector *src, Vector *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 diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript index 5ba3a9e08..4aca0698c 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript @@ -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(); }