Some additions to ETM

emre2345

03-11-2008 13:00:06

Hi all,

I add smooth, equalization of heights and noise to ETM. Here are the codes, anyone needed these functions can use.

void CLTerrain::EquilizeHeight(int iVertexX, int iVertexZ, float fPower, float fTargetHeight)
{
iVertexX -= CLBrush::GetSingleton()->GetBrushWidth() / 2;
iVertexZ -= CLBrush::GetSingleton()->GetBrushHeight() / 2;

for(size_t i = 0; i < (size_t)CLBrush::GetSingleton()->GetBrushWidth(); ++i)
{
int posX = iVertexX + int(i);
if(posX < 0 || posX >= (int)pTerrainInfo->GetWidth())
continue;

for(size_t j = 0; j < (size_t)CLBrush::GetSingleton()->GetBrushHeight(); ++j)
{
int posZ = iVertexZ + int(j);
if(posZ < 0 || posZ >= (int)pTerrainInfo->GetHeight())
continue;

float &Height = pTerrainInfo->At(posX, posZ);
if(int(Height * pTerrainInfo->GetScaling().y) == int(fTargetHeight))
continue;

else
{
float fDir = (fTargetHeight > Height * pTerrainInfo->GetScaling().y) ? 1 : -1;
Height += CLBrush::GetSingleton()->GetValueAt(i, j) * fPower * CLBrush::GetSingleton()->GetBrushPower() * 0.5 * fDir;
if(Height > 1)
Height = 1;
if(Height < 0)
Height = 0;
}
}
}

UpdateTiles(iVertexX, iVertexZ, iVertexX + CLBrush::GetSingleton()->GetBrushWidth(), iVertexZ + CLBrush::GetSingleton()->GetBrushHeight());
}

void CLTerrain::Smooth(int iVertexX, int iVertexZ, float fPower)
{
iVertexX -= CLBrush::GetSingleton()->GetBrushWidth() / 2;
iVertexZ -= CLBrush::GetSingleton()->GetBrushHeight() / 2;

for(int i = 0; i < CLBrush::GetSingleton()->GetBrushWidth(); ++i)
{
int nPosX = iVertexX + i;
if(nPosX < 0 || (size_t)nPosX >= pTerrainInfo->GetWidth())
continue;

for(int j = 0; j < CLBrush::GetSingleton()->GetBrushHeight(); ++j)
{
float fValue = 0;
float fAverage = 0;

int nPosZ = iVertexZ + j;
if(nPosZ < 0 || (size_t)nPosZ >= pTerrainInfo->GetHeight())
continue;

//Komşu vertexlerin yükseklik değerlerini toplayıp, ortalamasını hesaplar
for(int k = -1; k < 2; ++k)
{
for(int t = -1; t < 2; ++t)
{
float height;
if(pTerrainInfo->at(nPosX + k, nPosZ + t, &height))
{
fValue += height;
fAverage++;
}
}
}

float &Height = pTerrainInfo->At(nPosX, nPosZ);
float fNewValue = fValue / fAverage;
float fDiff = fNewValue - Height;
Height += fDiff * fPower * CLBrush::GetSingleton()->GetBrushPower();
}
}

UpdateTiles(iVertexX, iVertexZ, iVertexX + CLBrush::GetSingleton()->GetBrushWidth(), iVertexZ + CLBrush::GetSingleton()->GetBrushHeight());
}

void CLTerrain::AddNoise(int iVertexX, int iVertexZ, float fPower)
{
iVertexX -= CLBrush::GetSingleton()->GetBrushWidth() / 2;
iVertexZ -= CLBrush::GetSingleton()->GetBrushHeight() / 2;

for(int i = 0; i < CLBrush::GetSingleton()->GetBrushWidth(); ++i)
{
int nPosX = iVertexX + i;
if(iVertexX < 0 || iVertexX >= pTerrainInfo->GetWidth())
continue;

for(int j = 0; j < CLBrush::GetSingleton()->GetBrushHeight(); ++j)
{
int nPosZ = iVertexZ + j;
if(nPosZ < 0 || nPosZ >= pTerrainInfo->GetHeight())
continue;

float nRandChange = (float)(rand() % 10) - 5;
nRandChange /= pTerrainInfo->GetScaling().y;

float &Height = pTerrainInfo->At(nPosX, nPosZ);
Height += nRandChange * fPower * 50;
}
}

UpdateTiles(iVertexX, iVertexZ, iVertexX + CLBrush::GetSingleton()->GetBrushWidth(), iVertexZ + CLBrush::GetSingleton()->GetBrushHeight());
}


CLBrush is the singleton class of mine. You can change it whatever you like

kungfoomasta

03-11-2008 17:51:40

Thank you for sharing, I will definately make use of these when I begin work on my editor. :)

Zero23

13-04-2009 23:24:52

Hi

I use this Smoothing function with ETM3.
void FlatTerrain::smooth(Ogre::Real x, Ogre::Real z, const ET::Brush *brush, Ogre::Real intensity)
{
Rect editRect = determineEditRect(x, z, brush);

for(unsigned int iz = editRect.y1; iz <= editRect.y2; ++iz)
{
if(iz < 0 || (size_t)iz >= getGridHeight())
continue;

for(unsigned int ix = editRect.x1; ix <= editRect.x2; ++ix)
{
if(ix < 0 || (size_t)ix >= getGridWidth())
continue;

float fValue = 0;
float fAverage = 0;

for(int k = -1; k < 2; ++k)
{
for(int t = -1; t < 2; ++t)
{
if(isOverTerrain(ix + k, iz + t))
{
fValue += getHeightValue(ix + k, iz + t);
fAverage++;
}
}
}

// get position of the vertex
Vector2 pos(mVertexScale.x * ix, mVertexScale.z * iz);
pair<bool, Vector2> brushQry = brush->getBrushPosition(Vector2(x,z), pos);
if(!brushQry.first)
continue; // not inside brush rectangle

float Height = getHeightValue(ix, iz);
float fNewValue = fValue / fAverage;
float fDiff = fNewValue - Height;
Height += fDiff * intensity * brush->getIntensityAt(brushQry.second);

setHeightValue(ix, iz, Height);
}
}
}


Here is the code, but I have some problems ...
Sometimes when I edit at the border I get an assert(assert(x < mXlen && y < mYlen && "Array2D index out of bounds");) from ETArray2D.h ...

And I get some strange results when I use a huge Brush width and a big brush intensity
Here you can see the result:


May someone know a solution?

Zero