Browse Source

Merge pull request #1388 from Azaezel/alpha41/erosionBrushes

additional terrain brushes
Brian Roberts 8 months ago
parent
commit
7bb8587db5
40 changed files with 342 additions and 55 deletions
  1. 186 33
      Engine/source/gui/worldEditor/terrainActions.cpp
  2. 78 11
      Engine/source/gui/worldEditor/terrainActions.h
  3. 7 2
      Engine/source/gui/worldEditor/terrainEditor.cpp
  4. BIN
      Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_d.png
  5. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_d_image.asset.taml
  6. BIN
      Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_h.png
  7. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_h_image.asset.taml
  8. BIN
      Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_n.png
  9. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_n_image.asset.taml
  10. BIN
      Templates/BaseGame/game/tools/worldEditor/images/erodeH_d.png
  11. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/erodeH_d_image.asset.taml
  12. BIN
      Templates/BaseGame/game/tools/worldEditor/images/erodeH_h.png
  13. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/erodeH_h_image.asset.taml
  14. BIN
      Templates/BaseGame/game/tools/worldEditor/images/erodeH_n.png
  15. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/erodeH_n_image.asset.taml
  16. BIN
      Templates/BaseGame/game/tools/worldEditor/images/erodeT_d.png
  17. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/erodeT_d_image.asset.taml
  18. BIN
      Templates/BaseGame/game/tools/worldEditor/images/erodeT_h.png
  19. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/erodeT_h_image.asset.taml
  20. BIN
      Templates/BaseGame/game/tools/worldEditor/images/erodeT_n.png
  21. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/erodeT_n_image.asset.taml
  22. BIN
      Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_d.png
  23. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_d_image.asset.taml
  24. BIN
      Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_h.png
  25. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_h_image.asset.taml
  26. BIN
      Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_n.png
  27. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_n_image.asset.taml
  28. BIN
      Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_d.png
  29. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_d_image.asset.taml
  30. BIN
      Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_h.png
  31. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_h_image.asset.taml
  32. BIN
      Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_n.png
  33. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_n_image.asset.taml
  34. BIN
      Templates/BaseGame/game/tools/worldEditor/images/paste_terr_d.png
  35. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/paste_terr_d_image.asset.taml
  36. BIN
      Templates/BaseGame/game/tools/worldEditor/images/paste_terr_h.png
  37. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/paste_terr_h_image.asset.taml
  38. BIN
      Templates/BaseGame/game/tools/worldEditor/images/paste_terr_n.png
  39. 3 0
      Templates/BaseGame/game/tools/worldEditor/images/paste_terr_n_image.asset.taml
  40. 17 9
      Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript

+ 186 - 33
Engine/source/gui/worldEditor/terrainActions.cpp

@@ -26,6 +26,7 @@
 
 #include "gui/core/guiCanvas.h"
 
