From 16c911dcbb883e60d7a49176db8b2cea650cc929 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 12 Apr 2011 19:46:27 -0700 Subject: [PATCH] Implemented terrain save-tile command. Does the opposite of load-tile. For now, only saves to .png. --- .../FileLoaders/GenericSystemDrawing.cs | 46 ++++++++++++++++ .../World/Terrain/FileLoaders/JPEG.cs | 8 +++ .../World/Terrain/FileLoaders/LLRAW.cs | 8 +++ .../World/Terrain/FileLoaders/RAW32.cs | 7 +++ .../World/Terrain/FileLoaders/Terragen.cs | 8 +++ .../World/Terrain/ITerrainLoader.cs | 1 + .../World/Terrain/TerrainModule.cs | 54 +++++++++++++++++++ 7 files changed, 132 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index d6fa0937e5..21a9999ba0 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs @@ -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() diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs index 8667607d0b..1a0d8ecf60 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs @@ -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() diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs index a70ef13ed0..fad7641e42 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs @@ -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() diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs index 3c76665d5e..ba073cae5a 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs @@ -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() diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 2919897153..2f37d9d7e9 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs @@ -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() diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs index 7403281621..7237f90a38 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs @@ -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); } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 8a79d78b22..9c7b2fab9c 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -540,6 +540,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain } } + /// + /// Saves the terrain to a larger terrain file. + /// + /// The terrain file to save + /// The width of the file in units + /// The height of the file in units + /// Where to begin our slice + /// Where to begin our slice + 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 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; + } + } + } + } + /// /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections /// @@ -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);