* Attempted fix for lag/pause when doing lots of updates.
* Some naming fixes to libTerrain.
* Refactored terrain bitmap generation into a common call for both world map and export.

General:
* Switched some calls to Console.WriteLine to use MainLog.Warn/Verbose/Notice.
afrisby
Adam Frisby 2007-09-25 11:48:43 +00:00
parent 2528c28211
commit 569ba9eb9a
7 changed files with 66 additions and 62 deletions

View File

@ -354,7 +354,7 @@ namespace OpenSim.Region.Environment.Scenes
private void UpdateTerrain()
{
if (Terrain.Tainted())
if (Terrain.Tainted() && !Terrain.StillEditing())
{
CreateTerrainTexture();
@ -466,7 +466,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (string.IsNullOrEmpty(m_regInfo.estateSettings.terrainFile))
{
Console.WriteLine("No default terrain, procedurally generating...");
MainLog.Instance.Verbose("TERRAIN", "No default terrain. Generating a new terrain.");
Terrain.HillsGenerator();
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
@ -480,7 +480,7 @@ namespace OpenSim.Region.Environment.Scenes
}
catch
{
Console.WriteLine("Unable to load default terrain, procedurally generating instead...");
MainLog.Instance.Verbose("TERRAIN","No terrain found in database or default. Generating a new terrain.");
Terrain.HillsGenerator();
}
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());

View File

@ -142,7 +142,7 @@ namespace OpenSim.DataStore.MonoSqlite
}
else
{
Console.WriteLine("No shape found for prim in storage, so setting default box shape");
MainLog.Instance.Notice("No shape found for prim in storage, so setting default box shape");
prim.Shape = BoxShape.Default;
}
group.AddPart(prim);
@ -161,7 +161,7 @@ namespace OpenSim.DataStore.MonoSqlite
}
else
{
Console.WriteLine("No shape found for prim in storage, so setting default box shape");
MainLog.Instance.Notice("No shape found for prim in storage, so setting default box shape");
prim.Shape = BoxShape.Default;
}
createdObjects[new LLUUID(objID)].AddPart(prim);

View File

@ -81,6 +81,11 @@ namespace OpenSim.Region.Terrain
/// </summary>
public double minLower = 500.0;
/// <summary>
/// The last time the terrain was edited
/// </summary>
public DateTime lastEdit = DateTime.Now;
/// <summary>
/// Whether or not the terrain has been modified since it was last saved and sent to the Physics engine.
@ -120,6 +125,16 @@ namespace OpenSim.Region.Terrain
return (tainted != 0);
}
public bool StillEditing()
{
TimeSpan gap = DateTime.Now - lastEdit;
if (gap.TotalSeconds <= 2.0)
return true;
return false;
}
public bool Tainted(int x, int y)
{
return (heightmap.diff[x / 16, y / 16] != 0);
@ -197,6 +212,8 @@ namespace OpenSim.Region.Terrain
}
}
lastEdit = DateTime.Now;
return;
}
@ -1171,6 +1188,40 @@ namespace OpenSim.Region.Terrain
public void ExportImage(string filename, string gradientmap)
{
try
{
Bitmap bmp = TerrainToBitmap(gradientmap);
bmp.Save(filename, ImageFormat.Png);
}
catch (Exception e)
{
Console.WriteLine("Failed generating terrain map: " + e.ToString());
}
}
/// <summary>
/// Exports the current heightmap in Jpeg2000 format to a byte[]
/// </summary>
/// <param name="gradientmap">A 1x*height* image which contains the colour gradient to export with. Must be at least 1x2 pixels, 1x256 or more is ideal.</param>
public byte[] ExportJpegImage(string gradientmap)
{
byte[] imageData = null;
try
{
Bitmap bmp = TerrainToBitmap(gradientmap);
imageData = OpenJPEG.EncodeFromImage(bmp, true );
}
catch (Exception e)
{
Console.WriteLine("Failed generating terrain map: " + e.ToString());
}
return imageData;
}
private Bitmap TerrainToBitmap(string gradientmap)
{
Bitmap gradientmapLd = new Bitmap(gradientmap);
@ -1194,57 +1245,8 @@ namespace OpenSim.Region.Terrain
bmp.SetPixel(x, y, colours[colorindex]);
}
}
bmp.Save(filename, ImageFormat.Png);
}
catch (Exception e)
{
Console.WriteLine("Failed generating terrain map: " + e.ToString());
}
return bmp;
}
/// <summary>
/// Exports the current heightmap in Jpeg2000 format to a byte[]
/// </summary>
/// <param name="gradientmap">A 1x*height* image which contains the colour gradient to export with. Must be at least 1x2 pixels, 1x256 or more is ideal.</param>
public byte[] ExportJpegImage(string gradientmap)
{
byte[] imageData = null;
try
{
Bitmap gradientmapLd = new Bitmap(gradientmap);
int pallete = gradientmapLd.Height;
Bitmap bmp = new Bitmap(heightmap.w, heightmap.h);
Color[] colours = new Color[pallete];
for (int i = 0; i < pallete; i++)
{
colours[i] = gradientmapLd.GetPixel(0, i);
}
Channel copy = heightmap.Copy();
for (int y = 0; y < copy.h; y++)
{
for (int x = 0; x < copy.w; x++)
{
// 512 is the largest possible height before colours clamp
int colorindex = (int)(Math.Max(Math.Min(1.0, copy.Get(x, copy.h - y) / 512.0), 0.0) * (pallete - 1));
bmp.SetPixel(x, y, colours[colorindex]);
}
}
//bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
imageData = OpenJPEG.EncodeFromImage(bmp, true );
}
catch (Exception e)
{
Console.WriteLine("Failed generating terrain map: " + e.ToString());
}
return imageData;
}
}
}

View File

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

View File

@ -100,7 +100,7 @@ namespace libTerrain
{
for (int y = 0; y < h; y++)
{
double miny = Tools.linearInterpolate(a[1], b[1], (double)x / (double)w);
double miny = Tools.LinearInterpolate(a[1], b[1], (double)x / (double)w);
if (v >= 0.5)
{
@ -108,14 +108,14 @@ namespace libTerrain
{
if (y > miny)
{
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
map[x, y] += Tools.LinearInterpolate(scalemin, scalemax, z);
}
}
else
{
if (y < miny)
{
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
map[x, y] += Tools.LinearInterpolate(scalemin, scalemax, z);
}
}
}
@ -125,14 +125,14 @@ namespace libTerrain
{
if (x > miny)
{
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
map[x, y] += Tools.LinearInterpolate(scalemin, scalemax, z);
}
}
else
{
if (x < miny)
{
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
map[x, y] += Tools.LinearInterpolate(scalemin, scalemax, z);
}
}
}

View File

@ -341,7 +341,7 @@ namespace libTerrain
{
for (y = 0; y < h; y++)
{
Set(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;
@ -354,7 +354,7 @@ namespace libTerrain
{
for (y = 0; y < h; y++)
{
Set(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

@ -37,17 +37,19 @@ namespace libTerrain
{
class Tools
{
public static double linearInterpolate(double a, double b, double amount)
public static double LinearInterpolate(double a, double b, double amount)
{
return a + ((b - a) * amount);
}
public static double exponentialInterpolate(double a, double b, double amount)
public static double ExponentialInterpolate(double a, double b, double amount)
{
a = Math.Pow(a, amount);
b = Math.Pow(b - a, 1.0 - amount);
return a+b;
}
public static int powerOf2Log2(int n) {
public static int PowerOf2Log2(int n) {
for (int i = 0; i < 31; i++) {
if ((n & 1) == 1) {
return i;