+TerrainScratchPad gTerrainScratchPad;
 //------------------------------------------------------------------------------
 bool TerrainAction::isValid(GridInfo tile)
 {
@@ -746,60 +747,212 @@ 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 this is the ending
+   // mouse down event, then
+   // update the noise values.
+
+   TerrainBlock* tblock = mTerrainEditor->getActiveTerrain();
+   if (!tblock)
+      return;
+
+   F32 selRange = sel->getMaxHeight()-sel->getMinHeight();
+   F32 avg = sel->getAvgHeight();
+   if (selChanged)
    {
-      TerrainBlock *tblock = mTerrainEditor->getActiveTerrain();
-      if ( !tblock )
-         return;
-      
-      F32 height = 0;
-      F32 maxHeight = 0;
-      U32 shift = getBinLog2( TerrainBlock::BlockSize );
+      F32 heightDiff = 0;
 
-      for ( U32 x = 0; x < TerrainBlock::BlockSize; x++ )
+      for (U32 i = 0; i < sel->size(); i++)
       {
-         for ( U32 y = 0; y < TerrainBlock::BlockSize; y++ )
-         {
-            height = fixedToFloat( tblock->getHeight( x, y ) );
-            mTerrainHeights[ x + (y << 8)] = height;
+         if (!isValid((*sel)[i]))
+            continue;
 
-            if ( height > maxHeight )
-               maxHeight = height;
-         }
+         mTerrainEditor->getUndoSel()->add((*sel)[i]);
+
+         F32 bias = ((*sel)[i].mHeight - avg) / selRange;
+         F32 nudge = mRandF(-mTerrainEditor->getBrushPressure(), mTerrainEditor->getBrushPressure());
+         F32 heightTarg = mRoundF((*sel)[i].mHeight - bias * nudge, mTerrainEditor->getBrushPressure() * 2.0f) ;
+         heightDiff = heightTarg - (*sel)[i].mHeight;
+         (*sel)[i].mHeight += heightDiff * (*sel)[i].mWeight;
+
+         if ((*sel)[i].mHeight > mTerrainEditor->mTileMaxHeight)
+            (*sel)[i].mHeight = mTerrainEditor->mTileMaxHeight;
+
+         if ((*sel)[i].mHeight < mTerrainEditor->mTileMinHeight)
+            (*sel)[i].mHeight = mTerrainEditor->mTileMinHeight;
+         mTerrainEditor->setGridInfo((*sel)[i]);
       }
 
-      //mNoise.erodeThermal( &mTerrainHeights, &mNoiseData, 30.0f, 5.0f, 5, TerrainBlock::BlockSize, tblock->getSquareSize(), maxHeight );
-         
-      mNoise.erodeHydraulic( &mTerrainHeights, &mNoiseData, 1, TerrainBlock::BlockSize );
+      mTerrainEditor->scheduleGridUpdate();
+   }
+}
+
+void HydraulicErosionAction::process(Selection* sel, const Gui3DMouseEvent&, bool selChanged, Type type)
+{
+   // If this is the ending
+   // mouse down event, then
+   // update the noise values.
+
+   TerrainBlock* tblock = mTerrainEditor->getActiveTerrain();
+   if (!tblock)
+      return;
 
+   F32 selRange = sel->getMaxHeight() - sel->getMinHeight();
+   F32 avg = sel->getAvgHeight();
+   if (selChanged)
+   {
       F32 heightDiff = 0;
+      const F32 squareSize = tblock->getSquareSize();
 
-      for( U32 i = 0; i < sel->size(); i++ )
+      for (U32 i = 0; i < sel->size(); i++)
       {
+         if (!isValid((*sel)[i]))
+            continue;
+
          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)];
+         Point2F p;
+         Point3F norm;
+
+         p.x = (*sel)[i].mGridPoint.gridPos.x * squareSize;
+         p.y = (*sel)[i].mGridPoint.gridPos.y * squareSize;
+         tblock->getNormal(p, &norm, true);
+
+         F32 bias = mPow(norm.z,3.0f) * ((*sel)[i].mHeight - avg) / selRange;
+         F32 nudge = mRandF(-mTerrainEditor->getBrushPressure(), mTerrainEditor->getBrushPressure());
+
+         heightDiff = bias * (-(*sel)[i].mHeight + bias * nudge) / tblock->getObjBox().len_z() * 2.0;
+
+         (*sel)[i].mHeight += heightDiff * (*sel)[i].mWeight;
+
+         if ((*sel)[i].mHeight > mTerrainEditor->mTileMaxHeight)
+            (*sel)[i].mHeight = mTerrainEditor->mTileMaxHeight;
+
+         if ((*sel)[i].mHeight < mTerrainEditor->mTileMinHeight)
+            (*sel)[i].mHeight = mTerrainEditor->mTileMinHeight;
+         mTerrainEditor->setGridInfo((*sel)[i]);
+      }
+
+      mTerrainEditor->scheduleGridUpdate();
+   }
+
+}
+
+void TerrainScratchPad::addTile(F32 height, U8 material)
+{
+   mContents.push_back(new gridStub(height, material));
+
+   mBottom = mMin(height, mBottom);
+   mTop = mMax(height, mTop);
+};
+
+void TerrainScratchPad::clear()
+{
+   for (U32 i = 0; i < mContents.size(); i++)
+      delete(mContents[i]);
+   mContents.clear();
+   mBottom = F32_MAX;
+   mTop = F32_MIN_EX;
+}
 
