Terrain:
* 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
parent
2528c28211
commit
569ba9eb9a
|
@ -354,7 +354,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
private void UpdateTerrain()
|
private void UpdateTerrain()
|
||||||
{
|
{
|
||||||
if (Terrain.Tainted())
|
if (Terrain.Tainted() && !Terrain.StillEditing())
|
||||||
{
|
{
|
||||||
CreateTerrainTexture();
|
CreateTerrainTexture();
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(m_regInfo.estateSettings.terrainFile))
|
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();
|
Terrain.HillsGenerator();
|
||||||
|
|
||||||
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
|
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
|
||||||
|
@ -480,7 +480,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
catch
|
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();
|
Terrain.HillsGenerator();
|
||||||
}
|
}
|
||||||
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
|
storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
|
||||||
|
|
|
@ -142,7 +142,7 @@ namespace OpenSim.DataStore.MonoSqlite
|
||||||
}
|
}
|
||||||
else
|
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;
|
prim.Shape = BoxShape.Default;
|
||||||
}
|
}
|
||||||
group.AddPart(prim);
|
group.AddPart(prim);
|
||||||
|
@ -161,7 +161,7 @@ namespace OpenSim.DataStore.MonoSqlite
|
||||||
}
|
}
|
||||||
else
|
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;
|
prim.Shape = BoxShape.Default;
|
||||||
}
|
}
|
||||||
createdObjects[new LLUUID(objID)].AddPart(prim);
|
createdObjects[new LLUUID(objID)].AddPart(prim);
|
||||||
|
|
|
@ -81,6 +81,11 @@ namespace OpenSim.Region.Terrain
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double minLower = 500.0;
|
public double minLower = 500.0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The last time the terrain was edited
|
||||||
|
/// </summary>
|
||||||
|
public DateTime lastEdit = DateTime.Now;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not the terrain has been modified since it was last saved and sent to the Physics engine.
|
/// 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);
|
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)
|
public bool Tainted(int x, int y)
|
||||||
{
|
{
|
||||||
return (heightmap.diff[x / 16, y / 16] != 0);
|
return (heightmap.diff[x / 16, y / 16] != 0);
|
||||||
|
@ -197,6 +212,8 @@ namespace OpenSim.Region.Terrain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastEdit = DateTime.Now;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,6 +1188,40 @@ namespace OpenSim.Region.Terrain
|
||||||
public void ExportImage(string filename, string gradientmap)
|
public void ExportImage(string filename, string gradientmap)
|
||||||
{
|
{
|
||||||
try
|
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);
|
Bitmap gradientmapLd = new Bitmap(gradientmap);
|
||||||
|
|
||||||
|
@ -1194,57 +1245,8 @@ namespace OpenSim.Region.Terrain
|
||||||
bmp.SetPixel(x, y, colours[colorindex]);
|
bmp.SetPixel(x, y, colours[colorindex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return bmp;
|
||||||
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 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace libTerrain
|
||||||
if (z < 0)
|
if (z < 0)
|
||||||
z = 0;
|
z = 0;
|
||||||
|
|
||||||
Set(x, y, Tools.linearInterpolate(map[x, y], height, z));
|
Set(x, y, Tools.LinearInterpolate(map[x, y], height, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace libTerrain
|
||||||
{
|
{
|
||||||
for (int y = 0; y < h; y++)
|
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)
|
if (v >= 0.5)
|
||||||
{
|
{
|
||||||
|
@ -108,14 +108,14 @@ namespace libTerrain
|
||||||
{
|
{
|
||||||
if (y > miny)
|
if (y > miny)
|
||||||
{
|
{
|
||||||
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
|
map[x, y] += Tools.LinearInterpolate(scalemin, scalemax, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (y < miny)
|
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)
|
if (x > miny)
|
||||||
{
|
{
|
||||||
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
|
map[x, y] += Tools.LinearInterpolate(scalemin, scalemax, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (x < miny)
|
if (x < miny)
|
||||||
{
|
{
|
||||||
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
|
map[x, y] += Tools.LinearInterpolate(scalemin, scalemax, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -341,7 +341,7 @@ namespace libTerrain
|
||||||
{
|
{
|
||||||
for (y = 0; y < h; y++)
|
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;
|
return this;
|
||||||
|
@ -354,7 +354,7 @@ namespace libTerrain
|
||||||
{
|
{
|
||||||
for (y = 0; y < h; y++)
|
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;
|
return this;
|
||||||
|
|
|
@ -37,17 +37,19 @@ namespace libTerrain
|
||||||
{
|
{
|
||||||
class Tools
|
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);
|
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);
|
a = Math.Pow(a, amount);
|
||||||
b = Math.Pow(b - a, 1.0 - amount);
|
b = Math.Pow(b - a, 1.0 - amount);
|
||||||
return a+b;
|
return a+b;
|
||||||
}
|
}
|
||||||
public static int powerOf2Log2(int n) {
|
|
||||||
|
public static int PowerOf2Log2(int n) {
|
||||||
for (int i = 0; i < 31; i++) {
|
for (int i = 0; i < 31; i++) {
|
||||||
if ((n & 1) == 1) {
|
if ((n & 1) == 1) {
|
||||||
return i;
|
return i;
|
||||||
|
|
Loading…
Reference in New Issue