* Terrain should now send just updated patches.

afrisby
Adam Frisby 2007-07-24 05:22:33 +00:00
parent 4b0734c4ad
commit d8997b59d3
20 changed files with 170 additions and 30 deletions

View File

@ -235,25 +235,40 @@ namespace OpenSim.Region.Environment.Scenes
storageCount = 0;
}
if (Terrain.tainted > 0)
if (Terrain.Tainted())
{
lock (m_syncRoot)
lock (Terrain.heightmap)
{
phyScene.SetTerrain(Terrain.GetHeights1D());
lock (m_syncRoot)
{
phyScene.SetTerrain(Terrain.GetHeights1D());
}
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
float[] terData = Terrain.GetHeights1D();
ForEachScenePresence(delegate(ScenePresence presence)
{
for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
{
if (Terrain.Tainted(x, y))
{
SendLayerData(x, y, presence.ControllingClient, terData);
}
}
}
});
foreach (LLUUID UUID in Entities.Keys)
{
Entities[UUID].LandRenegerated();
}
Terrain.ResetTaint();
}
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
ForEachScenePresence(delegate(ScenePresence presence)
{
SendLayerData(presence.ControllingClient);
});
foreach (LLUUID UUID in Entities.Keys)
{
Entities[UUID].LandRenegerated();
}
Terrain.tainted = 0;
}
landPrimCheckCount++;
@ -365,9 +380,11 @@ namespace OpenSim.Region.Environment.Scenes
{
/* Dont save here, rely on tainting system instead */
float[] terrain = Terrain.GetHeights1D();
ForEachScenePresence(delegate(ScenePresence presence)
{
SendLayerData(pointx, pointy, presence.ControllingClient);
SendLayerData(pointx, pointy, presence.ControllingClient, terrain);
});
}
}

View File

@ -90,9 +90,9 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="px">Patch coordinate (x) 0..16</param>
/// <param name="py">Patch coordinate (y) 0..16</param>
/// <param name="RemoteClient">The client to send to</param>
public virtual void SendLayerData(int px, int py, IClientAPI RemoteClient)
public virtual void SendLayerData(int px, int py, IClientAPI RemoteClient, float[] terrain)
{
RemoteClient.SendLayerData(px, py, Terrain.GetHeights1D());
RemoteClient.SendLayerData(px, py, terrain);
}
#endregion

View File

@ -99,6 +99,22 @@ namespace OpenSim.Region.Terrain
tainted++;
}
public bool Tainted()
{
return (tainted != 0);
}
public bool Tainted(int x, int y)
{
return (heightmap.diff[x / 16, y / 16] != 0);
}
public void ResetTaint()
{
tainted = 0;
heightmap.diff = new int[w / 16, h / 16];
}
/// <summary>
/// Checks to make sure the terrain is within baked values +/- maxRaise/minLower
/// </summary>

View File

@ -40,6 +40,7 @@ namespace libTerrain
partial class Channel
{
public double[,] map;
public int[,] diff;
public int w;
public int h;
@ -50,6 +51,7 @@ namespace libTerrain
w = 256;
h = 256;
map = new double[w, h];
diff = new int[(int)(w / 16), (int)(h / 16)];
}
public Channel(int width, int height)
@ -57,6 +59,7 @@ namespace libTerrain
w = width;
h = height;
map = new double[w, h];
diff = new int[(int)(w / 16), (int)(h / 16)];
}
}

View File

@ -51,8 +51,31 @@ namespace libTerrain
return x;
}
public void SetDiff()
{
SetDiff(1);
}
public void SetDiff(int val)
{
for (int x = 0; x < w / 16; x++)
{
for (int y = 0; y < h / 16; y++)
{
diff[x, y] = val;
}
}
}
public void SetDiff(int x, int y)
{
diff[x / 16, y / 16]++;
}
public void Set(int x, int y, double val)
{
SetDiff(x, y);
if (x >= w)
throw new Exception("Bounds error while setting pixel (width)");
if (y >= h)
@ -67,6 +90,8 @@ namespace libTerrain
public void SetClip(int x, int y, double val)
{
SetDiff(x, y);
if (x >= w)
throw new Exception("Bounds error while setting pixel (width)");
if (y >= h)
@ -129,11 +154,15 @@ namespace libTerrain
public void SetWrap(int x, int y, double val)
{
SetDiff(x, y);
map[x % w, y % h] = val;
}
public void SetWrapClip(int x, int y, double val)
{
SetDiff(x, y);
if (val > 1.0)
val = 1.0;
if (val < 0.0)
@ -144,6 +173,8 @@ namespace libTerrain
public void Fill(double val)
{
SetDiff();
int x, y;
for (x = 0; x < w; x++)
{
@ -156,6 +187,8 @@ namespace libTerrain
public void Fill(double min, double max, double val)
{
SetDiff();
int x, y;
for (x = 0; x < w; x++)
{

View File

@ -115,7 +115,7 @@ namespace libTerrain
if (z < 0)
z = 0;
map[x, y] = Tools.linearInterpolate(map[x, y], height, z);
Set(x, y, Tools.linearInterpolate(map[x, y], height, z));
}
}
}

View File

@ -68,7 +68,7 @@ namespace libTerrain
if (z < 0)
z = 0;
map[x, y] += z * amount;
Set(x, y, map[x, y] + (z * amount));
}
}
}
@ -93,7 +93,7 @@ namespace libTerrain
if (z < 0)
z = 0;
map[x, y] += z * amount;
Set(x, y, map[x, y] + (z * amount));
}
}
}
@ -131,7 +131,7 @@ namespace libTerrain
if (z < 0)
z = 0;
map[x, y] -= z * amount;
Set(x, y, map[x, y] - (z * amount));
}
}
}

