more changes on terrain edit. Silent ignore comand if busy (large area smooth can take ages), brush changes, etc
parent
01832b3e3c
commit
9eb5fd4330
|
@ -36,18 +36,23 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
|
|||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, float height, float strength,
|
||||
int startX, int endX, int startY, int endY)
|
||||
{
|
||||
double area = 4;
|
||||
double step = 1;
|
||||
int sx = (endX - startX + 1) / 2;
|
||||
if (sx > 4)
|
||||
sx = 4;
|
||||
|
||||
int sy = (endY - startY + 1) / 2;
|
||||
if (sy > 4)
|
||||
sy = 4;
|
||||
|
||||
strength *= 0.002f;
|
||||
if(strength > 1.0f)
|
||||
strength = 1.0f;
|
||||
|
||||
double[,] manipulate = new double[map.Width,map.Height];
|
||||
int x, y;
|
||||
for (x = startX; x <= endX; x++)
|
||||
double[,] tweak = new double[endX - startX + 1, endX - startX + 1];
|
||||
|
||||
for (int x = startX, i = 0; x <= endX; x++, i++)
|
||||
{
|
||||
for (y = startY; y <= endY; y++)
|
||||
for (int y = startY, j = 0; y <= endY; y++, j++)
|
||||
{
|
||||
if (!fillArea[x, y])
|
||||
continue;
|
||||
|
@ -55,65 +60,31 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
|
|||
double average = 0.0;
|
||||
int avgsteps = 0;
|
||||
|
||||
double n;
|
||||
for (n = -area; n < area; n += step)
|
||||
for (int n = x - sx; n <= x + sx; ++n)
|
||||
{
|
||||
double l;
|
||||
for (l = -area; l < area; l += step)
|
||||
for (int l = y - sy; l < y + sy; ++l)
|
||||
{
|
||||
avgsteps++;
|
||||
average += GetBilinearInterpolate(x + n, y + l, map);
|
||||
average += map[n, l];
|
||||
}
|
||||
}
|
||||
|
||||
manipulate[x, y] = average / avgsteps;
|
||||
tweak[i, j] = average / avgsteps;
|
||||
}
|
||||
}
|
||||
for (x = startX; x <= endX; x++)
|
||||
|
||||
for (int x = startX, i = 0; x <= endX; x++, i++)
|
||||
{
|
||||
for (y = startY; y <= endY; y++)
|
||||
for (int y = startY, j = 0; y <= endY; y++, j++)
|
||||
{
|
||||
if (!fillArea[x, y])
|
||||
double ty = tweak[i, j];
|
||||
if (ty == 0.0)
|
||||
continue;
|
||||
|
||||
map[x, y] = (1.0 - strength) * map[x, y] + strength * manipulate[x, y];
|
||||
map[x, y] = (1.0 - strength) * map[x, y] + strength * ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
|
||||
{
|
||||
int w = map.Width;
|
||||
int h = map.Height;
|
||||
|
||||
if (x > w - 2.0)
|
||||
x = w - 2.0;
|
||||
if (y > h - 2.0)
|
||||
y = h - 2.0;
|
||||
if (x < 0.0)
|
||||
x = 0.0;
|
||||
if (y < 0.0)
|
||||
y = 0.0;
|
||||
|
||||
const int stepSize = 1;
|
||||
double h00 = map[(int) x, (int) y];
|
||||
double h10 = map[(int) x + stepSize, (int) y];
|
||||
double h01 = map[(int) x, (int) y + stepSize];
|
||||
double h11 = map[(int) x + stepSize, (int) y + stepSize];
|
||||
double h1 = h00;
|
||||
double h2 = h10;
|
||||
double h3 = h01;
|
||||
double h4 = h11;
|
||||
double a00 = h1;
|
||||
double a10 = h2 - h1;
|
||||
double a01 = h3 - h1;
|
||||
double a11 = h1 - h2 - h3 + h4;
|
||||
double partialx = x - (int) x;
|
||||
double partialz = y - (int) y;
|
||||
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||
return hi;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,22 +39,26 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
|
|||
float size, float strength, int startX, int endX, int startY, int endY)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
size *= 2;
|
||||
|
||||
float distancefactor;
|
||||
float dx2;
|
||||
|
||||
size *= 2 * size;
|
||||
|
||||
// blend in map
|
||||
for (x = startX; x <= endX; ++x)
|
||||
{
|
||||
dx2 = (x - rx) * (x - rx);
|
||||
for (y = startY; y <= endY; ++y)
|
||||
{
|
||||
if (!mask[x,y])
|
||||
continue;
|
||||
|
||||
distancefactor = strength * TerrainUtil.SphericalFactor(x - rx, y - ry, size);
|
||||
distancefactor = (dx2 + (y - ry) * (y - ry)) / size;
|
||||
if(distancefactor > 1.0f)
|
||||
continue;
|
||||
|
||||
if(distancefactor >= 1.0f)
|
||||
distancefactor = strength * (1.0f - distancefactor);
|
||||
if (distancefactor >= 1.0f)
|
||||
map[x, y] = rz;
|
||||
else
|
||||
map[x, y] += (rz - (float)map[x, y]) * distancefactor;
|
||||
|
|
|
@ -38,18 +38,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
|
|||
float size, float strength, int startX, int endX, int startY, int endY)
|
||||
{
|
||||
size = 0.5f * (float)Math.PI / size;
|
||||
strength *= 2;
|
||||
int x, y;
|
||||
|
||||
for (x = startX; x <= endX; x++)
|
||||
float dx2;
|
||||
for (int x = startX; x <= endX; ++x)
|
||||
{
|
||||
for (y = startY; y <= endY; y++)
|
||||
dx2 = (x - rx) * (x - rx);
|
||||
for (int y = startY; y <= endY; ++y)
|
||||
{
|
||||
if (!mask[x, y])
|
||||
continue;
|
||||
|
||||
// Calculate a cos-sphere and add it to the heighmap
|
||||
double r = Math.Sqrt((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
double r = Math.Sqrt(dx2 + (y - ry) * (y - ry));
|
||||
double distancefactor = Math.Cos(r * size);
|
||||
if (distancefactor > 0.0)
|
||||
{
|
||||
|
|
|
@ -39,21 +39,27 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
|
|||
float size, float strength, int startX, int endX, int startY, int endY)
|
||||
{
|
||||
int x, y;
|
||||
float distancefactor;
|
||||
float dx2;
|
||||
|
||||
size *= size;
|
||||
|
||||
for (x = startX; x <= endX; x++)
|
||||
{
|
||||
dx2 = (x - rx) * (x - rx);
|
||||
for (y = startY; y <= endY; y++)
|
||||
{
|
||||
if (!mask[x, y])
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
float distancefactor = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
|
||||
distancefactor = (dx2 + (y - ry) * (y - ry)) / size;
|
||||
if (distancefactor > 1.0f)
|
||||
continue;
|
||||
|
||||
distancefactor = strength * (1.0f - distancefactor);
|
||||
double noise = TerrainUtil.PerlinNoise2D(x / (double) map.Width, y / (double) map.Height, 8, 1.0);
|
||||
|
||||
if (distancefactor > 0.0)
|
||||
map[x, y] += noise * distancefactor * strength;
|
||||
map[x, y] += noise * distancefactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,19 +39,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
|
|||
float size, float strength, int startX, int endX, int startY, int endY)
|
||||
{
|
||||
size = 0.5f *(float)Math.PI / size;
|
||||
strength *= 2;
|
||||
|
||||
int x, y;
|
||||
|
||||
for (x = startX; x <= endX; ++x)
|
||||
float dx2;
|
||||
for (int x = startX; x <= endX; ++x)
|
||||
{
|
||||
for (y = startY; y <= endY; ++y)
|
||||
dx2 = (x - rx) * (x - rx);
|
||||
for (int y = startY; y <= endY; ++y)
|
||||
{
|
||||
if (!mask[x, y])
|
||||
continue;
|
||||
|
||||
// Calculate a cos-sphere and add it to the heighmap
|
||||
double r = Math.Sqrt((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
double r = Math.Sqrt(dx2 + (y - ry) * (y - ry));
|
||||
double distancefactor = Math.Cos(r * size);
|
||||
if (distancefactor > 0.0)
|
||||
map[x, y] += distancefactor * strength;
|
||||
|
|
|
@ -50,24 +50,28 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
|
|||
if (strength > 1.0f)
|
||||
strength = 1.0f;
|
||||
|
||||
int x,y;
|
||||
int x, y;
|
||||
float distancefactor;
|
||||
float dx2;
|
||||
|
||||
for (x = startX; x <= endX; x++)
|
||||
{
|
||||
dx2 = (x - rx) * (x - rx);
|
||||
for (y = startY; y <= endY; y++)
|
||||
{
|
||||
if (!mask[x, y])
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double distancefactor = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
|
||||
if (distancefactor > 0.0)
|
||||
{
|
||||
distancefactor *= strength;
|
||||
distancefactor = (dx2 + (y - ry) * (y - ry)) / size;
|
||||
if (distancefactor > 1.0f)
|
||||
continue;
|
||||
|
||||
distancefactor = strength * (1.0f - distancefactor);
|
||||
map[x, y] = (map[x, y] * (1.0 - distancefactor)) + (m_revertmap[x, y] * distancefactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -35,60 +35,66 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
|
|||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
|
||||
float size, float strengh, int startX, int endX, int startY, int endY)
|
||||
float size, float strength, int startX, int endX, int startY, int endY)
|
||||
{
|
||||
int x, y;
|
||||
double[,] tweak = new double[map.Width, map.Height];
|
||||
float distancefactor;
|
||||
float dx2;
|
||||
|
||||
double step = size / 4.0;
|
||||
double[,] tweak = new double[endX - startX + 1, endX - startX + 1];
|
||||
int ssize = (int)(size + 0.5);
|
||||
if(ssize > 4)
|
||||
ssize = 4;
|
||||
|
||||
if(strengh > 1.0f)
|
||||
strengh = 1.0f;
|
||||
size *= size;
|
||||
|
||||
if (strength > 1.0f)
|
||||
strength = 1.0f;
|
||||
|
||||
// compute delta map
|
||||
for (x = startX; x <= endX; x++)
|
||||
for (int x = startX, i = 0; x <= endX; x++, i++)
|
||||
{
|
||||
for (y = startY; y <= endY; y++)
|
||||
dx2 = (x - rx) * (x - rx);
|
||||
for (int y = startY, j = 0; y <= endY; y++, j++)
|
||||
{
|
||||
if (!mask[x, y])
|
||||
continue;
|
||||
|
||||
double z = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
distancefactor = (dx2 + (y - ry) * (y - ry)) / size;
|
||||
if (distancefactor <= 1.0f)
|
||||
{
|
||||
distancefactor = strength * (1.0f - distancefactor);
|
||||
|
||||
double average = 0.0;
|
||||
int avgsteps = 0;
|
||||
|
||||
double n;
|
||||
for (n =- size; n < size; n += step)
|
||||
for (int n = x - ssize; n <= x + ssize; ++n)
|
||||
{
|
||||
double l;
|
||||
for (l = -size; l < size; l += step)
|
||||
if(n > 0 && n < map.Width)
|
||||
{
|
||||
for (int l = y - ssize; l <= y + ssize; ++l)
|
||||
{
|
||||
if (l > 0 && l < map.Height)
|
||||
{
|
||||
avgsteps++;
|
||||
average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
|
||||
average += map[n, l];
|
||||
}
|
||||
}
|
||||
tweak[x, y] = average / avgsteps;
|
||||
}
|
||||
}
|
||||
average /= avgsteps;
|
||||
tweak[i, j] = distancefactor * (map[x, y] - average);
|
||||
}
|
||||
}
|
||||
}
|
||||
// blend in map
|
||||
for (x = startX; x <= endX; x++)
|
||||
for (int x = startX, i = 0; x <= endX; x++, i++)
|
||||
{
|
||||
for (y = startY; y <= endY; y++)
|
||||
for (int y = startY, j = 0; y <= endY; y++, j++)
|
||||
{
|
||||
if (!mask[x, y])
|
||||
continue;
|
||||
|
||||
float distancefactor = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
|
||||
|
||||
if (distancefactor > 0) // add in non-zero amount
|
||||
double tz = tweak[i, j];
|
||||
if(tz != 0.0)
|
||||
{
|
||||
double a = (map[x, y] - tweak[x, y]) * distancefactor;
|
||||
double newz = map[x, y] - (a * strengh);
|
||||
|
||||
double newz = map[x, y] - tz;
|
||||
if (newz > 0.0)
|
||||
map[x, y] = newz;
|
||||
}
|
||||
|
|
|
@ -516,12 +516,35 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
/// <param name="agentId">UUID of script-owner</param>
|
||||
public void ModifyTerrain(UUID user, Vector3 pos, byte size, byte action)
|
||||
{
|
||||
float duration = 0.25f;
|
||||
float duration;
|
||||
float brushSize;
|
||||
if(action == (byte)StandardTerrainEffects.Lower || action == (byte)StandardTerrainEffects.Raise)
|
||||
brushSize = (int)(Math.Pow(2, size) + 0.5);
|
||||
if (size > 2)
|
||||
{
|
||||
size = 3;
|
||||
brushSize = 4.0f;
|
||||
}
|
||||
else
|
||||
brushSize = (size + 1) * 1.35f;
|
||||
{
|
||||
size++;
|
||||
brushSize = size;
|
||||
}
|
||||
|
||||
switch((StandardTerrainEffects)action)
|
||||
{
|
||||
case StandardTerrainEffects.Flatten:
|
||||
duration = 7.29f * size * size;
|
||||
break;
|
||||
case StandardTerrainEffects.Smooth:
|
||||
case StandardTerrainEffects.Revert:
|
||||
duration = 0.06f * size * size;
|
||||
break;
|
||||
case StandardTerrainEffects.Noise:
|
||||
duration = 0.46f * size * size;
|
||||
break;
|
||||
default:
|
||||
duration = 0.25f;
|
||||
break;
|
||||
}
|
||||
|
||||
client_OnModifyTerrain(user, pos.Z, duration, brushSize, action, pos.Y, pos.X, pos.Y, pos.X, -1);
|
||||
}
|
||||
|
@ -1304,9 +1327,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
return ret;
|
||||
}
|
||||
|
||||
private double NextModifyTerrainTime = double.MinValue;
|
||||
|
||||
private void client_OnModifyTerrain(UUID user, float height, float seconds, float brushSize, byte action,
|
||||
float north, float west, float south, float east, int parcelLocalID)
|
||||
{
|
||||
double now = Util.GetTimeStamp();
|
||||
if(now < NextModifyTerrainTime)
|
||||
return;
|
||||
|
||||
NextModifyTerrainTime = double.MaxValue; // block it
|
||||
|
||||
//m_log.DebugFormat("brushs {0} seconds {1} height {2}, parcel {3}", brushSize, seconds, height, parcelLocalID);
|
||||
bool god = m_scene.Permissions.IsGod(user);
|
||||
bool allowed = false;
|
||||
|
@ -1454,6 +1485,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
m_log.Debug("Unknown terrain flood type " + action);
|
||||
}
|
||||
}
|
||||
NextModifyTerrainTime = Util.GetTimeStamp() + 0.02; // 20ms cooldown
|
||||
}
|
||||
|
||||
private void client_OnBakeTerrain(IClientAPI remoteClient)
|
||||
|
|
Loading…
Reference in New Issue