ソースを参照

work towards adding erosion noise

AzaezelX 7 ヶ月 前
コミット
329ffab86c

+ 53 - 32
Engine/source/gui/worldEditor/terrainActions.cpp

@@ -749,42 +749,56 @@ void PaintNoiseAction::process(Selection * sel, const Gui3DMouseEvent &, bool se
 
 void ThermalErosionAction::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);
+   // If this is the ending
+   // mouse down event, then
+   // update the noise values.
+   U32 shift = getBinLog2(mNoiseSize);
+   TerrainBlock* tblock = mTerrainEditor->getActiveTerrain();
+   if (!tblock)
+      return;
 
-      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 );
+   mSelectionOrigin = Point2I(S32_MAX, S32_MAX);
 
-      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)];
+   F32 height = 0;
+   F32 maxHeight = 0;
+   U32 i = 0;
+   for (i=0; i < sel->size(); i++)
+   {
+      mSelectionOrigin.x = S32(mMin(F32((*sel)[i].mGridPoint.gridPos.x), F32(mSelectionOrigin.x)));
+      mSelectionOrigin.y = S32(mMin(F32((*sel)[i].mGridPoint.gridPos.y), F32(mSelectionOrigin.y)));
+      height = fixedToFloat(tblock->getHeight((*sel)[i].mGridPoint.gridPos));
+      if (height > maxHeight)
+         maxHeight = height;
+   }
 
-            if (height > maxHeight)
-               maxHeight = height;
-         }
-      }
+   for (i = 0; i < mTerrainHeights.size(); i++)
+   {
+      mTerrainHeights[i] = 0;
+   }
 
-      mNoise.erodeThermal( &mTerrainHeights, &mNoiseData, 45.0f, 0.5f, 12, size, tblock->getSquareSize(), maxHeight );
+   for (i = 0; i < sel->size(); i++)
+   {
+      mTerrainHeights[((*sel)[i].mGridPoint.gridPos.x - mSelectionOrigin.x) + (((*sel)[i].mGridPoint.gridPos.y - mSelectionOrigin.y) << shift)] = (*sel)[i].mHeight;
+   }
 
-      //mNoise.erodeHydraulic(&mTerrainHeights, &mNoiseData, 1, tblock->getBlockSize());
+   mNoise.setSeed(Sim::getCurrentTime());
+   //mNoise.fBm(&mNoiseData, mNoiseSize, 12, 1.0f, 5.0f);
+   //generate noise based on terrain hieghts
+   mNoise.rigidMultiFractal( &mNoiseData, &mTerrainHeights, mNoiseSize, 12, 1.0f, 5.0f );
+   //erode the noise
+   mNoise.erodeThermal(&mNoiseData, &mTerrainHeights, 45.0f, 0.5f, 12, mNoiseSize, 1, maxHeight);
 
-      F32 heightDiff = 0;
+   mNoise.getMinMax(&mTerrainHeights, &mMinMaxNoise.x, &mMinMaxNoise.y, mNoiseSize);
+   mScale = (mMinMaxNoise.x - mMinMaxNoise.y) / maxHeight;
 
-      for (U32 i = 0; i < sel->size(); i++)
+   if (selChanged)
+   {
+      F32 heightDiff = 0;
+      for (i = 0; i < sel->size(); i++)
       {
+         if (!isValid((*sel)[i]))
+            continue;
+
          mTerrainEditor->getUndoSel()->add((*sel)[i]);
 
          const Point2I& gridPos = (*sel)[i].mGridPoint.gridPos;
@@ -794,15 +808,22 @@ void ThermalErosionAction::process(Selection * sel, const Gui3DMouseEvent &, boo
          // 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 - mTerrainHeights[(gridPos.x - mSelectionOrigin.x) + ((gridPos.y-mSelectionOrigin.y) << shift)]) * mScale;
 
-         (*sel)[i].mHeight -= (heightDiff * (*sel)[i].mWeight) / maxHeight;
+         (*sel)[i].mHeight += heightDiff * (*sel)[i].mWeight * mTerrainEditor->getBrushPressure();
+
+         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->gridUpdateComplete();
+      mTerrainEditor->scheduleGridUpdate();
    }
+
 }
 
 void HydraulicErosionAction::process(Selection* sel, const Gui3DMouseEvent&, bool selChanged, Type type)
@@ -826,7 +847,7 @@ void HydraulicErosionAction::process(Selection* sel, const Gui3DMouseEvent&, boo
          for (U32 y = 0; y < size; y++)
          {
             height = fixedToFloat(tblock->getHeight(Point2I(x, y)));
-            mTerrainHeights[x + (y << 8)] = height * mNoiseData[x + (y << 8)];
+            mTerrainHeights[x + (y << shift)] = height * mNoiseData[x + (y << shift)];
 
             if (height > maxHeight)
                maxHeight = height;

+ 14 - 1
Engine/source/gui/worldEditor/terrainActions.h

@@ -307,18 +307,31 @@ class ThermalErosionAction : public TerrainAction
 {
    public:
       ThermalErosionAction(TerrainEditor * editor) 
-      : TerrainAction(editor)
+      : TerrainAction(editor),
+         mNoiseSize(256)
       {
          mNoise.setSeed( 1 );//Sim::getCurrentTime() );
+         mNoiseData.setSize(mNoiseSize * mNoiseSize);
+         mTerrainHeights.setSize(mNoiseSize * mNoiseSize);
+         mNoise.fBm(&mNoiseData, mNoiseSize, 12, 1.0f, 5.0f);
+         //Vector<F32> scratch = mNoiseData;
+         //mNoise.rigidMultiFractal( &mNoiseData, &scratch, TerrainBlock::BlockSize, 12, 1.0f, 5.0f );
+         mNoise.getMinMax(&mNoiseData, &mMinMaxNoise.x, &mMinMaxNoise.y, mNoiseSize);
+
+         mScale = 1.5f / (mMinMaxNoise.x - mMinMaxNoise.y);
       }
       
       StringTableEntry getName(){return("thermalErode");}
 
       void process(Selection * sel, const Gui3DMouseEvent & event, bool selChanged, Type type);
 
+      const U32 mNoiseSize;
       Noise2D mNoise;
       Vector<F32> mNoiseData;
       Vector<F32> mTerrainHeights;
+      Point2F mMinMaxNoise;
+      Point2I mSelectionOrigin;
+      F32 mScale;
 };
 
 class HydraulicErosionAction : public TerrainAction