View File

@ -37,6 +37,8 @@ namespace libTerrain
{
public Channel LoadImage(string filename)
{
SetDiff();
Bitmap bit = new Bitmap(filename);
Channel chan = new Channel(bit.Width, bit.Height);

View File

@ -82,6 +82,8 @@ namespace libTerrain
public void Fracture(int number, double scalemin, double scalemax)
{
SetDiff();
Random rand = new Random(seed);
for (int i = 0; i < number; i++)

View File

@ -37,6 +37,8 @@ namespace libTerrain
public void GradientCube()
{
SetDiff();
int x, y;
for (x = 0; x < w; x++)
{

View File

@ -46,6 +46,8 @@ namespace libTerrain
/// <param name="noisy">Generates hill-shaped noise instead of consistent hills</param>
public void HillsSpheres(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{
SetDiff();
Random random = new Random(seed);
int x, y;
@ -110,6 +112,8 @@ namespace libTerrain
/// <param name="noisy">Generates hill-shaped noise instead of consistent hills</param>
public void HillsCones(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{
SetDiff();
Random random = new Random(seed);
int x, y;
@ -163,6 +167,8 @@ namespace libTerrain
public void HillsBlocks(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{
SetDiff();
Random random = new Random(seed);
int x, y;
@ -217,6 +223,8 @@ namespace libTerrain
public void HillsSquared(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{
SetDiff();
Random random = new Random(seed);
int x, y;

View File

@ -40,6 +40,8 @@ namespace libTerrain
/// <remarks>3-Clause BSD Licensed</remarks>
public void Noise()
{
SetDiff();
Random rand = new Random(seed);
int x, y;
for (x = 0; x < w; x++)

View File

@ -36,7 +36,6 @@ namespace libTerrain
{
private double[] CoordinatesToPolar(int x, int y)
{
double theta = Math.Atan2(x - (w / 2), y - (h / 2));
double rx = (double)x - ((double)w / 2);
double ry = (double)y - ((double)h / 2);
@ -78,6 +77,8 @@ namespace libTerrain
public void Polar()
{
SetDiff();
Channel n = this.Copy();
int x, y;
@ -97,6 +98,8 @@ namespace libTerrain
public void SpiralPlanter(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle)
{
SetDiff();
int i;
double r = offsetRadius;
double theta = offsetAngle;
@ -112,6 +115,8 @@ namespace libTerrain
public void SpiralCells(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle, double[] c)
{
SetDiff();
List<Point2D> points = new List<Point2D>();
int i;
@ -131,6 +136,8 @@ namespace libTerrain
public void Spiral(double wid, double hig, double offset)
{
SetDiff();
int x, y, z;
z = 0;
for (x = 0; x < w; x++)

View File

@ -44,6 +44,8 @@ namespace libTerrain
/// <param name="c">The Voronoi diagram type. Usually an array with values consisting of [-1,1]. Experiment with the chain, you can have as many values as you like.</param>
public void VoronoiDiagram(int pointsPerBlock, int blockSize, double[] c)
{
SetDiff();
List<Point2D> points = new List<Point2D>();
Random generator = new Random(seed);
@ -103,7 +105,8 @@ namespace libTerrain
public void VoronoiDiagram(List<Point2D> points, double[] c)
{
SetDiff();
Random generator = new Random(seed);
int x, y, i;
double[] distances = new double[points.Count];
@ -146,6 +149,8 @@ namespace libTerrain
public void VoroflatDiagram(int pointsPerBlock, int blockSize)
{
SetDiff();
List<Point2D> points = new List<Point2D>();
Random generator = new Random(seed);

View File

@ -44,6 +44,8 @@ namespace libTerrain
/// <param name="centerspawn">Do worms start in the middle, or randomly?</param>
public void Worms(int number, int rounds, double movement, double size, bool centerspawn)
{
SetDiff();
Random random = new Random(seed);
int i, j;

View File

@ -36,6 +36,8 @@ namespace libTerrain
{
public Channel Normalise()
{
SetDiff();
double max = FindMax();
double min = FindMin();
@ -54,6 +56,8 @@ namespace libTerrain
public Channel Normalise(double minv, double maxv)
{
SetDiff();
double max = FindMax();
double min = FindMin();
@ -99,7 +103,8 @@ namespace libTerrain
double val = map[x, y];
if (val > max) val = max;
if (val < min) val = min;
map[x, y] = val;
Set(x, y, val);
}
}
return this;
@ -132,6 +137,8 @@ namespace libTerrain
public Channel AddClip(Channel other)
{
SetDiff();
int x, y;
for (x = 0; x < w; x++)
{
@ -149,6 +156,8 @@ namespace libTerrain
public void Smooth(double amount)
{
SetDiff();
double area = amount;
double step = amount / 4.0;
@ -179,6 +188,8 @@ namespace libTerrain
public void Pertubation(double amount)
{
SetDiff();
// Simple pertubation filter
double[,] manipulated = new double[w, h];
Random generator = new Random(seed); // Seeds FTW!
@ -227,6 +238,7 @@ namespace libTerrain
double p = GetBilinearInterpolate(offset_x, offset_y);
manipulated[x, y] = p;
SetDiff(x, y);
}
}
map = manipulated;
@ -239,7 +251,7 @@ namespace libTerrain
{
for (y = 0; y < h; y++)
{
map[x, y] = Tools.linearInterpolate(map[x,y],other.map[x,y],amount);
Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount));
}
}
return this;
@ -252,7 +264,7 @@ namespace libTerrain
{
for (y = 0; y < h; y++)
{
map[x, y] = Tools.linearInterpolate(map[x, y], other.map[x, y], amount.map[x,y]);
Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount.map[x, y]));
}
}
return this;

View File

@ -118,7 +118,7 @@ namespace libTerrain
if (surfacearea > pickupTalusMinimum)
{
this.map[x, y] -= amount;
Set(x, y, map[x, y] - amount);
sediment.map[x, y] += amount;
}
}
@ -168,7 +168,7 @@ namespace libTerrain
if (surfacearea > dropTalusMinimum)
{
this.map[x + minside[0], y + minside[1]] += amount;
Set(x + minside[0], y + minside[1], map[x + minside[0], y + minside[1]] + amount);
sediment.map[x, y] -= amount;
}
}

View File

@ -36,6 +36,8 @@ namespace libTerrain
{
public void HydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds)
{
SetDiff();
Channel water = new Channel(w, h);
Channel sediment = new Channel(w, h);
Channel terrain = this;

View File

@ -42,6 +42,8 @@ namespace libTerrain
/// <param name="c">The amount of rock to carry each round</param>
public Channel ThermalWeathering(double talus, int rounds, double c)
{
SetDiff();
double[,] lastFrame;
double[,] thisFrame;

View File

@ -49,6 +49,9 @@ namespace libTerrain
{
for (y = 0; y < A.h; y++)
{
if (B.map[x, y] != 0)
A.SetDiff(x, y);
A.map[x, y] += B.map[x, y];
}
}
@ -73,6 +76,8 @@ namespace libTerrain
}
}
A.SetDiff();
return A;
}
@ -89,6 +94,8 @@ namespace libTerrain
{
for (y = 0; y < A.h; y++)
{
if (B.map[x, y] != 0)
A.SetDiff(x, y);
A.map[x, y] -= B.map[x, y];
}
}
@ -113,6 +120,8 @@ namespace libTerrain
}
}
A.SetDiff();
return A;
}
@ -133,6 +142,8 @@ namespace libTerrain
}
}
A.SetDiff();
return A;
}
@ -151,6 +162,9 @@ namespace libTerrain
}
}
if (B != 0)
A.SetDiff();
return A;
}
@ -166,6 +180,9 @@ namespace libTerrain
}
}
if (B != 0)
A.SetDiff();
return A;
}
@ -181,6 +198,9 @@ namespace libTerrain
}
}
if (B != 1)
A.SetDiff();
return A;
}
@ -196,6 +216,9 @@ namespace libTerrain
}
}
if (B != 1)
A.SetDiff();
return A;
}
@ -211,6 +234,8 @@ namespace libTerrain
}
}
A.SetDiff();
return A;
}