diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 46364a5a7c..ab24b765a9 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -639,6 +639,53 @@ namespace OpenSim.Data.MySQL }); } + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + Util.FireAndForget(delegate(object x) + { + m_log.Info("[REGION DB]: Storing Baked terrain"); + + lock (m_dbLock) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from bakedterrain where RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (MySqlCommand cmd2 = dbcon.CreateCommand()) + { + try + { + cmd2.CommandText = "insert into bakedterrain (RegionUUID, " + + "Revision, Heightfield) values (?RegionUUID, " + + "?Revision, ?Heightfield)"; + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); + cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); + + ExecuteNonQuery(cmd); + ExecuteNonQuery(cmd2); + } + catch (Exception e) + { + m_log.ErrorFormat(e.ToString()); + } + } + } + } + } + }); + } + // Legacy region loading public virtual double[,] LoadTerrain(UUID regionID) { @@ -686,6 +733,41 @@ namespace OpenSim.Data.MySQL return terrData; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + TerrainData terrData = null; + + lock (m_dbLock) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "select RegionUUID, Revision, Heightfield " + + "from bakedterrain where RegionUUID = ?RegionUUID "; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (IDataReader reader = ExecuteReader(cmd)) + { + while (reader.Read()) + { + int rev = Convert.ToInt32(reader["Revision"]); + if ((reader["Heightfield"] != DBNull.Value)) + { + byte[] blob = (byte[])reader["Heightfield"]; + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + } + } + } + } + } + } + + return terrData; + } + public virtual void RemoveLandObject(UUID globalID) { lock (m_dbLock) diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index c32f645539..1de5a01cfc 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -379,3 +379,14 @@ ALTER TABLE `prims` ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default ' COMMIT; +:VERSION 54 #----- add baked terrain store + +BEGIN; + +CREATE TABLE IF NOT EXISTS `bakedterrain` ( + `RegionUUID` varchar(255) DEFAULT NULL, + `Revision` int(11) DEFAULT NULL, + `Heightfield` longblob +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +COMMIT; diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index 339e7f45b0..7bb6da323f 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -133,6 +133,7 @@ namespace OpenSim.Data.Null } Dictionary m_terrains = new Dictionary(); + Dictionary m_bakedterrains = new Dictionary(); public void StoreTerrain(TerrainData ter, UUID regionID) { if (m_terrains.ContainsKey(regionID)) @@ -140,6 +141,13 @@ namespace OpenSim.Data.Null m_terrains.Add(regionID, ter); } + public void StoreBakedTerrain(TerrainData ter, UUID regionID) + { + if (m_bakedterrains.ContainsKey(regionID)) + m_bakedterrains.Remove(regionID); + m_bakedterrains.Add(regionID, ter); + } + // Legacy. Just don't do this. public void StoreTerrain(double[,] ter, UUID regionID) { @@ -167,6 +175,15 @@ namespace OpenSim.Data.Null return null; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + if (m_bakedterrains.ContainsKey(regionID)) + { + return m_bakedterrains[regionID]; + } + return null; + } + public void RemoveLandObject(UUID globalID) { } diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 25e1a7f84b..902aae0ae5 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -573,6 +573,39 @@ namespace OpenSim.Data.PGSQL return terrData; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + TerrainData terrData = null; + + string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from bakedterrain + where ""RegionUUID"" = :RegionUUID; "; + + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + // PGSqlParameter param = new PGSqlParameter(); + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + conn.Open(); + using (NpgsqlDataReader reader = cmd.ExecuteReader()) + { + int rev; + if (reader.Read()) + { + rev = Convert.ToInt32(reader["Revision"]); + if ((reader["Heightfield"] != DBNull.Value)) + { + byte[] blob = (byte[])reader["Heightfield"]; + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + } + } + } + } + } + + return terrData; + } + // Legacy entry point for when terrain was always a 256x256 heightmap public void StoreTerrain(double[,] terrain, UUID regionID) { @@ -623,6 +656,49 @@ namespace OpenSim.Data.PGSQL } + /// + /// Stores the baked terrain map to DB. + /// + /// terrain map data. + /// regionID. + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + //Delete old terrain map + string sql = @"delete from bakedterrain where ""RegionUUID""=:RegionUUID"; + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + conn.Open(); + cmd.ExecuteNonQuery(); + + _Log.InfoFormat("{0} Deleted bakedterrain id = {1}", LogHeader, regionID); + } + } + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + sql = @"insert into bakedterrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)"; + + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision)); + cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob)); + conn.Open(); + cmd.ExecuteNonQuery(); + + _Log.InfoFormat("{0} Stored bakedterrain id = {1}, terrainSize = <{2},{3}>", + LogHeader, regionID, terrData.SizeX, terrData.SizeY); + } + } + } + /// /// Loads all the land objects of a region. /// diff --git a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations index 9a2c19b83d..c08593917d 100644 --- a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations @@ -1182,3 +1182,16 @@ BEGIN TRANSACTION; ALTER TABLE prims ADD "RotationAxisLocks" smallint NOT NULL DEFAULT (0); COMMIT; + +:VERSION 44 #---- add baked terrain store + +BEGIN TRANSACTION; + +CREATE TABLE bakedterrain + ( + "RegionUUID" uuid NULL, + "Revision" int NULL, + "Heightfield" bytea NULL + ); + +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index 25f3ad96fb..64624db9b0 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -352,3 +352,14 @@ BEGIN; ALTER TABLE prims ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default '0'; COMMIT; + +:VERSION 34 #---- add baked terrain store + +BEGIN; + +CREATE TABLE IF NOT EXISTS bakedterrain( + RegionUUID varchar(255), + Revision integer, + Heightfield blob); + +COMMIT; diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index cd20c4e777..c1c7b7e8f1 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -827,7 +827,7 @@ namespace OpenSim.Data.SQLite } /// - /// Store a terrain revision in region storage + /// Store a terrain in region storage /// /// terrain heightfield /// region UUID @@ -851,7 +851,44 @@ namespace OpenSim.Data.SQLite Array terrainDBblob; terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); - m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision); + m_log.DebugFormat("{0} Storing terrain format {1}", LogHeader, terrainDBRevision); + + using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision)); + cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob)); + cmd.ExecuteNonQuery(); + } + } + } + + /// + /// Store baked terrain in region storage + /// + /// terrain heightfield + /// region UUID + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + lock (ds) + { + using ( + SqliteCommand cmd = new SqliteCommand("delete from bakedterrain where RegionUUID=:RegionUUID", m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + cmd.ExecuteNonQuery(); + } + + // the following is an work around for .NET. The perf + // issues associated with it aren't as bad as you think. + String sql = "insert into bakedterrain(RegionUUID, Revision, Heightfield)" + + " values(:RegionUUID, :Revision, :Heightfield)"; + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + m_log.DebugFormat("{0} Storing bakedterrain format {1}", LogHeader, terrainDBRevision); using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) { @@ -913,6 +950,34 @@ namespace OpenSim.Data.SQLite return terrData; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + TerrainData terrData = null; + + lock (ds) + { + String sql = "select RegionUUID, Revision, Heightfield from bakedterrain" + + " where RegionUUID=:RegionUUID"; + + using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + + using (IDataReader row = cmd.ExecuteReader()) + { + int rev = 0; + if (row.Read()) + { + rev = Convert.ToInt32(row["Revision"]); + byte[] blob = (byte[])row["Heightfield"]; + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + } + } + } + } + return terrData; + } + public void RemoveLandObject(UUID globalID) { lock (ds) @@ -1354,7 +1419,7 @@ namespace OpenSim.Data.SQLite createCol(land, "Name", typeof(String)); createCol(land, "Desc", typeof(String)); createCol(land, "OwnerUUID", typeof(String)); - createCol(land, "IsGroupOwned", typeof(String)); + createCol(land, "IsGroupOwned", typeof(string)); createCol(land, "Area", typeof(Int32)); createCol(land, "AuctionID", typeof(Int32)); //Unemplemented createCol(land, "Category", typeof(Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory @@ -2942,7 +3007,8 @@ namespace OpenSim.Data.SQLite { return DbType.Binary; } - else if (type == typeof(Boolean)) { + else if (type == typeof(Boolean)) + { return DbType.Boolean; } else diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs index d2e1c6a236..5cec2b5017 100644 --- a/OpenSim/Framework/TerrainData.cs +++ b/OpenSim/Framework/TerrainData.cs @@ -201,6 +201,7 @@ namespace OpenSim.Framework public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob) { bool ret = false; +/* save all as Variable2DGzip if (SizeX == Constants.RegionSize && SizeY == Constants.RegionSize) { DBRevisionCode = (int)DBTerrainRevision.Legacy256; @@ -209,12 +210,13 @@ namespace OpenSim.Framework } else { +*/ DBRevisionCode = (int)DBTerrainRevision.Variable2DGzip; // DBRevisionCode = (int)DBTerrainRevision.Variable2D; blob = ToCompressedTerrainSerializationV2DGzip(); // blob = ToCompressedTerrainSerializationV2D(); ret = true; - } +// } return ret; } diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 69fa5f6d6f..e21681ddd1 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -231,20 +231,27 @@ namespace OpenSim.Region.CoreModules.World.Terrain // Install terrain module in the simulator lock(m_scene) { + if(m_scene.Bakedmap != null) + { + m_baked = m_scene.Bakedmap; + } if (m_scene.Heightmap == null) { - m_channel = new TerrainChannel(m_InitialTerrain, (int)m_scene.RegionInfo.RegionSizeX, - (int)m_scene.RegionInfo.RegionSizeY, - (int)m_scene.RegionInfo.RegionSizeZ); + if(m_baked != null) + m_channel = m_baked.MakeCopy(); + else + m_channel = new TerrainChannel(m_InitialTerrain, + (int)m_scene.RegionInfo.RegionSizeX, + (int)m_scene.RegionInfo.RegionSizeY, + (int)m_scene.RegionInfo.RegionSizeZ); m_scene.Heightmap = m_channel; - - UpdateBakedMap(); } else { m_channel = m_scene.Heightmap; - UpdateBakedMap(); } + if(m_baked == null) + UpdateBakedMap(); m_scene.RegisterModuleInterface(this); m_scene.EventManager.OnNewClient += EventManager_OnNewClient; @@ -724,6 +731,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain m_baked = m_channel.MakeCopy(); m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_baked); m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_baked); + m_scene.Bakedmap = m_baked; + m_scene.SaveBakedTerrain(); } /// diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index 13358cb360..f8a6b53d47 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs @@ -64,12 +64,19 @@ namespace OpenSim.Region.Framework.Interfaces List LoadObjects(UUID regionUUID); /// - /// Store a terrain revision in region storage + /// Store terrain in region storage /// /// HeightField data /// region UUID void StoreTerrain(TerrainData terrain, UUID regionID); + /// + /// Store baked terrain in region storage + /// + /// HeightField data + /// region UUID + void StoreBakedTerrain(TerrainData terrain, UUID regionID); + // Legacy version kept for downward compabibility void StoreTerrain(double[,] terrain, UUID regionID); @@ -82,6 +89,7 @@ namespace OpenSim.Region.Framework.Interfaces /// the Z dimension of the region being filled /// Heightfield data TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ); + TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ); // Legacy version kept for downward compabibility double[,] LoadTerrain(UUID regionID); diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index e09f775642..8536db0e98 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -75,17 +75,25 @@ namespace OpenSim.Region.Framework.Interfaces List LoadObjects(UUID regionUUID); /// - /// Store a terrain revision in region storage + /// Store a terrain in region storage /// /// HeightField data /// region UUID void StoreTerrain(TerrainData terrain, UUID regionID); + /// + /// Store baked terrain in region storage + /// + /// HeightField data + /// region UUID + void StoreBakedTerrain(TerrainData terrain, UUID regionID); + + // Legacy version kept for downward compabibility void StoreTerrain(double[,] terrain, UUID regionID); /// - /// Load the latest terrain revision from region storage + /// Load terrain from region storage /// /// the region UUID /// the X dimension of the terrain being filled @@ -93,6 +101,7 @@ namespace OpenSim.Region.Framework.Interfaces /// the Z dimension of the terrain being filled /// Heightfield data TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ); + TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ); // Legacy version kept for downward compabibility double[,] LoadTerrain(UUID regionID); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d77b8ae662..168080fa8e 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2172,7 +2172,16 @@ namespace OpenSim.Region.Framework.Scenes /// public void SaveTerrain() { - SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); + SimulationDataService.StoreTerrain(Heightmap.GetTerrainData(), RegionInfo.RegionID); + } + + /// + /// Store the terrain in the persistant data store + /// + public void SaveBakedTerrain() + { + if(Bakedmap != null) + SimulationDataService.StoreBakedTerrain(Bakedmap.GetTerrainData(), RegionInfo.RegionID); } public void StoreWindlightProfile(RegionLightShareData wl) @@ -2193,22 +2202,46 @@ namespace OpenSim.Region.Framework.Scenes /// public override void LoadWorldMap() { + try + { + Bakedmap = null; + TerrainData map = SimulationDataService.LoadBakedTerrain(RegionInfo.RegionID, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); + if (map != null) + { + Bakedmap = new TerrainChannel(map); + } + } + catch (Exception e) + { + m_log.WarnFormat( + "[TERRAIN]: Scene.cs: LoadWorldMap() baked terrain - Failed with exception {0}{1}", e.Message, e.StackTrace); + } + try { TerrainData map = SimulationDataService.LoadTerrain(RegionInfo.RegionID, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); if (map == null) { - // This should be in the Terrain module, but it isn't because - // the heightmap is needed _way_ before the modules are initialized... - IConfig terrainConfig = m_config.Configs["Terrain"]; - String m_InitialTerrain = "pinhead-island"; - if (terrainConfig != null) - m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); + if(Bakedmap != null) + { + m_log.Warn("[TERRAIN]: terrain not found. Used stored baked terrain."); + Heightmap = Bakedmap.MakeCopy(); + SimulationDataService.StoreTerrain(Heightmap.GetTerrainData(), RegionInfo.RegionID); + } + else + { + // This should be in the Terrain module, but it isn't because + // the heightmap is needed _way_ before the modules are initialized... + IConfig terrainConfig = m_config.Configs["Terrain"]; + String m_InitialTerrain = "pinhead-island"; + if (terrainConfig != null) + m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); - m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain); - Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); + m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain); + Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); - SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); + SimulationDataService.StoreTerrain(Heightmap.GetTerrainData(), RegionInfo.RegionID); + } } else { @@ -2221,13 +2254,12 @@ namespace OpenSim.Region.Framework.Scenes "[TERRAIN]: Scene.cs: LoadWorldMap() - Regenerating as failed with exception {0}{1}", e.Message, e.StackTrace); - // Non standard region size. If there's an old terrain in the database, it might read past the buffer #pragma warning disable 0162 if ((int)Constants.RegionSize != 256) { Heightmap = new TerrainChannel(); - SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); + SimulationDataService.StoreTerrain(Heightmap.GetTerrainData(), RegionInfo.RegionID); } } catch (Exception e) @@ -2235,6 +2267,12 @@ namespace OpenSim.Region.Framework.Scenes m_log.WarnFormat( "[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception {0}{1}", e.Message, e.StackTrace); } + + if(Bakedmap == null && Heightmap != null) + { + Bakedmap = Heightmap.MakeCopy(); + SimulationDataService.StoreBakedTerrain(Bakedmap.GetTerrainData(), RegionInfo.RegionID); + } } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index f420f69aa5..1de55ec9f6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -153,6 +153,7 @@ namespace OpenSim.Region.Framework.Scenes } public ITerrainChannel Heightmap; + public ITerrainChannel Bakedmap; /// /// Allows retrieval of land information for this scene. diff --git a/OpenSim/Services/SimulationService/SimulationDataService.cs b/OpenSim/Services/SimulationService/SimulationDataService.cs index 7a544fa9ed..eef958ac4e 100644 --- a/OpenSim/Services/SimulationService/SimulationDataService.cs +++ b/OpenSim/Services/SimulationService/SimulationDataService.cs @@ -104,6 +104,11 @@ namespace OpenSim.Services.SimulationService m_database.StoreTerrain(terrain, regionID); } + public void StoreBakedTerrain(TerrainData terrain, UUID regionID) + { + m_database.StoreBakedTerrain(terrain, regionID); + } + public void StoreTerrain(double[,] terrain, UUID regionID) { m_database.StoreTerrain(terrain, regionID); @@ -119,6 +124,11 @@ namespace OpenSim.Services.SimulationService return m_database.LoadTerrain(regionID, pSizeX, pSizeY, pSizeZ); } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + return m_database.LoadBakedTerrain(regionID, pSizeX, pSizeY, pSizeZ); + } + public void StoreLandObject(ILandObject Parcel) { m_database.StoreLandObject(Parcel); diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index 3ab90207a5..8daa19d361 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs @@ -74,6 +74,11 @@ namespace OpenSim.Data.Null m_store.StoreTerrain(terrain, regionID); } + public void StoreBakedTerrain(TerrainData terrain, UUID regionID) + { + m_store.StoreBakedTerrain(terrain, regionID); + } + public double[,] LoadTerrain(UUID regionID) { return m_store.LoadTerrain(regionID); @@ -84,6 +89,11 @@ namespace OpenSim.Data.Null return m_store.LoadTerrain(regionID, pSizeX, pSizeY, pSizeZ); } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + return m_store.LoadBakedTerrain(regionID, pSizeX, pSizeY, pSizeZ); + } + public void StoreLandObject(ILandObject Parcel) { m_store.StoreLandObject(Parcel); @@ -170,6 +180,7 @@ namespace OpenSim.Data.Null protected Dictionary> m_primItems = new Dictionary>(); protected Dictionary m_terrains = new Dictionary(); + protected Dictionary m_bakedterrains = new Dictionary(); protected Dictionary m_landData = new Dictionary(); public void Initialise(string dbfile) @@ -319,6 +330,11 @@ namespace OpenSim.Data.Null m_terrains[regionID] = ter; } + public void StoreBakedTerrain(TerrainData ter, UUID regionID) + { + m_bakedterrains[regionID] = ter; + } + public void StoreTerrain(double[,] ter, UUID regionID) { m_terrains[regionID] = new HeightmapTerrainData(ter); @@ -332,6 +348,14 @@ namespace OpenSim.Data.Null return null; } + public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) + { + if (m_bakedterrains.ContainsKey(regionID)) + return m_bakedterrains[regionID]; + else + return null; + } + public double[,] LoadTerrain(UUID regionID) { if (m_terrains.ContainsKey(regionID))