-         (*sel)[i].mHeight -= (heightDiff * (*sel)[i].mWeight);
+void copyAction::process(Selection* sel, const Gui3DMouseEvent&, bool selChanged, Type type)
+{
+   gTerrainScratchPad.clear();
+   for (U32 i=0;i<sel->size();i++)
+   {
+      if (isValid((*sel)[i]))
+         gTerrainScratchPad.addTile((*sel)[i].mHeight, (*sel)[i].mMaterial);
+      else
+         gTerrainScratchPad.addTile(0, 0);
+   }
+}
+
+void pasteAction::process(Selection* sel, const Gui3DMouseEvent&, bool selChanged, Type type)
+{
+   if (gTerrainScratchPad.size() == 0)
+      return;
+
+   if (gTerrainScratchPad.size() != sel->size())
+      return;
 
+   if (type != Begin)
+      return;
+
+   for (U32 i = 0; i < sel->size(); i++)
+   {
+      if (isValid((*sel)[i]))
+      {
+         mTerrainEditor->getUndoSel()->add((*sel)[i]);
+         (*sel)[i].mHeight = gTerrainScratchPad[i]->mHeight;
+         (*sel)[i].mMaterial = gTerrainScratchPad[i]->mMaterial;
          mTerrainEditor->setGridInfo((*sel)[i]);
       }
+   }
+   mTerrainEditor->scheduleGridUpdate();
+   mTerrainEditor->scheduleMaterialUpdate();
+}
+
+void pasteUpAction::process(Selection* sel, const Gui3DMouseEvent&, bool selChanged, Type type)
+{
+   if (gTerrainScratchPad.size() == 0)
+      return;
+
+   if (gTerrainScratchPad.size() != sel->size())
+      return;
 
-      mTerrainEditor->gridUpdateComplete();
+   if (type != Begin)
+      return;
+   F32 floor = F32_MAX;
+   for (U32 i = 0; i < sel->size(); i++)
+   {
+      floor = mMin((*sel)[i].mHeight, floor);
+   }
+   for (U32 i = 0; i < sel->size(); i++)
+   {
+      if (isValid((*sel)[i]))
+      {
+         mTerrainEditor->getUndoSel()->add((*sel)[i]);
+         (*sel)[i].mHeight = gTerrainScratchPad[i]->mHeight - gTerrainScratchPad.mBottom + floor;
+         (*sel)[i].mMaterial = gTerrainScratchPad[i]->mMaterial;
+         mTerrainEditor->setGridInfo((*sel)[i]);
+      }
    }
+   mTerrainEditor->scheduleGridUpdate();
+   mTerrainEditor->scheduleMaterialUpdate();
 }
-*/
 
+void pasteDownAction::process(Selection* sel, const Gui3DMouseEvent&, bool selChanged, Type type)
+{
+   if (gTerrainScratchPad.size() == 0)
+      return;
+
+   if (gTerrainScratchPad.size() != sel->size())
+      return;
+
+   if (type != Begin)
+      return;
+
+   F32 ceiling = F32_MIN_EX;
+   for (U32 i = 0; i < sel->size(); i++)
+   {
+      ceiling = mMax((*sel)[i].mHeight, ceiling);
+   }
+
+   for (U32 i = 0; i < sel->size(); i++)
+   {
+      if (isValid((*sel)[i]))
+      {
+         mTerrainEditor->getUndoSel()->add((*sel)[i]);
+         (*sel)[i].mHeight = gTerrainScratchPad[i]->mHeight - gTerrainScratchPad.mTop + ceiling;
+         (*sel)[i].mMaterial = gTerrainScratchPad[i]->mMaterial;
+         mTerrainEditor->setGridInfo((*sel)[i]);
+      }
+   }
+   mTerrainEditor->scheduleGridUpdate();
+   mTerrainEditor->scheduleMaterialUpdate();
+}
 
 IMPLEMENT_CONOBJECT( TerrainSmoothAction );
 

