* Assorted terrain fixes
parent
aa704172d1
commit
cd88a4914d
|
@ -277,7 +277,7 @@ namespace OpenSim.Region.Terrain
|
|||
resultText += "terrain save grdmap <filename> <gradient map> - creates a PNG snapshot of the region using a named gradient map\n";
|
||||
resultText += "terrain rescale <min> <max> - rescales a terrain to be between <min> and <max> meters high\n";
|
||||
resultText += "terrain fill <val> - fills a terrain at the specified height\n";
|
||||
resultText += "terrain erode aerobic <windspeed> <pickupmin> <dropmin> <carry> <rounds> <lowest>\n";
|
||||
resultText += "terrain erode aerobic <windspeed> <pickupmin> <dropmin> <carry> <rounds> <lowest t/f> <fluid dynamics t/f>\n";
|
||||
resultText += "terrain erode thermal <talus> <rounds> <carry>\n";
|
||||
resultText += "terrain erode hydraulic <rain> <evaporation> <solubility> <frequency> <rounds>\n";
|
||||
resultText += "terrain multiply <val> - multiplies a terrain by <val>\n";
|
||||
|
@ -426,11 +426,14 @@ namespace OpenSim.Region.Terrain
|
|||
|
||||
private bool ConsoleErosion(string[] args, ref string resultText)
|
||||
{
|
||||
double min = heightmap.FindMin();
|
||||
double max = heightmap.FindMax();
|
||||
|
||||
switch (args[1].ToLower())
|
||||
{
|
||||
case "aerobic":
|
||||
// WindSpeed, PickupMinimum,DropMinimum,Carry,Rounds,Lowest
|
||||
heightmap.AerobicErosion(Convert.ToDouble(args[2]), Convert.ToDouble(args[3]), Convert.ToDouble(args[4]), Convert.ToDouble(args[5]), Convert.ToInt32(args[6]), Convert.ToBoolean(args[7]), true);
|
||||
heightmap.AerobicErosion(Convert.ToDouble(args[2]), Convert.ToDouble(args[3]), Convert.ToDouble(args[4]), Convert.ToDouble(args[5]), Convert.ToInt32(args[6]), Convert.ToBoolean(args[7]), Convert.ToBoolean(args[8]));
|
||||
break;
|
||||
case "thermal":
|
||||
heightmap.ThermalWeathering(Convert.ToDouble(args[2]), Convert.ToInt32(args[3]), Convert.ToDouble(args[4]));
|
||||
|
@ -444,6 +447,9 @@ namespace OpenSim.Region.Terrain
|
|||
resultText = "Unknown erosion type";
|
||||
return false;
|
||||
}
|
||||
|
||||
heightmap.Normalise(min, max);
|
||||
|
||||
tainted++;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -257,5 +257,21 @@ namespace libTerrain
|
|||
{
|
||||
return Sum() / (w * h);
|
||||
}
|
||||
|
||||
public bool ContainsNaN()
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
double elm = map[x, y];
|
||||
|
||||
if (Double.IsNaN(elm))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,13 +57,16 @@ namespace libTerrain
|
|||
|
||||
public void SaveImage(string filename)
|
||||
{
|
||||
Channel outmap = this.Copy();
|
||||
outmap.Normalise();
|
||||
|
||||
Bitmap bit = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
|
||||
int x, y;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
int val = Math.Min(255, (int)(map[x,y] * 255));
|
||||
int val = Math.Min(255, (int)(outmap.map[x,y] * 255));
|
||||
Color col = Color.FromArgb(val,val,val);
|
||||
bit.SetPixel(x, y, col);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ namespace libTerrain
|
|||
|
||||
int x, y;
|
||||
|
||||
if (max != min)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
|
@ -50,6 +52,11 @@ namespace libTerrain
|
|||
map[x, y] = (map[x, y] - min) * (1.0 / (max - min));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Fill(0.5);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -244,6 +251,76 @@ namespace libTerrain
|
|||
map = manipulated;
|
||||
}
|
||||
|
||||
public void Distort(Channel mask, double str)
|
||||
{
|
||||
// Simple pertubation filter
|
||||
double[,] manipulated = new double[w, h];
|
||||
|
||||
double amount;
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
amount = mask.map[x, y];
|
||||
double offset_x = (double)x + (amount * str) - (0.5 * str);
|
||||
double offset_y = (double)y + (amount * str) - (0.5 * str);
|
||||
|
||||
if (offset_x > w)
|
||||
offset_x = w - 1;
|
||||
if (offset_y > h)
|
||||
offset_y = h - 1;
|
||||
if (offset_y < 0)
|
||||
offset_y = 0;
|
||||
if (offset_x < 0)
|
||||
offset_x = 0;
|
||||
|
||||
double p = GetBilinearInterpolate(offset_x, offset_y);
|
||||
manipulated[x, y] = p;
|
||||
SetDiff(x, y);
|
||||
}
|
||||
}
|
||||
map = manipulated;
|
||||
|
||||
}
|
||||
|
||||
public void Distort(Channel mask, Channel mask2, double str)
|
||||
{
|
||||
// Simple pertubation filter
|
||||
double[,] manipulated = new double[w, h];
|
||||
|
||||
double amountX;
|
||||
double amountY;
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
amountX = mask.map[x, y];
|
||||
amountY = mask2.map[x, y];
|
||||
double offset_x = (double)x + (amountX * str) - (0.5 * str);
|
||||
double offset_y = (double)y + (amountY * str) - (0.5 * str);
|
||||
|
||||
if (offset_x > w)
|
||||
offset_x = w - 1;
|
||||
if (offset_y > h)
|
||||
offset_y = h - 1;
|
||||
if (offset_y < 0)
|
||||
offset_y = 0;
|
||||
if (offset_x < 0)
|
||||
offset_x = 0;
|
||||
|
||||
double p = GetBilinearInterpolate(offset_x, offset_y);
|
||||
manipulated[x, y] = p;
|
||||
SetDiff(x, y);
|
||||
}
|
||||
}
|
||||
map = manipulated;
|
||||
|
||||
}
|
||||
|
||||
public Channel Blend(Channel other, double amount)
|
||||
{
|
||||
int x, y;
|
||||
|
|
|
@ -76,13 +76,19 @@ namespace libTerrain
|
|||
/// <param name="lowest">Drop sediment at the lowest point?</param>
|
||||
public void AerobicErosion(double windspeed, double pickupTalusMinimum, double dropTalusMinimum, double carry, int rounds, bool lowest, bool usingFluidDynamics)
|
||||
{
|
||||
bool debugImages = true;
|
||||
|
||||
Channel wind = new Channel(w, h) ;
|
||||
Channel sediment = new Channel(w, h);
|
||||
int x, y, i, j;
|
||||
|
||||
this.Normalise();
|
||||
|
||||
wind = this.Copy();
|
||||
wind.Normalise(); // Cheap wind calculations
|
||||
wind *= windspeed;
|
||||
wind.Noise();
|
||||
|
||||
if (debugImages)
|
||||
wind.SaveImage("testimg/wind_start.png");
|
||||
|
||||
if (usingFluidDynamics)
|
||||
{
|
||||
|
@ -90,9 +96,12 @@ namespace libTerrain
|
|||
}
|
||||
else
|
||||
{
|
||||
wind.Pertubation(30); // Can do better later
|
||||
wind.Pertubation(30);
|
||||
}
|
||||
|
||||
if (debugImages)
|
||||
wind.SaveImage("testimg/wind_begin.png");
|
||||
|
||||
for (i = 0; i < rounds; i++)
|
||||
{
|
||||
// Convert some rocks to sand
|
||||
|
@ -127,7 +136,14 @@ namespace libTerrain
|
|||
if (usingFluidDynamics)
|
||||
{
|
||||
sediment.navierStokes(7, 0.1, 0.0, 0.1);
|
||||
wind.navierStokes(10, 0.1, 0.0, 0.0);
|
||||
|
||||
Channel noiseChan = new Channel(w, h);
|
||||
noiseChan.Noise();
|
||||
wind.Blend(noiseChan, 0.01);
|
||||
|
||||
wind.navierStokes(10, 0.1, 0.01, 0.01);
|
||||
|
||||
sediment.Distort(wind, windspeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -137,6 +153,9 @@ namespace libTerrain
|
|||
sediment.seed++;
|
||||
}
|
||||
|
||||
if (debugImages)
|
||||
wind.SaveImage("testimg/wind_" + i.ToString() + ".png");
|
||||
|
||||
// Convert some sand to rock
|
||||
for (x = 1; x < w - 1; x++)
|
||||
{
|
||||
|
@ -174,11 +193,21 @@ namespace libTerrain
|
|||
}
|
||||
}
|
||||
|
||||
if (debugImages)
|
||||
sediment.SaveImage("testimg/sediment_" + i.ToString() + ".png");
|
||||
|
||||
wind.Normalise();
|
||||
wind *= windspeed;
|
||||
|
||||
this.Normalise();
|
||||
}
|
||||
|
||||
Channel myself = this;
|
||||
myself += sediment;
|
||||
myself.Normalise();
|
||||
|
||||
if (debugImages)
|
||||
this.SaveImage("testimg/output.png");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -211,11 +211,11 @@ namespace libTerrain
|
|||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i <= N; i++)
|
||||
for (i = 1; i <= N; i++)
|
||||
{
|
||||
for (j = 0; j <= N; j++)
|
||||
for (j = 1; j <= N; j++)
|
||||
{
|
||||
doubles[i, j] = dens[nsIX(i, j, N)];
|
||||
doubles[i - 1, j - 1] = dens[nsIX(i, j, N)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ namespace libTerrain
|
|||
{
|
||||
for (j = 1; j <= N; j++)
|
||||
{
|
||||
dens[nsIX(i, j, N)] = doubles[i, j];
|
||||
dens[nsIX(i, j, N)] = doubles[i - 1, j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,5 +272,36 @@ namespace libTerrain
|
|||
{
|
||||
nsSimulate(this.h, rounds, dt, diff, visc);
|
||||
}
|
||||
|
||||
public void navierStokes(int rounds, double dt, double diff, double visc, ref double[,] uret, ref double[,] vret)
|
||||
{
|
||||
int N = this.h;
|
||||
|
||||
int size = (N * 2) * (N * 2);
|
||||
|
||||
double[] u = new double[size]; // Force, X axis
|
||||
double[] v = new double[size]; // Force, Y axis
|
||||
double[] u_prev = new double[size];
|
||||
double[] v_prev = new double[size];
|
||||
double[] dens = new double[size];
|
||||
double[] dens_prev = new double[size];
|
||||
|
||||
nsDoublesToBuffer(this.map, N, ref dens);
|
||||
nsDoublesToBuffer(this.map, N, ref dens_prev);
|
||||
|
||||
for (int i = 0; i < rounds; i++)
|
||||
{
|
||||
u_prev = u;
|
||||
v_prev = v;
|
||||
dens_prev = dens;
|
||||
|
||||
nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt);
|
||||
nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt);
|
||||
}
|
||||
|
||||
nsBufferToDoubles(ref u, N, ref uret);
|
||||
nsBufferToDoubles(ref v, N, ref vret);
|
||||
nsBufferToDoubles(ref dens, N, ref this.map);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue