Implemented terrain save-tile command. Does the opposite of load-tile. For now, only saves to .png.

bulletsim
Diva Canto 2011-04-12 19:46:27 -07:00
parent 5c870fce54
commit 16c911dcbb
7 changed files with 132 additions and 0 deletions

View File

@ -124,6 +124,52 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
colours.Save(stream, ImageFormat.Png);
}
public virtual void SaveFile(ITerrainChannel m_channel, string filename,
int offsetX, int offsetY,
int fileWidth, int fileHeight,
int regionSizeX, int regionSizeY)
{
// We need to do this because:
// "Saving the image to the same file it was constructed from is not allowed and throws an exception."
string tempName = offsetX + "_ " + offsetY + "_" + filename;
Bitmap entireBitmap = null;
Bitmap thisBitmap = null;
if (File.Exists(filename))
{
File.Copy(filename, tempName);
entireBitmap = new Bitmap(tempName);
if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY)
{
// old file, let's overwrite it
entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY);
}
}
else
{
entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY);
}
thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
for (int x = 0; x < regionSizeX; x++)
for (int y = 0; y < regionSizeY; y++)
entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));
Save(entireBitmap, filename);
thisBitmap.Dispose();
entireBitmap.Dispose();
if (File.Exists(tempName))
File.Delete(tempName);
}
protected virtual void Save(Bitmap bmp, string filename)
{
bmp.Save(filename, ImageFormat.Png);
}
#endregion
public override string ToString()

View File

@ -76,6 +76,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
colours.Save(stream, ImageFormat.Jpeg);
}
public virtual void SaveFile(ITerrainChannel m_channel, string filename,
int offsetX, int offsetY,
int fileWidth, int fileHeight,
int regionSizeX, int regionSizeY)
{
throw new System.Exception("Not Implemented");
}
#endregion
public override string ToString()

View File

@ -240,6 +240,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
get { return ".raw"; }
}
public virtual void SaveFile(ITerrainChannel m_channel, string filename,
int offsetX, int offsetY,
int fileWidth, int fileHeight,
int regionSizeX, int regionSizeY)
{
throw new System.Exception("Not Implemented");
}
#endregion
public override string ToString()

View File

@ -160,6 +160,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
bs.Close();
}
public virtual void SaveFile(ITerrainChannel m_channel, string filename,
int offsetX, int offsetY,
int fileWidth, int fileHeight,
int regionSizeX, int regionSizeY)
{
throw new System.Exception("Not Implemented");
}
#endregion
public override string ToString()

View File

@ -308,6 +308,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
get { return ".ter"; }
}
public virtual void SaveFile(ITerrainChannel m_channel, string filename,
int offsetX, int offsetY,
int fileWidth, int fileHeight,
int regionSizeX, int regionSizeY)
{
throw new System.Exception("Not Implemented");
}
#endregion
public override string ToString()

View File

@ -38,5 +38,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
ITerrainChannel LoadStream(Stream stream);
void SaveFile(string filename, ITerrainChannel map);
void SaveStream(Stream stream, ITerrainChannel map);
void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY);
}
}

View File

@ -540,6 +540,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
}
/// <summary>
/// Saves the terrain to a larger terrain file.
/// </summary>
/// <param name="filename">The terrain file to save</param>
/// <param name="fileWidth">The width of the file in units</param>
/// <param name="fileHeight">The height of the file in units</param>
/// <param name="fileStartX">Where to begin our slice</param>
/// <param name="fileStartY">Where to begin our slice</param>
public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
{
int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
{
// this region is included in the tile request
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
fileWidth, fileHeight,
(int)Constants.RegionSize,
(int)Constants.RegionSize);
}
return;
}
}
}
}
/// <summary>
/// Performs updates to the region periodically, synchronising physics and other heightmap aware sections
/// </summary>
@ -860,6 +893,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain
SaveToFile((string) args[0]);
}
private void InterfaceSaveTileFile(Object[] args)
{
SaveToFile((string)args[0],
(int)args[1],
(int)args[2],
(int)args[3],
(int)args[4]);
}
private void InterfaceBakeTerrain(Object[] args)
{
UpdateRevertMap();
@ -1115,6 +1157,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
"Integer");
Command saveToTileCommand =
new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file.");
saveToTileCommand.AddArgument("filename",
"The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " +
supportedFileExtensions, "String");
saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
"Integer");
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
"Integer");
// Terrain adjustments
Command fillRegionCommand =
new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
@ -1166,6 +1219,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
m_commander.RegisterCommand("load", loadFromFileCommand);
m_commander.RegisterCommand("load-tile", loadFromTileCommand);
m_commander.RegisterCommand("save", saveToFileCommand);
m_commander.RegisterCommand("save-tile", saveToTileCommand);
m_commander.RegisterCommand("fill", fillRegionCommand);
m_commander.RegisterCommand("elevate", elevateCommand);
m_commander.RegisterCommand("lower", lowerCommand);