+ 78 - 11
Engine/source/gui/worldEditor/terrainActions.h

@@ -302,27 +302,94 @@ class PaintNoiseAction : public TerrainAction
       F32 mScale;
 };
 
-/*
+
 class ThermalErosionAction : public TerrainAction
 {
    public:
       ThermalErosionAction(TerrainEditor * editor) 
       : TerrainAction(editor)
       {
-         mNoise.setSeed( 1 );//Sim::getCurrentTime() );
-         mNoiseData.setSize( TerrainBlock::BlockSize * TerrainBlock::BlockSize );
-         mTerrainHeights.setSize( TerrainBlock::BlockSize * TerrainBlock::BlockSize );
-      }
-      
+      }      
       StringTableEntry getName(){return("thermalErode");}
-
       void process(Selection * sel, const Gui3DMouseEvent & event, bool selChanged, Type type);
+};
 
-      Noise2D mNoise;
-      Vector<F32> mNoiseData;
-      Vector<F32> mTerrainHeights;
+class HydraulicErosionAction : public TerrainAction
+{
+public:
+   HydraulicErosionAction(TerrainEditor* editor)
+      : TerrainAction(editor)
+   {
+   }
+
+   StringTableEntry getName() { return("hydraulicErode"); }
+   void process(Selection* sel, const Gui3DMouseEvent& event, bool selChanged, Type type);
+};
+
+class TerrainScratchPad
+{
+public:
+   F32 mBottom, mTop;
+   TerrainScratchPad(): mBottom(F32_MAX), mTop(F32_MIN_EX){};
+   ~TerrainScratchPad() { mContents.clear(); };
+   void clear();
+   class gridStub
+   {
+   public:
+      gridStub(F32 height, U8 material) : mHeight(height), mMaterial(material) {};
+      F32 mHeight;
+      U8 mMaterial;
+   };
+   void addTile(F32 height, U8 material);
+   U32 size() { return(mContents.size()); };
+   gridStub* operator [](U32 index) { return mContents[index]; };
+private:
+   Vector<gridStub*> mContents;
+};
+
+class copyAction : public TerrainAction
+{
+public:
+   copyAction(TerrainEditor* editor)
+      : TerrainAction(editor)
+   {
+   }
+   StringTableEntry getName() { return("copy"); }
+   void process(Selection* sel, const Gui3DMouseEvent& event, bool selChanged, Type type);
+};
+
+class pasteAction : public TerrainAction
+{
+public:
+   pasteAction(TerrainEditor* editor)
+      : TerrainAction(editor)
+   {
+   }
+   StringTableEntry getName() { return("paste"); }
+   void process(Selection* sel, const Gui3DMouseEvent& event, bool selChanged, Type type);
+};
+
+class pasteUpAction : public TerrainAction
+{
+public:
+   pasteUpAction(TerrainEditor* editor)
+      : TerrainAction(editor)
+   {
+   }
+   StringTableEntry getName() { return("pasteUp"); }
+   void process(Selection* sel, const Gui3DMouseEvent& event, bool selChanged, Type type);
+};
+
+class pasteDownAction : public TerrainAction
+{
+public:
+   pasteDownAction(TerrainEditor* editor)
+      : TerrainAction(editor)
+   {
+   }
+   StringTableEntry getName() { return("pasteDown"); }
+   void process(Selection* sel, const Gui3DMouseEvent& event, bool selChanged, Type type);
 };
-*/
 
 /// An undo action used to perform terrain wide smoothing.
 class TerrainSmoothAction : public UndoAction

