From 0cdad0faf4a773358a0fce7db4e7b9910b56a8e7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 14:54:41 +0100 Subject: [PATCH 1/8] stop using legacy storeterrain in scene.cs --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d77b8ae662..f7bfc246c8 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2172,7 +2172,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SaveTerrain() { - SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); + SimulationDataService.StoreTerrain(Heightmap.GetTerrainData(), RegionInfo.RegionID); } public void StoreWindlightProfile(RegionLightShareData wl) @@ -2208,7 +2208,7 @@ namespace OpenSim.Region.Framework.Scenes 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 { @@ -2227,7 +2227,7 @@ namespace OpenSim.Region.Framework.Scenes { Heightmap = new TerrainChannel(); - SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); + SimulationDataService.StoreTerrain(Heightmap.GetTerrainData(), RegionInfo.RegionID); } } catch (Exception e) From 3f9f10529548599d1810ca8a630734586ed3fa9d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 15:45:11 +0100 Subject: [PATCH 2/8] add to databases a table to store baked terrain. --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 47 ++++++++++++++++ .../MySQL/Resources/RegionStore.migrations | 11 ++++ OpenSim/Data/Null/NullSimulationData.cs | 8 +++ OpenSim/Data/PGSQL/PGSQLSimulationData.cs | 43 +++++++++++++++ .../PGSQL/Resources/RegionStore.migrations | 13 +++++ .../SQLite/Resources/RegionStore.migrations | 11 ++++ OpenSim/Data/SQLite/SQLiteSimulationData.cs | 53 +++++++++++++++---- .../Interfaces/ISimulationDataService.cs | 9 +++- .../Interfaces/ISimulationDataStore.cs | 10 +++- .../SimulationDataService.cs | 5 ++ .../Tests/Common/Mock/MockRegionDataPlugin.cs | 11 ++++ 11 files changed, 208 insertions(+), 13 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 46364a5a7c..1a571995ba 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) { 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..5ea8bfaa9a 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) { diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 25e1a7f84b..e6161a2dc5 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -623,6 +623,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..76b367a46e 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)) { @@ -1354,7 +1391,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(Boolean)); createCol(land, "Area", typeof(Int32)); createCol(land, "AuctionID", typeof(Int32)); //Unemplemented createCol(land, "Category", typeof(Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory @@ -1387,9 +1424,6 @@ namespace OpenSim.Data.SQLite createCol(land, "MediaLoop", typeof(Boolean)); createCol(land, "ObscureMedia", typeof(Boolean)); createCol(land, "ObscureMusic", typeof(Boolean)); - createCol(land, "SeeAVs", typeof(Boolean)); - createCol(land, "AnyAVSounds", typeof(Boolean)); - createCol(land, "GroupAVSounds", typeof(Boolean)); land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; @@ -1832,7 +1866,7 @@ namespace OpenSim.Data.SQLite newData.Name = (String)row["Name"]; newData.Description = (String)row["Desc"]; newData.OwnerID = (UUID)(String)row["OwnerUUID"]; - newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); + newData.IsGroupOwned = (Boolean)row["IsGroupOwned"]; newData.Area = Convert.ToInt32(row["Area"]); newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); @@ -2248,7 +2282,7 @@ namespace OpenSim.Data.SQLite row["Name"] = land.Name; row["Desc"] = land.Description; row["OwnerUUID"] = land.OwnerID.ToString(); - row["IsGroupOwned"] = land.IsGroupOwned.ToString(); + row["IsGroupOwned"] = land.IsGroupOwned; row["Area"] = land.Area; row["AuctionID"] = land.AuctionID; //Unemplemented row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory @@ -2942,9 +2976,6 @@ namespace OpenSim.Data.SQLite { return DbType.Binary; } - else if (type == typeof(Boolean)) { - return DbType.Boolean; - } else { return DbType.String; diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index 13358cb360..d5e3f7a950 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); diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index e09f775642..4940a28a2f 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -75,12 +75,20 @@ 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); diff --git a/OpenSim/Services/SimulationService/SimulationDataService.cs b/OpenSim/Services/SimulationService/SimulationDataService.cs index 7a544fa9ed..4ec8293d5c 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); diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index 3ab90207a5..61fee4b2e7 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); @@ -170,6 +175,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 +325,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); From 71bd3ce49f1159251ec4339d098d93c2119729f0 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 16:42:40 +0100 Subject: [PATCH 3/8] add load baked terrain methods --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 35 +++++++++++++++++++ OpenSim/Data/Null/NullSimulationData.cs | 9 +++++ OpenSim/Data/PGSQL/PGSQLSimulationData.cs | 33 +++++++++++++++++ OpenSim/Data/SQLite/SQLiteSimulationData.cs | 28 +++++++++++++++ .../Interfaces/ISimulationDataStore.cs | 3 +- .../SimulationDataService.cs | 5 +++ .../Tests/Common/Mock/MockRegionDataPlugin.cs | 13 +++++++ 7 files changed, 125 insertions(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 1a571995ba..ab24b765a9 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -733,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/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index 5ea8bfaa9a..7bb6da323f 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -175,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 e6161a2dc5..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) { diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 76b367a46e..0d565f7e69 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -950,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 backedterrain" + + " 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) diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index 4940a28a2f..8536db0e98 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -93,7 +93,7 @@ namespace OpenSim.Region.Framework.Interfaces 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 @@ -101,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/Services/SimulationService/SimulationDataService.cs b/OpenSim/Services/SimulationService/SimulationDataService.cs index 4ec8293d5c..eef958ac4e 100644 --- a/OpenSim/Services/SimulationService/SimulationDataService.cs +++ b/OpenSim/Services/SimulationService/SimulationDataService.cs @@ -124,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 61fee4b2e7..8daa19d361 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs @@ -89,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); @@ -343,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)) From 47ce0f8641c69e005c1b7ef875c5cd82de2388d5 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 16:46:56 +0100 Subject: [PATCH 4/8] add load baked terrain methods. missing file --- OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index d5e3f7a950..f8a6b53d47 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs @@ -89,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); From 592a915d8d9335784998d02418d1eee757f76350 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 17:56:35 +0100 Subject: [PATCH 5/8] add rest of wiring for terrain bake persistent store (mantis 8024 but not using its code). Only did minor testing in MySQL --- .../World/Terrain/TerrainModule.cs | 21 +++++-- OpenSim/Region/Framework/Scenes/Scene.cs | 58 +++++++++++++++---- OpenSim/Region/Framework/Scenes/SceneBase.cs | 1 + 3 files changed, 64 insertions(+), 16 deletions(-) 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/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f7bfc246c8..168080fa8e 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2175,6 +2175,15 @@ namespace OpenSim.Region.Framework.Scenes 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) { RegionInfo.WindlightSettings = 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.GetTerrainData(), RegionInfo.RegionID); + SimulationDataService.StoreTerrain(Heightmap.GetTerrainData(), RegionInfo.RegionID); + } } else { @@ -2221,7 +2254,6 @@ 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) { @@ -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. From 4dc787eb32858cb672292b5100c4109667d41af8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 19:13:46 +0100 Subject: [PATCH 6/8] store all terrain in Variable2DGzip format --- OpenSim/Framework/TerrainData.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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; } From 188b5030f74cde47475fb82a91c3efbed79561ec Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 19:46:40 +0100 Subject: [PATCH 7/8] restore sqlite fixes from commit 0e6874..that got lost --- OpenSim/Data/SQLite/SQLiteSimulationData.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 0d565f7e69..5b06f7fb5e 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -1419,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(Boolean)); + 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 @@ -1452,6 +1452,9 @@ namespace OpenSim.Data.SQLite createCol(land, "MediaLoop", typeof(Boolean)); createCol(land, "ObscureMedia", typeof(Boolean)); createCol(land, "ObscureMusic", typeof(Boolean)); + createCol(land, "SeeAVs", typeof(Boolean)); + createCol(land, "AnyAVSounds", typeof(Boolean)); + createCol(land, "GroupAVSounds", typeof(Boolean)); land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; @@ -1894,7 +1897,7 @@ namespace OpenSim.Data.SQLite newData.Name = (String)row["Name"]; newData.Description = (String)row["Desc"]; newData.OwnerID = (UUID)(String)row["OwnerUUID"]; - newData.IsGroupOwned = (Boolean)row["IsGroupOwned"]; + newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); newData.Area = Convert.ToInt32(row["Area"]); newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); @@ -2310,7 +2313,7 @@ namespace OpenSim.Data.SQLite row["Name"] = land.Name; row["Desc"] = land.Description; row["OwnerUUID"] = land.OwnerID.ToString(); - row["IsGroupOwned"] = land.IsGroupOwned; + row["IsGroupOwned"] = land.IsGroupOwned.ToString(); row["Area"] = land.Area; row["AuctionID"] = land.AuctionID; //Unemplemented row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory @@ -3004,6 +3007,10 @@ namespace OpenSim.Data.SQLite { return DbType.Binary; } + else if (type == typeof(Boolean)) + { + return DbType.Boolean; + } else { return DbType.String; From 092d4fb9ff9c586ac6cd41dd47e7f8a2018b9835 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 18 Sep 2016 20:00:47 +0100 Subject: [PATCH 8/8] fix typo in table name, thx tglion --- OpenSim/Data/SQLite/SQLiteSimulationData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 5b06f7fb5e..c1c7b7e8f1 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -956,7 +956,7 @@ namespace OpenSim.Data.SQLite lock (ds) { - String sql = "select RegionUUID, Revision, Heightfield from backedterrain" + + String sql = "select RegionUUID, Revision, Heightfield from bakedterrain" + " where RegionUUID=:RegionUUID"; using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))