+ 7 - 2
Engine/source/gui/worldEditor/terrainEditor.cpp

@@ -712,8 +712,13 @@ 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));
+   mActions.push_back(new copyAction(this));
+   mActions.push_back(new pasteAction(this));
+   mActions.push_back(new pasteUpAction(this));
+   mActions.push_back(new pasteDownAction(this));
+   
 
    // set the default action
    mCurrentAction = mActions[0];

BIN
Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_d.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_d_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="Copy_terr_d_image"
+    imageFile="@assetFile=Copy_terr_d.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_h.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_h_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="Copy_terr_h_image"
+    imageFile="@assetFile=Copy_terr_h.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_n.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/Copy_terr_n_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="Copy_terr_n_image"
+    imageFile="@assetFile=Copy_terr_n.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/erodeH_d.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/erodeH_d_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="erodeH_d_image"
+    imageFile="@assetFile=erodeH_d.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/erodeH_h.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/erodeH_h_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="erodeH_h_image"
+    imageFile="@assetFile=erodeH_h.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/erodeH_n.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/erodeH_n_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="erodeH_n_image"
+    imageFile="@assetFile=erodeH_n.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/erodeT_d.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/erodeT_d_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="erodeT_d_image"
+    imageFile="@assetFile=erodeT_d.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/erodeT_h.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/erodeT_h_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="erodeT_h_image"
+    imageFile="@assetFile=erodeT_h.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/erodeT_n.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/erodeT_n_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="erodeT_n_image"
+    imageFile="@assetFile=erodeT_n.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_d.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_d_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="pasteDown_terr_d_image"
+    imageFile="@assetFile=pasteDown_terr_d.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_h.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_h_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="pasteDown_terr_h_image"
+    imageFile="@assetFile=pasteDown_terr_h.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_n.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/pasteDown_terr_n_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="pasteDown_terr_n_image"
+    imageFile="@assetFile=pasteDown_terr_n.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_d.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_d_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="pasteUp_terr_d_image"
+    imageFile="@assetFile=pasteUp_terr_d.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_h.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_h_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="pasteUp_terr_h_image"
+    imageFile="@assetFile=pasteUp_terr_h.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_n.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/pasteUp_terr_n_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="pasteUp_terr_n_image"
+    imageFile="@assetFile=pasteUp_terr_n.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/paste_terr_d.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/paste_terr_d_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="paste_terr_d_image"
+    imageFile="@assetFile=paste_terr_d.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/paste_terr_h.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/paste_terr_h_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="paste_terr_h_image"
+    imageFile="@assetFile=paste_terr_h.png"/>

BIN
Templates/BaseGame/game/tools/worldEditor/images/paste_terr_n.png


+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/images/paste_terr_n_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="paste_terr_n_image"
+    imageFile="@assetFile=paste_terr_n.png"/>

+ 17 - 9
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,17 @@ 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.addButton("Copy", "ToolsModule:setHeight_n_image", "ETerrainEditor.switchAction( copy );", "", "copy", "ctrl C");
+   EWToolsPaletteWindow.addButton("Paste", "ToolsModule:setHeight_n_image", "ETerrainEditor.switchAction( paste );", "", "paste", "ctrl v"); 
+   EWToolsPaletteWindow.addButton("pasteUp", "ToolsModule:setHeight_n_image", "ETerrainEditor.switchAction( pasteUp );", "", "pasteUp", "ctrl b");
+   EWToolsPaletteWindow.addButton("PasteDown", "ToolsModule:setHeight_n_image", "ETerrainEditor.switchAction( pasteDown );", "", "pasteDown", "ctrl n");
    EWToolsPaletteWindow.refresh();
 }