aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs4
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs26
-rw-r--r--OpenSim/Data/IRegionData.cs4
-rw-r--r--OpenSim/Data/MSSQL/MSSQLSimulationData.cs103
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs82
-rw-r--r--OpenSim/Data/Null/NullSimulationData.cs21
-rw-r--r--OpenSim/Data/PGSQL/PGSQLSimulationData.cs117
-rw-r--r--OpenSim/Data/SQLite/SQLiteSimulationData.cs97
-rw-r--r--OpenSim/Data/Tests/RegionTests.cs8
-rw-r--r--OpenSim/Framework/Constants.cs11
-rw-r--r--OpenSim/Framework/RegionInfo.cs219
-rw-r--r--OpenSim/Framework/TerrainData.cs418
-rw-r--r--OpenSim/Framework/UserProfileData.cs14
-rw-r--r--OpenSim/Framework/Util.cs38
-rw-r--r--OpenSim/Region/Application/OpenSim.cs4
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs9
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs92
-rw-r--r--OpenSim/Region/ClientStack/RegionApplicationBase.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs266
-rw-r--r--OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs6
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs3
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs322
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs187
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs73
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs24
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs9
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs10
-rw-r--r--OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs105
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs88
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs278
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainCompressor.cs944
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs5
-rw-r--r--OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs11
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs12
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs6
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs5
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs6
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs9
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs8
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs28
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionConnections.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs4
-rw-r--r--OpenSim/Server/Handlers/Map/MapAddServerConnector.cs10
-rw-r--r--OpenSim/Services/Connectors/Land/LandServicesConnector.cs2
-rw-r--r--OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs2
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs4
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationDataService.cs10
-rw-r--r--OpenSim/Services/GridService/GridService.cs9
-rw-r--r--OpenSim/Services/Interfaces/IGridService.cs33
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs36
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs5
-rw-r--r--OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs8
-rw-r--r--OpenSim/Tests/Common/Helpers/SceneHelpers.cs3
-rw-r--r--OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs29
77 files changed, 2994 insertions, 994 deletions
diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
index 1d63d26..74a7a50 100644
--- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
+++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
@@ -184,11 +184,11 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
184 return false; 184 return false;
185 } 185 }
186 else if ( 186 else if (
187 regions[i].RegionLocX == regions[j].RegionLocX && regions[i].RegionLocY == regions[j].RegionLocY) 187 regions[i].LegacyRegionLocX == regions[j].LegacyRegionLocX && regions[i].LegacyRegionLocY == regions[j].LegacyRegionLocY)
188 { 188 {
189 m_log.ErrorFormat( 189 m_log.ErrorFormat(
190 "[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same grid location ({2}, {3})", 190 "[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same grid location ({2}, {3})",
191 regions[i].RegionName, regions[j].RegionName, regions[i].RegionLocX, regions[i].RegionLocY); 191 regions[i].RegionName, regions[j].RegionName, regions[i].LegacyRegionLocX, regions[i].LegacyRegionLocY);
192 return false; 192 return false;
193 } 193 }
194 else if (regions[i].InternalEndPoint.Port == regions[j].InternalEndPoint.Port) 194 else if (regions[i].InternalEndPoint.Port == regions[j].InternalEndPoint.Port)
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 354f587..642e82e 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -545,7 +545,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
545 throw new Exception( 545 throw new Exception(
546 String.Format("region UUID already in use by region {0}, UUID {1}, <{2},{3}>", 546 String.Format("region UUID already in use by region {0}, UUID {1}, <{2},{3}>",
547 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, 547 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
548 scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); 548 scene.RegionInfo.LegacyRegionLocX, scene.RegionInfo.LegacyRegionLocY));
549 } 549 }
550 else 550 else
551 { 551 {
@@ -559,8 +559,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
559 region.RegionID = regionID; 559 region.RegionID = regionID;
560 region.originRegionID = regionID; 560 region.originRegionID = regionID;
561 region.RegionName = (string) requestData["region_name"]; 561 region.RegionName = (string) requestData["region_name"];
562 region.RegionLocX = Convert.ToUInt32(requestData["region_x"]); 562 region.LegacyRegionLocX = Convert.ToUInt32(requestData["region_x"]);
563 region.RegionLocY = Convert.ToUInt32(requestData["region_y"]); 563 region.LegacyRegionLocY = Convert.ToUInt32(requestData["region_y"]);
564 564
565 // check for collisions: region name, region UUID, 565 // check for collisions: region name, region UUID,
566 // region location 566 // region location
@@ -568,14 +568,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController
568 throw new Exception( 568 throw new Exception(
569 String.Format("region name already in use by region {0}, UUID {1}, <{2},{3}>", 569 String.Format("region name already in use by region {0}, UUID {1}, <{2},{3}>",
570 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, 570 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
571 scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); 571 scene.RegionInfo.LegacyRegionLocX, scene.RegionInfo.LegacyRegionLocY));
572 572
573 if (m_application.SceneManager.TryGetScene(region.RegionLocX, region.RegionLocY, out scene)) 573 if (m_application.SceneManager.TryGetScene(region.LegacyRegionLocX, region.LegacyRegionLocY, out scene))
574 throw new Exception( 574 throw new Exception(
575 String.Format("region location <{0},{1}> already in use by region {2}, UUID {3}, <{4},{5}>", 575 String.Format("region location <{0},{1}> already in use by region {2}, UUID {3}, <{4},{5}>",
576 region.RegionLocX, region.RegionLocY, 576 region.LegacyRegionLocX, region.LegacyRegionLocY,
577 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, 577 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
578 scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); 578 scene.RegionInfo.LegacyRegionLocX, scene.RegionInfo.LegacyRegionLocY));
579 579
580 region.InternalEndPoint = 580 region.InternalEndPoint =
581 new IPEndPoint(IPAddress.Parse((string) requestData["listen_ip"]), 0); 581 new IPEndPoint(IPAddress.Parse((string) requestData["listen_ip"]), 0);
@@ -589,7 +589,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
589 region.InternalEndPoint.Address, 589 region.InternalEndPoint.Address,
590 region.InternalEndPoint.Port, 590 region.InternalEndPoint.Port,
591 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, 591 scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
592 scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); 592 scene.RegionInfo.LegacyRegionLocX, scene.RegionInfo.LegacyRegionLocY));
593 593
594 region.ExternalHostName = (string) requestData["external_address"]; 594 region.ExternalHostName = (string) requestData["external_address"];
595 595
@@ -628,8 +628,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
628 String.Format( 628 String.Format(
629 m_config.GetString("region_file_template", 629 m_config.GetString("region_file_template",
630 "{0}x{1}-{2}.ini"), 630 "{0}x{1}-{2}.ini"),
631 region.RegionLocX.ToString(), 631 region.LegacyRegionLocX.ToString(),
632 region.RegionLocY.ToString(), 632 region.LegacyRegionLocY.ToString(),
633 regionID.ToString(), 633 regionID.ToString(),
634 region.InternalEndPoint.Port.ToString(), 634 region.InternalEndPoint.Port.ToString(),
635 region.RegionName.Replace(" ", "_").Replace(":", "_"). 635 region.RegionName.Replace(" ", "_").Replace(":", "_").
@@ -1022,7 +1022,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1022 // Set home position 1022 // Set home position
1023 1023
1024 GridRegion home = scene.GridService.GetRegionByPosition(scopeID, 1024 GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
1025 (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); 1025 (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
1026 if (null == home) 1026 if (null == home)
1027 { 1027 {
1028 m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName); 1028 m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName);
@@ -1252,7 +1252,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1252 if ((null != regionXLocation) && (null != regionYLocation)) 1252 if ((null != regionXLocation) && (null != regionYLocation))
1253 { 1253 {
1254 GridRegion home = scene.GridService.GetRegionByPosition(scopeID, 1254 GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
1255 (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); 1255 (int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
1256 if (null == home) { 1256 if (null == home) {
1257 m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName); 1257 m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
1258 } else { 1258 } else {
@@ -2883,7 +2883,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
2883 // Set home position 2883 // Set home position
2884 2884
2885 GridRegion home = scene.GridService.GetRegionByPosition(scopeID, 2885 GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
2886 (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); 2886 (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
2887 if (null == home) { 2887 if (null == home) {
2888 m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]); 2888 m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
2889 } else { 2889 } else {
diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs
index 463c621..50433ba 100644
--- a/OpenSim/Data/IRegionData.cs
+++ b/OpenSim/Data/IRegionData.cs
@@ -54,12 +54,12 @@ namespace OpenSim.Data
54 /// <summary> 54 /// <summary>
55 /// Return the x-coordinate of this region. 55 /// Return the x-coordinate of this region.
56 /// </summary> 56 /// </summary>
57 public int coordX { get { return posX / (int)Constants.RegionSize; } } 57 public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
58 58
59 /// <summary> 59 /// <summary>
60 /// Return the y-coordinate of this region. 60 /// Return the y-coordinate of this region.
61 /// </summary> 61 /// </summary>
62 public int coordY { get { return posY / (int)Constants.RegionSize; } } 62 public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
63 63
64 public Dictionary<string, object> Data; 64 public Dictionary<string, object> Data;
65 } 65 }
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
index f41f60c..9f5991b 100644
--- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
@@ -49,6 +49,7 @@ namespace OpenSim.Data.MSSQL
49 49
50 // private static FileSystemDataStore Instance = new FileSystemDataStore(); 50 // private static FileSystemDataStore Instance = new FileSystemDataStore();
51 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 private static string LogHeader = "[REGION DB MSSQL]";
52 53
53 /// <summary> 54 /// <summary>
54 /// The database manager 55 /// The database manager
@@ -530,43 +531,49 @@ ELSE
530 /// <returns></returns> 531 /// <returns></returns>
531 public double[,] LoadTerrain(UUID regionID) 532 public double[,] LoadTerrain(UUID regionID)
532 { 533 {
533 double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 534 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
534 terrain.Initialize(); 535 return terrData.GetDoubles();
536 }
537
538 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
539 {
540 TerrainData terrData = null;
535 541
536 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; 542 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc";
537 543
538 using (SqlConnection conn = new SqlConnection(m_connectionString)) 544 using (SqlConnection conn = new SqlConnection(m_connectionString))
539 using (SqlCommand cmd = new SqlCommand(sql, conn))
540 { 545 {
541 // MySqlParameter param = new MySqlParameter(); 546 using (SqlCommand cmd = new SqlCommand(sql, conn))
542 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
543 conn.Open();
544 using (SqlDataReader reader = cmd.ExecuteReader())
545 { 547 {
546 int rev; 548 // MySqlParameter param = new MySqlParameter();
547 if (reader.Read()) 549 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
550 conn.Open();
551 using (SqlDataReader reader = cmd.ExecuteReader())
548 { 552 {
549 MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); 553 int rev;
550 BinaryReader br = new BinaryReader(str); 554 if (reader.Read())
551 for (int x = 0; x < (int)Constants.RegionSize; x++)
552 { 555 {
553 for (int y = 0; y < (int)Constants.RegionSize; y++) 556 rev = (int)reader["Revision"];
554 { 557 byte[] blob = (byte[])reader["Heightfield"];
555 terrain[x, y] = br.ReadDouble(); 558 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
556 }
557 } 559 }
558 rev = (int)reader["Revision"]; 560 else
559 } 561 {
560 else 562 _Log.Info("[REGION DB]: No terrain found for region");
561 { 563 return null;
562 _Log.Info("[REGION DB]: No terrain found for region"); 564 }
563 return null; 565 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
564 } 566 }
565 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
566 } 567 }
567 } 568 }
568 569
569 return terrain; 570 return terrData;
571 }
572
573 // Legacy entry point for when terrain was always a 256x256 hieghtmap
574 public void StoreTerrain(double[,] ter, UUID regionID)
575 {
576 StoreTerrain(new HeightmapTerrainData(ter), regionID);
570 } 577 }
571 578
572 /// <summary> 579 /// <summary>
@@ -574,10 +581,8 @@ ELSE
574 /// </summary> 581 /// </summary>
575 /// <param name="terrain">terrain map data.</param> 582 /// <param name="terrain">terrain map data.</param>
576 /// <param name="regionID">regionID.</param> 583 /// <param name="regionID">regionID.</param>
577 public void StoreTerrain(double[,] terrain, UUID regionID) 584 public void StoreTerrain(TerrainData terrData, UUID regionID)
578 { 585 {
579 int revision = Util.UnixTimeSinceEpoch();
580
581 //Delete old terrain map 586 //Delete old terrain map
582 string sql = "delete from terrain where RegionUUID=@RegionUUID"; 587 string sql = "delete from terrain where RegionUUID=@RegionUUID";
583 using (SqlConnection conn = new SqlConnection(m_connectionString)) 588 using (SqlConnection conn = new SqlConnection(m_connectionString))
@@ -590,17 +595,23 @@ ELSE
590 595
591 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; 596 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)";
592 597
598 int terrainDBRevision;
599 Array terrainDBblob;
600 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
601
593 using (SqlConnection conn = new SqlConnection(m_connectionString)) 602 using (SqlConnection conn = new SqlConnection(m_connectionString))
594 using (SqlCommand cmd = new SqlCommand(sql, conn))
595 { 603 {
596 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); 604 using (SqlCommand cmd = new SqlCommand(sql, conn))
597 cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); 605 {
598 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); 606 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
599 conn.Open(); 607 cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
600 cmd.ExecuteNonQuery(); 608 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
609 conn.Open();
610 cmd.ExecuteNonQuery();
611 }
601 } 612 }
602 613
603 _Log.Info("[REGION DB]: Stored terrain revision r " + revision); 614 _Log.InfoFormat("{0} Stored terrain revision r={1}", LogHeader, terrainDBRevision);
604 } 615 }
605 616
606 /// <summary> 617 /// <summary>
@@ -1345,30 +1356,6 @@ VALUES
1345 #region Private Methods 1356 #region Private Methods
1346 1357
1347 /// <summary> 1358 /// <summary>
1348 /// Serializes the terrain data for storage in DB.
1349 /// </summary>
1350 /// <param name="val">terrain data</param>
1351 /// <returns></returns>
1352 private static Array serializeTerrain(double[,] val)
1353 {
1354 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double));
1355 BinaryWriter bw = new BinaryWriter(str);
1356
1357 // TODO: COMPATIBILITY - Add byte-order conversions
1358 for (int x = 0; x < (int)Constants.RegionSize; x++)
1359 for (int y = 0; y < (int)Constants.RegionSize; y++)
1360 {
1361 double height = val[x, y];
1362 if (height == 0.0)
1363 height = double.Epsilon;
1364
1365 bw.Write(height);
1366 }
1367
1368 return str.ToArray();
1369 }
1370
1371 /// <summary>
1372 /// Stores new regionsettings. 1359 /// Stores new regionsettings.
1373 /// </summary> 1360 /// </summary>
1374 /// <param name="regionSettings">The region settings.</param> 1361 /// <param name="regionSettings">The region settings.</param>
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index b03a904..42f2ebb 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -48,6 +48,7 @@ namespace OpenSim.Data.MySQL
48 public class MySQLSimulationData : ISimulationDataStore 48 public class MySQLSimulationData : ISimulationDataStore
49 { 49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static string LogHeader = "[REGION DB MYSQL]";
51 52
52 private string m_connectionString; 53 private string m_connectionString;
53 private object m_dbLock = new object(); 54 private object m_dbLock = new object();
@@ -91,7 +92,7 @@ namespace OpenSim.Data.MySQL
91 } 92 }
92 catch (Exception e) 93 catch (Exception e)
93 { 94 {
94 m_log.Error("[REGION DB]: MySQL error in ExecuteReader: " + e.Message); 95 m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e);
95 throw; 96 throw;
96 } 97 }
97 98
@@ -572,10 +573,14 @@ namespace OpenSim.Data.MySQL
572 } 573 }
573 } 574 }
574 575
576 // Legacy entry point for when terrain was always a 256x256 hieghtmap
575 public void StoreTerrain(double[,] ter, UUID regionID) 577 public void StoreTerrain(double[,] ter, UUID regionID)
576 { 578 {
577 m_log.Info("[REGION DB]: Storing terrain"); 579 StoreTerrain(new HeightmapTerrainData(ter), regionID);
580 }
578 581
582 public void StoreTerrain(TerrainData terrData, UUID regionID)
583 {
579 lock (m_dbLock) 584 lock (m_dbLock)
580 { 585 {
581 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 586 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
@@ -589,11 +594,18 @@ namespace OpenSim.Data.MySQL
589 594
590 ExecuteNonQuery(cmd); 595 ExecuteNonQuery(cmd);
591 596
592 cmd.CommandText = "insert into terrain (RegionUUID, " + 597 int terrainDBRevision;
593 "Revision, Heightfield) values (?RegionUUID, " + 598 Array terrainDBblob;
594 "1, ?Heightfield)"; 599 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
595 600
596 cmd.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter)); 601 m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}",
602 LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision);
603
604 cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)"
605 + "values (?RegionUUID, ?Revision, ?Heightfield)";
606
607 cmd.Parameters.AddWithValue("Revision", terrainDBRevision);
608 cmd.Parameters.AddWithValue("Heightfield", terrainDBblob);
597 609
598 ExecuteNonQuery(cmd); 610 ExecuteNonQuery(cmd);
599 } 611 }
@@ -601,9 +613,16 @@ namespace OpenSim.Data.MySQL
601 } 613 }
602 } 614 }
603 615
616 // Legacy region loading
604 public double[,] LoadTerrain(UUID regionID) 617 public double[,] LoadTerrain(UUID regionID)
605 { 618 {
606 double[,] terrain = null; 619 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
620 return terrData.GetDoubles();
621 }
622
623 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
624 {
625 TerrainData terrData = null;
607 626
608 lock (m_dbLock) 627 lock (m_dbLock)
609 { 628 {
@@ -623,32 +642,15 @@ namespace OpenSim.Data.MySQL
623 while (reader.Read()) 642 while (reader.Read())
624 { 643 {
625 int rev = Convert.ToInt32(reader["Revision"]); 644 int rev = Convert.ToInt32(reader["Revision"]);
626 645 byte[] blob = (byte[])reader["Heightfield"];
627 terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 646 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
628 terrain.Initialize();
629
630 using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"]))
631 {
632 using (BinaryReader br = new BinaryReader(mstr))
633 {
634 for (int x = 0; x < (int)Constants.RegionSize; x++)
635 {
636 for (int y = 0; y < (int)Constants.RegionSize; y++)
637 {
638 terrain[x, y] = br.ReadDouble();
639 }
640 }
641 }
642
643 m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev);
644 }
645 } 647 }
646 } 648 }
647 } 649 }
648 } 650 }
649 } 651 }
650 652
651 return terrain; 653 return terrData;
652 } 654 }
653 655
654 public void RemoveLandObject(UUID globalID) 656 public void RemoveLandObject(UUID globalID)
@@ -1525,30 +1527,6 @@ namespace OpenSim.Data.MySQL
1525 } 1527 }
1526 1528
1527 /// <summary> 1529 /// <summary>
1528 ///
1529 /// </summary>
1530 /// <param name="val"></param>
1531 /// <returns></returns>
1532 private static Array SerializeTerrain(double[,] val)
1533 {
1534 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
1535 BinaryWriter bw = new BinaryWriter(str);
1536
1537 // TODO: COMPATIBILITY - Add byte-order conversions
1538 for (int x = 0; x < (int)Constants.RegionSize; x++)
1539 for (int y = 0; y < (int)Constants.RegionSize; y++)
1540 {
1541 double height = val[x, y];
1542 if (height == 0.0)
1543 height = double.Epsilon;
1544
1545 bw.Write(height);
1546 }
1547
1548 return str.ToArray();
1549 }
1550
1551 /// <summary>
1552 /// Fill the prim command with prim values 1530 /// Fill the prim command with prim values
1553 /// </summary> 1531 /// </summary>
1554 /// <param name="row"></param> 1532 /// <param name="row"></param>
diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs
index d11ad72..acde1a1 100644
--- a/OpenSim/Data/Null/NullSimulationData.cs
+++ b/OpenSim/Data/Null/NullSimulationData.cs
@@ -132,18 +132,35 @@ namespace OpenSim.Data.Null
132 return new List<SceneObjectGroup>(); 132 return new List<SceneObjectGroup>();
133 } 133 }
134 134
135 Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>(); 135 Dictionary<UUID, TerrainData> m_terrains = new Dictionary<UUID, TerrainData>();
136 public void StoreTerrain(double[,] ter, UUID regionID) 136 public void StoreTerrain(TerrainData ter, UUID regionID)
137 { 137 {
138 if (m_terrains.ContainsKey(regionID)) 138 if (m_terrains.ContainsKey(regionID))
139 m_terrains.Remove(regionID); 139 m_terrains.Remove(regionID);
140 m_terrains.Add(regionID, ter); 140 m_terrains.Add(regionID, ter);
141 } 141 }
142 142
143 // Legacy. Just don't do this.
144 public void StoreTerrain(double[,] ter, UUID regionID)
145 {
146 TerrainData terrData = new HeightmapTerrainData(ter);
147 StoreTerrain(terrData, regionID);
148 }
149
150 // Legacy. Just don't do this.
143 public double[,] LoadTerrain(UUID regionID) 151 public double[,] LoadTerrain(UUID regionID)
144 { 152 {
145 if (m_terrains.ContainsKey(regionID)) 153 if (m_terrains.ContainsKey(regionID))
146 { 154 {
155 return m_terrains[regionID].GetDoubles();
156 }
157 return null;
158 }
159
160 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
161 {
162 if (m_terrains.ContainsKey(regionID))
163 {
147 return m_terrains[regionID]; 164 return m_terrains[regionID];
148 } 165 }
149 return null; 166 return null;
diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
index 354d749..1505f87 100644
--- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
+++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
@@ -46,6 +46,7 @@ namespace OpenSim.Data.PGSQL
46 public class PGSQLSimulationData : ISimulationDataStore 46 public class PGSQLSimulationData : ISimulationDataStore
47 { 47 {
48 private const string _migrationStore = "RegionStore"; 48 private const string _migrationStore = "RegionStore";
49 private const string LogHeader = "[REGION DB PGSQL]";
49 50
50 // private static FileSystemDataStore Instance = new FileSystemDataStore(); 51 // private static FileSystemDataStore Instance = new FileSystemDataStore();
51 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -523,44 +524,50 @@ namespace OpenSim.Data.PGSQL
523 /// <returns></returns> 524 /// <returns></returns>
524 public double[,] LoadTerrain(UUID regionID) 525 public double[,] LoadTerrain(UUID regionID)
525 { 526 {
526 double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 527 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
527 terrain.Initialize(); 528 return terrData.GetDoubles();
529 }
530
531 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
532 {
533 TerrainData terrData = null;
528 534
529 string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain 535 string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain
530 where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; "; 536 where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; ";
531 537
532 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 538 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
533 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
534 { 539 {
535 // PGSqlParameter param = new PGSqlParameter(); 540 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
536 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
537 conn.Open();
538 using (NpgsqlDataReader reader = cmd.ExecuteReader())
539 { 541 {
540 int rev; 542 // PGSqlParameter param = new PGSqlParameter();
541 if (reader.Read()) 543 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
544 conn.Open();
545 using (NpgsqlDataReader reader = cmd.ExecuteReader())
542 { 546 {
543 MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); 547 int rev;
544 BinaryReader br = new BinaryReader(str); 548 if (reader.Read())
545 for (int x = 0; x < (int)Constants.RegionSize; x++)
546 { 549 {
547 for (int y = 0; y < (int)Constants.RegionSize; y++) 550 rev = Convert.ToInt32(reader["Revision"]);
548 { 551 byte[] blob = (byte[])reader["Heightfield"];
549 terrain[x, y] = br.ReadDouble(); 552 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
550 }
551 } 553 }
552 rev = (int)reader["Revision"]; 554 else
553 } 555 {
554 else 556 _Log.Info("[REGION DB]: No terrain found for region");
555 { 557 return null;
556 _Log.Info("[REGION DB]: No terrain found for region"); 558 }
557 return null; 559 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
558 } 560 }
559 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
560 } 561 }
561 } 562 }
562 563
563 return terrain; 564 return terrData;
565 }
566
567 // Legacy entry point for when terrain was always a 256x256 heightmap
568 public void StoreTerrain(double[,] terrain, UUID regionID)
569 {
570 StoreTerrain(new HeightmapTerrainData(terrain), regionID);
564 } 571 }
565 572
566 /// <summary> 573 /// <summary>
@@ -568,35 +575,43 @@ namespace OpenSim.Data.PGSQL
568 /// </summary> 575 /// </summary>
569 /// <param name="terrain">terrain map data.</param> 576 /// <param name="terrain">terrain map data.</param>
570 /// <param name="regionID">regionID.</param> 577 /// <param name="regionID">regionID.</param>
571 public void StoreTerrain(double[,] terrain, UUID regionID) 578 public void StoreTerrain(TerrainData terrData, UUID regionID)
572 { 579 {
573 int revision = Util.UnixTimeSinceEpoch();
574
575 //Delete old terrain map 580 //Delete old terrain map
576 string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID"; 581 string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID";
577 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 582 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
578 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
579 { 583 {
580 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); 584 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
581 conn.Open(); 585 {
582 cmd.ExecuteNonQuery(); 586 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
587 conn.Open();
588 cmd.ExecuteNonQuery();
589
590 _Log.InfoFormat("{0} Deleted terrain revision id = {1}", LogHeader, regionID);
591 }
583 } 592 }
584 593
585 _Log.Info("[REGION DB]: Deleted terrain revision r " + revision); 594 int terrainDBRevision;
595 Array terrainDBblob;
596 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
586 597
587 sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)"; 598 sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)";
588 599
589 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 600 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
590 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
591 { 601 {
592 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); 602 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
593 cmd.Parameters.Add(_Database.CreateParameter("Revision", revision)); 603 {
594 cmd.Parameters.Add(_Database.CreateParameter("Heightfield", serializeTerrain(terrain))); 604 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
595 conn.Open(); 605 cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision));
596 cmd.ExecuteNonQuery(); 606 cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob));
607 conn.Open();
608 cmd.ExecuteNonQuery();
609
610 _Log.InfoFormat("{0} Stored terrain id = {1}, terrainSize = <{2},{3}>",
611 LogHeader, regionID, terrData.SizeX, terrData.SizeY);
612 }
597 } 613 }
598 614
599 _Log.Info("[REGION DB]: Stored terrain revision r " + revision);
600 } 615 }
601 616
602 /// <summary> 617 /// <summary>
@@ -1350,30 +1365,6 @@ namespace OpenSim.Data.PGSQL
1350 #region Private Methods 1365 #region Private Methods
1351 1366
1352 /// <summary> 1367 /// <summary>
1353 /// Serializes the terrain data for storage in DB.
1354 /// </summary>
1355 /// <param name="val">terrain data</param>
1356 /// <returns></returns>
1357 private static Array serializeTerrain(double[,] val)
1358 {
1359 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double));
1360 BinaryWriter bw = new BinaryWriter(str);
1361
1362 // TODO: COMPATIBILITY - Add byte-order conversions
1363 for (int x = 0; x < (int)Constants.RegionSize; x++)
1364 for (int y = 0; y < (int)Constants.RegionSize; y++)
1365 {
1366 double height = val[x, y];
1367 if (height == 0.0)
1368 height = double.Epsilon;
1369
1370 bw.Write(height);
1371 }
1372
1373 return str.ToArray();
1374 }
1375
1376 /// <summary>
1377 /// Stores new regionsettings. 1368 /// Stores new regionsettings.
1378 /// </summary> 1369 /// </summary>
1379 /// <param name="regionSettings">The region settings.</param> 1370 /// <param name="regionSettings">The region settings.</param>
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
index d938b6b..5a34f09 100644
--- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs
+++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
@@ -51,6 +51,7 @@ namespace OpenSim.Data.SQLite
51 public class SQLiteSimulationData : ISimulationDataStore 51 public class SQLiteSimulationData : ISimulationDataStore
52 { 52 {
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 private static readonly string LogHeader = "[REGION DB SQLLITE]";
54 55
55 private const string primSelect = "select * from prims"; 56 private const string primSelect = "select * from prims";
56 private const string shapeSelect = "select * from primshapes"; 57 private const string shapeSelect = "select * from primshapes";
@@ -819,45 +820,44 @@ namespace OpenSim.Data.SQLite
819 prim.Inventory.RestoreInventoryItems(inventory); 820 prim.Inventory.RestoreInventoryItems(inventory);
820 } 821 }
821 822
823 // Legacy entry point for when terrain was always a 256x256 hieghtmap
824 public void StoreTerrain(double[,] ter, UUID regionID)
825 {
826 StoreTerrain(new HeightmapTerrainData(ter), regionID);
827 }
828
822 /// <summary> 829 /// <summary>
823 /// Store a terrain revision in region storage 830 /// Store a terrain revision in region storage
824 /// </summary> 831 /// </summary>
825 /// <param name="ter">terrain heightfield</param> 832 /// <param name="ter">terrain heightfield</param>
826 /// <param name="regionID">region UUID</param> 833 /// <param name="regionID">region UUID</param>
827 public void StoreTerrain(double[,] ter, UUID regionID) 834 public void StoreTerrain(TerrainData terrData, UUID regionID)
828 { 835 {
829 lock (ds) 836 lock (ds)
830 { 837 {
831 int revision = Util.UnixTimeSinceEpoch();
832
833 // This is added to get rid of the infinitely growing
834 // terrain databases which negatively impact on SQLite
835 // over time. Before reenabling this feature there
836 // needs to be a limitter put on the number of
837 // revisions in the database, as this old
838 // implementation is a DOS attack waiting to happen.
839
840 using ( 838 using (
841 SqliteCommand cmd = 839 SqliteCommand cmd = new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID", m_conn))
842 new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision <= :Revision",
843 m_conn))
844 { 840 {
845 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); 841 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
846 cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
847 cmd.ExecuteNonQuery(); 842 cmd.ExecuteNonQuery();
848 } 843 }
849 844
850 // the following is an work around for .NET. The perf 845 // the following is an work around for .NET. The perf
851 // issues associated with it aren't as bad as you think. 846 // issues associated with it aren't as bad as you think.
852 m_log.Debug("[SQLITE REGION DB]: Storing terrain revision r" + revision.ToString());
853 String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + 847 String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
854 " values(:RegionUUID, :Revision, :Heightfield)"; 848 " values(:RegionUUID, :Revision, :Heightfield)";
855 849
850 int terrainDBRevision;
851 Array terrainDBblob;
852 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
853
854 m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision);
855
856 using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) 856 using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
857 { 857 {
858 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); 858 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
859 cmd.Parameters.Add(new SqliteParameter(":Revision", revision)); 859 cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision));
860 cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter))); 860 cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob));
861 cmd.ExecuteNonQuery(); 861 cmd.ExecuteNonQuery();
862 } 862 }
863 } 863 }
@@ -870,11 +870,16 @@ namespace OpenSim.Data.SQLite
870 /// <returns>Heightfield data</returns> 870 /// <returns>Heightfield data</returns>
871 public double[,] LoadTerrain(UUID regionID) 871 public double[,] LoadTerrain(UUID regionID)
872 { 872 {
873 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
874 return terrData.GetDoubles();
875 }
876
877 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
878 {
879 TerrainData terrData = null;
880
873 lock (ds) 881 lock (ds)
874 { 882 {
875 double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
876 terret.Initialize();
877
878 String sql = "select RegionUUID, Revision, Heightfield from terrain" + 883 String sql = "select RegionUUID, Revision, Heightfield from terrain" +
879 " where RegionUUID=:RegionUUID order by Revision desc"; 884 " where RegionUUID=:RegionUUID order by Revision desc";
880 885
@@ -887,21 +892,9 @@ namespace OpenSim.Data.SQLite
887 int rev = 0; 892 int rev = 0;
888 if (row.Read()) 893 if (row.Read())
889 { 894 {
890 // TODO: put this into a function
891 using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"]))
892 {
893 using (BinaryReader br = new BinaryReader(str))
894 {
895 for (int x = 0; x < (int)Constants.RegionSize; x++)
896 {
897 for (int y = 0; y < (int)Constants.RegionSize; y++)
898 {
899 terret[x, y] = br.ReadDouble();
900 }
901 }
902 }
903 }
904 rev = Convert.ToInt32(row["Revision"]); 895 rev = Convert.ToInt32(row["Revision"]);
896 byte[] blob = (byte[])row["Heightfield"];
897 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
905 } 898 }
906 else 899 else
907 { 900 {
@@ -912,8 +905,8 @@ namespace OpenSim.Data.SQLite
912 m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString()); 905 m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString());
913 } 906 }
914 } 907 }
915 return terret;
916 } 908 }
909 return terrData;
917 } 910 }
918 911
919 public void RemoveLandObject(UUID globalID) 912 public void RemoveLandObject(UUID globalID)
@@ -2019,40 +2012,6 @@ namespace OpenSim.Data.SQLite
2019 /// <summary> 2012 /// <summary>
2020 /// 2013 ///
2021 /// </summary> 2014 /// </summary>
2022 /// <param name="val"></param>
2023 /// <returns></returns>
2024 private static Array serializeTerrain(double[,] val)
2025 {
2026 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double));
2027 BinaryWriter bw = new BinaryWriter(str);
2028
2029 // TODO: COMPATIBILITY - Add byte-order conversions
2030 for (int x = 0; x < (int)Constants.RegionSize; x++)
2031 for (int y = 0; y < (int)Constants.RegionSize; y++)
2032 bw.Write(val[x, y]);
2033
2034 return str.ToArray();
2035 }
2036
2037 // private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val)
2038 // {
2039 // row["RegionUUID"] = regionUUID;
2040 // row["Revision"] = rev;
2041
2042 // MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize)*sizeof (double));
2043 // BinaryWriter bw = new BinaryWriter(str);
2044
2045 // // TODO: COMPATIBILITY - Add byte-order conversions
2046 // for (int x = 0; x < (int)Constants.RegionSize; x++)
2047 // for (int y = 0; y < (int)Constants.RegionSize; y++)
2048 // bw.Write(val[x, y]);
2049
2050 // row["Heightfield"] = str.ToArray();
2051 // }
2052
2053 /// <summary>
2054 ///
2055 /// </summary>
2056 /// <param name="row"></param> 2015 /// <param name="row"></param>
2057 /// <param name="prim"></param> 2016 /// <param name="prim"></param>
2058 /// <param name="sceneGroupID"></param> 2017 /// <param name="sceneGroupID"></param>
diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs
index dbed8f6..b4989d1 100644
--- a/OpenSim/Data/Tests/RegionTests.cs
+++ b/OpenSim/Data/Tests/RegionTests.cs
@@ -300,8 +300,8 @@ namespace OpenSim.Data.Tests
300 300
301 RegionInfo regionInfo = new RegionInfo(); 301 RegionInfo regionInfo = new RegionInfo();
302 regionInfo.RegionID = region3; 302 regionInfo.RegionID = region3;
303 regionInfo.RegionLocX = 0; 303 regionInfo.LegacyRegionLocX = 0;
304 regionInfo.RegionLocY = 0; 304 regionInfo.LegacyRegionLocY = 0;
305 305
306 SceneObjectPart sop = new SceneObjectPart(); 306 SceneObjectPart sop = new SceneObjectPart();
307 SceneObjectGroup sog = new SceneObjectGroup(sop); 307 SceneObjectGroup sog = new SceneObjectGroup(sop);
@@ -1066,8 +1066,8 @@ namespace OpenSim.Data.Tests
1066 { 1066 {
1067 RegionInfo regionInfo = new RegionInfo(); 1067 RegionInfo regionInfo = new RegionInfo();
1068 regionInfo.RegionID = regionId; 1068 regionInfo.RegionID = regionId;
1069 regionInfo.RegionLocX = 0; 1069 regionInfo.LegacyRegionLocX = 0;
1070 regionInfo.RegionLocY = 0; 1070 regionInfo.LegacyRegionLocY = 0;
1071 1071
1072 SceneObjectPart sop = new SceneObjectPart(); 1072 SceneObjectPart sop = new SceneObjectPart();
1073 sop.Name = name; 1073 sop.Name = name;
diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs
index a2eb5ee..d80808c 100644
--- a/OpenSim/Framework/Constants.cs
+++ b/OpenSim/Framework/Constants.cs
@@ -30,9 +30,18 @@ namespace OpenSim.Framework
30{ 30{
31 public class Constants 31 public class Constants
32 { 32 {
33 // 'RegionSize' is the legacy region size.
34 // DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionSize[XYZ] as a region might not
35 // be the legacy region size.
33 public const uint RegionSize = 256; 36 public const uint RegionSize = 256;
34 public const uint RegionHeight = 4096; 37 public const uint RegionHeight = 4096;
35 public const byte TerrainPatchSize = 16; 38 // This could be a parameters but, really, a region of greater than this is pretty unmanageable
39 public const uint MaximumRegionSize = 8192;
40
41 // Since terrain is stored in 16x16 heights, regions must be a multiple of this number and that is the minimum
42 public const int MinRegionSize = 16;
43 public const int TerrainPatchSize = 16;
44
36 public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f"; 45 public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f";
37 46
38 public enum EstateAccessCodex : uint 47 public enum EstateAccessCodex : uint
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 24b9c89..63b3d89 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -99,6 +99,7 @@ namespace OpenSim.Framework
99 public class RegionInfo 99 public class RegionInfo
100 { 100 {
101 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 101 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
102 private static readonly string LogHeader = "[REGION INFO]";
102 103
103 public bool commFailTF = false; 104 public bool commFailTF = false;
104 public ConfigurationMember configMember; 105 public ConfigurationMember configMember;
@@ -137,16 +138,20 @@ namespace OpenSim.Framework
137 public bool m_allow_alternate_ports; 138 public bool m_allow_alternate_ports;
138 protected string m_externalHostName; 139 protected string m_externalHostName;
139 protected IPEndPoint m_internalEndPoint; 140 protected IPEndPoint m_internalEndPoint;
140 protected uint? m_regionLocX;
141 protected uint? m_regionLocY;
142 protected uint m_remotingPort; 141 protected uint m_remotingPort;
143 public UUID RegionID = UUID.Zero; 142 public UUID RegionID = UUID.Zero;
144 public string RemotingAddress; 143 public string RemotingAddress;
145 public UUID ScopeID = UUID.Zero; 144 public UUID ScopeID = UUID.Zero;
146 private UUID m_maptileStaticUUID = UUID.Zero; 145 private UUID m_maptileStaticUUID = UUID.Zero;
147 146
148 private Dictionary<String, String> m_otherSettings = new Dictionary<string, string>(); 147 public uint RegionWorldLocX = 0;
148 public uint RegionWorldLocY = 0;
149 public uint RegionWorldLocZ = 0;
150 public uint RegionSizeX = Constants.RegionSize;
151 public uint RegionSizeY = Constants.RegionSize;
152 public uint RegionSizeZ = Constants.RegionHeight;
149 153
154 private Dictionary<String, String> m_otherSettings = new Dictionary<string, string>();
150 155
151 // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. 156 // Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
152 157
@@ -229,11 +234,8 @@ namespace OpenSim.Framework
229 m_serverURI = string.Empty; 234 m_serverURI = string.Empty;
230 } 235 }
231 236
232 public RegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) 237 public RegionInfo(uint legacyRegionLocX, uint legacyRegionLocY, IPEndPoint internalEndPoint, string externalUri)
233 { 238 {
234 m_regionLocX = regionLocX;
235 m_regionLocY = regionLocY;
236
237 m_internalEndPoint = internalEndPoint; 239 m_internalEndPoint = internalEndPoint;
238 m_externalHostName = externalUri; 240 m_externalHostName = externalUri;
239 m_serverURI = string.Empty; 241 m_serverURI = string.Empty;
@@ -447,25 +449,66 @@ namespace OpenSim.Framework
447 449
448 /// <summary> 450 /// <summary>
449 /// The x co-ordinate of this region in map tiles (e.g. 1000). 451 /// The x co-ordinate of this region in map tiles (e.g. 1000).
452 /// Coordinate is scaled as world coordinates divided by the legacy region size
453 /// and is thus is the number of legacy regions.
454 /// </summary>
455 public uint LegacyRegionLocX
456 {
457 get { return RegionWorldLocX / Constants.RegionSize; }
458 set { RegionWorldLocX = value * Constants.RegionSize; }
459 }
460
461 /// <summary>
462 /// The y co-ordinate of this region in map tiles (e.g. 1000).
463 /// Coordinate is scaled as world coordinates divided by the legacy region size
464 /// and is thus is the number of legacy regions.
465 /// </summary>
466 public uint LegacyRegionLocY
467 {
468 get { return RegionWorldLocY / Constants.RegionSize; }
469 set { RegionWorldLocY = value * Constants.RegionSize; }
470 }
471
472 /// <summary>
473 /// The x co-ordinate of this region in map tiles (e.g. 1000).
474 /// Coordinate is scaled as world coordinates divided by the legacy region size
475 /// and is thus is the number of legacy regions.
476 /// DO NOT USE FOR NEW CODE! This entrypoint exists for downward compatability with external modules.
450 /// </summary> 477 /// </summary>
451 public uint RegionLocX 478 public uint RegionLocX
452 { 479 {
453 get { return m_regionLocX.Value; } 480 get { return LegacyRegionLocX; }
454 set { m_regionLocX = value; } 481 set { LegacyRegionLocX = value; }
455 } 482 }
456 483
457 /// <summary> 484 /// <summary>
458 /// The y co-ordinate of this region in map tiles (e.g. 1000). 485 /// The y co-ordinate of this region in map tiles (e.g. 1000).
486 /// Coordinate is scaled as world coordinates divided by the legacy region size
487 /// and is thus is the number of legacy regions.
488 /// DO NOT USE FOR NEW CODE! This entrypoint exists for downward compatability with external modules.
459 /// </summary> 489 /// </summary>
460 public uint RegionLocY 490 public uint RegionLocY
461 { 491 {
462 get { return m_regionLocY.Value; } 492 get { return LegacyRegionLocY; }
463 set { m_regionLocY = value; } 493 set { LegacyRegionLocY = value; }
494 }
495
496 public void SetDefaultRegionSize()
497 {
498 RegionWorldLocX = 0;
499 RegionWorldLocY = 0;
500 RegionWorldLocZ = 0;
501 RegionSizeX = Constants.RegionSize;
502 RegionSizeY = Constants.RegionSize;
503 RegionSizeZ = Constants.RegionHeight;
464 } 504 }
465 505
506 // A unique region handle is created from the region's world coordinates.
507 // This cannot be changed because some code expects to receive the region handle and then
508 // compute the region coordinates from it.
466 public ulong RegionHandle 509 public ulong RegionHandle
467 { 510 {
468 get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); } 511 get { return Util.UIntsToLong(RegionWorldLocX, RegionWorldLocY); }
469 } 512 }
470 513
471 public void SetEndPoint(string ipaddr, int port) 514 public void SetEndPoint(string ipaddr, int port)
@@ -572,8 +615,25 @@ namespace OpenSim.Framework
572 615
573 string[] locationElements = location.Split(new char[] {','}); 616 string[] locationElements = location.Split(new char[] {','});
574 617
575 m_regionLocX = Convert.ToUInt32(locationElements[0]); 618 LegacyRegionLocX = Convert.ToUInt32(locationElements[0]);
576 m_regionLocY = Convert.ToUInt32(locationElements[1]); 619 LegacyRegionLocY = Convert.ToUInt32(locationElements[1]);
620
621 // Region size
622 // Default to legacy region size if not specified.
623 allKeys.Remove("SizeX");
624 string configSizeX = config.GetString("SizeX", Constants.RegionSize.ToString());
625 config.Set("SizeX", configSizeX);
626 RegionSizeX = Convert.ToUInt32(configSizeX);
627 allKeys.Remove("SizeY");
628 string configSizeY = config.GetString("SizeY", Constants.RegionSize.ToString());
629 config.Set("SizeY", configSizeX);
630 RegionSizeY = Convert.ToUInt32(configSizeY);
631 allKeys.Remove("SizeZ");
632 string configSizeZ = config.GetString("SizeZ", Constants.RegionHeight.ToString());
633 config.Set("SizeZ", configSizeX);
634 RegionSizeZ = Convert.ToUInt32(configSizeZ);
635
636 DoRegionSizeSanityChecks();
577 637
578 // InternalAddress 638 // InternalAddress
579 // 639 //
@@ -693,6 +753,57 @@ namespace OpenSim.Framework
693 } 753 }
694 } 754 }
695 755
756 // Make sure user specified region sizes are sane.
757 // Must be multiples of legacy region size (256).
758 private void DoRegionSizeSanityChecks()
759 {
760 if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
761 {
762 // Doing non-legacy region sizes.
763 // Enforce region size to be multiples of the legacy region size (256)
764 uint partial = RegionSizeX % Constants.RegionSize;
765 if (partial != 0)
766 {
767 RegionSizeX -= partial;
768 if (RegionSizeX == 0)
769 RegionSizeX = Constants.RegionSize;
770 m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeX={3} instead of specified {4}",
771 LogHeader, Constants.RegionSize, m_regionName, RegionSizeX, RegionSizeX + partial);
772 }
773 partial = RegionSizeY % Constants.RegionSize;
774 if (partial != 0)
775 {
776 RegionSizeY -= partial;
777 if (RegionSizeY == 0)
778 RegionSizeY = Constants.RegionSize;
779 m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeY={3} instead of specified {4}",
780 LogHeader, Constants.RegionSize, m_regionName, RegionSizeY, RegionSizeY + partial);
781 }
782
783 // Because of things in the viewer, regions MUST be square.
784 // Remove this check when viewers have been updated.
785 if (RegionSizeX != RegionSizeY)
786 {
787 uint minSize = Math.Min(RegionSizeX, RegionSizeY);
788 RegionSizeX = minSize;
789 RegionSizeY = minSize;
790 m_log.ErrorFormat("{0} Regions must be square until viewers are updated. Forcing region {1} size to <{2},{3}>",
791 LogHeader, m_regionName, RegionSizeX, RegionSizeY);
792 }
793
794 // There is a practical limit to region size.
795 if (RegionSizeX > Constants.MaximumRegionSize || RegionSizeY > Constants.MaximumRegionSize)
796 {
797 RegionSizeX = Util.Clamp<uint>(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize);
798 RegionSizeY = Util.Clamp<uint>(RegionSizeY, Constants.RegionSize, Constants.MaximumRegionSize);
799 m_log.ErrorFormat("{0} Region dimensions must be less than {1}. Clamping {2}'s size to <{3},{4}>",
800 LogHeader, Constants.MaximumRegionSize, m_regionName, RegionSizeX, RegionSizeY);
801 }
802
803 m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY);
804 }
805 }
806
696 private void WriteNiniConfig(IConfigSource source) 807 private void WriteNiniConfig(IConfigSource source)
697 { 808 {
698 IConfig config = source.Configs[RegionName]; 809 IConfig config = source.Configs[RegionName];
@@ -704,9 +815,16 @@ namespace OpenSim.Framework
704 815
705 config.Set("RegionUUID", RegionID.ToString()); 816 config.Set("RegionUUID", RegionID.ToString());
706 817
707 string location = String.Format("{0},{1}", m_regionLocX, m_regionLocY); 818 string location = String.Format("{0},{1}", LegacyRegionLocX, LegacyRegionLocY);
708 config.Set("Location", location); 819 config.Set("Location", location);
709 820
821 if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
822 {
823 config.Set("SizeX", RegionSizeX);
824 config.Set("SizeY", RegionSizeY);
825 config.Set("SizeZ", RegionSizeZ);
826 }
827
710 config.Set("InternalAddress", m_internalEndPoint.Address.ToString()); 828 config.Set("InternalAddress", m_internalEndPoint.Address.ToString());
711 config.Set("InternalPort", m_internalEndPoint.Port); 829 config.Set("InternalPort", m_internalEndPoint.Port);
712 830
@@ -789,10 +907,18 @@ namespace OpenSim.Framework
789 RegionID.ToString(), true); 907 RegionID.ToString(), true);
790 configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, 908 configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
791 "Region Name", RegionName, true); 909 "Region Name", RegionName, true);
910
792 configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, 911 configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
793 "Grid Location (X Axis)", m_regionLocX.ToString(), true); 912 "Grid Location (X Axis)", LegacyRegionLocX.ToString(), true);
794 configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, 913 configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
795 "Grid Location (Y Axis)", m_regionLocY.ToString(), true); 914 "Grid Location (Y Axis)", LegacyRegionLocY.ToString(), true);
915 configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
916 "Size of region in X dimension", RegionSizeX.ToString(), true);
917 configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
918 "Size of region in Y dimension", RegionSizeY.ToString(), true);
919 configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
920 "Size of region in Z dimension", RegionSizeZ.ToString(), true);
921
796 //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); 922 //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
797 configMember.addConfigurationOption("internal_ip_address", 923 configMember.addConfigurationOption("internal_ip_address",
798 ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, 924 ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
@@ -855,10 +981,18 @@ namespace OpenSim.Framework
855 UUID.Random().ToString(), true); 981 UUID.Random().ToString(), true);
856 configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, 982 configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
857 "Region Name", "OpenSim Test", false); 983 "Region Name", "OpenSim Test", false);
984
858 configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, 985 configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
859 "Grid Location (X Axis)", "1000", false); 986 "Grid Location (X Axis)", "1000", false);
860 configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, 987 configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
861 "Grid Location (Y Axis)", "1000", false); 988 "Grid Location (Y Axis)", "1000", false);
989 configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
990 "Size of region in X dimension", Constants.RegionSize.ToString(), false);
991 configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
992 "Size of region in Y dimension", Constants.RegionSize.ToString(), false);
993 configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
994 "Size of region in Z dimension", Constants.RegionHeight.ToString(), false);
995
862 //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); 996 //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
863 configMember.addConfigurationOption("internal_ip_address", 997 configMember.addConfigurationOption("internal_ip_address",
864 ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, 998 ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
@@ -916,10 +1050,19 @@ namespace OpenSim.Framework
916 RegionName = (string) configuration_result; 1050 RegionName = (string) configuration_result;
917 break; 1051 break;
918 case "sim_location_x": 1052 case "sim_location_x":
919 m_regionLocX = (uint) configuration_result; 1053 LegacyRegionLocX = (uint) configuration_result;
920 break; 1054 break;
921 case "sim_location_y": 1055 case "sim_location_y":
922 m_regionLocY = (uint) configuration_result; 1056 LegacyRegionLocY = (uint) configuration_result;
1057 break;
1058 case "sim_size_x":
1059 RegionSizeX = (uint) configuration_result;
1060 break;
1061 case "sim_size_y":
1062 RegionSizeY = (uint) configuration_result;
1063 break;
1064 case "sim_size_z":
1065 RegionSizeZ = (uint) configuration_result;
923 break; 1066 break;
924 case "internal_ip_address": 1067 case "internal_ip_address":
925 IPAddress address = (IPAddress) configuration_result; 1068 IPAddress address = (IPAddress) configuration_result;
@@ -1000,8 +1143,13 @@ namespace OpenSim.Framework
1000 args["external_host_name"] = OSD.FromString(ExternalHostName); 1143 args["external_host_name"] = OSD.FromString(ExternalHostName);
1001 args["http_port"] = OSD.FromString(HttpPort.ToString()); 1144 args["http_port"] = OSD.FromString(HttpPort.ToString());
1002 args["server_uri"] = OSD.FromString(ServerURI); 1145 args["server_uri"] = OSD.FromString(ServerURI);
1003 args["region_xloc"] = OSD.FromString(RegionLocX.ToString()); 1146
1004 args["region_yloc"] = OSD.FromString(RegionLocY.ToString()); 1147 args["region_xloc"] = OSD.FromString(LegacyRegionLocX.ToString());
1148 args["region_yloc"] = OSD.FromString(LegacyRegionLocY.ToString());
1149 args["region_size_x"] = OSD.FromString(RegionSizeX.ToString());
1150 args["region_size_y"] = OSD.FromString(RegionSizeY.ToString());
1151 args["region_size_z"] = OSD.FromString(RegionSizeZ.ToString());
1152
1005 args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString()); 1153 args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString());
1006 args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString()); 1154 args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString());
1007 if ((RemotingAddress != null) && !RemotingAddress.Equals("")) 1155 if ((RemotingAddress != null) && !RemotingAddress.Equals(""))
@@ -1032,14 +1180,21 @@ namespace OpenSim.Framework
1032 { 1180 {
1033 uint locx; 1181 uint locx;
1034 UInt32.TryParse(args["region_xloc"].AsString(), out locx); 1182 UInt32.TryParse(args["region_xloc"].AsString(), out locx);
1035 RegionLocX = locx; 1183 LegacyRegionLocX = locx;
1036 } 1184 }
1037 if (args["region_yloc"] != null) 1185 if (args["region_yloc"] != null)
1038 { 1186 {
1039 uint locy; 1187 uint locy;
1040 UInt32.TryParse(args["region_yloc"].AsString(), out locy); 1188 UInt32.TryParse(args["region_yloc"].AsString(), out locy);
1041 RegionLocY = locy; 1189 LegacyRegionLocY = locy;
1042 } 1190 }
1191 if (args.ContainsKey("region_size_x"))
1192 RegionSizeX = (uint)args["region_size_x"].AsInteger();
1193 if (args.ContainsKey("region_size_y"))
1194 RegionSizeY = (uint)args["region_size_y"].AsInteger();
1195 if (args.ContainsKey("region_size_z"))
1196 RegionSizeZ = (uint)args["region_size_z"].AsInteger();
1197
1043 IPAddress ip_addr = null; 1198 IPAddress ip_addr = null;
1044 if (args["internal_ep_address"] != null) 1199 if (args["internal_ep_address"] != null)
1045 { 1200 {
@@ -1076,23 +1231,5 @@ namespace OpenSim.Framework
1076 regionInfo.ServerURI = serverURI; 1231 regionInfo.ServerURI = serverURI;
1077 return regionInfo; 1232 return regionInfo;
1078 } 1233 }
1079
1080 public Dictionary<string, object> ToKeyValuePairs()
1081 {
1082 Dictionary<string, object> kvp = new Dictionary<string, object>();
1083 kvp["uuid"] = RegionID.ToString();
1084 kvp["locX"] = RegionLocX.ToString();
1085 kvp["locY"] = RegionLocY.ToString();
1086 kvp["external_ip_address"] = ExternalEndPoint.Address.ToString();
1087 kvp["external_port"] = ExternalEndPoint.Port.ToString();
1088 kvp["external_host_name"] = ExternalHostName;
1089 kvp["http_port"] = HttpPort.ToString();
1090 kvp["internal_ip_address"] = InternalEndPoint.Address.ToString();
1091 kvp["internal_port"] = InternalEndPoint.Port.ToString();
1092 kvp["alternate_ports"] = m_allow_alternate_ports.ToString();
1093 kvp["server_uri"] = ServerURI;
1094
1095 return kvp;
1096 }
1097 } 1234 }
1098} 1235}
diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs
new file mode 100644
index 0000000..1c52a69
--- /dev/null
+++ b/OpenSim/Framework/TerrainData.cs
@@ -0,0 +1,418 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32
33using OpenMetaverse;
34
35using log4net;
36
37namespace OpenSim.Framework
38{
39 public abstract class TerrainData
40 {
41 // Terrain always is a square
42 public int SizeX { get; protected set; }
43 public int SizeY { get; protected set; }
44 public int SizeZ { get; protected set; }
45
46 // A height used when the user doesn't specify anything
47 public const float DefaultTerrainHeight = 21f;
48
49 public abstract float this[int x, int y] { get; set; }
50 // Someday terrain will have caves
51 public abstract float this[int x, int y, int z] { get; set; }
52
53 public bool IsTainted { get; protected set; }
54 public abstract bool IsTaintedAt(int xx, int yy);
55 public abstract void ClearTaint();
56
57 public abstract void ClearLand();
58 public abstract void ClearLand(float height);
59
60 // Return a representation of this terrain for storing as a blob in the database.
61 // Returns 'true' to say blob was stored in the 'out' locations.
62 public abstract bool GetDatabaseBlob(out int DBFormatRevisionCode, out Array blob);
63
64 // Given a revision code and a blob from the database, create and return the right type of TerrainData.
65 // The sizes passed are the expected size of the region. The database info will be used to
66 // initialize the heightmap of that sized region with as much data is in the blob.
67 // Return created TerrainData or 'null' if unsuccessful.
68 public static TerrainData CreateFromDatabaseBlobFactory(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob)
69 {
70 // For the moment, there is only one implementation class
71 return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob);
72 }
73
74 // return a special compressed representation of the heightmap in shorts
75 public abstract short[] GetCompressedMap();
76 public abstract float CompressionFactor { get; }
77
78 public abstract double[,] GetDoubles();
79 public abstract TerrainData Clone();
80 }
81
82 // The terrain is stored in the database as a blob with a 'revision' field.
83 // Some implementations of terrain storage would fill the revision field with
84 // the time the terrain was stored. When real revisions were added and this
85 // feature removed, that left some old entries with the time in the revision
86 // field.
87 // Thus, if revision is greater than 'RevisionHigh' then terrain db entry is
88 // left over and it is presumed to be 'Legacy256'.
89 // Numbers are arbitrary and are chosen to to reduce possible mis-interpretation.
90 // If a revision does not match any of these, it is assumed to be Legacy256.
91 public enum DBTerrainRevision
92 {
93 // Terrain is 'double[256,256]'
94 Legacy256 = 11,
95 // Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions
96 // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
97 Variable2D = 22,
98 // Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions
99 // and third int is the 'compression factor'. The heights are compressed as
100 // "short compressedHeight = (short)(height * compressionFactor);"
101 // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
102 Compressed2D = 27,
103 // A revision that is not listed above or any revision greater than this value is 'Legacy256'.
104 RevisionHigh = 1234
105 }
106
107 // Version of terrain that is a heightmap.
108 // This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge
109 // of 'patches' which are 16x16 terrain areas which can be sent separately to the viewer.
110 // The heighmap is kept as an array of short integers. The integer values are converted to
111 // and from floats by TerrainCompressionFactor. Shorts are used to limit storage used.
112 public class HeightmapTerrainData : TerrainData
113 {
114 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
115 private static string LogHeader = "[HEIGHTMAP TERRAIN DATA]";
116
117 // TerrainData.this[x, y]
118 public override float this[int x, int y]
119 {
120 get { return FromCompressedHeight(m_heightmap[x, y]); }
121 set {
122 short newVal = ToCompressedHeight(value);
123 if (m_heightmap[x, y] != newVal)
124 {
125 m_heightmap[x, y] = newVal;
126 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
127 }
128 }
129 }
130
131 // TerrainData.this[x, y, z]
132 public override float this[int x, int y, int z]
133 {
134 get { return this[x, y]; }
135 set { this[x, y] = value; }
136 }
137
138 // TerrainData.ClearTaint
139 public override void ClearTaint()
140 {
141 IsTainted = false;
142 for (int ii = 0; ii < m_taint.GetLength(0); ii++)
143 for (int jj = 0; jj < m_taint.GetLength(1); jj++)
144 m_taint[ii, jj] = false;
145 }
146
147 // TerrainData.ClearLand
148 public override void ClearLand()
149 {
150 ClearLand(DefaultTerrainHeight);
151 }
152 // TerrainData.ClearLand(float)
153 public override void ClearLand(float pHeight)
154 {
155 short flatHeight = ToCompressedHeight(pHeight);
156 for (int xx = 0; xx < SizeX; xx++)
157 for (int yy = 0; yy < SizeY; yy++)
158 m_heightmap[xx, yy] = flatHeight;
159 }
160
161 public override bool IsTaintedAt(int xx, int yy)
162 {
163 return m_taint[xx / Constants.TerrainPatchSize, yy / Constants.TerrainPatchSize];
164 }
165
166 // TerrainData.GetDatabaseBlob
167 // The user wants something to store in the database.
168 public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob)
169 {
170 bool ret = false;
171 if (SizeX == Constants.RegionSize && SizeY == Constants.RegionSize)
172 {
173 DBRevisionCode = (int)DBTerrainRevision.Legacy256;
174 blob = ToLegacyTerrainSerialization();
175 ret = true;
176 }
177 else
178 {
179 DBRevisionCode = (int)DBTerrainRevision.Compressed2D;
180 blob = ToCompressedTerrainSerialization();
181 ret = true;
182 }
183 return ret;
184 }
185
186 // TerrainData.CompressionFactor
187 private float m_compressionFactor = 100.0f;
188 public override float CompressionFactor { get { return m_compressionFactor; } }
189
190 // TerrainData.GetCompressedMap
191 public override short[] GetCompressedMap()
192 {
193 short[] newMap = new short[SizeX * SizeY];
194
195 int ind = 0;
196 for (int xx = 0; xx < SizeX; xx++)
197 for (int yy = 0; yy < SizeY; yy++)
198 newMap[ind++] = m_heightmap[xx, yy];
199
200 return newMap;
201
202 }
203 // TerrainData.Clone
204 public override TerrainData Clone()
205 {
206 HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ);
207 ret.m_heightmap = (short[,])this.m_heightmap.Clone();
208 return ret;
209 }
210
211 // TerrainData.GetDoubles
212 public override double[,] GetDoubles()
213 {
214 double[,] ret = new double[SizeX, SizeY];
215 for (int xx = 0; xx < SizeX; xx++)
216 for (int yy = 0; yy < SizeY; yy++)
217 ret[xx, yy] = FromCompressedHeight(m_heightmap[xx, yy]);
218
219 return ret;
220 }
221
222
223 // =============================================================
224
225 private short[,] m_heightmap;
226 // Remember subregions of the heightmap that has changed.
227 private bool[,] m_taint;
228
229 // To save space (especially for large regions), keep the height as a short integer
230 // that is coded as the float height times the compression factor (usually '100'
231 // to make for two decimal points).
232 public short ToCompressedHeight(double pHeight)
233 {
234 return (short)(pHeight * CompressionFactor);
235 }
236
237 public float FromCompressedHeight(short pHeight)
238 {
239 return ((float)pHeight) / CompressionFactor;
240 }
241
242 // To keep with the legacy theme, create an instance of this class based on the
243 // way terrain used to be passed around.
244 public HeightmapTerrainData(double[,] pTerrain)
245 {
246 SizeX = pTerrain.GetLength(0);
247 SizeY = pTerrain.GetLength(1);
248 SizeZ = (int)Constants.RegionHeight;
249 m_compressionFactor = 100.0f;
250
251 m_heightmap = new short[SizeX, SizeY];
252 for (int ii = 0; ii < SizeX; ii++)
253 {
254 for (int jj = 0; jj < SizeY; jj++)
255 {
256 m_heightmap[ii, jj] = ToCompressedHeight(pTerrain[ii, jj]);
257
258 }
259 }
260 // m_log.DebugFormat("{0} new by doubles. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
261
262 m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
263 ClearTaint();
264 }
265
266 // Create underlying structures but don't initialize the heightmap assuming the caller will immediately do that
267 public HeightmapTerrainData(int pX, int pY, int pZ)
268 {
269 SizeX = pX;
270 SizeY = pY;
271 SizeZ = pZ;
272 m_compressionFactor = 100.0f;
273 m_heightmap = new short[SizeX, SizeY];
274 m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
275 // m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
276 ClearTaint();
277 }
278
279 public HeightmapTerrainData(short[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ)
280 {
281 m_compressionFactor = pCompressionFactor;
282 int ind = 0;
283 for (int xx = 0; xx < SizeX; xx++)
284 for (int yy = 0; yy < SizeY; yy++)
285 m_heightmap[xx, yy] = cmap[ind++];
286 // m_log.DebugFormat("{0} new by compressed map. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
287 }
288
289 // Create a heighmap from a database blob
290 public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob) : this(pSizeX, pSizeY, pSizeZ)
291 {
292 switch ((DBTerrainRevision)pFormatCode)
293 {
294 case DBTerrainRevision.Compressed2D:
295 FromCompressedTerrainSerialization(pBlob);
296 m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
297 break;
298 default:
299 FromLegacyTerrainSerialization(pBlob);
300 m_log.DebugFormat("{0} HeightmapTerrainData create from legacy serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
301 break;
302 }
303 }
304
305 // Just create an array of doubles. Presumes the caller implicitly knows the size.
306 public Array ToLegacyTerrainSerialization()
307 {
308 Array ret = null;
309
310 using (MemoryStream str = new MemoryStream((int)Constants.RegionSize * (int)Constants.RegionSize * sizeof(double)))
311 {
312 using (BinaryWriter bw = new BinaryWriter(str))
313 {
314 for (int xx = 0; xx < Constants.RegionSize; xx++)
315 {
316 for (int yy = 0; yy < Constants.RegionSize; yy++)
317 {
318 double height = this[xx, yy];
319 if (height == 0.0)
320 height = double.Epsilon;
321 bw.Write(height);
322 }
323 }
324 }
325 ret = str.ToArray();
326 }
327 return ret;
328 }
329
330 // Just create an array of doubles. Presumes the caller implicitly knows the size.
331 public void FromLegacyTerrainSerialization(byte[] pBlob)
332 {
333 // In case database info doesn't match real terrain size, initialize the whole terrain.
334 ClearLand();
335
336 using (MemoryStream mstr = new MemoryStream(pBlob))
337 {
338 using (BinaryReader br = new BinaryReader(mstr))
339 {
340 for (int xx = 0; xx < (int)Constants.RegionSize; xx++)
341 {
342 for (int yy = 0; yy < (int)Constants.RegionSize; yy++)
343 {
344 float val = (float)br.ReadDouble();
345 if (xx < SizeX && yy < SizeY)
346 m_heightmap[xx, yy] = ToCompressedHeight(val);
347 }
348 }
349 }
350 ClearTaint();
351 }
352 }
353
354 // See the reader below.
355 public Array ToCompressedTerrainSerialization()
356 {
357 Array ret = null;
358 using (MemoryStream str = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(Int16))))
359 {
360 using (BinaryWriter bw = new BinaryWriter(str))
361 {
362 bw.Write((Int32)DBTerrainRevision.Compressed2D);
363 bw.Write((Int32)SizeX);
364 bw.Write((Int32)SizeY);
365 bw.Write((Int32)CompressionFactor);
366 for (int yy = 0; yy < SizeY; yy++)
367 for (int xx = 0; xx < SizeX; xx++)
368 {
369 bw.Write((Int16)m_heightmap[xx, yy]);
370 }
371 }
372 ret = str.ToArray();
373 }
374 return ret;
375 }
376
377 // Initialize heightmap from blob consisting of:
378 // int32, int32, int32, int32, int16[]
379 // where the first int32 is format code, next two int32s are the X and y of heightmap data and
380 // the forth int is the compression factor for the following int16s
381 // This is just sets heightmap info. The actual size of the region was set on this instance's
382 // creation and any heights not initialized by theis blob are set to the default height.
383 public void FromCompressedTerrainSerialization(byte[] pBlob)
384 {
385 Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
386
387 using (MemoryStream mstr = new MemoryStream(pBlob))
388 {
389 using (BinaryReader br = new BinaryReader(mstr))
390 {
391 hmFormatCode = br.ReadInt32();
392 hmSizeX = br.ReadInt32();
393 hmSizeY = br.ReadInt32();
394 hmCompressionFactor = br.ReadInt32();
395
396 m_compressionFactor = hmCompressionFactor;
397
398 // In case database info doesn't match real terrain size, initialize the whole terrain.
399 ClearLand();
400
401 for (int yy = 0; yy < hmSizeY; yy++)
402 {
403 for (int xx = 0; xx < hmSizeX; xx++)
404 {
405 Int16 val = br.ReadInt16();
406 if (xx < SizeX && yy < SizeY)
407 m_heightmap[xx, yy] = val;
408 }
409 }
410 }
411 ClearTaint();
412
413 m_log.InfoFormat("{0} Read compressed 2d heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}",
414 LogHeader, hmSizeX, hmSizeY, SizeX, SizeY, hmCompressionFactor);
415 }
416 }
417 }
418}
diff --git a/OpenSim/Framework/UserProfileData.cs b/OpenSim/Framework/UserProfileData.cs
index 9bac739..266ccf0 100644
--- a/OpenSim/Framework/UserProfileData.cs
+++ b/OpenSim/Framework/UserProfileData.cs
@@ -160,15 +160,19 @@ namespace OpenSim.Framework
160 public virtual ulong HomeRegion 160 public virtual ulong HomeRegion
161 { 161 {
162 get 162 get
163 { 163 {
164 return Utils.UIntsToLong( 164 return Util.RegionWorldLocToHandle(Util.RegionToWorldLoc(m_homeRegionX), Util.RegionToWorldLoc(m_homeRegionY));
165 m_homeRegionX * (uint)Constants.RegionSize, m_homeRegionY * (uint)Constants.RegionSize); 165 // return Utils.UIntsToLong( m_homeRegionX * (uint)Constants.RegionSize, m_homeRegionY * (uint)Constants.RegionSize);
166 } 166 }
167 167
168 set 168 set
169 { 169 {
170 m_homeRegionX = (uint) (value >> 40); 170 uint regionWorldLocX, regionWorldLocY;
171 m_homeRegionY = (((uint) (value)) >> 8); 171 Util.RegionHandleToWorldLoc(value, out regionWorldLocX, out regionWorldLocY);
172 m_homeRegionX = Util.WorldToRegionLoc(regionWorldLocX);
173 m_homeRegionY = Util.WorldToRegionLoc(regionWorldLocY);
174 // m_homeRegionX = (uint) (value >> 40);
175 // m_homeRegionY = (((uint) (value)) >> 8);
172 } 176 }
173 } 177 }
174 178
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index e8dfec1..2276951 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -333,6 +333,44 @@ namespace OpenSim.Framework
333 return Utils.UIntsToLong(X, Y); 333 return Utils.UIntsToLong(X, Y);
334 } 334 }
335 335
336 // Regions are identified with a 'handle' made up of its region coordinates packed into a ulong.
337 // Several places rely on the ability to extract a region's location from its handle.
338 // Note the location is in 'world coordinates' (see below).
339 // Region handles are based on the lowest coordinate of the region so trim the passed x,y to be the regions 0,0.
340 public static ulong RegionWorldLocToHandle(uint X, uint Y)
341 {
342 return Utils.UIntsToLong(X, Y);
343 }
344
345 public static void RegionHandleToWorldLoc(ulong handle, out uint X, out uint Y)
346 {
347 X = (uint)(handle >> 32);
348 Y = (uint)(handle & (ulong)uint.MaxValue);
349 }
350
351 public static void RegionHandleToRegionLoc(ulong handle, out uint X, out uint Y)
352 {
353 uint worldX, worldY;
354 RegionHandleToWorldLoc(handle, out worldX, out worldY);
355 X = WorldToRegionLoc(worldX);
356 Y = WorldToRegionLoc(worldY);
357 }
358
359 // A region location can be 'world coordinates' (meters from zero) or 'region coordinates'
360 // (number of regions from zero). This measurement of regions relies on the legacy 256 region size.
361 // These routines exist to make what is being converted explicit so the next person knows what was meant.
362 // Convert a region's 'world coordinate' to its 'region coordinate'.
363 public static uint WorldToRegionLoc(uint worldCoord)
364 {
365 return worldCoord / Constants.RegionSize;
366 }
367
368 // Convert a region's 'region coordinate' to its 'world coordinate'.
369 public static uint RegionToWorldLoc(uint regionCoord)
370 {
371 return regionCoord * Constants.RegionSize;
372 }
373
336 public static T Clamp<T>(T x, T min, T max) 374 public static T Clamp<T>(T x, T min, T max)
337 where T : IComparable<T> 375 where T : IComparable<T>
338 { 376 {
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index c2d9942..1d93e9b 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -825,8 +825,8 @@ namespace OpenSim
825 MainConsole.Instance.Output(String.Format( 825 MainConsole.Instance.Output(String.Format(
826 "Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}, Estate Name: {4}", 826 "Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}, Estate Name: {4}",
827 scene.RegionInfo.RegionName, 827 scene.RegionInfo.RegionName,
828 scene.RegionInfo.RegionLocX, 828 scene.RegionInfo.LegacyRegionLocX,
829 scene.RegionInfo.RegionLocY, 829 scene.RegionInfo.LegacyRegionLocY,
830 scene.RegionInfo.InternalEndPoint.Port, 830 scene.RegionInfo.InternalEndPoint.Port,
831 scene.RegionInfo.EstateSettings.EstateName)); 831 scene.RegionInfo.EstateSettings.EstateName));
832 }); 832 });
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 308638c..7e7f42e 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -690,7 +690,8 @@ namespace OpenSim
690 clientServer = clientNetworkServers; 690 clientServer = clientNetworkServers;
691 scene.LoadWorldMap(); 691 scene.LoadWorldMap();
692 692
693 scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName); 693 Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
694 scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName, regionExtent);
694 scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset; 695 scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset;
695 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); 696 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
696 scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight); 697 scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight);
@@ -742,7 +743,7 @@ namespace OpenSim
742 { 743 {
743 m_log.InfoFormat( 744 m_log.InfoFormat(
744 "[OPENSIM]: Got restart signal from SceneManager for region {0} ({1},{2})", 745 "[OPENSIM]: Got restart signal from SceneManager for region {0} ({1},{2})",
745 whichRegion.RegionName, whichRegion.RegionLocX, whichRegion.RegionLocY); 746 whichRegion.RegionName, whichRegion.LegacyRegionLocX, whichRegion.LegacyRegionLocY);
746 747
747 ShutdownClientServer(whichRegion); 748 ShutdownClientServer(whichRegion);
748 IScene scene; 749 IScene scene;
@@ -752,10 +753,10 @@ namespace OpenSim
752 753
753 # region Setup methods 754 # region Setup methods
754 755
755 protected override PhysicsScene GetPhysicsScene(string osSceneIdentifier) 756 protected override PhysicsScene GetPhysicsScene(string osSceneIdentifier, Vector3 regionExtent)
756 { 757 {
757 return GetPhysicsScene( 758 return GetPhysicsScene(
758 m_configSettings.PhysicsEngine, m_configSettings.MeshEngineName, Config, osSceneIdentifier); 759 m_configSettings.PhysicsEngine, m_configSettings.MeshEngineName, Config, osSceneIdentifier, regionExtent);
759 } 760 }
760 761
761 /// <summary> 762 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index c1aae3f..8a6270d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -34,11 +34,13 @@ using System.Text;
34using System.Threading; 34using System.Threading;
35using System.Timers; 35using System.Timers;
36using System.Xml; 36using System.Xml;
37
37using log4net; 38using log4net;
38using OpenMetaverse; 39using OpenMetaverse;
39using OpenMetaverse.Packets; 40using OpenMetaverse.Packets;
40using OpenMetaverse.Messages.Linden; 41using OpenMetaverse.Messages.Linden;
41using OpenMetaverse.StructuredData; 42using OpenMetaverse.StructuredData;
43
42using OpenSim.Framework; 44using OpenSim.Framework;
43using OpenSim.Framework.Client; 45using OpenSim.Framework.Client;
44using OpenSim.Framework.Monitoring; 46using OpenSim.Framework.Monitoring;
@@ -48,7 +50,6 @@ using OpenSim.Services.Interfaces;
48using Timer = System.Timers.Timer; 50using Timer = System.Timers.Timer;
49using AssetLandmark = OpenSim.Framework.AssetLandmark; 51using AssetLandmark = OpenSim.Framework.AssetLandmark;
50using RegionFlags = OpenMetaverse.RegionFlags; 52using RegionFlags = OpenMetaverse.RegionFlags;
51using Nini.Config;
52 53
53using System.IO; 54using System.IO;
54using PermissionMask = OpenSim.Framework.PermissionMask; 55using PermissionMask = OpenSim.Framework.PermissionMask;
@@ -307,6 +308,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
307 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; 308 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f;
308 309
309 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 310 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
311 private static string LogHeader = "[LLCLIENTVIEW]";
310 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients 312 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
311 313
312 /// <summary> 314 /// <summary>
@@ -447,7 +449,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
447 449
448// ~LLClientView() 450// ~LLClientView()
449// { 451// {
450// m_log.DebugFormat("[LLCLIENTVIEW]: Destructor called for {0}, circuit code {1}", Name, CircuitCode); 452// m_log.DebugFormat("{0} Destructor called for {1}, circuit code {2}", LogHeader, Name, CircuitCode);
451// } 453// }
452 454
453 /// <summary> 455 /// <summary>
@@ -513,9 +515,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 // there is some unidentified connection problem, not where we have issues due to deadlock 515 // there is some unidentified connection problem, not where we have issues due to deadlock
514 if (!IsActive && !force) 516 if (!IsActive && !force)
515 { 517 {
516 m_log.DebugFormat( 518 m_log.DebugFormat( "{0} Not attempting to close inactive client {1} in {2} since force flag is not set",
517 "[CLIENT]: Not attempting to close inactive client {0} in {1} since force flag is not set", 519 LogHeader, Name, m_scene.Name);
518 Name, m_scene.Name);
519 520
520 return; 521 return;
521 } 522 }
@@ -1153,7 +1154,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1153 /// <param name="map">heightmap</param> 1154 /// <param name="map">heightmap</param>
1154 public virtual void SendLayerData(float[] map) 1155 public virtual void SendLayerData(float[] map)
1155 { 1156 {
1156 Util.FireAndForget(DoSendLayerData, map); 1157 Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData());
1157 } 1158 }
1158 1159
1159 /// <summary> 1160 /// <summary>
@@ -1162,10 +1163,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1162 /// <param name="o"></param> 1163 /// <param name="o"></param>
1163 private void DoSendLayerData(object o) 1164 private void DoSendLayerData(object o)
1164 { 1165 {
1165 float[] map = LLHeightFieldMoronize((float[])o); 1166 TerrainData map = (TerrainData)o;
1166 1167
1167 try 1168 try
1168 { 1169 {
1170 // Send LayerData in typerwriter pattern
1169 //for (int y = 0; y < 16; y++) 1171 //for (int y = 0; y < 16; y++)
1170 //{ 1172 //{
1171 // for (int x = 0; x < 16; x++) 1173 // for (int x = 0; x < 16; x++)
@@ -1175,7 +1177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1175 //} 1177 //}
1176 1178
1177 // Send LayerData in a spiral pattern. Fun! 1179 // Send LayerData in a spiral pattern. Fun!
1178 SendLayerTopRight(map, 0, 0, 15, 15); 1180 SendLayerTopRight(map, 0, 0, map.SizeX/Constants.TerrainPatchSize-1, map.SizeY/Constants.TerrainPatchSize-1);
1179 } 1181 }
1180 catch (Exception e) 1182 catch (Exception e)
1181 { 1183 {
@@ -1183,7 +1185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1183 } 1185 }
1184 } 1186 }
1185 1187
1186 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2) 1188 private void SendLayerTopRight(TerrainData map, int x1, int y1, int x2, int y2)
1187 { 1189 {
1188 // Row 1190 // Row
1189 for (int i = x1; i <= x2; i++) 1191 for (int i = x1; i <= x2; i++)
@@ -1193,11 +1195,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1193 for (int j = y1 + 1; j <= y2; j++) 1195 for (int j = y1 + 1; j <= y2; j++)
1194 SendLayerData(x2, j, map); 1196 SendLayerData(x2, j, map);
1195 1197
1196 if (x2 - x1 > 0) 1198 if (x2 - x1 > 0 && y2 - y1 > 0)
1197 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2); 1199 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1198 } 1200 }
1199 1201
1200 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2) 1202 void SendLayerBottomLeft(TerrainData map, int x1, int y1, int x2, int y2)
1201 { 1203 {
1202 // Row in reverse 1204 // Row in reverse
1203 for (int i = x2; i >= x1; i--) 1205 for (int i = x2; i >= x1; i--)
@@ -1207,7 +1209,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1207 for (int j = y2 - 1; j >= y1; j--) 1209 for (int j = y2 - 1; j >= y1; j--)
1208 SendLayerData(x1, j, map); 1210 SendLayerData(x1, j, map);
1209 1211
1210 if (x2 - x1 > 0) 1212 if (x2 - x1 > 0 && y2 - y1 > 0)
1211 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1); 1213 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1212 } 1214 }
1213 1215
@@ -1229,22 +1231,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1229 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1231 // OutPacket(layerpack, ThrottleOutPacketType.Land);
1230 // } 1232 // }
1231 1233
1234 // Legacy form of invocation that passes around a bare data array.
1235 // Just ignore what was passed and use the real terrain info that is part of the scene.
1236 public void SendLayerData(int px, int py, float[] map)
1237 {
1238 SendLayerData(px, py, m_scene.Heightmap.GetTerrainData());
1239 }
1240
1232 /// <summary> 1241 /// <summary>
1233 /// Sends a specified patch to a client 1242 /// Sends a terrain packet for the point specified.
1243 /// This is a legacy call that has refarbed the terrain into a flat map of floats.
1244 /// We just use the terrain from the region we know about.
1234 /// </summary> 1245 /// </summary>
1235 /// <param name="px">Patch coordinate (x) 0..15</param> 1246 /// <param name="px">Patch coordinate (x) 0..15</param>
1236 /// <param name="py">Patch coordinate (y) 0..15</param> 1247 /// <param name="py">Patch coordinate (y) 0..15</param>
1237 /// <param name="map">heightmap</param> 1248 /// <param name="map">heightmap</param>
1238 public void SendLayerData(int px, int py, float[] map) 1249 public void SendLayerData(int px, int py, TerrainData terrData)
1239 { 1250 {
1240 try 1251 try
1241 { 1252 {
1242 int[] patches = new int[] { py * 16 + px }; 1253 LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, px, py);
1243 float[] heightmap = (map.Length == 65536) ?
1244 map :
1245 LLHeightFieldMoronize(map);
1246
1247 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1248 1254
1249 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience. 1255 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience.
1250 // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain. 1256 // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain.
@@ -1262,14 +1268,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1262 if (m_justEditedTerrain) 1268 if (m_justEditedTerrain)
1263 { 1269 {
1264 layerpack.Header.Reliable = false; 1270 layerpack.Header.Reliable = false;
1265 OutPacket(layerpack, 1271 OutPacket(layerpack, ThrottleOutPacketType.Unknown );
1266 ThrottleOutPacketType.Unknown );
1267 } 1272 }
1268 else 1273 else
1269 { 1274 {
1270 layerpack.Header.Reliable = true; 1275 layerpack.Header.Reliable = true;
1271 OutPacket(layerpack, 1276 OutPacket(layerpack, ThrottleOutPacketType.Land);
1272 ThrottleOutPacketType.Land);
1273 } 1277 }
1274 } 1278 }
1275 catch (Exception e) 1279 catch (Exception e)
@@ -1279,38 +1283,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1279 } 1283 }
1280 1284
1281 /// <summary> 1285 /// <summary>
1282 /// Munges heightfield into the LLUDP backed in restricted heightfield.
1283 /// </summary>
1284 /// <param name="map">float array in the base; Constants.RegionSize</param>
1285 /// <returns>float array in the base 256</returns>
1286 internal float[] LLHeightFieldMoronize(float[] map)
1287 {
1288 if (map.Length == 65536)
1289 return map;
1290 else
1291 {
1292 float[] returnmap = new float[65536];
1293
1294 if (map.Length < 65535)
1295 {
1296 // rebase the vector stride to 256
1297 for (int i = 0; i < Constants.RegionSize; i++)
1298 Array.Copy(map, i * (int)Constants.RegionSize, returnmap, i * 256, (int)Constants.RegionSize);
1299 }
1300 else
1301 {
1302 for (int i = 0; i < 256; i++)
1303 Array.Copy(map, i * (int)Constants.RegionSize, returnmap, i * 256, 256);
1304 }
1305
1306 //Array.Copy(map,0,returnmap,0,(map.Length < 65536)? map.Length : 65536);
1307
1308 return returnmap;
1309 }
1310
1311 }
1312
1313 /// <summary>
1314 /// Send the wind matrix to the client 1286 /// Send the wind matrix to the client
1315 /// </summary> 1287 /// </summary>
1316 /// <param name="windSpeeds">16x16 array of wind speeds</param> 1288 /// <param name="windSpeeds">16x16 array of wind speeds</param>
@@ -2785,8 +2757,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2785 { 2757 {
2786 if (req.AssetInf.Data == null) 2758 if (req.AssetInf.Data == null)
2787 { 2759 {
2788 m_log.ErrorFormat("Cannot send asset {0} ({1}), asset data is null", 2760 m_log.ErrorFormat("{0} Cannot send asset {1} ({2}), asset data is null",
2789 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2761 LogHeader, req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2790 return; 2762 return;
2791 } 2763 }
2792 2764
@@ -2913,8 +2885,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2913 { 2885 {
2914 pos = (land.AABBMax + land.AABBMin) * 0.5f; 2886 pos = (land.AABBMax + land.AABBMin) * 0.5f;
2915 } 2887 }
2916 reply.Data.GlobalX = info.RegionLocX + x; 2888 reply.Data.GlobalX = info.LegacyRegionLocX + x;
2917 reply.Data.GlobalY = info.RegionLocY + y; 2889 reply.Data.GlobalY = info.LegacyRegionLocY + y;
2918 reply.Data.GlobalZ = pos.Z; 2890 reply.Data.GlobalZ = pos.Z;
2919 reply.Data.SimName = Utils.StringToBytes(info.RegionName); 2891 reply.Data.SimName = Utils.StringToBytes(info.RegionName);
2920 reply.Data.SnapshotID = land.SnapshotID; 2892 reply.Data.SnapshotID = land.SnapshotID;
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index 853b72d..1ce166e 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -69,7 +69,7 @@ namespace OpenSim.Region.ClientStack
69 /// The name of the OpenSim scene this physics scene is serving. This will be used in log messages. 69 /// The name of the OpenSim scene this physics scene is serving. This will be used in log messages.
70 /// </param> 70 /// </param>
71 /// <returns></returns> 71 /// <returns></returns>
72 protected abstract PhysicsScene GetPhysicsScene(string osSceneIdentifier); 72 protected abstract PhysicsScene GetPhysicsScene(string osSceneIdentifier, Vector3 regionExtent);
73 73
74 protected abstract ClientStackManager CreateClientStackManager(); 74 protected abstract ClientStackManager CreateClientStackManager();
75 protected abstract Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService, IEstateDataService estateDataService, AgentCircuitManager circuitManager); 75 protected abstract Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService, IEstateDataService estateDataService, AgentCircuitManager circuitManager);
@@ -123,13 +123,13 @@ namespace OpenSim.Region.ClientStack
123 /// </param> 123 /// </param>
124 /// <returns></returns> 124 /// <returns></returns>
125 protected PhysicsScene GetPhysicsScene( 125 protected PhysicsScene GetPhysicsScene(
126 string engine, string meshEngine, IConfigSource config, string osSceneIdentifier) 126 string engine, string meshEngine, IConfigSource config, string osSceneIdentifier, Vector3 regionExtent)
127 { 127 {
128 PhysicsPluginManager physicsPluginManager; 128 PhysicsPluginManager physicsPluginManager;
129 physicsPluginManager = new PhysicsPluginManager(); 129 physicsPluginManager = new PhysicsPluginManager();
130 physicsPluginManager.LoadPluginsFromAssemblies("Physics"); 130 physicsPluginManager.LoadPluginsFromAssemblies("Physics");
131 131
132 return physicsPluginManager.GetPhysicsScene(engine, meshEngine, config, osSceneIdentifier); 132 return physicsPluginManager.GetPhysicsScene(engine, meshEngine, config, osSceneIdentifier, regionExtent);
133 } 133 }
134 } 134 }
135} \ No newline at end of file 135} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 27ace68..db62b31 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -189,8 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
189 string message = c.Message; 189 string message = c.Message;
190 Scene scene = (Scene)c.Scene; 190 Scene scene = (Scene)c.Scene;
191 Vector3 fromPos = c.Position; 191 Vector3 fromPos = c.Position;
192 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 192 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionWorldLocX, scene.RegionInfo.RegionWorldLocY, 0);
193 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
194 193
195 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel; 194 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel;
196 195
@@ -342,8 +341,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
342 { 341 {
343 Vector3 fromRegionPos = fromPos + regionPos; 342 Vector3 fromRegionPos = fromPos + regionPos;
344 Vector3 toRegionPos = presence.AbsolutePosition + 343 Vector3 toRegionPos = presence.AbsolutePosition +
345 new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, 344 new Vector3(presence.Scene.RegionInfo.RegionWorldLocX, presence.Scene.RegionInfo.RegionWorldLocY, 0);
346 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
347 345
348 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 346 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
349 347
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index 56ff2bd..a982466 100644
--- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -663,8 +663,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
663 663
664 Vector3 avaPos = p.AbsolutePosition; 664 Vector3 avaPos = p.AbsolutePosition;
665 // Getting the global position for the Avatar 665 // Getting the global position for the Avatar
666 Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX*Constants.RegionSize + avaPos.X, 666 Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionWorldLocX + avaPos.X,
667 remoteClient.Scene.RegionInfo.RegionLocY*Constants.RegionSize + avaPos.Y, 667 remoteClient.Scene.RegionInfo.RegionWorldLocY + avaPos.Y,
668 avaPos.Z); 668 avaPos.Z);
669 669
670 string landOwnerName = string.Empty; 670 string landOwnerName = string.Empty;
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 6545a99..13cc99a 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -269,9 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework
269 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID]) 269 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID])
270 { 270 {
271 uint x, y; 271 uint x, y;
272 Utils.LongToUInts(kvp.Key, out x, out y); 272 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
273 x = x / Constants.RegionSize;
274 y = y / Constants.RegionSize;
275 m_log.Info(" >> "+x+", "+y+": "+kvp.Value); 273 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
276 } 274 }
277 } 275 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index aa8a4db..c3d0765 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule 52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
55 56
56 public const int DefaultMaxTransferDistance = 4095; 57 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 58 public const bool WaitForAgentArrivedAtDestinationDefault = true;
@@ -433,10 +434,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
433 float posZLimit = 22; 434 float posZLimit = 22;
434 435
435 // TODO: Check other Scene HeightField 436 // TODO: Check other Scene HeightField
436 if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) 437 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
437 {
438 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
439 }
440 438
441 float newPosZ = posZLimit + localAVHeight; 439 float newPosZ = posZLimit + localAVHeight;
442 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 440 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
@@ -485,17 +483,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
485 483
486 if (finalDestination == null) 484 if (finalDestination == null)
487 { 485 {
488 m_log.WarnFormat( 486 m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}",
489 "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", 487 LogHeader, sp.Name, sp.UUID);
490 sp.Name, sp.UUID);
491 488
492 sp.ControllingClient.SendTeleportFailed("Problem at destination"); 489 sp.ControllingClient.SendTeleportFailed("Problem at destination");
493 return; 490 return;
494 } 491 }
495 492
496 // Check that these are not the same coordinates 493 // Check that these are not the same coordinates
497 if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && 494 if (finalDestination.RegionLocX == sp.Scene.RegionInfo.LegacyRegionLocX &&
498 finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) 495 finalDestination.RegionLocY == sp.Scene.RegionInfo.LegacyRegionLocY)
499 { 496 {
500 // Can't do. Viewer crashes 497 // Can't do. Viewer crashes
501 sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); 498 sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again.");
@@ -528,11 +525,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
528 525
529 // and set the map-tile to '(Offline)' 526 // and set the map-tile to '(Offline)'
530 uint regX, regY; 527 uint regX, regY;
531 Utils.LongToUInts(regionHandle, out regX, out regY); 528 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
532 529
533 MapBlockData block = new MapBlockData(); 530 MapBlockData block = new MapBlockData();
534 block.X = (ushort)(regX / Constants.RegionSize); 531 block.X = (ushort)Util.WorldToRegionLoc(regX);
535 block.Y = (ushort)(regY / Constants.RegionSize); 532 block.Y = (ushort)Util.WorldToRegionLoc(regY);
536 block.Access = 254; // == not there 533 block.Access = 254; // == not there
537 534
538 List<MapBlockData> blocks = new List<MapBlockData>(); 535 List<MapBlockData> blocks = new List<MapBlockData>();
@@ -567,8 +564,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
567// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); 564// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI);
568 565
569 // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position. 566 // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position.
570 return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance 567 return Math.Abs(sourceRegion.LegacyRegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance
571 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; 568 && Math.Abs(sourceRegion.LegacyRegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
572 } 569 }
573 570
574 /// <summary> 571 /// <summary>
@@ -635,7 +632,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
635 string.Format( 632 string.Format(
636 "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", 633 "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
637 finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, 634 finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY,
638 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, 635 sourceRegion.RegionName, sourceRegion.LegacyRegionLocX, sourceRegion.LegacyRegionLocY,
639 MaxTransferDistance)); 636 MaxTransferDistance));
640 637
641 return; 638 return;
@@ -1372,10 +1369,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1372 1369
1373// m_log.DebugFormat( 1370// m_log.DebugFormat(
1374// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1371// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1372 /*
1375 1373
1376 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1374 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1377 uint neighbourx = scene.RegionInfo.RegionLocX; 1375 uint neighbourx = scene.RegionInfo.LegacyRegionLocX;
1378 uint neighboury = scene.RegionInfo.RegionLocY; 1376 uint neighboury = scene.RegionInfo.LegacyRegionLocY;
1379 const float boundaryDistance = 1.7f; 1377 const float boundaryDistance = 1.7f;
1380 Vector3 northCross = new Vector3(0, boundaryDistance, 0); 1378 Vector3 northCross = new Vector3(0, boundaryDistance, 0);
1381 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); 1379 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
@@ -1408,8 +1406,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1408 neighbourx = b.TriggerRegionX; 1406 neighbourx = b.TriggerRegionX;
1409 1407
1410 Vector3 newposition = pos; 1408 Vector3 newposition = pos;
1411 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; 1409 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1412 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; 1410 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1413 agent.ControllingClient.SendAgentAlertMessage( 1411 agent.ControllingClient.SendAgentAlertMessage(
1414 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); 1412 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1415 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); 1413 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
@@ -1431,8 +1429,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1431 neighbourx = ba.TriggerRegionX; 1429 neighbourx = ba.TriggerRegionX;
1432 1430
1433 Vector3 newposition = pos; 1431 Vector3 newposition = pos;
1434 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; 1432 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1435 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; 1433 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1436 agent.ControllingClient.SendAgentAlertMessage( 1434 agent.ControllingClient.SendAgentAlertMessage(
1437 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); 1435 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1438 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); 1436 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
@@ -1462,8 +1460,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1462 neighboury = ba.TriggerRegionY; 1460 neighboury = ba.TriggerRegionY;
1463 neighbourx = ba.TriggerRegionX; 1461 neighbourx = ba.TriggerRegionX;
1464 Vector3 newposition = pos; 1462 Vector3 newposition = pos;
1465 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; 1463 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1466 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; 1464 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1467 agent.ControllingClient.SendAgentAlertMessage( 1465 agent.ControllingClient.SendAgentAlertMessage(
1468 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); 1466 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1469 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); 1467 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
@@ -1492,8 +1490,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1492 neighboury = b.TriggerRegionY; 1490 neighboury = b.TriggerRegionY;
1493 neighbourx = b.TriggerRegionX; 1491 neighbourx = b.TriggerRegionX;
1494 Vector3 newposition = pos; 1492 Vector3 newposition = pos;
1495 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; 1493 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1496 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; 1494 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1497 agent.ControllingClient.SendAgentAlertMessage( 1495 agent.ControllingClient.SendAgentAlertMessage(
1498 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); 1496 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1499 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); 1497 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
@@ -1506,6 +1504,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1506 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); 1504 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1507 newpos.Y = enterDistance; 1505 newpos.Y = enterDistance;
1508 } 1506 }
1507 */
1509 1508
1510 /* 1509 /*
1511 1510
@@ -1532,52 +1531,71 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1532 } 1531 }
1533 */ 1532 */
1534 1533
1535 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1534 double presenceWorldX = (double)scene.RegionInfo.RegionLocX + pos.X;
1536 1535 double presenceWorldY = (double)scene.RegionInfo.RegionLocY + pos.Y;
1537 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1538 1536
1539 ExpiringCache<ulong, DateTime> r; 1537 // Call the grid service to lookup the region containing the new position.
1540 DateTime banUntil; 1538 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
1539 presenceWorldX, presenceWorldY);
1541 1540
1542 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1541 if (neighbourRegion != null)
1543 {
1544 if (r.TryGetValue(neighbourHandle, out banUntil))
1545 {
1546 if (DateTime.Now < banUntil)
1547 return false;
1548 r.Remove(neighbourHandle);
1549 }
1550 }
1551 else
1552 { 1542 {
1553 r = null; 1543 Vector3 newRegionRelativeObjectPosition = new Vector3(
1554 } 1544 (float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1545 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1546 pos.Z);
1547 agent.ControllingClient.SendAgentAlertMessage(
1548 String.Format("Moving you to region {0},{1}", neighbourRegion.RegionCoordX, neighbourRegion.RegionCoordY), false);
1549 InformClientToInitiateTeleportToLocation(agent, (uint)neighbourRegion.RegionCoordX, (uint)neighbourRegion.RegionCoordY,
1550 newRegionRelativeObjectPosition, scene);
1555 1551
1556 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1552 ExpiringCache<ulong, DateTime> r;
1553 DateTime banUntil;
1557 1554
1558 string reason; 1555 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
1559 string version;
1560 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1561 {
1562 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1563 if (r == null)
1564 { 1556 {
1565 r = new ExpiringCache<ulong, DateTime>(); 1557 if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil))
1566 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1558 {
1567 1559 if (DateTime.Now < banUntil)
1568 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1560 return false;
1561 r.Remove(neighbourRegion.RegionHandle);
1562 }
1569 } 1563 }
1570 else 1564 else
1571 { 1565 {
1572 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1566 r = null;
1573 } 1567 }
1574 return false;
1575 }
1576 1568
1577 agent.IsInTransit = true; 1569 string reason;
1570 string version;
1571 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newRegionRelativeObjectPosition, out version, out reason))
1572 {
1573 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1574 if (r == null)
1575 {
1576 r = new ExpiringCache<ulong, DateTime>();
1577 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1578
1579 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
1580 }
1581 else
1582 {
1583 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1584 }
1585 return false;
1586 }
1578 1587
1579 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1588 agent.IsInTransit = true;
1580 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1589
1590 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1591 d.BeginInvoke(agent, newRegionRelativeObjectPosition,
1592 (uint)neighbourRegion.RegionLocX, (uint)neighbourRegion.RegionLocY,
1593 neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1594 }
1595 else
1596 {
1597 m_log.ErrorFormat("{0} Cross(sp). Did not find target region. SP.AbsolutePosition={1}", LogHeader, pos);
1598 }
1581 1599
1582 return true; 1600 return true;
1583 } 1601 }
@@ -1901,7 +1919,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1901 1919
1902 if (m_regionInfo != null) 1920 if (m_regionInfo != null)
1903 { 1921 {
1904 neighbours = RequestNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); 1922 neighbours = RequestNeighbours(sp, m_regionInfo.LegacyRegionLocX, m_regionInfo.LegacyRegionLocY);
1905 } 1923 }
1906 else 1924 else
1907 { 1925 {
@@ -2055,15 +2073,80 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2055 } 2073 }
2056 } 2074 }
2057 2075
2076 // Computes the difference between two region bases.
2077 // Returns a vector of world coordinates (meters) from base of first region to the second.
2078 // The first region is the home region of the passed scene presence.
2058 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) 2079 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
2059 { 2080 {
2060 int rRegionX = (int)sp.Scene.RegionInfo.RegionLocX; 2081 /*
2061 int rRegionY = (int)sp.Scene.RegionInfo.RegionLocY; 2082 int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
2083 int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
2062 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize; 2084 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
2063 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize; 2085 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize;
2064 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize; 2086 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
2065 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize; 2087 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
2066 return new Vector3(shiftx, shifty, 0f); 2088 return new Vector3(shiftx, shifty, 0f);
2089 */
2090 return new Vector3(sp.Scene.RegionInfo.RegionLocX - neighbour.RegionLocX,
2091 sp.Scene.RegionInfo.RegionLocY - neighbour.RegionLocY,
2092 0f);
2093 }
2094
2095 // Given a world position (fractional meter coordinate), get the GridRegion info for
2096 // the region containing that point.
2097 // Return 'null' if no such region exists.
2098 private GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
2099 {
2100 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
2101 GridRegion ret = null;
2102
2103 // As an optimization, since most regions will be legacy sized regions (256x256), first try to get
2104 // the region at the appropriate legacy region location.
2105 uint possibleX = (uint)Math.Floor(px);
2106 possibleX -= possibleX % Constants.RegionSize;
2107 uint possibleY = (uint)Math.Floor(py);
2108 possibleY -= possibleY % Constants.RegionSize;
2109 ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
2110 if (ret != null)
2111 {
2112 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
2113 LogHeader, possibleX, possibleY, ret.RegionName);
2114 }
2115
2116 if (ret == null)
2117 {
2118 // If the simple lookup failed, search the larger area for a region that contains this point
2119 double range = (double)Constants.RegionSize + 2;
2120 while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
2121 {
2122 // Get from the grid service a list of regions that might contain this point
2123 List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
2124 (int)(px - range), (int)(px + range),
2125 (int)(py - range), (int)(py + range));
2126 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
2127 LogHeader, possibleRegions.Count, range);
2128 if (possibleRegions != null && possibleRegions.Count > 0)
2129 {
2130 // If we found some regions, check to see if the point is within
2131 foreach (GridRegion gr in possibleRegions)
2132 {
2133 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
2134 LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
2135 if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
2136 && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
2137 {
2138 // Found a region that contains the point
2139 ret = gr;
2140 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
2141 break;
2142 }
2143 }
2144 }
2145 // Larger search area for next time around if not found
2146 range *= 2;
2147 }
2148 }
2149 return ret;
2067 } 2150 }
2068 2151
2069 private void InformClientOfNeighbourCompleted(IAsyncResult iar) 2152 private void InformClientOfNeighbourCompleted(IAsyncResult iar)
@@ -2161,10 +2244,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2161 extent.X = ((int)extent.X / (int)Constants.RegionSize); 2244 extent.X = ((int)extent.X / (int)Constants.RegionSize);
2162 extent.Y = ((int)extent.Y / (int)Constants.RegionSize); 2245 extent.Y = ((int)extent.Y / (int)Constants.RegionSize);
2163 2246
2164 swCorner.X = Scene.RegionInfo.RegionLocX - 1; 2247 swCorner.X = Scene.RegionInfo.LegacyRegionLocX - 1;
2165 swCorner.Y = Scene.RegionInfo.RegionLocY - 1; 2248 swCorner.Y = Scene.RegionInfo.LegacyRegionLocY - 1;
2166 neCorner.X = Scene.RegionInfo.RegionLocX + extent.X; 2249 neCorner.X = Scene.RegionInfo.LegacyRegionLocX + extent.X;
2167 neCorner.Y = Scene.RegionInfo.RegionLocY + extent.Y; 2250 neCorner.Y = Scene.RegionInfo.LegacyRegionLocY + extent.Y;
2168 } 2251 }
2169 2252
2170 /// <summary> 2253 /// <summary>
@@ -2272,10 +2355,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2272 /// Move the given scene object into a new region depending on which region its absolute position has moved 2355 /// Move the given scene object into a new region depending on which region its absolute position has moved
2273 /// into. 2356 /// into.
2274 /// 2357 ///
2275 /// This method locates the new region handle and offsets the prim position for the new region 2358 /// Using the objects new world location, ask the grid service for a the new region and adjust the prim
2359 /// position to be relative to the new region.
2276 /// </summary> 2360 /// </summary>
2277 /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
2278 /// <param name="grp">the scene object that we're crossing</param> 2361 /// <param name="grp">the scene object that we're crossing</param>
2362 /// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is
2363 /// relative to the region the object currently is in.</param>
2364 /// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param>
2279 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) 2365 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
2280 { 2366 {
2281 if (grp == null) 2367 if (grp == null)
@@ -2301,18 +2387,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2301 return; 2387 return;
2302 } 2388 }
2303 2389
2304 int thisx = (int)scene.RegionInfo.RegionLocX; 2390 /*
2305 int thisy = (int)scene.RegionInfo.RegionLocY; 2391 int thisx = (int)scene.RegionInfo.LegacyRegionLocX;
2392 int thisy = (int)scene.RegionInfo.LegacyRegionLocY;
2306 Vector3 EastCross = new Vector3(0.1f, 0, 0); 2393 Vector3 EastCross = new Vector3(0.1f, 0, 0);
2307 Vector3 WestCross = new Vector3(-0.1f, 0, 0); 2394 Vector3 WestCross = new Vector3(-0.1f, 0, 0);
2308 Vector3 NorthCross = new Vector3(0, 0.1f, 0); 2395 Vector3 NorthCross = new Vector3(0, 0.1f, 0);
2309 Vector3 SouthCross = new Vector3(0, -0.1f, 0); 2396 Vector3 SouthCross = new Vector3(0, -0.1f, 0);
2310 2397
2311 2398
2312 // use this if no borders were crossed! 2399 // use this default if no borders were crossed (handle of the current region)
2313 ulong newRegionHandle 2400 ulong newRegionHandle = Util.RegionWorldLocToHandle(scene.RegionInfo.RegionWorldLocX, scene.RegionInfo.RegionWorldLocY);
2314 = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
2315 (uint)((thisy) * Constants.RegionSize));
2316 2401
2317 Vector3 pos = attemptedPosition; 2402 Vector3 pos = attemptedPosition;
2318 2403
@@ -2469,30 +2554,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2469 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize)); 2554 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
2470 // y + 1 2555 // y + 1
2471 } 2556 }
2557 */
2472 2558
2473 // Offset the positions for the new region across the border 2559 // Remember the old group position in case the region lookup fails so position can be restored.
2474 Vector3 oldGroupPosition = grp.RootPart.GroupPosition; 2560 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2475 2561
2476 // If we fail to cross the border, then reset the position of the scene object on that border. 2562 // Compute the absolute position of the object.
2477 uint x = 0, y = 0; 2563 double objectWorldLocX = (double)scene.RegionInfo.RegionWorldLocX + attemptedPosition.X;
2478 Utils.LongToUInts(newRegionHandle, out x, out y); 2564 double objectWorldLocY = (double)scene.RegionInfo.RegionWorldLocY + attemptedPosition.Y;
2479 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2565
2566 // Ask the grid service for the region that contains the passed address
2567 GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, objectWorldLocX, objectWorldLocY);
2568
2569 Vector3 pos = Vector3.Zero;
2570 if (destination != null)
2571 {
2572 // Adjust the object's relative position from the old region (attemptedPosition)
2573 // to be relative to the new region (pos).
2574 pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX),
2575 (float)(objectWorldLocY - (double)destination.RegionLocY),
2576 attemptedPosition.Z);
2577 }
2480 2578
2481 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2579 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2482 { 2580 {
2483 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2581 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
2484 2582
2485 // We are going to move the object back to the old position so long as the old position 2583 // We are going to move the object back to the old position so long as the old position
2486 // is in the region 2584 // is in the region
2487 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2585 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
2488 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2586 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
2489 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f); 2587 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
2490 2588
2491 grp.RootPart.GroupPosition = oldGroupPosition; 2589 grp.RootPart.GroupPosition = oldGroupPosition;
2492 2590
2493 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2591 // Need to turn off the physics flags, otherwise the object will continue to attempt to
2494 // move out of the region creating an infinite loop of failed attempts to cross 2592 // move out of the region creating an infinite loop of failed attempts to cross
2495 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); 2593 grp.UpdatePrimFlags(grp.RootPart.LocalId, false, grp.IsTemporary, grp.IsPhantom, false);
2496 2594
2497 if (grp.RootPart.KeyframeMotion != null) 2595 if (grp.RootPart.KeyframeMotion != null)
2498 grp.RootPart.KeyframeMotion.CrossingFailure(); 2596 grp.RootPart.KeyframeMotion.CrossingFailure();
diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
index d943b20..bf87392 100644
--- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
@@ -213,8 +213,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
213 if (part != null) 213 if (part != null)
214 { 214 {
215 ObjectRegionName = s.RegionInfo.RegionName; 215 ObjectRegionName = s.RegionInfo.RegionName;
216 uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); 216 uint localX = s.RegionInfo.RegionWorldLocX;
217 uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); 217 uint localY = s.RegionInfo.RegionWorldLocY;
218 ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; 218 ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")";
219 return part; 219 return part;
220 } 220 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index 31ef79b..277293a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -192,8 +192,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
192 return m_GridService.GetRegionByUUID(scopeID, regionID); 192 return m_GridService.GetRegionByUUID(scopeID, regionID);
193 } 193 }
194 194
195 // Get a region given its base coordinates.
196 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
197 // be the base coordinate of the region.
195 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 198 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
196 { 199 {
200 m_log.DebugFormat("{0} GetRegionByPosition. pos=<{1},{2}>", "[LOCAL GRID SERVICE CONNECTOR", x, y);
197 GridRegion region = null; 201 GridRegion region = null;
198 202
199 // First see if it's a neighbour, even if it isn't on this sim. 203 // First see if it's a neighbour, even if it isn't on this sim.
@@ -206,6 +210,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
206 region = rcache.GetRegionByPosition(x, y); 210 region = rcache.GetRegionByPosition(x, y);
207 if (region != null) 211 if (region != null)
208 { 212 {
213 m_log.DebugFormat("{0} GetRegionByPosition. Found region {1}. Pos=<{2},{3}>",
214 "[LOCAL GRID SERVICE CONNECTOR", region.RegionName, x, y);
209 return region; 215 return region;
210 } 216 }
211 } 217 }
@@ -268,7 +274,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
268 caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key); 274 caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key);
269 List<GridRegion> regions = kvp.Value.GetNeighbours(); 275 List<GridRegion> regions = kvp.Value.GetNeighbours();
270 foreach (GridRegion r in regions) 276 foreach (GridRegion r in regions)
271 caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize); 277 caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, Util.WorldToRegionLoc((uint)r.RegionLocX), Util.WorldToRegionLoc((uint)r.RegionLocY));
272 } 278 }
273 } 279 }
274 280
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs
index 9172536..33ff7ea 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
66 return; 66 return;
67 67
68 m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}", 68 m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}",
69 m_scene.RegionInfo.RegionName, otherRegion.RegionName, otherRegion.RegionLocX / Constants.RegionSize, otherRegion.RegionLocY / Constants.RegionSize); 69 m_scene.RegionInfo.RegionName, otherRegion.RegionName, Util.WorldToRegionLoc((uint)otherRegion.RegionLocX), Util.WorldToRegionLoc((uint)otherRegion.RegionLocY));
70 70
71 m_neighbours[otherRegion.RegionHandle] = otherRegion; 71 m_neighbours[otherRegion.RegionHandle] = otherRegion;
72 } 72 }
@@ -82,11 +82,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
82 return new List<GridRegion>(m_neighbours.Values); 82 return new List<GridRegion>(m_neighbours.Values);
83 } 83 }
84 84
85 // Get a region given its base coordinates.
86 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
87 // be the base coordinate of the region.
88 // The snapping is technically unnecessary but is harmless because regions are always
89 // multiples of the legacy region size (256).
85 public GridRegion GetRegionByPosition(int x, int y) 90 public GridRegion GetRegionByPosition(int x, int y)
86 { 91 {
87 uint xsnap = (uint)(x / Constants.RegionSize) * Constants.RegionSize; 92 uint xsnap = (uint)(x / Constants.RegionSize) * Constants.RegionSize;
88 uint ysnap = (uint)(y / Constants.RegionSize) * Constants.RegionSize; 93 uint ysnap = (uint)(y / Constants.RegionSize) * Constants.RegionSize;
89 ulong handle = Utils.UIntsToLong(xsnap, ysnap); 94 ulong handle = Util.RegionWorldLocToHandle(xsnap, ysnap);
90 95
91 if (m_neighbours.ContainsKey(handle)) 96 if (m_neighbours.ContainsKey(handle))
92 return m_neighbours[handle]; 97 return m_neighbours[handle];
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
index 6a57d1f..ac81337 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
@@ -186,10 +186,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
186 return rinfo; 186 return rinfo;
187 } 187 }
188 188
189 // Get a region given its base coordinates.
190 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
191 // be the base coordinate of the region.
192 // The coordinates are world coords (meters), NOT region units.
189 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 193 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
190 { 194 {
191 bool inCache = false; 195 bool inCache = false;
192 GridRegion rinfo = m_RegionInfoCache.Get(scopeID, Util.UIntsToLong((uint)x, (uint)y), out inCache); 196 GridRegion rinfo = m_RegionInfoCache.Get(scopeID, Util.RegionWorldLocToHandle((uint)x, (uint)y), out inCache);
193 if (inCache) 197 if (inCache)
194 return rinfo; 198 return rinfo;
195 199
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
index 4338133..25ae689 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
@@ -34,6 +34,7 @@ using log4net.Config;
34using Nini.Config; 34using Nini.Config;
35using NUnit.Framework; 35using NUnit.Framework;
36using OpenMetaverse; 36using OpenMetaverse;
37
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid; 39using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid;
39using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
@@ -141,7 +142,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
141 Assert.IsNotNull(result, "Retrieved GetRegionByUUID is null"); 142 Assert.IsNotNull(result, "Retrieved GetRegionByUUID is null");
142 Assert.That(result.RegionID, Is.EqualTo(new UUID(1)), "Retrieved region's UUID does not match"); 143 Assert.That(result.RegionID, Is.EqualTo(new UUID(1)), "Retrieved region's UUID does not match");
143 144
144 result = m_LocalConnector.GetRegionByPosition(UUID.Zero, 1000 * (int)Constants.RegionSize, 1000 * (int)Constants.RegionSize); 145 result = m_LocalConnector.GetRegionByPosition(UUID.Zero, (int)Util.RegionToWorldLoc(1000), (int)Util.RegionToWorldLoc(1000));
145 Assert.IsNotNull(result, "Retrieved GetRegionByPosition is null"); 146 Assert.IsNotNull(result, "Retrieved GetRegionByPosition is null");
146 Assert.That(result.RegionLocX, Is.EqualTo(1000 * (int)Constants.RegionSize), "Retrieved region's position does not match"); 147 Assert.That(result.RegionLocX, Is.EqualTo(1000 * (int)Constants.RegionSize), "Retrieved region's position does not match");
147 148
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 26d22b8..c1f2f04 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -224,10 +224,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
224 } 224 }
225 225
226 string reason = string.Empty; 226 string reason = string.Empty;
227 if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason)) 227 if (!m_MapService.AddMapTile((int)scene.RegionInfo.LegacyRegionLocX, (int)scene.RegionInfo.LegacyRegionLocY, jpgData, out reason))
228 { 228 {
229 m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}", 229 m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}",
230 scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason); 230 scene.RegionInfo.RegionName, scene.RegionInfo.LegacyRegionLocX, scene.RegionInfo.LegacyRegionLocY, reason);
231 } 231 }
232 } 232 }
233 } 233 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
index d8dace2..9aa4243 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
@@ -71,8 +71,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
71 71
72 public void AddScene(Scene scene) 72 public void AddScene(Scene scene)
73 { 73 {
74 uint x = scene.RegionInfo.RegionLocX; 74 uint x = scene.RegionInfo.LegacyRegionLocX;
75 uint y = scene.RegionInfo.RegionLocY; 75 uint y = scene.RegionInfo.LegacyRegionLocY;
76 76
77 SortedDictionary<uint, Scene> row; 77 SortedDictionary<uint, Scene> row;
78 if (!Regions.TryGetValue(y, out row)) 78 if (!Regions.TryGetValue(y, out row))
@@ -120,8 +120,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
120 { 120 {
121 // We add the region's coordinates to ensure uniqueness even if multiple regions have the same name 121 // We add the region's coordinates to ensure uniqueness even if multiple regions have the same name
122 string path = string.Format("{0}_{1}_{2}", 122 string path = string.Format("{0}_{1}_{2}",
123 scene.RegionInfo.RegionLocX - Rect.X + 1, 123 scene.RegionInfo.LegacyRegionLocX - Rect.X + 1,
124 scene.RegionInfo.RegionLocY - Rect.Y + 1, 124 scene.RegionInfo.LegacyRegionLocY - Rect.Y + 1,
125 scene.RegionInfo.RegionName.Replace(' ', '_')); 125 scene.RegionInfo.RegionName.Replace(' ', '_'));
126 m_regionDirs[scene.RegionInfo.RegionID] = path; 126 m_regionDirs[scene.RegionInfo.RegionID] = path;
127 }); 127 });
diff --git a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
index 3dcc020..25f1e5c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
@@ -145,7 +145,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
145 { 145 {
146 foreach (RegionInfo archivedRegion in m_directory2region.Values) 146 foreach (RegionInfo archivedRegion in m_directory2region.Values)
147 { 147 {
148 Point location = new Point((int)rootScene.RegionInfo.RegionLocX, (int)rootScene.RegionInfo.RegionLocY); 148 Point location = new Point((int)rootScene.RegionInfo.LegacyRegionLocX, (int)rootScene.RegionInfo.LegacyRegionLocY);
149 location.Offset(archivedRegion.Location); 149 location.Offset(archivedRegion.Location);
150 150
151 Scene scene; 151 Scene scene;
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
index 173b603..bc172a4 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
@@ -96,9 +96,9 @@ namespace OpenSim.Region.CoreModules.World.Estate
96 int x = (args.Length > 5 ? int.Parse(args[5]) : -1); 96 int x = (args.Length > 5 ? int.Parse(args[5]) : -1);
97 int y = (args.Length > 6 ? int.Parse(args[6]) : -1); 97 int y = (args.Length > 6 ? int.Parse(args[6]) : -1);
98 98
99 if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x) 99 if (x == -1 || m_module.Scene.RegionInfo.LegacyRegionLocX == x)
100 { 100 {
101 if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y) 101 if (y == -1 || m_module.Scene.RegionInfo.LegacyRegionLocY == y)
102 { 102 {
103 int corner = int.Parse(num); 103 int corner = int.Parse(num);
104 UUID texture = UUID.Parse(uuid); 104 UUID texture = UUID.Parse(uuid);
@@ -135,9 +135,9 @@ namespace OpenSim.Region.CoreModules.World.Estate
135 int x = (args.Length > 4 ? int.Parse(args[4]) : -1); 135 int x = (args.Length > 4 ? int.Parse(args[4]) : -1);
136 int y = (args.Length > 5 ? int.Parse(args[5]) : -1); 136 int y = (args.Length > 5 ? int.Parse(args[5]) : -1);
137 137
138 if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x) 138 if (x == -1 || m_module.Scene.RegionInfo.LegacyRegionLocX == x)
139 { 139 {
140 if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y) 140 if (y == -1 || m_module.Scene.RegionInfo.LegacyRegionLocY == y)
141 { 141 {
142 double selectedheight = double.Parse(heightstring); 142 double selectedheight = double.Parse(heightstring);
143 143
@@ -159,9 +159,9 @@ namespace OpenSim.Region.CoreModules.World.Estate
159 int x = (args.Length > 6 ? int.Parse(args[6]) : -1); 159 int x = (args.Length > 6 ? int.Parse(args[6]) : -1);
160 int y = (args.Length > 7 ? int.Parse(args[7]) : -1); 160 int y = (args.Length > 7 ? int.Parse(args[7]) : -1);
161 161
162 if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x) 162 if (x == -1 || m_module.Scene.RegionInfo.LegacyRegionLocX == x)
163 { 163 {
164 if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y) 164 if (y == -1 || m_module.Scene.RegionInfo.LegacyRegionLocY == y)
165 { 165 {
166 int corner = int.Parse(num); 166 int corner = int.Parse(num);
167 float lowValue = float.Parse(min, Culture.NumberFormatInfo); 167 float lowValue = float.Parse(min, Culture.NumberFormatInfo);
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 73c4d6c..a68f67f 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -64,6 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Land
64 public class LandManagementModule : INonSharedRegionModule 64 public class LandManagementModule : INonSharedRegionModule
65 { 65 {
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
67 private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]";
67 68
68 private static readonly string remoteParcelRequestPath = "0009/"; 69 private static readonly string remoteParcelRequestPath = "0009/";
69 70
@@ -74,15 +75,11 @@ namespace OpenSim.Region.CoreModules.World.Land
74 protected IPrimCountModule m_primCountModule; 75 protected IPrimCountModule m_primCountModule;
75 protected IDialogModule m_Dialog; 76 protected IDialogModule m_Dialog;
76 77
77 // Minimum for parcels to work is 64m even if we don't actually use them.
78 #pragma warning disable 0429
79 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
80 #pragma warning restore 0429
81
82 /// <value> 78 /// <value>
83 /// Local land ids at specified region co-ordinates (region size / 4) 79 /// Local land ids at specified region co-ordinates (region size / 4)
84 /// </value> 80 /// </value>
85 private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax]; 81 private int[,] m_landIDList;
82 private const int landUnit = 4;
86 83
87 /// <value> 84 /// <value>
88 /// Land objects keyed by local id 85 /// Land objects keyed by local id
@@ -115,6 +112,8 @@ namespace OpenSim.Region.CoreModules.World.Land
115 public void AddRegion(Scene scene) 112 public void AddRegion(Scene scene)
116 { 113 {
117 m_scene = scene; 114 m_scene = scene;
115 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
116
118 m_landIDList.Initialize(); 117 m_landIDList.Initialize();
119 landChannel = new LandChannel(scene, this); 118 landChannel = new LandChannel(scene, this);
120 119
@@ -297,6 +296,7 @@ namespace OpenSim.Region.CoreModules.World.Land
297 { 296 {
298 m_landList.Clear(); 297 m_landList.Clear();
299 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 298 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
299 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
300 m_landIDList.Initialize(); 300 m_landIDList.Initialize();
301 } 301 }
302 } 302 }
@@ -311,7 +311,8 @@ namespace OpenSim.Region.CoreModules.World.Land
311 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 311 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
312 312
313 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 313 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
314 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 314 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
315 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
315 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 316 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
316 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 317 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
317 318
@@ -438,8 +439,8 @@ namespace OpenSim.Region.CoreModules.World.Land
438 439
439 public void SendLandUpdate(ScenePresence avatar, bool force) 440 public void SendLandUpdate(ScenePresence avatar, bool force)
440 { 441 {
441 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 442 ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
442 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 443 (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
443 444
444 if (over != null) 445 if (over != null)
445 { 446 {
@@ -605,17 +606,29 @@ namespace OpenSim.Region.CoreModules.World.Land
605 new_land.LandData.LocalID = newLandLocalID; 606 new_land.LandData.LocalID = newLandLocalID;
606 607
607 bool[,] landBitmap = new_land.GetLandBitmap(); 608 bool[,] landBitmap = new_land.GetLandBitmap();
608 for (int x = 0; x < landArrayMax; x++) 609 // m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). newLocalID={3}",
610 // LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), newLandLocalID);
611
612 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
609 { 613 {
610 for (int y = 0; y < landArrayMax; y++) 614 // Going to variable sized regions can cause mismatches
615 m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
616 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1) );
617 }
618 else
619 {
620 for (int x = 0; x < landBitmap.GetLength(0); x++)
611 { 621 {
612 if (landBitmap[x, y]) 622 for (int y = 0; y < landBitmap.GetLength(1); y++)
613 { 623 {
614// m_log.DebugFormat( 624 if (landBitmap[x, y])
615// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", 625 {
616// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); 626 // m_log.DebugFormat(
617 627 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
618 m_landIDList[x, y] = newLandLocalID; 628 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
629
630 m_landIDList[x, y] = newLandLocalID;
631 }
619 } 632 }
620 } 633 }
621 } 634 }
@@ -637,9 +650,9 @@ namespace OpenSim.Region.CoreModules.World.Land
637 ILandObject land; 650 ILandObject land;
638 lock (m_landList) 651 lock (m_landList)
639 { 652 {
640 for (int x = 0; x < 64; x++) 653 for (int x = 0; x < m_landIDList.GetLength(0); x++)
641 { 654 {
642 for (int y = 0; y < 64; y++) 655 for (int y = 0; y < m_landIDList.GetLength(1); y++)
643 { 656 {
644 if (m_landIDList[x, y] == local_id) 657 if (m_landIDList[x, y] == local_id)
645 { 658 {
@@ -691,9 +704,9 @@ namespace OpenSim.Region.CoreModules.World.Land
691 bool[,] landBitmapSlave = slave.GetLandBitmap(); 704 bool[,] landBitmapSlave = slave.GetLandBitmap();
692 lock (m_landList) 705 lock (m_landList)
693 { 706 {
694 for (int x = 0; x < 64; x++) 707 for (int x = 0; x < landBitmapSlave.GetLength(0); x++)
695 { 708 {
696 for (int y = 0; y < 64; y++) 709 for (int y = 0; y < landBitmapSlave.GetLength(1); y++)
697 { 710 {
698 if (landBitmapSlave[x, y]) 711 if (landBitmapSlave[x, y])
699 { 712 {
@@ -727,23 +740,28 @@ namespace OpenSim.Region.CoreModules.World.Land
727 /// <returns>Land object at the point supplied</returns> 740 /// <returns>Land object at the point supplied</returns>
728 public ILandObject GetLandObject(float x_float, float y_float) 741 public ILandObject GetLandObject(float x_float, float y_float)
729 { 742 {
743 return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */);
744 /*
730 int x; 745 int x;
731 int y; 746 int y;
732 747
733 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 748 if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
734 return null; 749 return null;
735 750
736 try 751 try
737 { 752 {
738 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0)); 753 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit));
739 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0)); 754 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit));
740 } 755 }
741 catch (OverflowException) 756 catch (OverflowException)
742 { 757 {
743 return null; 758 return null;
744 } 759 }
745 760
746 if (x >= 64 || y >= 64 || x < 0 || y < 0) 761 if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit)
762 || y >= (m_scene.RegionInfo.RegionSizeY / landUnit)
763 || x < 0
764 || y < 0)
747 { 765 {
748 return null; 766 return null;
749 } 767 }
@@ -759,38 +777,122 @@ namespace OpenSim.Region.CoreModules.World.Land
759// m_log.DebugFormat( 777// m_log.DebugFormat(
760// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}", 778// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
761// x, y, m_scene.RegionInfo.RegionName); 779// x, y, m_scene.RegionInfo.RegionName);
762 780
763 if (m_landList.ContainsKey(m_landIDList[x, y])) 781 try
764 return m_landList[m_landIDList[x, y]]; 782 {
783 if (m_landList.ContainsKey(m_landIDList[x, y]))
784 return m_landList[m_landIDList[x, y]];
785 }
786 catch (Exception e)
787 {
788 m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})",
789 LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
790 }
765 791
766 return null; 792 return null;
767 } 793 }
794 */
768 } 795 }
769 796
797 // Public entry.
798 // Throws exception if land object is not found
770 public ILandObject GetLandObject(int x, int y) 799 public ILandObject GetLandObject(int x, int y)
771 { 800 {
772 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) 801 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
802 }
803
804 // Given a region position, return the parcel land object for that location
805 private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectNotFound)
806 {
807 ILandObject ret = null;
808
809 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
773 { 810 {
774 // These exceptions here will cause a lot of complaints from the users specifically because 811 // These exceptions here will cause a lot of complaints from the users specifically because
775 // they happen every time at border crossings 812 // they happen every time at border crossings
776 throw new Exception("Error: Parcel not found at point " + x + ", " + y); 813 if (returnNullIfLandObjectNotFound)
814 return null;
815 else
816 throw new Exception(
817 String.Format("{0} GetLandObject for non-existant position. Region={1}, pos=<{2},{3}",
818 LogHeader, m_scene.RegionInfo.RegionName, x, y)
819 );
777 } 820 }
778 821
779 lock (m_landIDList) 822 lock (m_landIDList)
780 { 823 {
781 try 824 try
782 { 825 {
783 return m_landList[m_landIDList[x / 4, y / 4]]; 826 int landID = m_landIDList[x / landUnit, y / landUnit];
827 if (landID == 0)
828 {
829 // Zero is the uninitialized value saying there is no parcel for this location.
830 // This sometimes happens when terrain is resized.
831 if (m_landList.Count == 1)
832 {
833 int onlyParcelID = 0;
834 ILandObject onlyLandObject = null;
835 foreach (KeyValuePair<int, ILandObject> kvp in m_landList)
836 {
837 onlyParcelID = kvp.Key;
838 onlyLandObject = kvp.Value;
839 break;
840 }
841
842 // There is only one parcel. Grow it to fill all the unallocated spaces.
843 for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
844 for (int yy = 0; yy < m_landIDList.GetLength(1); yy++)
845 if (m_landIDList[xx, yy] == 0)
846 m_landIDList[xx, yy] = onlyParcelID;
847
848 onlyLandObject.LandBitmap = CreateBitmapForID(onlyParcelID);
849 landID = onlyParcelID;
850 }
851 else
852 {
853 // There are several other parcels so we must create a new one for the unassigned space
854 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
855 // Claim all the unclaimed "0" ids
856 newLand.SetLandBitmap(CreateBitmapForID(0));
857 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
858 newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
859 AddLandObject(newLand);
860 landID = m_lastLandLocalID;
861 }
862 }
863
864 ret = m_landList[landID];
784 } 865 }
785 catch (IndexOutOfRangeException) 866 catch (IndexOutOfRangeException)
786 { 867 {
787// m_log.WarnFormat( 868 m_log.ErrorFormat(
788// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}", 869 "{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})",
789// x, y, m_scene.RegionInfo.RegionName); 870 LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
790 871 return null;
872 }
873 catch
874 {
875 m_log.ErrorFormat(
876 "{0} GetLandObject: LandID not in landlist. XY=<{1},{2}> in {3}. landID[x,y]={4}",
877 LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList[x/landUnit, y/landUnit]);
791 return null; 878 return null;
792 } 879 }
793 } 880 }
881 return ret;
882 }
883
884 // Create a 'parcel is here' bitmap for the parcel identified by the passed landID
885 private bool[,] CreateBitmapForID(int landID)
886 {
887 bool[,] ret = new bool[m_landIDList.GetLength(0), m_landIDList.GetLength(1)];
888 ret.Initialize();
889
890 for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
891 for (int yy = 0; yy < m_landIDList.GetLength(0); yy++)
892 if (m_landIDList[xx, yy] == landID)
893 ret[xx, yy] = true;
894
895 return ret;
794 } 896 }
795 897
796 #endregion 898 #endregion
@@ -1053,85 +1155,93 @@ namespace OpenSim.Region.CoreModules.World.Land
1053 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1155 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1054 int byteArrayCount = 0; 1156 int byteArrayCount = 0;
1055 int sequenceID = 0; 1157 int sequenceID = 0;
1056 int blockmeters = 4 * (int) Constants.RegionSize/(int)Constants.TerrainPatchSize;
1057
1058 1158
1059 for (int y = 0; y < blockmeters; y++) 1159 // Layer data is in landUnit (4m) chunks
1160 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); y++)
1060 { 1161 {
1061 for (int x = 0; x < blockmeters; x++) 1162 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); x++)
1062 { 1163 {
1063 byte tempByte = 0; //This represents the byte for the current 4x4 1164 byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * landUnit, y * landUnit), x, y, remote_client);
1165 byteArrayCount++;
1166 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1167 {
1168 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1169 byteArrayCount = 0;
1170 sequenceID++;
1171 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1172 }
1064 1173
1065 ILandObject currentParcelBlock = GetLandObject(x * 4, y * 4); 1174 }
1175 }
1176 if (byteArrayCount != 0)
1177 {
1178 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1179 }
1180 }
1066 1181
1067 if (currentParcelBlock != null) 1182 private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client)
1068 { 1183 {
1069 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) 1184 byte tempByte = 0; //This represents the byte for the current 4x4
1070 {
1071 //Owner Flag
1072 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1073 }
1074 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1075 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1076 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1077 {
1078 //Sale Flag
1079 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1080 }
1081 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1082 {
1083 //Public Flag
1084 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1085 }
1086 else
1087 {
1088 //Other Flag
1089 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1090 }
1091 1185
1092 //Now for border control 1186 if (currentParcelBlock != null)
1187 {
1188 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
1189 {
1190 //Owner Flag
1191 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1192 }
1193 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1194 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1195 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1196 {
1197 //Sale Flag
1198 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1199 }
1200 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1201 {
1202 //Public Flag
1203 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1204 }
1205 else
1206 {
1207 //Other Flag
1208 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1209 }
1093 1210
1094 ILandObject westParcel = null; 1211 //Now for border control
1095 ILandObject southParcel = null;
1096 if (x > 0)
1097 {
1098 westParcel = GetLandObject((x - 1) * 4, y * 4);
1099 }
1100 if (y > 0)
1101 {
1102 southParcel = GetLandObject(x * 4, (y - 1) * 4);
1103 }
1104 1212
1105 if (x == 0) 1213 ILandObject westParcel = null;
1106 { 1214 ILandObject southParcel = null;
1107 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); 1215 if (x > 0)
1108 } 1216 {
1109 else if (westParcel != null && westParcel != currentParcelBlock) 1217 westParcel = GetLandObject((x - 1) * landUnit, y * landUnit);
1110 { 1218 }
1111 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); 1219 if (y > 0)
1112 } 1220 {
1221 southParcel = GetLandObject(x * landUnit, (y - 1) * landUnit);
1222 }
1113 1223
1114 if (y == 0) 1224 if (x == 0)
1115 { 1225 {
1116 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1226 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1117 } 1227 }
1118 else if (southParcel != null && southParcel != currentParcelBlock) 1228 else if (westParcel != null && westParcel != currentParcelBlock)
1119 { 1229 {
1120 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1230 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1121 } 1231 }
1122 1232
1123 byteArray[byteArrayCount] = tempByte; 1233 if (y == 0)
1124 byteArrayCount++; 1234 {
1125 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) 1235 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
1126 { 1236 }
1127 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1237 else if (southParcel != null && southParcel != currentParcelBlock)
1128 byteArrayCount = 0; 1238 {
1129 sequenceID++; 1239 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
1130 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1131 }
1132 }
1133 } 1240 }
1241
1134 } 1242 }
1243
1244 return tempByte;
1135 } 1245 }
1136 1246
1137 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 1247 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
@@ -1679,7 +1789,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1679 { 1789 {
1680 // most likely still cached from building the extLandData entry 1790 // most likely still cached from building the extLandData entry
1681 uint x = 0, y = 0; 1791 uint x = 0, y = 0;
1682 Utils.LongToUInts(data.RegionHandle, out x, out y); 1792 Util.RegionHandleToWorldLoc(data.RegionHandle, out x, out y);
1683 info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); 1793 info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y);
1684 } 1794 }
1685 // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. 1795 // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.
@@ -1688,8 +1798,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1688 // HACK for now 1798 // HACK for now
1689 RegionInfo r = new RegionInfo(); 1799 RegionInfo r = new RegionInfo();
1690 r.RegionName = info.RegionName; 1800 r.RegionName = info.RegionName;
1691 r.RegionLocX = (uint)info.RegionLocX; 1801 r.LegacyRegionLocX = (uint)info.RegionLocX;
1692 r.RegionLocY = (uint)info.RegionLocY; 1802 r.LegacyRegionLocY = (uint)info.RegionLocY;
1693 r.RegionSettings.Maturity = (int)Util.ConvertAccessLevelToMaturity(data.RegionAccess); 1803 r.RegionSettings.Maturity = (int)Util.ConvertAccessLevelToMaturity(data.RegionAccess);
1694 remoteClient.SendParcelInfo(r, data.LandData, parcelID, data.X, data.Y); 1804 remoteClient.SendParcelInfo(r, data.LandData, parcelID, data.X, data.Y);
1695 } 1805 }
@@ -2007,4 +2117,4 @@ namespace OpenSim.Region.CoreModules.World.Land
2007 cdl.AddToStringBuilder(report); 2117 cdl.AddToStringBuilder(report);
2008 } 2118 }
2009 } 2119 }
2010} \ No newline at end of file 2120}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index e55c9ed..2a4d8d8 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -45,10 +45,10 @@ namespace OpenSim.Region.CoreModules.World.Land
45 #region Member Variables 45 #region Member Variables
46 46
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 #pragma warning disable 0429 48 private static readonly string LogHeader = "[LAND OBJECT]";
49 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; 49
50 #pragma warning restore 0429 50 private bool[,] m_landBitmap;
51 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 51 private readonly int landUnit = 4;
52 52
53 private int m_lastSeqId = 0; 53 private int m_lastSeqId = 0;
54 54
@@ -93,15 +93,17 @@ namespace OpenSim.Region.CoreModules.World.Land
93 { 93 {
94 get 94 get
95 { 95 {
96 for (int y = 0; y < landArrayMax; y++) 96 for (int y = 0; y < LandBitmap.GetLength(1); y++)
97 { 97 {
98 for (int x = 0; x < landArrayMax; x++) 98 for (int x = 0; x < LandBitmap.GetLength(0); x++)
99 { 99 {
100 if (LandBitmap[x, y]) 100 if (LandBitmap[x, y])
101 return new Vector3(x * 4, y * 4, 0); 101 return new Vector3(x * landUnit, y * landUnit, 0);
102 } 102 }
103 } 103 }
104 104
105 m_log.ErrorFormat("{0} StartPoint. No start point found. bitmapSize=<{1},{2}>",
106 LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
105 return new Vector3(-1, -1, -1); 107 return new Vector3(-1, -1, -1);
106 } 108 }
107 } 109 }
@@ -110,17 +112,19 @@ namespace OpenSim.Region.CoreModules.World.Land
110 { 112 {
111 get 113 get
112 { 114 {
113 for (int y = landArrayMax - 1; y >= 0; y--) 115 for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--)
114 { 116 {
115 for (int x = landArrayMax - 1; x >= 0; x--) 117 for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--)
116 { 118 {
117 if (LandBitmap[x, y]) 119 if (LandBitmap[x, y])
118 { 120 {
119 return new Vector3(x * 4 + 4, y * 4 + 4, 0); 121 return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0);
120 } 122 }
121 } 123 }
122 } 124 }
123 125
126 m_log.ErrorFormat("{0} EndPoint. No end point found. bitmapSize=<{1},{2}>",
127 LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
124 return new Vector3(-1, -1, -1); 128 return new Vector3(-1, -1, -1);
125 } 129 }
126 } 130 }
@@ -130,6 +134,8 @@ namespace OpenSim.Region.CoreModules.World.Land
130 public LandObject(UUID owner_id, bool is_group_owned, Scene scene) 134 public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
131 { 135 {
132 m_scene = scene; 136 m_scene = scene;
137 m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
138
133 LandData.OwnerID = owner_id; 139 LandData.OwnerID = owner_id;
134 if (is_group_owned) 140 if (is_group_owned)
135 LandData.GroupID = owner_id; 141 LandData.GroupID = owner_id;
@@ -152,9 +158,9 @@ namespace OpenSim.Region.CoreModules.World.Land
152 /// <returns>Returns true if the piece of land contains the specified point</returns> 158 /// <returns>Returns true if the piece of land contains the specified point</returns>
153 public bool ContainsPoint(int x, int y) 159 public bool ContainsPoint(int x, int y)
154 { 160 {
155 if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize) 161 if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY)
156 { 162 {
157 return (LandBitmap[x / 4, y / 4] == true); 163 return (LandBitmap[x / landUnit, y / landUnit] == true);
158 } 164 }
159 else 165 else
160 { 166 {
@@ -194,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Land
194 else 200 else
195 { 201 {
196 // Normal Calculations 202 // Normal Calculations
197 int parcelMax = (int)(((float)LandData.Area / 65536.0f) 203 int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
198 * (float)m_scene.RegionInfo.ObjectCapacity 204 * (float)m_scene.RegionInfo.ObjectCapacity
199 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 205 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
200 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 206 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL!
@@ -211,7 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Land
211 else 217 else
212 { 218 {
213 //Normal Calculations 219 //Normal Calculations
214 int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) 220 int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
215 * (float)m_scene.RegionInfo.ObjectCapacity); 221 * (float)m_scene.RegionInfo.ObjectCapacity);
216 return simMax; 222 return simMax;
217 } 223 }
@@ -224,7 +230,12 @@ namespace OpenSim.Region.CoreModules.World.Land
224 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 230 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
225 { 231 {
226 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 232 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
227 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 233 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
234 uint regionFlags = (uint)(RegionFlags.PublicAllowed
235 | RegionFlags.AllowDirectTeleport
236 | RegionFlags.AllowParcelChanges
237 | RegionFlags.AllowVoice );
238
228 if (estateModule != null) 239 if (estateModule != null)
229 regionFlags = estateModule.GetRegionFlags(); 240 regionFlags = estateModule.GetRegionFlags();
230 241
@@ -546,8 +557,8 @@ namespace OpenSim.Region.CoreModules.World.Land
546 try 557 try
547 { 558 {
548 over = 559 over =
549 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), 560 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
550 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); 561 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
551 } 562 }
552 catch (Exception) 563 catch (Exception)
553 { 564 {
@@ -694,15 +705,15 @@ namespace OpenSim.Region.CoreModules.World.Land
694 /// </summary> 705 /// </summary>
695 private void UpdateAABBAndAreaValues() 706 private void UpdateAABBAndAreaValues()
696 { 707 {
697 int min_x = 64; 708 int min_x = 10000;
698 int min_y = 64; 709 int min_y = 10000;
699 int max_x = 0; 710 int max_x = 0;
700 int max_y = 0; 711 int max_y = 0;
701 int tempArea = 0; 712 int tempArea = 0;
702 int x, y; 713 int x, y;
703 for (x = 0; x < 64; x++) 714 for (x = 0; x < LandBitmap.GetLength(0); x++)
704 { 715 {
705 for (y = 0; y < 64; y++) 716 for (y = 0; y < LandBitmap.GetLength(1); y++)
706 { 717 {
707 if (LandBitmap[x, y] == true) 718 if (LandBitmap[x, y] == true)
708 { 719 {
@@ -710,31 +721,31 @@ namespace OpenSim.Region.CoreModules.World.Land
710 if (min_y > y) min_y = y; 721 if (min_y > y) min_y = y;
711 if (max_x < x) max_x = x; 722 if (max_x < x) max_x = x;
712 if (max_y < y) max_y = y; 723 if (max_y < y) max_y = y;
713 tempArea += 16; //16sqm peice of land 724 tempArea += landUnit * landUnit; //16sqm peice of land
714 } 725 }
715 } 726 }
716 } 727 }
717 int tx = min_x * 4; 728 int tx = min_x * landUnit;
718 if (tx > ((int)Constants.RegionSize - 1)) 729 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
719 tx = ((int)Constants.RegionSize - 1); 730 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
720 int ty = min_y * 4; 731 int ty = min_y * landUnit;
721 if (ty > ((int)Constants.RegionSize - 1)) 732 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
722 ty = ((int)Constants.RegionSize - 1); 733 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
723 734
724 LandData.AABBMin = 735 LandData.AABBMin =
725 new Vector3( 736 new Vector3(
726 (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 737 (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
727 738
728 tx = max_x * 4; 739 tx = max_x * landUnit;
729 if (tx > ((int)Constants.RegionSize - 1)) 740 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
730 tx = ((int)Constants.RegionSize - 1); 741 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
731 ty = max_y * 4; 742 ty = max_y * landUnit;
732 if (ty > ((int)Constants.RegionSize - 1)) 743 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
733 ty = ((int)Constants.RegionSize - 1); 744 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
734 745
735 LandData.AABBMax 746 LandData.AABBMax
736 = new Vector3( 747 = new Vector3(
737 (float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 748 (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
738 749
739 LandData.Area = tempArea; 750 LandData.Area = tempArea;
740 } 751 }
@@ -746,20 +757,12 @@ namespace OpenSim.Region.CoreModules.World.Land
746 /// <summary> 757 /// <summary>
747 /// Sets the land's bitmap manually 758 /// Sets the land's bitmap manually
748 /// </summary> 759 /// </summary>
749 /// <param name="bitmap">64x64 block representing where this land is on a map</param> 760 /// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param>
750 public void SetLandBitmap(bool[,] bitmap) 761 public void SetLandBitmap(bool[,] bitmap)
751 { 762 {
752 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 763 LandBitmap = bitmap;
753 { 764 // m_log.DebugFormat("{0} SetLandBitmap. BitmapSize=<{1},{2}>", LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
754 //Throw an exception - The bitmap is not 64x64 765 ForceUpdateLandInfo();
755 //throw new Exception("Error: Invalid Parcel Bitmap");
756 }
757 else
758 {
759 //Valid: Lets set it
760 LandBitmap = bitmap;
761 ForceUpdateLandInfo();
762 }
763 } 766 }
764 767
765 /// <summary> 768 /// <summary>
@@ -773,15 +776,19 @@ namespace OpenSim.Region.CoreModules.World.Land
773 776
774 public bool[,] BasicFullRegionLandBitmap() 777 public bool[,] BasicFullRegionLandBitmap()
775 { 778 {
776 return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); 779 return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY);
777 } 780 }
778 781
779 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 782 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
780 { 783 {
781 bool[,] tempBitmap = new bool[64,64]; 784 // Empty bitmap for the whole region
785 bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
782 tempBitmap.Initialize(); 786 tempBitmap.Initialize();
783 787
788 // Fill the bitmap square area specified by state and end
784 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 789 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
790 // m_log.DebugFormat("{0} GetSquareLandBitmap. tempBitmapSize=<{1},{2}>",
791 // LogHeader, tempBitmap.GetLength(0), tempBitmap.GetLength(1));
785 return tempBitmap; 792 return tempBitmap;
786 } 793 }
787 794
@@ -798,24 +805,20 @@ namespace OpenSim.Region.CoreModules.World.Land
798 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, 805 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
799 bool set_value) 806 bool set_value)
800 { 807 {
801 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
802 {
803 //Throw an exception - The bitmap is not 64x64
804 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
805 }
806
807 int x, y; 808 int x, y;
808 for (y = 0; y < 64; y++) 809 for (y = 0; y < land_bitmap.GetLength(1); y++)
809 { 810 {
810 for (x = 0; x < 64; x++) 811 for (x = 0; x < land_bitmap.GetLength(0); x++)
811 { 812 {
812 if (x >= start_x / 4 && x < end_x / 4 813 if (x >= start_x / landUnit && x < end_x / landUnit
813 && y >= start_y / 4 && y < end_y / 4) 814 && y >= start_y / landUnit && y < end_y / landUnit)
814 { 815 {
815 land_bitmap[x, y] = set_value; 816 land_bitmap[x, y] = set_value;
816 } 817 }
817 } 818 }
818 } 819 }
820 // m_log.DebugFormat("{0} ModifyLandBitmapSquare. startXY=<{1},{2}>, endXY=<{3},{4}>, val={5}, landBitmapSize=<{6},{7}>",
821 // LogHeader, start_x, start_y, end_x, end_y, set_value, land_bitmap.GetLength(0), land_bitmap.GetLength(1));
819 return land_bitmap; 822 return land_bitmap;
820 } 823 }
821 824
@@ -827,21 +830,21 @@ namespace OpenSim.Region.CoreModules.World.Land
827 /// <returns></returns> 830 /// <returns></returns>
828 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 831 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
829 { 832 {
830 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 833 if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0)
834 || bitmap_base.GetLength(1) != bitmap_add.GetLength(1)
835 || bitmap_add.Rank != 2
836 || bitmap_base.Rank != 2)
831 { 837 {
832 //Throw an exception - The bitmap is not 64x64 838 throw new Exception(
833 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); 839 String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>",
834 } 840 LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1))
835 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) 841 );
836 {
837 //Throw an exception - The bitmap is not 64x64
838 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
839 } 842 }
840 843
841 int x, y; 844 int x, y;
842 for (y = 0; y < 64; y++) 845 for (y = 0; y < bitmap_base.GetLength(1); y++)
843 { 846 {
844 for (x = 0; x < 64; x++) 847 for (x = 0; x < bitmap_add.GetLength(0); x++)
845 { 848 {
846 if (bitmap_add[x, y]) 849 if (bitmap_add[x, y])
847 { 850 {
@@ -858,13 +861,13 @@ namespace OpenSim.Region.CoreModules.World.Land
858 /// <returns></returns> 861 /// <returns></returns>
859 private byte[] ConvertLandBitmapToBytes() 862 private byte[] ConvertLandBitmapToBytes()
860 { 863 {
861 byte[] tempConvertArr = new byte[512]; 864 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
862 byte tempByte = 0; 865 byte tempByte = 0;
863 int x, y, i, byteNum = 0; 866 int byteNum = 0;
864 i = 0; 867 int i = 0;
865 for (y = 0; y < 64; y++) 868 for (int y = 0; y < LandBitmap.GetLength(1); y++)
866 { 869 {
867 for (x = 0; x < 64; x++) 870 for (int x = 0; x < LandBitmap.GetLength(0); x++)
868 { 871 {
869 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 872 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
870 if (i % 8 == 0) 873 if (i % 8 == 0)
@@ -876,30 +879,52 @@ namespace OpenSim.Region.CoreModules.World.Land
876 } 879 }
877 } 880 }
878 } 881 }
882 // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>",
883 // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
879 return tempConvertArr; 884 return tempConvertArr;
880 } 885 }
881 886
882 private bool[,] ConvertBytesToLandBitmap() 887 private bool[,] ConvertBytesToLandBitmap()
883 { 888 {
884 bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; 889 bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
885 tempConvertMap.Initialize(); 890 tempConvertMap.Initialize();
886 byte tempByte = 0; 891 byte tempByte = 0;
887 int x = 0, y = 0, i = 0, bitNum = 0; 892 // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
888 for (i = 0; i < 512; i++) 893 int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
894 int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
895
896 if (bitmapLen == 512)
897 {
898 // Legacy bitmap being passed in. Use the legacy region size
899 // and only set the lower area of the larger region.
900 xLen = (int)(Constants.RegionSize / landUnit);
901 }
902 // m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
903
904 int x = 0, y = 0;
905 for (int i = 0; i < bitmapLen; i++)
889 { 906 {
890 tempByte = LandData.Bitmap[i]; 907 tempByte = LandData.Bitmap[i];
891 for (bitNum = 0; bitNum < 8; bitNum++) 908 for (int bitNum = 0; bitNum < 8; bitNum++)
892 { 909 {
893 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); 910 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
894 tempConvertMap[x, y] = bit; 911 try
912 {
913 tempConvertMap[x, y] = bit;
914 }
915 catch (Exception e)
916 {
917 m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y);
918 }
895 x++; 919 x++;
896 if (x > 63) 920 if (x >= xLen)
897 { 921 {
898 x = 0; 922 x = 0;
899 y++; 923 y++;
900 } 924 }
901 } 925 }
902 } 926 }
927
903 return tempConvertMap; 928 return tempConvertMap;
904 } 929 }
905 930
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index f8e93e1..45617fc 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -1571,10 +1571,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
1571 float X = position.X; 1571 float X = position.X;
1572 float Y = position.Y; 1572 float Y = position.Y;
1573 1573
1574 if (X > ((int)Constants.RegionSize - 1)) 1574 if (X > ((int)m_scene.RegionInfo.RegionSizeX - 1))
1575 X = ((int)Constants.RegionSize - 1); 1575 X = ((int)m_scene.RegionInfo.RegionSizeX - 1);
1576 if (Y > ((int)Constants.RegionSize - 1)) 1576 if (Y > ((int)m_scene.RegionInfo.RegionSizeY - 1))
1577 Y = ((int)Constants.RegionSize - 1); 1577 Y = ((int)m_scene.RegionInfo.RegionSizeY - 1);
1578 if (X < 0) 1578 if (X < 0)
1579 X = 0; 1579 X = 0;
1580 if (Y < 0) 1580 if (Y < 0)
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs b/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
index 7186dd7..89087b1 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
42 for (y = 0; y < map.Height; y++) 42 for (y = 0; y < map.Height; y++)
43 { 43 {
44 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; 44 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
45 double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01; 45 double spherFac = TerrainUtil.SphericalFactor(x, y, map.Width / 2, map.Height / 2, 50) * 0.01;
46 if (map[x, y] < spherFac) 46 if (map[x, y] < spherFac)
47 { 47 {
48 map[x, y] = spherFac; 48 map[x, y] = spherFac;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
index d78ade5..d5c77ec 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
67 { 67 {
68 using (Bitmap bitmap = new Bitmap(filename)) 68 using (Bitmap bitmap = new Bitmap(filename))
69 { 69 {
70 ITerrainChannel retval = new TerrainChannel(true); 70 ITerrainChannel retval = new TerrainChannel(w, h);
71 71
72 for (int x = 0; x < retval.Width; x++) 72 for (int x = 0; x < retval.Width; x++)
73 { 73 {
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index fd30c46..d991a30 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -30,10 +30,14 @@ using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using System.Net; 32using System.Net;
33
33using log4net; 34using log4net;
34using Nini.Config; 35using Nini.Config;
36
35using OpenMetaverse; 37using OpenMetaverse;
36using Mono.Addins; 38using Mono.Addins;
39
40using OpenSim.Data;
37using OpenSim.Framework; 41using OpenSim.Framework;
38using OpenSim.Region.CoreModules.Framework.InterfaceCommander; 42using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
39using OpenSim.Region.CoreModules.World.Terrain.FileLoaders; 43using OpenSim.Region.CoreModules.World.Terrain.FileLoaders;
@@ -70,6 +74,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
70 #endregion 74 #endregion
71 75
72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 private static readonly string LogHeader = "[TERRAIN MODULE]";
73 78
74 private readonly Commander m_commander = new Commander("terrain"); 79 private readonly Commander m_commander = new Commander("terrain");
75 80
@@ -130,15 +135,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain
130 { 135 {
131 if (m_scene.Heightmap == null) 136 if (m_scene.Heightmap == null)
132 { 137 {
133 m_channel = new TerrainChannel(m_InitialTerrain); 138 m_channel = new TerrainChannel(m_InitialTerrain, (int)m_scene.RegionInfo.RegionSizeX,
139 (int)m_scene.RegionInfo.RegionSizeY,
140 (int)m_scene.RegionInfo.RegionSizeZ);
134 m_scene.Heightmap = m_channel; 141 m_scene.Heightmap = m_channel;
135 m_revert = new TerrainChannel();
136 UpdateRevertMap(); 142 UpdateRevertMap();
137 } 143 }
138 else 144 else
139 { 145 {
140 m_channel = m_scene.Heightmap; 146 m_channel = m_scene.Heightmap;
141 m_revert = new TerrainChannel();
142 UpdateRevertMap(); 147 UpdateRevertMap();
143 } 148 }
144 149
@@ -230,11 +235,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
230 try 235 try
231 { 236 {
232 ITerrainChannel channel = loader.Value.LoadFile(filename); 237 ITerrainChannel channel = loader.Value.LoadFile(filename);
233 if (channel.Width != Constants.RegionSize || channel.Height != Constants.RegionSize) 238 if (channel.Width != m_scene.RegionInfo.RegionSizeX || channel.Height != m_scene.RegionInfo.RegionSizeY)
234 { 239 {
235 // TerrainChannel expects a RegionSize x RegionSize map, currently 240 // TerrainChannel expects a RegionSize x RegionSize map, currently
236 throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}", 241 throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}",
237 Constants.RegionSize, Constants.RegionSize)); 242 m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY));
238 } 243 }
239 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height); 244 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height);
240 m_scene.Heightmap = channel; 245 m_scene.Heightmap = channel;
@@ -532,6 +537,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
532 /// </summary> 537 /// </summary>
533 public void UpdateRevertMap() 538 public void UpdateRevertMap()
534 { 539 {
540 /*
535 int x; 541 int x;
536 for (x = 0; x < m_channel.Width; x++) 542 for (x = 0; x < m_channel.Width; x++)
537 { 543 {
@@ -541,6 +547,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
541 m_revert[x, y] = m_channel[x, y]; 547 m_revert[x, y] = m_channel[x, y];
542 } 548 }
543 } 549 }
550 */
551 m_revert = m_channel.MakeCopy();
544 } 552 }
545 553
546 /// <summary> 554 /// <summary>
@@ -553,8 +561,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
553 /// <param name="fileStartY">Where to begin our slice</param> 561 /// <param name="fileStartY">Where to begin our slice</param>
554 public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) 562 public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
555 { 563 {
556 int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX; 564 int offsetX = (int) m_scene.RegionInfo.LegacyRegionLocX - fileStartX;
557 int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY; 565 int offsetY = (int) m_scene.RegionInfo.LegacyRegionLocY - fileStartY;
558 566
559 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) 567 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
560 { 568 {
@@ -567,8 +575,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
567 { 575 {
568 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, 576 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
569 fileWidth, fileHeight, 577 fileWidth, fileHeight,
570 (int) Constants.RegionSize, 578 (int) m_scene.RegionInfo.RegionSizeX,
571 (int) Constants.RegionSize); 579 (int) m_scene.RegionInfo.RegionSizeY);
572 m_scene.Heightmap = channel; 580 m_scene.Heightmap = channel;
573 m_channel = channel; 581 m_channel = channel;
574 UpdateRevertMap(); 582 UpdateRevertMap();
@@ -594,14 +602,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
594 /// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param> 602 /// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param>
595 public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) 603 public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
596 { 604 {
597 int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; 605 int offsetX = (int)m_scene.RegionInfo.LegacyRegionLocX - fileStartX;
598 int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; 606 int offsetY = (int)m_scene.RegionInfo.LegacyRegionLocY - fileStartY;
599 607
600 if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight) 608 if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight)
601 { 609 {
602 MainConsole.Instance.OutputFormat( 610 MainConsole.Instance.OutputFormat(
603 "ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.", 611 "ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.",
604 m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY); 612 m_scene.RegionInfo.LegacyRegionLocX, m_scene.RegionInfo.LegacyRegionLocY, fileWidth, fileStartX, fileHeight, fileStartY);
605 613
606 return; 614 return;
607 } 615 }
@@ -615,8 +623,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
615 { 623 {
616 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, 624 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
617 fileWidth, fileHeight, 625 fileWidth, fileHeight,
618 (int)Constants.RegionSize, 626 (int)m_scene.RegionInfo.RegionSizeX,
619 (int)Constants.RegionSize); 627 (int)m_scene.RegionInfo.RegionSizeY);
620 628
621 MainConsole.Instance.OutputFormat( 629 MainConsole.Instance.OutputFormat(
622 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}", 630 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
@@ -705,7 +713,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
705 private void CheckForTerrainUpdates(bool respectEstateSettings) 713 private void CheckForTerrainUpdates(bool respectEstateSettings)
706 { 714 {
707 bool shouldTaint = false; 715 bool shouldTaint = false;
708 float[] serialised = m_channel.GetFloatsSerialised(); 716 float[] terrHeights = m_channel.GetFloatsSerialised();
709 int x; 717 int x;
710 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) 718 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
711 { 719 {
@@ -714,16 +722,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
714 { 722 {
715 if (m_channel.Tainted(x, y)) 723 if (m_channel.Tainted(x, y))
716 { 724 {
717 // if we should respect the estate settings then 725 // If we should respect the estate settings then
718 // fixup and height deltas that don't respect them 726 // fixup and height deltas that don't respect them.
727 // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values.
719 if (respectEstateSettings && LimitChannelChanges(x, y)) 728 if (respectEstateSettings && LimitChannelChanges(x, y))
720 { 729 {
721 // this has been vetoed, so update 730 // Terrain heights were modified. Refetch the terrain info.
722 // what we are going to send to the client 731 terrHeights = m_channel.GetFloatsSerialised();
723 serialised = m_channel.GetFloatsSerialised();
724 } 732 }
725 733
726 SendToClients(serialised, x, y); 734 // m_log.DebugFormat("{0} Patch modified. Sending (x,y) = ({1},{2})", LogHeader, x, y);
735 SendToClients(terrHeights, x, y);
727 shouldTaint = true; 736 shouldTaint = true;
728 } 737 }
729 } 738 }
@@ -792,13 +801,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
792 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> 801 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
793 /// <param name="x">The patch corner to send</param> 802 /// <param name="x">The patch corner to send</param>
794 /// <param name="y">The patch corner to send</param> 803 /// <param name="y">The patch corner to send</param>
795 private void SendToClients(float[] serialised, int x, int y) 804 private void SendToClients(float[] heightMap, int x, int y)
796 { 805 {
797 m_scene.ForEachClient( 806 m_scene.ForEachClient(
798 delegate(IClientAPI controller) 807 delegate(IClientAPI controller)
799 { controller.SendLayerData( 808 { controller.SendLayerData( x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, heightMap); }
800 x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised);
801 }
802 ); 809 );
803 } 810 }
804 811
@@ -984,28 +991,28 @@ namespace OpenSim.Region.CoreModules.World.Terrain
984 991
985 if (direction.ToLower().StartsWith("y")) 992 if (direction.ToLower().StartsWith("y"))
986 { 993 {
987 for (int x = 0; x < Constants.RegionSize; x++) 994 for (int x = 0; x < m_channel.Width; x++)
988 { 995 {
989 for (int y = 0; y < Constants.RegionSize / 2; y++) 996 for (int y = 0; y < m_channel.Height / 2; y++)
990 { 997 {
991 double height = m_channel[x, y]; 998 double height = m_channel[x, y];
992 double flippedHeight = m_channel[x, (int)Constants.RegionSize - 1 - y]; 999 double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y];
993 m_channel[x, y] = flippedHeight; 1000 m_channel[x, y] = flippedHeight;
994 m_channel[x, (int)Constants.RegionSize - 1 - y] = height; 1001 m_channel[x, (int)m_channel.Height - 1 - y] = height;
995 1002
996 } 1003 }
997 } 1004 }
998 } 1005 }
999 else if (direction.ToLower().StartsWith("x")) 1006 else if (direction.ToLower().StartsWith("x"))
1000 { 1007 {
1001 for (int y = 0; y < Constants.RegionSize; y++) 1008 for (int y = 0; y < m_channel.Height; y++)
1002 { 1009 {
1003 for (int x = 0; x < Constants.RegionSize / 2; x++) 1010 for (int x = 0; x < m_channel.Width / 2; x++)
1004 { 1011 {
1005 double height = m_channel[x, y]; 1012 double height = m_channel[x, y];
1006 double flippedHeight = m_channel[(int)Constants.RegionSize - 1 - x, y]; 1013 double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y];
1007 m_channel[x, y] = flippedHeight; 1014 m_channel[x, y] = flippedHeight;
1008 m_channel[(int)Constants.RegionSize - 1 - x, y] = height; 1015 m_channel[(int)m_channel.Width - 1 - x, y] = height;
1009 1016
1010 } 1017 }
1011 } 1018 }
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index cdf1467..2d564fe 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -249,7 +249,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
249 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 249 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
250 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 250 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
251 251
252 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 252 if (m_scene.RegionInfo.LegacyRegionLocX >= 2048 || m_scene.RegionInfo.LegacyRegionLocY >= 2048)
253 { 253 {
254 ScenePresence avatarPresence = null; 254 ScenePresence avatarPresence = null;
255 255
@@ -278,10 +278,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
278 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 278 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
279 279
280 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 280 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
281 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 281 (int)(m_scene.RegionInfo.LegacyRegionLocX - 8) * (int)Constants.RegionSize,
282 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 282 (int)(m_scene.RegionInfo.LegacyRegionLocX + 8) * (int)Constants.RegionSize,
283 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 283 (int)(m_scene.RegionInfo.LegacyRegionLocY - 8) * (int)Constants.RegionSize,
284 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 284 (int)(m_scene.RegionInfo.LegacyRegionLocY + 8) * (int)Constants.RegionSize);
285 foreach (GridRegion r in regions) 285 foreach (GridRegion r in regions)
286 { 286 {
287 MapBlockData block = new MapBlockData(); 287 MapBlockData block = new MapBlockData();
@@ -803,7 +803,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
803 if (httpserver.Length == 0) 803 if (httpserver.Length == 0)
804 { 804 {
805 uint x = 0, y = 0; 805 uint x = 0, y = 0;
806 Utils.LongToUInts(regionhandle, out x, out y); 806 Util.RegionHandleToWorldLoc(regionhandle, out x, out y);
807 GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); 807 GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y);
808 808
809 if (mreg != null) 809 if (mreg != null)
@@ -1218,10 +1218,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1218 1218
1219 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1219 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1220 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1220 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1221 (int)(m_scene.RegionInfo.RegionLocX - 9) * (int)Constants.RegionSize, 1221 (int)(m_scene.RegionInfo.LegacyRegionLocX - 9) * (int)Constants.RegionSize,
1222 (int)(m_scene.RegionInfo.RegionLocX + 9) * (int)Constants.RegionSize, 1222 (int)(m_scene.RegionInfo.LegacyRegionLocX + 9) * (int)Constants.RegionSize,
1223 (int)(m_scene.RegionInfo.RegionLocY - 9) * (int)Constants.RegionSize, 1223 (int)(m_scene.RegionInfo.LegacyRegionLocY - 9) * (int)Constants.RegionSize,
1224 (int)(m_scene.RegionInfo.RegionLocY + 9) * (int)Constants.RegionSize); 1224 (int)(m_scene.RegionInfo.LegacyRegionLocY + 9) * (int)Constants.RegionSize);
1225 List<AssetBase> textures = new List<AssetBase>(); 1225 List<AssetBase> textures = new List<AssetBase>();
1226 List<Image> bitImages = new List<Image>(); 1226 List<Image> bitImages = new List<Image>();
1227 1227
@@ -1262,8 +1262,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1262 1262
1263 for (int i = 0; i < mapBlocks.Count; i++) 1263 for (int i = 0; i < mapBlocks.Count; i++)
1264 { 1264 {
1265 ushort x = (ushort)((mapBlocks[i].X - m_scene.RegionInfo.RegionLocX) + 10); 1265 ushort x = (ushort)((mapBlocks[i].X - m_scene.RegionInfo.LegacyRegionLocX) + 10);
1266 ushort y = (ushort)((mapBlocks[i].Y - m_scene.RegionInfo.RegionLocY) + 10); 1266 ushort y = (ushort)((mapBlocks[i].Y - m_scene.RegionInfo.LegacyRegionLocY) + 10);
1267 g.DrawImage(bitImages[i], (x * 128), 2560 - (y * 128), 128, 128); // y origin is top 1267 g.DrawImage(bitImages[i], (x * 128), 2560 - (y * 128), 128, 128); // y origin is top
1268 } 1268 }
1269 1269
diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs
index 085b5ca..8948f04 100644
--- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs
@@ -68,13 +68,22 @@ namespace OpenSim.Region.Framework.Interfaces
68 /// </summary> 68 /// </summary>
69 /// <param name="ter">HeightField data</param> 69 /// <param name="ter">HeightField data</param>
70 /// <param name="regionID">region UUID</param> 70 /// <param name="regionID">region UUID</param>
71 void StoreTerrain(TerrainData terrain, UUID regionID);
72
73 // Legacy version kept for downward compabibility
71 void StoreTerrain(double[,] terrain, UUID regionID); 74 void StoreTerrain(double[,] terrain, UUID regionID);
72 75
73 /// <summary> 76 /// <summary>
74 /// Load the latest terrain revision from region storage 77 /// Load the latest terrain revision from region storage
75 /// </summary> 78 /// </summary>
76 /// <param name="regionID">the region UUID</param> 79 /// <param name="regionID">the region UUID</param>
80 /// <param name="sizeX">the X dimension of the region being filled</param>
81 /// <param name="sizeY">the Y dimension of the region being filled</param>
82 /// <param name="sizeZ">the Z dimension of the region being filled</param>
77 /// <returns>Heightfield data</returns> 83 /// <returns>Heightfield data</returns>
84 TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ);
85
86 // Legacy version kept for downward compabibility
78 double[,] LoadTerrain(UUID regionID); 87 double[,] LoadTerrain(UUID regionID);
79 88
80 void StoreLandObject(ILandObject Parcel); 89 void StoreLandObject(ILandObject Parcel);
diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs
index 3787ca0..917b5d1 100644
--- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs
@@ -79,13 +79,22 @@ namespace OpenSim.Region.Framework.Interfaces
79 /// </summary> 79 /// </summary>
80 /// <param name="ter">HeightField data</param> 80 /// <param name="ter">HeightField data</param>
81 /// <param name="regionID">region UUID</param> 81 /// <param name="regionID">region UUID</param>
82 void StoreTerrain(TerrainData terrain, UUID regionID);
83
84 // Legacy version kept for downward compabibility
82 void StoreTerrain(double[,] terrain, UUID regionID); 85 void StoreTerrain(double[,] terrain, UUID regionID);
83 86
84 /// <summary> 87 /// <summary>
85 /// Load the latest terrain revision from region storage 88 /// Load the latest terrain revision from region storage
86 /// </summary> 89 /// </summary>
87 /// <param name="regionID">the region UUID</param> 90 /// <param name="regionID">the region UUID</param>
91 /// <param name="pSizeX">the X dimension of the terrain being filled</param>
92 /// <param name="pSizeY">the Y dimension of the terrain being filled</param>
93 /// <param name="pSizeZ">the Z dimension of the terrain being filled</param>
88 /// <returns>Heightfield data</returns> 94 /// <returns>Heightfield data</returns>
95 TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ);
96
97 // Legacy version kept for downward compabibility
89 double[,] LoadTerrain(UUID regionID); 98 double[,] LoadTerrain(UUID regionID);
90 99
91 void StoreLandObject(ILandObject Parcel); 100 void StoreLandObject(ILandObject Parcel);
@@ -135,4 +144,5 @@ namespace OpenSim.Region.Framework.Interfaces
135 144
136 void Shutdown(); 145 void Shutdown();
137 } 146 }
147
138} 148}
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
index e467701..469bd31 100644
--- a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
+++ b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
@@ -25,13 +25,22 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using OpenSim.Framework;
29
28namespace OpenSim.Region.Framework.Interfaces 30namespace OpenSim.Region.Framework.Interfaces
29{ 31{
30 public interface ITerrainChannel 32 public interface ITerrainChannel
31 { 33 {
32 int Height { get; } 34 int Width { get;} // X dimension
35 int Height { get;} // Y dimension
36 int Altitude { get;} // Z dimension
37
33 double this[int x, int y] { get; set; } 38 double this[int x, int y] { get; set; }
34 int Width { get; } 39
40 float GetHeightAtXYZ(float x, float y, float z);
41
42 // Return the packaged terrain data for passing into lower levels of communication
43 TerrainData GetTerrainData();
35 44
36 /// <summary> 45 /// <summary>
37 /// Squash the entire heightmap into a single dimensioned array 46 /// Squash the entire heightmap into a single dimensioned array
@@ -40,7 +49,10 @@ namespace OpenSim.Region.Framework.Interfaces
40 float[] GetFloatsSerialised(); 49 float[] GetFloatsSerialised();
41 50
42 double[,] GetDoubles(); 51 double[,] GetDoubles();
52
53 // Check if a location has been updated. Clears the taint flag as a side effect.
43 bool Tainted(int x, int y); 54 bool Tainted(int x, int y);
55
44 ITerrainChannel MakeCopy(); 56 ITerrainChannel MakeCopy();
45 string SaveToXmlString(); 57 string SaveToXmlString();
46 void LoadFromXmlString(string data); 58 void LoadFromXmlString(string data);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 7772f94..be8aed1 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1033,7 +1033,7 @@ namespace OpenSim.Region.Framework.Scenes
1033 1033
1034 BordersLocked = true; 1034 BordersLocked = true;
1035 Border northBorder = new Border(); 1035 Border northBorder = new Border();
1036 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<--- 1036 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<---
1037 northBorder.CrossDirection = Cardinals.N; 1037 northBorder.CrossDirection = Cardinals.N;
1038 NorthBorders.Add(northBorder); 1038 NorthBorders.Add(northBorder);
1039 1039
@@ -1043,7 +1043,7 @@ namespace OpenSim.Region.Framework.Scenes
1043 SouthBorders.Add(southBorder); 1043 SouthBorders.Add(southBorder);
1044 1044
1045 Border eastBorder = new Border(); 1045 Border eastBorder = new Border();
1046 eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<--- 1046 eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<---
1047 eastBorder.CrossDirection = Cardinals.E; 1047 eastBorder.CrossDirection = Cardinals.E;
1048 EastBorders.Add(eastBorder); 1048 EastBorders.Add(eastBorder);
1049 1049
@@ -1099,16 +1099,19 @@ namespace OpenSim.Region.Framework.Scenes
1099 /// <returns>True after all operations complete, throws exceptions otherwise.</returns> 1099 /// <returns>True after all operations complete, throws exceptions otherwise.</returns>
1100 public override void OtherRegionUp(GridRegion otherRegion) 1100 public override void OtherRegionUp(GridRegion otherRegion)
1101 { 1101 {
1102 uint xcell = (uint)((int)otherRegion.RegionLocX / (int)Constants.RegionSize); 1102 // uint xcell = (uint)((int)otherRegion.RegionLocX / (int)Constants.RegionSize);
1103 uint ycell = (uint)((int)otherRegion.RegionLocY / (int)Constants.RegionSize); 1103 // uint ycell = (uint)((int)otherRegion.RegionLocY / (int)Constants.RegionSize);
1104 uint xcell = Util.WorldToRegionLoc((uint)otherRegion.RegionLocX);
1105 uint ycell = Util.WorldToRegionLoc((uint)otherRegion.RegionLocY);
1106
1104 //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}", 1107 //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
1105 // RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell); 1108 // RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell);
1106 1109
1107 if (RegionInfo.RegionHandle != otherRegion.RegionHandle) 1110 if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
1108 { 1111 {
1109 // If these are cast to INT because long + negative values + abs returns invalid data 1112 // If these are cast to INT because long + negative values + abs returns invalid data
1110 int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX); 1113 int resultX = Math.Abs((int)xcell - (int)RegionInfo.LegacyRegionLocX);
1111 int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY); 1114 int resultY = Math.Abs((int)ycell - (int)RegionInfo.LegacyRegionLocY);
1112 if (resultX <= 1 && resultY <= 1) 1115 if (resultX <= 1 && resultY <= 1)
1113 { 1116 {
1114 // Let the grid service module know, so this can be cached 1117 // Let the grid service module know, so this can be cached
@@ -1183,8 +1186,8 @@ namespace OpenSim.Region.Framework.Scenes
1183 /// </returns> 1186 /// </returns>
1184 public int HaveNeighbor(Cardinals car, ref int[] fix) 1187 public int HaveNeighbor(Cardinals car, ref int[] fix)
1185 { 1188 {
1186 uint neighbourx = RegionInfo.RegionLocX; 1189 uint neighbourx = RegionInfo.LegacyRegionLocX;
1187 uint neighboury = RegionInfo.RegionLocY; 1190 uint neighboury = RegionInfo.LegacyRegionLocY;
1188 1191
1189 int dir = (int)car; 1192 int dir = (int)car;
1190 1193
@@ -1198,14 +1201,16 @@ namespace OpenSim.Region.Framework.Scenes
1198 else if (dir > 3 && dir < 7) // Heading Sout 1201 else if (dir > 3 && dir < 7) // Heading Sout
1199 neighboury--; 1202 neighboury--;
1200 1203
1201 int x = (int)(neighbourx * Constants.RegionSize); 1204 // int x = (int)(neighbourx * Constants.RegionSize);
1202 int y = (int)(neighboury * Constants.RegionSize); 1205 // int y = (int)(neighboury * Constants.RegionSize);
1203 GridRegion neighbourRegion = GridService.GetRegionByPosition(RegionInfo.ScopeID, x, y); 1206 uint x = Util.RegionToWorldLoc(neighbourx);
1207 uint y = Util.RegionToWorldLoc(neighboury);
1208 GridRegion neighbourRegion = GridService.GetRegionByPosition(RegionInfo.ScopeID, (int)x, (int)y);
1204 1209
1205 if (neighbourRegion == null) 1210 if (neighbourRegion == null)
1206 { 1211 {
1207 fix[0] = (int)(RegionInfo.RegionLocX - neighbourx); 1212 fix[0] = (int)(RegionInfo.LegacyRegionLocX - neighbourx);
1208 fix[1] = (int)(RegionInfo.RegionLocY - neighboury); 1213 fix[1] = (int)(RegionInfo.LegacyRegionLocY - neighboury);
1209 return dir * (-1); 1214 return dir * (-1);
1210 } 1215 }
1211 else 1216 else
@@ -1894,7 +1899,7 @@ namespace OpenSim.Region.Framework.Scenes
1894 { 1899 {
1895 try 1900 try
1896 { 1901 {
1897 double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID); 1902 TerrainData map = SimulationDataService.LoadTerrain(RegionInfo.RegionID, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ);
1898 if (map == null) 1903 if (map == null)
1899 { 1904 {
1900 // This should be in the Terrain module, but it isn't because 1905 // This should be in the Terrain module, but it isn't because
@@ -1905,7 +1910,7 @@ namespace OpenSim.Region.Framework.Scenes
1905 m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); 1910 m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
1906 1911
1907 m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain); 1912 m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain);
1908 Heightmap = new TerrainChannel(m_InitialTerrain); 1913 Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ);
1909 1914
1910 SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1915 SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1911 } 1916 }
@@ -2478,6 +2483,23 @@ namespace OpenSim.Region.Framework.Scenes
2478 EntityTransferModule.Cross(grp, attemptedPosition, silent); 2483 EntityTransferModule.Cross(grp, attemptedPosition, silent);
2479 } 2484 }
2480 2485
2486 // Simple test to see if a position is in the current region.
2487 // Resuming the position is relative to the region so anything outside its bounds.
2488 // Return 'true' if position inside region.
2489 public bool PositionIsInCurrentRegion(Vector3 pos)
2490 {
2491 bool ret = true;
2492 int xx = (int)Math.Floor(pos.X);
2493 int yy = (int)Math.Floor(pos.Y);
2494 if (xx < 0
2495 || xx > RegionInfo.RegionSizeX
2496 || yy < 0
2497 || yy > RegionInfo.RegionSizeY)
2498 ret = false;
2499 return ret;
2500
2501 }
2502
2481 public Border GetCrossedBorder(Vector3 position, Cardinals gridline) 2503 public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
2482 { 2504 {
2483 if (BordersLocked) 2505 if (BordersLocked)
@@ -3994,12 +4016,12 @@ namespace OpenSim.Region.Framework.Scenes
3994 { 4016 {
3995 if (posX < 0) 4017 if (posX < 0)
3996 posX = 0; 4018 posX = 0;
3997 else if (posX >= 256) 4019 else if (posX >= (float)RegionInfo.RegionSizeX)
3998 posX = 255.999f; 4020 posX = (float)RegionInfo.RegionSizeX - 0.001f;
3999 if (posY < 0) 4021 if (posY < 0)
4000 posY = 0; 4022 posY = 0;
4001 else if (posY >= 256) 4023 else if (posY >= (float)RegionInfo.RegionSizeY)
4002 posY = 255.999f; 4024 posY = (float)RegionInfo.RegionSizeY - 0.001f;
4003 4025
4004 reason = String.Empty; 4026 reason = String.Empty;
4005 if (Permissions.IsGod(agentID)) 4027 if (Permissions.IsGod(agentID))
@@ -4293,7 +4315,7 @@ namespace OpenSim.Region.Framework.Scenes
4293 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4315 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
4294 4316
4295 // TODO: This check should probably be in QueryAccess(). 4317 // TODO: This check should probably be in QueryAccess().
4296 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 4318 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2);
4297 if (nearestParcel == null) 4319 if (nearestParcel == null)
4298 { 4320 {
4299 m_log.InfoFormat( 4321 m_log.InfoFormat(
@@ -4371,8 +4393,8 @@ namespace OpenSim.Region.Framework.Scenes
4371 { 4393 {
4372 uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); 4394 uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
4373 uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); 4395 uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
4374 uint tRegionX = RegionInfo.RegionLocX; 4396 uint tRegionX = RegionInfo.LegacyRegionLocX;
4375 uint tRegionY = RegionInfo.RegionLocY; 4397 uint tRegionY = RegionInfo.LegacyRegionLocY;
4376 //Send Data to ScenePresence 4398 //Send Data to ScenePresence
4377 childAgentUpdate.UpdateChildAgent(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); 4399 childAgentUpdate.UpdateChildAgent(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
4378 // Not Implemented: 4400 // Not Implemented:
@@ -4600,13 +4622,22 @@ namespace OpenSim.Region.Framework.Scenes
4600 ScenePresence sp = GetScenePresence(remoteClient.AgentId); 4622 ScenePresence sp = GetScenePresence(remoteClient.AgentId);
4601 if (sp != null) 4623 if (sp != null)
4602 { 4624 {
4603 uint regionX = RegionInfo.RegionLocX; 4625 /*
4604 uint regionY = RegionInfo.RegionLocY; 4626 uint regionX = RegionInfo.LegacyRegionLocX;
4627 uint regionY = RegionInfo.LegacyRegionLocY;
4605 4628
4629 Util.RegionHandleToWorldLoc(regionHandle, out regionX, out regionY);
4606 Utils.LongToUInts(regionHandle, out regionX, out regionY); 4630 Utils.LongToUInts(regionHandle, out regionX, out regionY);
4607 4631
4608 int shiftx = (int) regionX - (int) RegionInfo.RegionLocX * (int)Constants.RegionSize; 4632 int shiftx = (int) regionX - (int) RegionInfo.LegacyRegionLocX * (int)Constants.RegionSize;
4609 int shifty = (int) regionY - (int) RegionInfo.RegionLocY * (int)Constants.RegionSize; 4633 int shifty = (int) regionY - (int) RegionInfo.LegacyRegionLocY * (int)Constants.RegionSize;
4634 */
4635
4636 uint regionX, regionY;
4637 Util.RegionHandleToWorldLoc(regionHandle, out regionX, out regionY);
4638
4639 int shiftx = (int) regionX - (int)RegionInfo.RegionWorldLocX;
4640 int shifty = (int) regionY - (int)RegionInfo.RegionWorldLocY;
4610 4641
4611 position.X += shiftx; 4642 position.X += shiftx;
4612 position.Y += shifty; 4643 position.Y += shifty;
@@ -4817,7 +4848,7 @@ namespace OpenSim.Region.Framework.Scenes
4817 else 4848 else
4818 { 4849 {
4819 4850
4820 if (pos.X > 0f && pos.X < Constants.RegionSize && pos.Y > 0f && pos.Y < Constants.RegionSize) 4851 if (pos.X > 0f && pos.X < RegionInfo.RegionSizeX && pos.Y > 0f && pos.Y < RegionInfo.RegionSizeY)
4821 { 4852 {
4822 // The only time parcel != null when an object is inside a region is when 4853 // The only time parcel != null when an object is inside a region is when
4823 // there is nothing behind the landchannel. IE, no land plugin loaded. 4854 // there is nothing behind the landchannel. IE, no land plugin loaded.
@@ -5478,7 +5509,7 @@ namespace OpenSim.Region.Framework.Scenes
5478 { 5509 {
5479 Vector3 unitDirection = Vector3.Normalize(direction); 5510 Vector3 unitDirection = Vector3.Normalize(direction);
5480 //Making distance to search go through some sane limit of distance 5511 //Making distance to search go through some sane limit of distance
5481 for (float distance = 0; distance < Constants.RegionSize * 2; distance += .5f) 5512 for (float distance = 0; distance < Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY) * 2; distance += .5f)
5482 { 5513 {
5483 Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance)); 5514 Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance));
5484 if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y)) 5515 if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y))
@@ -5532,9 +5563,9 @@ namespace OpenSim.Region.Framework.Scenes
5532 int count = 0; 5563 int count = 0;
5533 int avgx = 0; 5564 int avgx = 0;
5534 int avgy = 0; 5565 int avgy = 0;
5535 for (int x = 0; x < Constants.RegionSize; x++) 5566 for (int x = 0; x < RegionInfo.RegionSizeX; x++)
5536 { 5567 {
5537 for (int y = 0; y < Constants.RegionSize; y++) 5568 for (int y = 0; y < RegionInfo.RegionSizeY; y++)
5538 { 5569 {
5539 //Just keep a running average as we check if all the points are inside or not 5570 //Just keep a running average as we check if all the points are inside or not
5540 if (parcel.ContainsPoint(x, y)) 5571 if (parcel.ContainsPoint(x, y))
@@ -5558,31 +5589,33 @@ namespace OpenSim.Region.Framework.Scenes
5558 5589
5559 private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar) 5590 private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar)
5560 { 5591 {
5561 float xdistance = avatar.AbsolutePosition.X < Constants.RegionSize / 2 ? avatar.AbsolutePosition.X : Constants.RegionSize - avatar.AbsolutePosition.X; 5592 float xdistance = avatar.AbsolutePosition.X < RegionInfo.RegionSizeX / 2
5562 float ydistance = avatar.AbsolutePosition.Y < Constants.RegionSize / 2 ? avatar.AbsolutePosition.Y : Constants.RegionSize - avatar.AbsolutePosition.Y; 5593 ? avatar.AbsolutePosition.X : RegionInfo.RegionSizeX - avatar.AbsolutePosition.X;
5594 float ydistance = avatar.AbsolutePosition.Y < RegionInfo.RegionSizeY / 2
5595 ? avatar.AbsolutePosition.Y : RegionInfo.RegionSizeY - avatar.AbsolutePosition.Y;
5563 5596
5564 //find out what vertical edge to go to 5597 //find out what vertical edge to go to
5565 if (xdistance < ydistance) 5598 if (xdistance < ydistance)
5566 { 5599 {
5567 if (avatar.AbsolutePosition.X < Constants.RegionSize / 2) 5600 if (avatar.AbsolutePosition.X < RegionInfo.RegionSizeX / 2)
5568 { 5601 {
5569 return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.0f, avatar.AbsolutePosition.Y); 5602 return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.0f, avatar.AbsolutePosition.Y);
5570 } 5603 }
5571 else 5604 else
5572 { 5605 {
5573 return GetPositionAtAvatarHeightOrGroundHeight(avatar, Constants.RegionSize, avatar.AbsolutePosition.Y); 5606 return GetPositionAtAvatarHeightOrGroundHeight(avatar, RegionInfo.RegionSizeY, avatar.AbsolutePosition.Y);
5574 } 5607 }
5575 } 5608 }
5576 //find out what horizontal edge to go to 5609 //find out what horizontal edge to go to
5577 else 5610 else
5578 { 5611 {
5579 if (avatar.AbsolutePosition.Y < Constants.RegionSize / 2) 5612 if (avatar.AbsolutePosition.Y < RegionInfo.RegionSizeY / 2)
5580 { 5613 {
5581 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, 0.0f); 5614 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, 0.0f);
5582 } 5615 }
5583 else 5616 else
5584 { 5617 {
5585 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, Constants.RegionSize); 5618 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, RegionInfo.RegionSizeY);
5586 } 5619 }
5587 } 5620 }
5588 } 5621 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 77889fa..c873e40 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Scenes
92 { 92 {
93 m_log.DebugFormat( 93 m_log.DebugFormat(
94 "[SCENE COMMUNICATION SERVICE]: Region {0} successfully informed neighbour {1} at {2}-{3} that it is up", 94 "[SCENE COMMUNICATION SERVICE]: Region {0} successfully informed neighbour {1} at {2}-{3} that it is up",
95 m_scene.Name, neighbour.RegionName, x / Constants.RegionSize, y / Constants.RegionSize); 95 m_scene.Name, neighbour.RegionName, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
96 96
97 m_scene.EventManager.TriggerOnRegionUp(neighbour); 97 m_scene.EventManager.TriggerOnRegionUp(neighbour);
98 } 98 }
@@ -100,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes
100 { 100 {
101 m_log.WarnFormat( 101 m_log.WarnFormat(
102 "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.", 102 "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.",
103 m_scene.Name, x / Constants.RegionSize, y / Constants.RegionSize); 103 m_scene.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
104 } 104 }
105 } 105 }
106 106
@@ -166,7 +166,7 @@ namespace OpenSim.Region.Framework.Scenes
166 // we only want to send one update to each simulator; the simulator will 166 // we only want to send one update to each simulator; the simulator will
167 // hand it off to the regions where a child agent exists, this does assume 167 // hand it off to the regions where a child agent exists, this does assume
168 // that the region position is cached or performance will degrade 168 // that the region position is cached or performance will degrade
169 Utils.LongToUInts(regionHandle, out x, out y); 169 Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
170 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); 170 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
171 if (dest == null) 171 if (dest == null)
172 continue; 172 continue;
@@ -203,7 +203,7 @@ namespace OpenSim.Region.Framework.Scenes
203 203
204 //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); 204 //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
205 uint x = 0, y = 0; 205 uint x = 0, y = 0;
206 Utils.LongToUInts(regionHandle, out x, out y); 206 Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
207 207
208 GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y); 208 GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
209 209
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 28f7896..2677989 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -445,8 +445,8 @@ namespace OpenSim.Region.Framework.Scenes
445 { 445 {
446 foreach (Scene mscene in m_localScenes) 446 foreach (Scene mscene in m_localScenes)
447 { 447 {
448 if (mscene.RegionInfo.RegionLocX == locX && 448 if (mscene.RegionInfo.LegacyRegionLocX == locX &&
449 mscene.RegionInfo.RegionLocY == locY) 449 mscene.RegionInfo.LegacyRegionLocY == locY)
450 { 450 {
451 scene = mscene; 451 scene = mscene;
452 return true; 452 return true;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4b4e4ba..eed8908 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -842,9 +842,9 @@ namespace OpenSim.Region.Framework.Scenes
842 maxX = -256f; 842 maxX = -256f;
843 maxY = -256f; 843 maxY = -256f;
844 maxZ = -256f; 844 maxZ = -256f;
845 minX = 256f; 845 minX = 10000f;
846 minY = 256f; 846 minY = 10000f;
847 minZ = 8192f; 847 minZ = 10000f;
848 848
849 SceneObjectPart[] parts = m_parts.GetArray(); 849 SceneObjectPart[] parts = m_parts.GetArray();
850 for (int i = 0; i < parts.Length; i++) 850 for (int i = 0; i < parts.Length; i++)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1dc7e20..7ae9be5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -700,10 +700,9 @@ namespace OpenSim.Region.Framework.Scenes
700 foreach (ulong handle in seeds.Keys) 700 foreach (ulong handle in seeds.Keys)
701 { 701 {
702 uint x, y; 702 uint x, y;
703 Utils.LongToUInts(handle, out x, out y); 703 Util.RegionHandleToRegionLoc(handle, out x, out y);
704 x = x / Constants.RegionSize; 704
705 y = y / Constants.RegionSize; 705 if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.LegacyRegionLocX, y, Scene.RegionInfo.LegacyRegionLocY))
706 if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY))
707 { 706 {
708 old.Add(handle); 707 old.Add(handle);
709 } 708 }
@@ -724,9 +723,7 @@ namespace OpenSim.Region.Framework.Scenes
724 foreach (KeyValuePair<ulong, string> kvp in KnownRegions) 723 foreach (KeyValuePair<ulong, string> kvp in KnownRegions)
725 { 724 {
726 uint x, y; 725 uint x, y;
727 Utils.LongToUInts(kvp.Key, out x, out y); 726 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
728 x = x / Constants.RegionSize;
729 y = y / Constants.RegionSize;
730 m_log.Info(" >> "+x+", "+y+": "+kvp.Value); 727 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
731 } 728 }
732 } 729 }
@@ -972,7 +969,7 @@ namespace OpenSim.Region.Framework.Scenes
972 969
973 float posZLimit = 0; 970 float posZLimit = 0;
974 971
975 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 972 if (pos.X < m_scene.RegionInfo.RegionSizeX && pos.Y < m_scene.RegionInfo.RegionSizeY)
976 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 973 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
977 974
978 float newPosZ = posZLimit + localAVHeight / 2; 975 float newPosZ = posZLimit + localAVHeight / 2;
@@ -2099,7 +2096,7 @@ namespace OpenSim.Region.Framework.Scenes
2099 if (regionCombinerModule != null) 2096 if (regionCombinerModule != null)
2100 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); 2097 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
2101 else 2098 else
2102 regionSize = new Vector2(Constants.RegionSize); 2099 regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY);
2103 2100
2104 if (pos.X < 0 || pos.X >= regionSize.X 2101 if (pos.X < 0 || pos.X >= regionSize.X
2105 || pos.Y < 0 || pos.Y >= regionSize.Y 2102 || pos.Y < 0 || pos.Y >= regionSize.Y
@@ -2117,8 +2114,8 @@ namespace OpenSim.Region.Framework.Scenes
2117// } 2114// }
2118 2115
2119 // Get terrain height for sub-region in a megaregion if necessary 2116 // Get terrain height for sub-region in a megaregion if necessary
2120 int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X); 2117 int X = (int)((m_scene.RegionInfo.RegionWorldLocX) + pos.X);
2121 int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y); 2118 int Y = (int)((m_scene.RegionInfo.RegionWorldLocY) + pos.Y);
2122 GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y); 2119 GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y);
2123 // If X and Y is NaN, target_region will be null 2120 // If X and Y is NaN, target_region will be null
2124 if (target_region == null) 2121 if (target_region == null)
@@ -2129,7 +2126,7 @@ namespace OpenSim.Region.Framework.Scenes
2129 if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) 2126 if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene))
2130 targetScene = m_scene; 2127 targetScene = m_scene;
2131 2128
2132 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; 2129 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % regionSize.X), (int)(pos.Y % regionSize.Y)];
2133 pos.Z = Math.Max(terrainHeight, pos.Z); 2130 pos.Z = Math.Max(terrainHeight, pos.Z);
2134 2131
2135 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is 2132 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
@@ -3226,6 +3223,9 @@ namespace OpenSim.Region.Framework.Scenes
3226 int neighbor = 0; 3223 int neighbor = 0;
3227 int[] fix = new int[2]; 3224 int[] fix = new int[2];
3228 3225
3226 // Compute the avatar position in the next physics tick.
3227 // If the avatar will be crossing, we force the crossing to happen now
3228 // in the hope that this will make the avatar movement smoother when crossing.
3229 float timeStep = 0.1f; 3229 float timeStep = 0.1f;
3230 pos2.X = pos2.X + (vel.X * timeStep); 3230 pos2.X = pos2.X + (vel.X * timeStep);
3231 pos2.Y = pos2.Y + (vel.Y * timeStep); 3231 pos2.Y = pos2.Y + (vel.Y * timeStep);
@@ -3233,12 +3233,48 @@ namespace OpenSim.Region.Framework.Scenes
3233 3233
3234 if (!IsInTransit) 3234 if (!IsInTransit)
3235 { 3235 {
3236// m_log.DebugFormat( 3236 m_log.DebugFormat(
3237// "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", 3237 "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
3238// pos2, Name, Scene.Name); 3238 pos2, Name, Scene.Name);
3239
3240 if (!m_scene.PositionIsInCurrentRegion(pos2))
3241 {
3242 // Disconnect from the current region
3243 bool isFlying = Flying;
3244 RemoveFromPhysicalScene();
3245 // pos2 is the forcasted position so make that the 'current' position so the crossing
3246 // code will move us into the newly addressed region.
3247 m_pos = pos2;
3248 if (CrossToNewRegion())
3249 {
3250 AddToPhysicalScene(isFlying);
3251 }
3252 else
3253 {
3254 // Tried to make crossing happen but it failed.
3255 if (m_requestedSitTargetUUID == UUID.Zero)
3256 {
3257
3258 Vector3 pos = AbsolutePosition;
3259 if (AbsolutePosition.X < 0)
3260 pos.X += Velocity.X * 2;
3261 else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX)
3262 pos.X -= Velocity.X * 2;
3263 if (AbsolutePosition.Y < 0)
3264 pos.Y += Velocity.Y * 2;
3265 else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY)
3266 pos.Y -= Velocity.Y * 2;
3267 Velocity = Vector3.Zero;
3268 AbsolutePosition = pos;
3269
3270 AddToPhysicalScene(isFlying);
3271 }
3272 }
3273
3274 }
3239 3275
3276 /*
3240 // Checks if where it's headed exists a region 3277 // Checks if where it's headed exists a region
3241 bool needsTransit = false;
3242 if (m_scene.TestBorderCross(pos2, Cardinals.W)) 3278 if (m_scene.TestBorderCross(pos2, Cardinals.W))
3243 { 3279 {
3244 if (m_scene.TestBorderCross(pos2, Cardinals.S)) 3280 if (m_scene.TestBorderCross(pos2, Cardinals.S))
@@ -3299,11 +3335,11 @@ namespace OpenSim.Region.Framework.Scenes
3299 Vector3 pos = AbsolutePosition; 3335 Vector3 pos = AbsolutePosition;
3300 if (AbsolutePosition.X < 0) 3336 if (AbsolutePosition.X < 0)
3301 pos.X += Velocity.X * 2; 3337 pos.X += Velocity.X * 2;
3302 else if (AbsolutePosition.X > Constants.RegionSize) 3338 else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX)
3303 pos.X -= Velocity.X * 2; 3339 pos.X -= Velocity.X * 2;
3304 if (AbsolutePosition.Y < 0) 3340 if (AbsolutePosition.Y < 0)
3305 pos.Y += Velocity.Y * 2; 3341 pos.Y += Velocity.Y * 2;
3306 else if (AbsolutePosition.Y > Constants.RegionSize) 3342 else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY)
3307 pos.Y -= Velocity.Y * 2; 3343 pos.Y -= Velocity.Y * 2;
3308 Velocity = Vector3.Zero; 3344 Velocity = Vector3.Zero;
3309 AbsolutePosition = pos; 3345 AbsolutePosition = pos;
@@ -3326,11 +3362,11 @@ namespace OpenSim.Region.Framework.Scenes
3326 Vector3 pos = AbsolutePosition; 3362 Vector3 pos = AbsolutePosition;
3327 if (AbsolutePosition.X < 0) 3363 if (AbsolutePosition.X < 0)
3328 pos.X += Velocity.X * 2; 3364 pos.X += Velocity.X * 2;
3329 else if (AbsolutePosition.X > Constants.RegionSize) 3365 else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX)
3330 pos.X -= Velocity.X * 2; 3366 pos.X -= Velocity.X * 2;
3331 if (AbsolutePosition.Y < 0) 3367 if (AbsolutePosition.Y < 0)
3332 pos.Y += Velocity.Y * 2; 3368 pos.Y += Velocity.Y * 2;
3333 else if (AbsolutePosition.Y > Constants.RegionSize) 3369 else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY)
3334 pos.Y -= Velocity.Y * 2; 3370 pos.Y -= Velocity.Y * 2;
3335 Velocity = Vector3.Zero; 3371 Velocity = Vector3.Zero;
3336 AbsolutePosition = pos; 3372 AbsolutePosition = pos;
@@ -3339,6 +3375,7 @@ namespace OpenSim.Region.Framework.Scenes
3339 } 3375 }
3340 } 3376 }
3341 } 3377 }
3378 */
3342 } 3379 }
3343 else 3380 else
3344 { 3381 {
@@ -3379,7 +3416,7 @@ namespace OpenSim.Region.Framework.Scenes
3379 3416
3380 // Put the child agent back at the center 3417 // Put the child agent back at the center
3381 AbsolutePosition 3418 AbsolutePosition
3382 = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); 3419 = new Vector3(((float)m_scene.RegionInfo.RegionSizeX * 0.5f), ((float)m_scene.RegionInfo.RegionSizeY * 0.5f), 70);
3383 3420
3384 Animator.ResetAnimations(); 3421 Animator.ResetAnimations();
3385 } 3422 }
@@ -3406,9 +3443,7 @@ namespace OpenSim.Region.Framework.Scenes
3406 if (handle != Scene.RegionInfo.RegionHandle) 3443 if (handle != Scene.RegionInfo.RegionHandle)
3407 { 3444 {
3408 uint x, y; 3445 uint x, y;
3409 Utils.LongToUInts(handle, out x, out y); 3446 Util.RegionHandleToRegionLoc(handle, out x, out y);
3410 x = x / Constants.RegionSize;
3411 y = y / Constants.RegionSize;
3412 3447
3413// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3448// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3414// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); 3449// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
@@ -3489,8 +3524,9 @@ namespace OpenSim.Region.Framework.Scenes
3489 return; 3524 return;
3490 3525
3491 //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); 3526 //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
3492 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; 3527 // Find the distance (in meters) between the two regions
3493 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; 3528 uint shiftx = Util.RegionToWorldLoc(rRegionX - tRegionX);
3529 uint shifty = Util.RegionToWorldLoc(rRegionY - tRegionY);
3494 3530
3495 Vector3 offset = new Vector3(shiftx, shifty, 0f); 3531 Vector3 offset = new Vector3(shiftx, shifty, 0f);
3496 3532
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 95f9caf..67998a0 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -437,7 +437,7 @@ namespace OpenSim.Region.Framework.Scenes
437 437
438 SimStats simStats 438 SimStats simStats
439 = new SimStats( 439 = new SimStats(
440 ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)m_objectCapacity, 440 ReportingRegion.LegacyRegionLocX, ReportingRegion.LegacyRegionLocY, regionFlags, (uint)m_objectCapacity,
441 rb, sb, m_scene.RegionInfo.originRegionID); 441 rb, sb, m_scene.RegionInfo.originRegionID);
442 442
443 handlerSendStatResult = OnSendStatsResult; 443 handlerSendStatResult = OnSendStatsResult;
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index c0ca48e..b4b1823 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -25,14 +25,19 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using OpenSim.Framework;
29using OpenSim.Region.Framework.Interfaces;
30using System; 28using System;
29using System.IO;
31using System.Text; 30using System.Text;
31using System.Reflection;
32using System.Xml; 32using System.Xml;
33using System.IO;
34using System.Xml.Serialization; 33using System.Xml.Serialization;
35 34
35using OpenSim.Data;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38
39using log4net;
40
36namespace OpenSim.Region.Framework.Scenes 41namespace OpenSim.Region.Framework.Scenes
37{ 42{
38 /// <summary> 43 /// <summary>
@@ -40,132 +45,146 @@ namespace OpenSim.Region.Framework.Scenes
40 /// </summary> 45 /// </summary>
41 public class TerrainChannel : ITerrainChannel 46 public class TerrainChannel : ITerrainChannel
42 { 47 {
43 private readonly bool[,] taint; 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 private double[,] map; 49 private static string LogHeader = "[TERRAIN CHANNEL]";
50
51 protected TerrainData m_terrainData;
45 52
53 public int Width { get { return m_terrainData.SizeX; } } // X dimension
54 // Unfortunately, for historical reasons, in this module 'Width' is X and 'Height' is Y
55 public int Height { get { return m_terrainData.SizeY; } } // Y dimension
56 public int Altitude { get { return m_terrainData.SizeZ; } } // Y dimension
57
58 // Default, not-often-used builder
46 public TerrainChannel() 59 public TerrainChannel()
47 { 60 {
48 map = new double[Constants.RegionSize, Constants.RegionSize]; 61 m_terrainData = new HeightmapTerrainData((int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
49 taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; 62 FlatLand();
50 63 // PinHeadIsland();
51 PinHeadIsland();
52 } 64 }
53 65
54 public TerrainChannel(String type) 66 // Create terrain of given size
67 public TerrainChannel(int pX, int pY)
55 { 68 {
56 map = new double[Constants.RegionSize, Constants.RegionSize]; 69 m_terrainData = new HeightmapTerrainData(pX, pY, (int)Constants.RegionHeight);
57 taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; 70 }
58 71
72 // Create terrain of specified size and initialize with specified terrain.
73 // TODO: join this with the terrain initializers.
74 public TerrainChannel(String type, int pX, int pY, int pZ)
75 {
76 m_terrainData = new HeightmapTerrainData(pX, pY, pZ);
59 if (type.Equals("flat")) 77 if (type.Equals("flat"))
60 FlatLand(); 78 FlatLand();
61 else 79 else
62 PinHeadIsland(); 80 PinHeadIsland();
63 } 81 }
64 82
65 public TerrainChannel(double[,] import) 83 // Create channel passed a heightmap and expected dimensions of the region.
84 // The heightmap might not fit the passed size so accomodations must be made.
85 public TerrainChannel(double[,] pM, int pSizeX, int pSizeY, int pAltitude)
66 { 86 {
67 map = import; 87 int hmSizeX = pM.GetLength(0);
68 taint = new bool[import.GetLength(0),import.GetLength(1)]; 88 int hmSizeY = pM.GetLength(1);
69 }
70 89
71 public TerrainChannel(bool createMap) 90 m_terrainData = new HeightmapTerrainData(pSizeX, pSizeY, pAltitude);
72 { 91
73 if (createMap) 92 for (int xx = 0; xx < pSizeX; xx++)
74 { 93 for (int yy = 0; yy < pSizeY; yy++)
75 map = new double[Constants.RegionSize,Constants.RegionSize]; 94 if (xx > hmSizeX || yy > hmSizeY)
76 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; 95 m_terrainData[xx, yy] = TerrainData.DefaultTerrainHeight;
77 } 96 else
97 m_terrainData[xx, yy] = (float)pM[xx, yy];
78 } 98 }
79 99
80 public TerrainChannel(int w, int h) 100 public TerrainChannel(TerrainData pTerrData)
81 { 101 {
82 map = new double[w,h]; 102 m_terrainData = pTerrData;
83 taint = new bool[w / 16,h / 16];
84 } 103 }
85 104
86 #region ITerrainChannel Members 105 #region ITerrainChannel Members
87 106
88 public int Width 107 // ITerrainChannel.MakeCopy()
108 public ITerrainChannel MakeCopy()
89 { 109 {
90 get { return map.GetLength(0); } 110 return this.Copy();
91 } 111 }
92 112
93 public int Height 113 // ITerrainChannel.GetTerrainData()
114 public TerrainData GetTerrainData()
94 { 115 {
95 get { return map.GetLength(1); } 116 return m_terrainData;
96 } 117 }
97 118
98 public ITerrainChannel MakeCopy() 119 // ITerrainChannel.GetFloatsSerialized()
120 // This one dimensional version is ordered so height = map[y*sizeX+x];
121 // DEPRECATED: don't use this function as it does not retain the dimensions of the terrain
122 // and the caller will probably do the wrong thing if the terrain is not the legacy 256x256.
123 public float[] GetFloatsSerialised()
99 { 124 {
100 TerrainChannel copy = new TerrainChannel(false); 125 int points = Width * Height;
101 copy.map = (double[,]) map.Clone(); 126 float[] heights = new float[points];
102 127
103 return copy; 128 int idx = 0;
129 for (int jj = 0; jj < Height; jj++)
130 for (int ii = 0; ii < Width; ii++)
131 {
132 heights[idx++] = m_terrainData[ii, jj];
133 }
134
135 return heights;
104 } 136 }
105 137
106 public float[] GetFloatsSerialised() 138 // ITerrainChannel.GetDoubles()
139 public double[,] GetDoubles()
107 { 140 {
108 // Move the member variables into local variables, calling 141 double[,] heights = new double[Width, Height];
109 // member variables 256*256 times gets expensive
110 int w = Width;
111 int h = Height;
112 float[] heights = new float[w * h];
113 142
114 int i, j; // map coordinates
115 int idx = 0; // index into serialized array 143 int idx = 0; // index into serialized array
116 for (i = 0; i < h; i++) 144 for (int ii = 0; ii < Width; ii++)
117 { 145 {
118 for (j = 0; j < w; j++) 146 for (int jj = 0; jj < Height; jj++)
119 { 147 {
120 heights[idx++] = (float)map[j, i]; 148 heights[ii, jj] = (double)m_terrainData[ii, jj];
149 idx++;
121 } 150 }
122 } 151 }
123 152
124 return heights; 153 return heights;
125 } 154 }
126 155
127 public double[,] GetDoubles() 156 // ITerrainChannel.this[x,y]
128 {
129 return map;
130 }
131
132 public double this[int x, int y] 157 public double this[int x, int y]
133 { 158 {
134 get { return map[x, y]; } 159 get {
160 if (x < 0 || x >= Width || y < 0 || y >= Height)
161 return 0;
162 return (double)m_terrainData[x, y];
163 }
135 set 164 set
136 { 165 {
137 // Will "fix" terrain hole problems. Although not fantastically.
138 if (Double.IsNaN(value) || Double.IsInfinity(value)) 166 if (Double.IsNaN(value) || Double.IsInfinity(value))
139 return; 167 return;
140 168
141 if (map[x, y] != value) 169 m_terrainData[x, y] = (float)value;
142 {
143 taint[x / 16, y / 16] = true;
144 map[x, y] = value;
145 }
146 } 170 }
147 } 171 }
148 172
149 public bool Tainted(int x, int y) 173 // ITerrainChannel.GetHieghtAtXYZ(x, y, z)
174 public float GetHeightAtXYZ(float x, float y, float z)
150 { 175 {
151 if (taint[x / 16, y / 16]) 176 if (x < 0 || x >= Width || y < 0 || y >= Height)
152 { 177 return 0;
153 taint[x / 16, y / 16] = false; 178 return m_terrainData[(int)x, (int)y];
154 return true;
155 }
156 return false;
157 } 179 }
158 180
159 #endregion 181 // ITerrainChannel.Tainted()
160 182 public bool Tainted(int x, int y)
161 public TerrainChannel Copy()
162 { 183 {
163 TerrainChannel copy = new TerrainChannel(false); 184 return m_terrainData.IsTaintedAt(x, y);
164 copy.map = (double[,]) map.Clone();
165
166 return copy;
167 } 185 }
168 186
187 // ITerrainChannel.SaveToXmlString()
169 public string SaveToXmlString() 188 public string SaveToXmlString()
170 { 189 {
171 XmlWriterSettings settings = new XmlWriterSettings(); 190 XmlWriterSettings settings = new XmlWriterSettings();
@@ -181,13 +200,7 @@ namespace OpenSim.Region.Framework.Scenes
181 } 200 }
182 } 201 }
183 202
184 private void WriteXml(XmlWriter writer) 203 // ITerrainChannel.LoadFromXmlString()
185 {
186 writer.WriteStartElement(String.Empty, "TerrainMap", String.Empty);
187 ToXml(writer);
188 writer.WriteEndElement();
189 }
190
191 public void LoadFromXmlString(string data) 204 public void LoadFromXmlString(string data)
192 { 205 {
193 StringReader sr = new StringReader(data); 206 StringReader sr = new StringReader(data);
@@ -199,12 +212,50 @@ namespace OpenSim.Region.Framework.Scenes
199 sr.Close(); 212 sr.Close();
200 } 213 }
201 214
215 #endregion
216
217 public TerrainChannel Copy()
218 {
219 TerrainChannel copy = new TerrainChannel();
220 copy.m_terrainData = m_terrainData.Clone();
221 return copy;
222 }
223
224 private void WriteXml(XmlWriter writer)
225 {
226 if (Width == Constants.RegionSize && Height == Constants.RegionSize)
227 {
228 // Downward compatibility for legacy region terrain maps.
229 // If region is exactly legacy size, return the old format XML.
230 writer.WriteStartElement(String.Empty, "TerrainMap", String.Empty);
231 ToXml(writer);
232 writer.WriteEndElement();
233 }
234 else
235 {
236 // New format XML that includes width and length.
237 writer.WriteStartElement(String.Empty, "TerrainMap2", String.Empty);
238 ToXml2(writer);
239 writer.WriteEndElement();
240 }
241 }
242
202 private void ReadXml(XmlReader reader) 243 private void ReadXml(XmlReader reader)
203 { 244 {
204 reader.ReadStartElement("TerrainMap"); 245 // Check the first element. If legacy element, use the legacy reader.
205 FromXml(reader); 246 if (reader.IsStartElement("TerrainMap"))
247 {
248 reader.ReadStartElement("TerrainMap");
249 FromXml(reader);
250 }
251 else
252 {
253 reader.ReadStartElement("TerrainMap2");
254 FromXml2(reader);
255 }
206 } 256 }
207 257
258 // Write legacy terrain map. Presumed to be 256x256 of data encoded as floats in a byte array.
208 private void ToXml(XmlWriter xmlWriter) 259 private void ToXml(XmlWriter xmlWriter)
209 { 260 {
210 float[] mapData = GetFloatsSerialised(); 261 float[] mapData = GetFloatsSerialised();
@@ -218,12 +269,15 @@ namespace OpenSim.Region.Framework.Scenes
218 serializer.Serialize(xmlWriter, buffer); 269 serializer.Serialize(xmlWriter, buffer);
219 } 270 }
220 271
272 // Read legacy terrain map. Presumed to be 256x256 of data encoded as floats in a byte array.
221 private void FromXml(XmlReader xmlReader) 273 private void FromXml(XmlReader xmlReader)
222 { 274 {
223 XmlSerializer serializer = new XmlSerializer(typeof(byte[])); 275 XmlSerializer serializer = new XmlSerializer(typeof(byte[]));
224 byte[] dataArray = (byte[])serializer.Deserialize(xmlReader); 276 byte[] dataArray = (byte[])serializer.Deserialize(xmlReader);
225 int index = 0; 277 int index = 0;
226 278
279 m_terrainData = new HeightmapTerrainData(Height, Width, (int)Constants.RegionHeight);
280
227 for (int y = 0; y < Height; y++) 281 for (int y = 0; y < Height; y++)
228 { 282 {
229 for (int x = 0; x < Width; x++) 283 for (int x = 0; x < Width; x++)
@@ -236,35 +290,63 @@ namespace OpenSim.Region.Framework.Scenes
236 } 290 }
237 } 291 }
238 292
293 private class TerrainChannelXMLPackage
294 {
295 public int Version;
296 public int SizeX;
297 public int SizeY;
298 public int SizeZ;
299 public float CompressionFactor;
300 public short[] Map;
301 public TerrainChannelXMLPackage(int pX, int pY, int pZ, float pCompressionFactor, short[] pMap)
302 {
303 Version = 1;
304 SizeX = pX;
305 SizeY = pY;
306 SizeZ = pZ;
307 CompressionFactor = pCompressionFactor;
308 Map = pMap;
309 }
310 }
311
312 // New terrain serialization format that includes the width and length.
313 private void ToXml2(XmlWriter xmlWriter)
314 {
315 TerrainChannelXMLPackage package = new TerrainChannelXMLPackage(Width, Height, Altitude, m_terrainData.CompressionFactor,
316 m_terrainData.GetCompressedMap());
317 XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage));
318 serializer.Serialize(xmlWriter, package);
319 }
320
321 // New terrain serialization format that includes the width and length.
322 private void FromXml2(XmlReader xmlReader)
323 {
324 XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage));
325 TerrainChannelXMLPackage package = (TerrainChannelXMLPackage)serializer.Deserialize(xmlReader);
326 m_terrainData = new HeightmapTerrainData(package.Map, package.CompressionFactor, package.SizeX, package.SizeY, package.SizeZ);
327 }
328
329 // Fill the heightmap with the center bump terrain
239 private void PinHeadIsland() 330 private void PinHeadIsland()
240 { 331 {
241 int x; 332 for (int x = 0; x < Width; x++)
242 for (x = 0; x < Constants.RegionSize; x++)
243 { 333 {
244 int y; 334 for (int y = 0; y < Height; y++)
245 for (y = 0; y < Constants.RegionSize; y++)
246 { 335 {
247 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; 336 m_terrainData[x, y] = (float)TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10;
248 double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01; 337 float spherFacA = (float)(TerrainUtil.SphericalFactor(x, y, m_terrainData.SizeX / 2.0, m_terrainData.SizeY / 2.0, 50) * 0.01d);
249 double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001; 338 float spherFacB = (float)(TerrainUtil.SphericalFactor(x, y, m_terrainData.SizeX / 2.0, m_terrainData.SizeY / 2.0, 100) * 0.001d);
250 if (map[x, y] < spherFacA) 339 if (m_terrainData[x, y]< spherFacA)
251 map[x, y] = spherFacA; 340 m_terrainData[x, y]= spherFacA;
252 if (map[x, y] < spherFacB) 341 if (m_terrainData[x, y]< spherFacB)
253 map[x, y] = spherFacB; 342 m_terrainData[x, y] = spherFacB;
254 } 343 }
255 } 344 }
256 } 345 }
257 346
258 private void FlatLand() 347 private void FlatLand()
259 { 348 {
260 int x; 349 m_terrainData.ClearLand();
261 for (x = 0; x < Constants.RegionSize; x++)
262 {
263 int y;
264 for (y = 0; y < Constants.RegionSize; y++)
265 map[x, y] = 21;
266 }
267 } 350 }
268
269 } 351 }
270} 352}
diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
new file mode 100644
index 0000000..ced62e2
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
@@ -0,0 +1,944 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/* Freely adapted from the Aurora version of the terrain compressor.
29 * Copyright (c) Contributors, http://aurora-sim.org/, http://opensimulator.org/
30 */
31
32using System;
33using System.Reflection;
34
35using log4net;
36
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Scenes;
40
41using OpenMetaverse;
42using OpenMetaverse.Packets;
43
44namespace OpenSim.Region.ClientStack.LindenUDP
45{
46 public static class OpenSimTerrainCompressor
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 private static string LogHeader = "[TERRAIN COMPRESSOR]";
50
51 public const int END_OF_PATCHES = 97;
52
53 private const float OO_SQRT2 = 0.7071067811865475244008443621049f;
54 private const int STRIDE = 264;
55
56 private const int ZERO_CODE = 0x0;
57 private const int ZERO_EOB = 0x2;
58 private const int POSITIVE_VALUE = 0x6;
59 private const int NEGATIVE_VALUE = 0x7;
60
61 private static readonly float[] DequantizeTable16 =
62 new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
63
64 private static readonly float[] DequantizeTable32 =
65 new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
66
67 private static readonly float[] CosineTable16 = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
68 //private static readonly float[] CosineTable32 = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
69 private static readonly int[] CopyMatrix16 = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
70 private static readonly int[] CopyMatrix32 = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
71
72 private static readonly float[] QuantizeTable16 =
73 new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
74
75 static OpenSimTerrainCompressor()
76 {
77 // Initialize the decompression tables
78 BuildDequantizeTable16();
79 SetupCosines16();
80 BuildCopyMatrix16();
81 BuildQuantizeTable16();
82 }
83
84 // Unused: left for historical reference.
85 public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, byte type, int pRegionSizeX,
86 int pRegionSizeY)
87 {
88 LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}};
89
90 TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
91 {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize};
92
93 // Should be enough to fit even the most poorly packed data
94 byte[] data = new byte[patches.Length*Constants.TerrainPatchSize*Constants.TerrainPatchSize*2];
95 BitPack bitpack = new BitPack(data, 0);
96 bitpack.PackBits(header.Stride, 16);
97 bitpack.PackBits(header.PatchSize, 8);
98 bitpack.PackBits(type, 8);
99
100 foreach (TerrainPatch t in patches)
101 CreatePatch(bitpack, t.Data, t.X, t.Y, pRegionSizeX, pRegionSizeY);
102
103 bitpack.PackBits(END_OF_PATCHES, 8);
104
105 layer.LayerData.Data = new byte[bitpack.BytePos + 1];
106 Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);
107
108 return layer;
109 }
110
111 // Create a land packet for a single patch.
112 public static LayerDataPacket CreateLandPacket(TerrainData terrData, int patchX, int patchY)
113 {
114 int[] xPieces = new int[1];
115 int[] yPieces = new int[1];
116 xPieces[0] = patchX; // patch X dimension
117 yPieces[0] = patchY;
118
119 byte landPacketType = (byte)TerrainPatch.LayerType.Land;
120 if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
121 {
122 // libOMV does not have a packet type defined for the extended parcel format.
123 // We just happen to know the extended parcel format code is one more than the usual code.
124 landPacketType++;
125 }
126
127 return CreateLandPacket(terrData, xPieces, yPieces, landPacketType);
128 }
129
130 /// <summary>
131 /// Creates a LayerData packet for compressed land data given a full
132 /// simulator heightmap and an array of indices of patches to compress
133 /// </summary>
134 /// <param name="terrData">
135 /// Terrain data that can result in a meter square heightmap.
136 /// </param>
137 /// <param name="x">
138 /// Array of indexes in the grid of patches
139 /// for this simulator.
140 /// If creating a packet for multiple patches, there will be entries in
141 /// both the X and Y arrays for each of the patches.
142 /// For example if patches 1 and 17 are to be sent,
143 /// x[] = {1,1} and y[] = {0,1} which specifies the patches at
144 /// indexes <1,0> and <1,1> (presuming the terrain size is 16x16 patches).
145 /// </param>
146 /// <param name="y">
147 /// Array of indexes in the grid of patches.
148 /// </param>
149 /// <param name="type"></param>
150 /// <param name="pRegionSizeX"></param>
151 /// <param name="pRegionSizeY"></param>
152 /// <returns></returns>
153 public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] x, int[] y, byte type)
154 {
155 LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}};
156
157 TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
158 {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize};
159
160 byte[] data = new byte[x.Length * Constants.TerrainPatchSize * Constants.TerrainPatchSize * 2];
161 BitPack bitpack = new BitPack(data, 0);
162 bitpack.PackBits(header.Stride, 16);
163 bitpack.PackBits(header.PatchSize, 8);
164 bitpack.PackBits(type, 8);
165
166 for (int i = 0; i < x.Length; i++)
167 CreatePatchFromHeightmap(bitpack, terrData, x[i], y[i]);
168
169 bitpack.PackBits(END_OF_PATCHES, 8);
170
171 layer.LayerData.Data = new byte[bitpack.BytePos + 1];
172 Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);
173
174 return layer;
175 }
176
177 // Unused: left for historical reference.
178 public static void CreatePatch(BitPack output, float[] patchData, int x, int y, int pRegionSizeX, int pRegionSizeY)
179 {
180 TerrainPatch.Header header = PrescanPatch(patchData);
181 header.QuantWBits = 136;
182 if (pRegionSizeX > Constants.RegionSize || pRegionSizeY > Constants.RegionSize)
183 {
184 header.PatchIDs = (y & 0xFFFF);
185 header.PatchIDs += (x << 16);
186 }
187 else
188 {
189 header.PatchIDs = (y & 0x1F);
190 header.PatchIDs += (x << 5);
191 }
192
193 // NOTE: No idea what prequant and postquant should be or what they do
194
195 int wbits;
196 int[] patch = CompressPatch(patchData, header, 10, out wbits);
197 wbits = EncodePatchHeader(output, header, patch, (uint)pRegionSizeX, (uint)pRegionSizeY, wbits);
198 EncodePatch(output, patch, 0, wbits);
199 }
200
201 /// <summary>
202 /// Add a patch of terrain to a BitPacker
203 /// </summary>
204 /// <param name="output">BitPacker to write the patch to</param>
205 /// <param name="heightmap">
206 /// Heightmap of the simulator. Presumed to be an sizeX*sizeY array.
207 /// </param>
208 /// <param name="patchX">
209 /// X offset of the patch to create.
210 /// </param>
211 /// <param name="patchY">
212 /// Y offset of the patch to create.
213 /// </param>
214 /// <param name="pRegionSizeX"></param>
215 /// <param name="pRegionSizeY"></param>
216 public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY)
217 {
218 TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY);
219 header.QuantWBits = 136;
220
221 // If larger than legacy region size, pack patch X and Y info differently.
222 if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
223 {
224 header.PatchIDs = (patchY & 0xFFFF);
225 header.PatchIDs += (patchX << 16);
226 }
227 else
228 {
229 header.PatchIDs = (patchY & 0x1F);
230 header.PatchIDs += (patchX << 5);
231 }
232
233 // m_log.DebugFormat("{0} CreatePatchFromHeightmap. patchX={1}, patchY={2}, DCOffset={3}, range={4}",
234 // LogHeader, patchX, patchY, header.DCOffset, header.Range);
235
236 // NOTE: No idea what prequant and postquant should be or what they do
237 int wbits;
238 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
239 wbits = EncodePatchHeader(output, header, patch, (uint)terrData.SizeX, (uint)terrData.SizeY, wbits);
240 EncodePatch(output, patch, 0, wbits);
241 }
242
243 private static TerrainPatch.Header PrescanPatch(float[] patch)
244 {
245 TerrainPatch.Header header = new TerrainPatch.Header();
246 float zmax = -99999999.0f;
247 float zmin = 99999999.0f;
248
249 for (int i = 0; i < Constants.TerrainPatchSize*Constants.TerrainPatchSize; i++)
250 {
251 float val = patch[i];
252 if (val > zmax) zmax = val;
253 if (val < zmin) zmin = val;
254 }
255
256 header.DCOffset = zmin;
257 header.Range = (int) ((zmax - zmin) + 1.0f);
258
259 return header;
260 }
261
262 // Scan the height info we're returning and return a patch packet header for this patch.
263 private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY)
264 {
265 TerrainPatch.Header header = new TerrainPatch.Header();
266 float zmax = -99999999.0f;
267 float zmin = 99999999.0f;
268
269 for (int j = patchY*Constants.TerrainPatchSize; j < (patchY + 1)*Constants.TerrainPatchSize; j++)
270 {
271 for (int i = patchX*Constants.TerrainPatchSize; i < (patchX + 1)*Constants.TerrainPatchSize; i++)
272 {
273 float val = terrData[i, j];
274 if (val > zmax) zmax = val;
275 if (val < zmin) zmin = val;
276 }
277 }
278
279 header.DCOffset = zmin;
280 header.Range = (int)(zmax - zmin + 1.0f);
281
282 return header;
283 }
284
285 public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack)
286 {
287 TerrainPatch.Header header = new TerrainPatch.Header {QuantWBits = bitpack.UnpackBits(8)};
288
289 // Quantized word bits
290 if (header.QuantWBits == END_OF_PATCHES)
291 return header;
292
293 // DC offset
294 header.DCOffset = bitpack.UnpackFloat();
295
296 // Range
297 header.Range = bitpack.UnpackBits(16);
298
299 // Patch IDs (10 bits)
300 header.PatchIDs = bitpack.UnpackBits(10);
301
302 // Word bits
303 header.WordBits = (uint) ((header.QuantWBits & 0x0f) + 2);
304
305 return header;
306 }
307
308 private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, uint pRegionSizeX,
309 uint pRegionSizeY, int wbits)
310 {
311 /*
312 int temp;
313 int wbits = (header.QuantWBits & 0x0f) + 2;
314 uint maxWbits = (uint)wbits + 5;
315 uint minWbits = ((uint)wbits >> 1);
316 int wbitsMaxValue;
317 */
318 // goal is to determ minimum number of bits to use so all data fits
319 /*
320 wbits = (int)minWbits;
321 wbitsMaxValue = (1 << wbits);
322
323 for (int i = 0; i < patch.Length; i++)
324 {
325 temp = patch[i];
326 if (temp != 0)
327 {
328 // Get the absolute value
329 if (temp < 0) temp *= -1;
330
331 no coments..
332
333 for (int j = (int)maxWbits; j > (int)minWbits; j--)
334 {
335 if ((temp & (1 << j)) != 0)
336 {
337 if (j > wbits) wbits = j;
338 break;
339 }
340 }
341
342 while (temp > wbitsMaxValue)
343 {
344 wbits++;
345 if (wbits == maxWbits)
346 goto Done;
347 wbitsMaxValue = 1 << wbits;
348 }
349 }
350 }
351
352 Done:
353
354 // wbits += 1;
355 */
356 // better check
357 if (wbits > 17)
358 wbits = 16;
359 else if (wbits < 3)
360 wbits = 3;
361
362 header.QuantWBits &= 0xf0;
363
364 header.QuantWBits |= (wbits - 2);
365
366 output.PackBits(header.QuantWBits, 8);
367 output.PackFloat(header.DCOffset);
368 output.PackBits(header.Range, 16);
369 if (pRegionSizeX > Constants.RegionSize || pRegionSizeY > Constants.RegionSize)
370 output.PackBits(header.PatchIDs, 32);
371 else
372 output.PackBits(header.PatchIDs, 10);
373
374 return wbits;
375 }
376
377 private static void IDCTColumn16(float[] linein, float[] lineout, int column)
378 {
379 for (int n = 0; n < Constants.TerrainPatchSize; n++)
380 {
381 float total = OO_SQRT2*linein[column];
382
383 for (int u = 1; u < Constants.TerrainPatchSize; u++)
384 {
385 int usize = u*Constants.TerrainPatchSize;
386 total += linein[usize + column]*CosineTable16[usize + n];
387 }
388
389 lineout[Constants.TerrainPatchSize*n + column] = total;
390 }
391 }
392
393 private static void IDCTLine16(float[] linein, float[] lineout, int line)
394 {
395 const float oosob = 2.0f/Constants.TerrainPatchSize;
396 int lineSize = line*Constants.TerrainPatchSize;
397
398 for (int n = 0; n < Constants.TerrainPatchSize; n++)
399 {
400 float total = OO_SQRT2*linein[lineSize];
401
402 for (int u = 1; u < Constants.TerrainPatchSize; u++)
403 {
404 total += linein[lineSize + u]*CosineTable16[u*Constants.TerrainPatchSize + n];
405 }
406
407 lineout[lineSize + n] = total*oosob;
408 }
409 }
410
411/*
412 private static void DCTLine16(float[] linein, float[] lineout, int line)
413 {
414 float total = 0.0f;
415 int lineSize = line * Constants.TerrainPatchSize;
416
417 for (int n = 0; n < Constants.TerrainPatchSize; n++)
418 {
419 total += linein[lineSize + n];
420 }
421
422 lineout[lineSize] = OO_SQRT2 * total;
423
424 int uptr = 0;
425 for (int u = 1; u < Constants.TerrainPatchSize; u++)
426 {
427 total = 0.0f;
428 uptr += Constants.TerrainPatchSize;
429
430 for (int n = 0; n < Constants.TerrainPatchSize; n++)
431 {
432 total += linein[lineSize + n] * CosineTable16[uptr + n];
433 }
434
435 lineout[lineSize + u] = total;
436 }
437 }
438*/
439
440 private static void DCTLine16(float[] linein, float[] lineout, int line)
441 {
442 // outputs transpose data (lines exchanged with coluns )
443 // so to save a bit of cpu when doing coluns
444 float total = 0.0f;
445 int lineSize = line*Constants.TerrainPatchSize;
446
447 for (int n = 0; n < Constants.TerrainPatchSize; n++)
448 {
449 total += linein[lineSize + n];
450 }
451
452 lineout[line] = OO_SQRT2*total;
453
454 for (int u = Constants.TerrainPatchSize;
455 u < Constants.TerrainPatchSize*Constants.TerrainPatchSize;
456 u += Constants.TerrainPatchSize)
457 {
458 total = 0.0f;
459 for (int ptrn = lineSize, ptru = u; ptrn < lineSize + Constants.TerrainPatchSize; ptrn++,ptru++)
460 {
461 total += linein[ptrn]*CosineTable16[ptru];
462 }
463
464 lineout[line + u] = total;
465 }
466 }
467
468
469 /*
470 private static void DCTColumn16(float[] linein, int[] lineout, int column)
471 {
472 float total = 0.0f;
473 // const float oosob = 2.0f / Constants.TerrainPatchSize;
474
475 for (int n = 0; n < Constants.TerrainPatchSize; n++)
476 {
477 total += linein[Constants.TerrainPatchSize * n + column];
478 }
479
480 // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]);
481 lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * QuantizeTable16[column]);
482
483 for (int uptr = Constants.TerrainPatchSize; uptr < Constants.TerrainPatchSize * Constants.TerrainPatchSize; uptr += Constants.TerrainPatchSize)
484 {
485 total = 0.0f;
486
487 for (int n = 0; n < Constants.TerrainPatchSize; n++)
488 {
489 total += linein[Constants.TerrainPatchSize * n + column] * CosineTable16[uptr + n];
490 }
491
492 // lineout[CopyMatrix16[Constants.TerrainPatchSize * u + column]] = (int)(total * oosob * QuantizeTable16[Constants.TerrainPatchSize * u + column]);
493 lineout[CopyMatrix16[uptr + column]] = (int)(total * QuantizeTable16[uptr + column]);
494 }
495 }
496 */
497
498 private static void DCTColumn16(float[] linein, int[] lineout, int column)
499 {
500 // input columns are in fact stored in lines now
501
502 float total = 0.0f;
503// const float oosob = 2.0f / Constants.TerrainPatchSize;
504 int inlinesptr = Constants.TerrainPatchSize*column;
505
506 for (int n = 0; n < Constants.TerrainPatchSize; n++)
507 {
508 total += linein[inlinesptr + n];
509 }
510
511 // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]);
512 lineout[CopyMatrix16[column]] = (int) (OO_SQRT2*total*QuantizeTable16[column]);
513
514 for (int uptr = Constants.TerrainPatchSize;
515 uptr < Constants.TerrainPatchSize*Constants.TerrainPatchSize;
516 uptr += Constants.TerrainPatchSize)
517 {
518 total = 0.0f;
519
520 for (int n = inlinesptr, ptru = uptr; n < inlinesptr + Constants.TerrainPatchSize; n++, ptru++)
521 {
522 total += linein[n]*CosineTable16[ptru];
523 }
524
525// lineout[CopyMatrix16[Constants.TerrainPatchSize * u + column]] = (int)(total * oosob * QuantizeTable16[Constants.TerrainPatchSize * u + column]);
526 lineout[CopyMatrix16[uptr + column]] = (int) (total*QuantizeTable16[uptr + column]);
527 }
528 }
529
530 private static int DCTColumn16Wbits(float[] linein, int[] lineout, int column, int wbits, int maxwbits)
531 {
532 // input columns are in fact stored in lines now
533
534 bool dowbits = wbits != maxwbits;
535 int wbitsMaxValue = 1 << wbits;
536
537 float total = 0.0f;
538 // const float oosob = 2.0f / Constants.TerrainPatchSize;
539 int inlinesptr = Constants.TerrainPatchSize*column;
540
541 for (int n = 0; n < Constants.TerrainPatchSize; n++)
542 {
543 total += linein[inlinesptr + n];
544 }
545
546 // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]);
547 int tmp = (int) (OO_SQRT2*total*QuantizeTable16[column]);
548 lineout[CopyMatrix16[column]] = tmp;
549
550 if (dowbits)
551 {
552 if (tmp < 0) tmp *= -1;
553 while (tmp > wbitsMaxValue)
554 {
555 wbits++;
556 wbitsMaxValue = 1 << wbits;
557 if (wbits == maxwbits)
558 {
559 dowbits = false;
560 break;
561 }
562 }
563 }
564
565 for (int uptr = Constants.TerrainPatchSize;
566 uptr < Constants.TerrainPatchSize*Constants.TerrainPatchSize;
567 uptr += Constants.TerrainPatchSize)
568 {
569 total = 0.0f;
570
571 for (int n = inlinesptr, ptru = uptr; n < inlinesptr + Constants.TerrainPatchSize; n++, ptru++)
572 {
573 total += linein[n]*CosineTable16[ptru];
574 }
575
576 tmp = (int) (total*QuantizeTable16[uptr + column]);
577 lineout[CopyMatrix16[uptr + column]] = tmp;
578
579 if (dowbits)
580 {
581 if (tmp < 0) tmp *= -1;
582 while (tmp > wbitsMaxValue)
583 {
584 wbits++;
585 wbitsMaxValue = 1 << wbits;
586 if (wbits == maxwbits)
587 {
588 dowbits = false;
589 break;
590 }
591 }
592 }
593 }
594 return wbits;
595 }
596
597 public static void DecodePatch(int[] patches, BitPack bitpack, TerrainPatch.Header header, int size)
598 {
599 for (int n = 0; n < size*size; n++)
600 {
601 // ?
602 int temp = bitpack.UnpackBits(1);
603 if (temp != 0)
604 {
605 // Value or EOB
606 temp = bitpack.UnpackBits(1);
607 if (temp != 0)
608 {
609 // Value
610 temp = bitpack.UnpackBits(1);
611 if (temp != 0)
612 {
613 // Negative
614 temp = bitpack.UnpackBits((int) header.WordBits);
615 patches[n] = temp*-1;
616 }
617 else
618 {
619 // Positive
620 temp = bitpack.UnpackBits((int) header.WordBits);
621 patches[n] = temp;
622 }
623 }
624 else
625 {
626 // Set the rest to zero
627 // TODO: This might not be necessary
628 for (int o = n; o < size*size; o++)
629 {
630 patches[o] = 0;
631 }
632 break;
633 }
634 }
635 else
636 {
637 patches[n] = 0;
638 }
639 }
640 }
641
642 private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits)
643 {
644 int maxwbitssize = (1 << wbits) - 1;
645
646 if (postquant > Constants.TerrainPatchSize*Constants.TerrainPatchSize || postquant < 0)
647 {
648 Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error);
649 return;
650 }
651
652 if (postquant != 0) patch[Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant] = 0;
653
654 for (int i = 0; i < Constants.TerrainPatchSize*Constants.TerrainPatchSize; i++)
655 {
656 int temp = patch[i];
657
658 if (temp == 0)
659 {
660 bool eob = true;
661
662 for (int j = i; j < Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant; j++)
663 {
664 if (patch[j] != 0)
665 {
666 eob = false;
667 break;
668 }
669 }
670
671 if (eob)
672 {
673 output.PackBits(ZERO_EOB, 2);
674 return;
675 }
676 output.PackBits(ZERO_CODE, 1);
677 }
678 else
679 {
680 if (temp < 0)
681 {
682 temp *= -1;
683
684 if (temp > maxwbitssize) temp = maxwbitssize;
685
686 output.PackBits(NEGATIVE_VALUE, 3);
687 output.PackBits(temp, wbits);
688 }
689 else
690 {
691 if (temp > maxwbitssize) temp = maxwbitssize;
692
693 output.PackBits(POSITIVE_VALUE, 3);
694 output.PackBits(temp, wbits);
695 }
696 }
697 }
698 }
699
700 public static float[] DecompressPatch(int[] patches, TerrainPatch.Header header, TerrainPatch.GroupHeader group)
701 {
702 float[] block = new float[group.PatchSize*group.PatchSize];
703 float[] output = new float[group.PatchSize*group.PatchSize];
704 int prequant = (header.QuantWBits >> 4) + 2;
705 int quantize = 1 << prequant;
706 float ooq = 1.0f/quantize;
707 float mult = ooq*header.Range;
708 float addval = mult*(1 << (prequant - 1)) + header.DCOffset;
709
710 if (group.PatchSize == Constants.TerrainPatchSize)
711 {
712 for (int n = 0; n < Constants.TerrainPatchSize*Constants.TerrainPatchSize; n++)
713 {
714 block[n] = patches[CopyMatrix16[n]]*DequantizeTable16[n];
715 }
716
717 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
718
719 for (int o = 0; o < Constants.TerrainPatchSize; o++)
720 IDCTColumn16(block, ftemp, o);
721 for (int o = 0; o < Constants.TerrainPatchSize; o++)
722 IDCTLine16(ftemp, block, o);
723 }
724 else
725 {
726 for (int n = 0; n < Constants.TerrainPatchSize*2*Constants.TerrainPatchSize*2; n++)
727 {
728 block[n] = patches[CopyMatrix32[n]]*DequantizeTable32[n];
729 }
730
731 Logger.Log("Implement IDCTPatchLarge", Helpers.LogLevel.Error);
732 }
733
734 for (int j = 0; j < block.Length; j++)
735 {
736 output[j] = block[j]*mult + addval;
737 }
738
739 return output;
740 }
741
742 private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits)
743 {
744 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
745 int wordsize = (prequant - 2) & 0x0f;
746 float oozrange = 1.0f/header.Range;
747 float range = (1 << prequant);
748 float premult = oozrange*range;
749 float sub = (1 << (prequant - 1)) + header.DCOffset*premult;
750
751 header.QuantWBits = wordsize;
752 header.QuantWBits |= wordsize << 4;
753
754 int k = 0;
755 for (int j = 0; j < Constants.TerrainPatchSize; j++)
756 {
757 for (int i = 0; i < Constants.TerrainPatchSize; i++)
758 block[k++] = patchData[j*Constants.TerrainPatchSize + i]*premult - sub;
759 }
760
761 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
762 int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
763
764
765 int maxWbits = prequant + 5;
766 wbits = (prequant >> 1);
767
768 for (int o = 0; o < Constants.TerrainPatchSize; o++)
769 DCTLine16(block, ftemp, o);
770 for (int o = 0; o < Constants.TerrainPatchSize; o++)
771 wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits);
772
773 return itemp;
774 }
775
776 private static int[] CompressPatch(float[,] patchData, TerrainPatch.Header header, int prequant, out int wbits)
777 {
778 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
779 float oozrange = 1.0f/header.Range;
780 float range = (1 << prequant);
781 float premult = oozrange*range;
782 float sub = (1 << (prequant - 1)) + header.DCOffset*premult;
783 int wordsize = (prequant - 2) & 0x0f;
784
785 header.QuantWBits = wordsize;
786 header.QuantWBits |= wordsize << 4;
787
788 int k = 0;
789 for (int j = 0; j < Constants.TerrainPatchSize; j++)
790 {
791 for (int i = 0; i < Constants.TerrainPatchSize; i++)
792 block[k++] = patchData[j, i]*premult - sub;
793 }
794
795 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
796 int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
797
798 int maxWbits = prequant + 5;
799 wbits = (prequant >> 1);
800
801 for (int o = 0; o < Constants.TerrainPatchSize; o++)
802 DCTLine16(block, ftemp, o);
803 for (int o = 0; o < Constants.TerrainPatchSize; o++)
804 wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits);
805
806 return itemp;
807 }
808
809 private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
810 int prequant, out int wbits)
811 {
812 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
813 int wordsize = prequant;
814 float oozrange = 1.0f/header.Range;
815 float range = (1 << prequant);
816 float premult = oozrange*range;
817 float sub = (1 << (prequant - 1)) + header.DCOffset*premult;
818
819 header.QuantWBits = wordsize - 2;
820 header.QuantWBits |= (prequant - 2) << 4;
821
822 int k = 0;
823
824 int yPatchLimit = patchY >= (terrData.SizeY / Constants.TerrainPatchSize) ?
825 (terrData.SizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchY;
826 yPatchLimit = (yPatchLimit + 1) * Constants.TerrainPatchSize;
827
828 int xPatchLimit = patchX >= (terrData.SizeX / Constants.TerrainPatchSize) ?
829 (terrData.SizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchX;
830 xPatchLimit = (xPatchLimit + 1) * Constants.TerrainPatchSize;
831
832 for (int yy = patchY * Constants.TerrainPatchSize; yy < yPatchLimit; yy++)
833 {
834 for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++)
835 {
836 block[k++] = terrData[xx, yy] * premult - sub;
837 }
838 }
839
840 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
841 int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
842
843 int maxWbits = prequant + 5;
844 wbits = (prequant >> 1);
845
846 for (int o = 0; o < Constants.TerrainPatchSize; o++)
847 DCTLine16(block, ftemp, o);
848 for (int o = 0; o < Constants.TerrainPatchSize; o++)
849 wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits);
850
851 return itemp;
852 }
853
854 #region Initialization
855
856 private static void BuildDequantizeTable16()
857 {
858 for (int j = 0; j < Constants.TerrainPatchSize; j++)
859 {
860 for (int i = 0; i < Constants.TerrainPatchSize; i++)
861 {
862 DequantizeTable16[j*Constants.TerrainPatchSize + i] = 1.0f + 2.0f*(i + j);
863 }
864 }
865 }
866
867 private static void BuildQuantizeTable16()
868 {
869 const float oosob = 2.0f/Constants.TerrainPatchSize;
870 for (int j = 0; j < Constants.TerrainPatchSize; j++)
871 {
872 for (int i = 0; i < Constants.TerrainPatchSize; i++)
873 {
874// QuantizeTable16[j * Constants.TerrainPatchSize + i] = 1.0f / (1.0f + 2.0f * ((float)i + (float)j));
875 QuantizeTable16[j*Constants.TerrainPatchSize + i] = oosob/(1.0f + 2.0f*(i + (float) j));
876 }
877 }
878 }
879
880 private static void SetupCosines16()
881 {
882 const float hposz = (float) Math.PI*0.5f/Constants.TerrainPatchSize;
883
884 for (int u = 0; u < Constants.TerrainPatchSize; u++)
885 {
886 for (int n = 0; n < Constants.TerrainPatchSize; n++)
887 {
888 CosineTable16[u*Constants.TerrainPatchSize + n] = (float) Math.Cos((2.0f*n + 1.0f)*u*hposz);
889 }
890 }
891 }
892
893 private static void BuildCopyMatrix16()
894 {
895 bool diag = false;
896 bool right = true;
897 int i = 0;
898 int j = 0;
899 int count = 0;
900
901 while (i < Constants.TerrainPatchSize && j < Constants.TerrainPatchSize)
902 {
903 CopyMatrix16[j*Constants.TerrainPatchSize + i] = count++;
904
905 if (!diag)
906 {
907 if (right)
908 {
909 if (i < Constants.TerrainPatchSize - 1) i++;
910 else j++;
911
912 right = false;
913 diag = true;
914 }
915 else
916 {
917 if (j < Constants.TerrainPatchSize - 1) j++;
918 else i++;
919
920 right = true;
921 diag = true;
922 }
923 }
924 else
925 {
926 if (right)
927 {
928 i++;
929 j--;
930 if (i == Constants.TerrainPatchSize - 1 || j == 0) diag = false;
931 }
932 else
933 {
934 i--;
935 j++;
936 if (j == Constants.TerrainPatchSize - 1 || i == 0) diag = false;
937 }
938 }
939 }
940 }
941
942 #endregion Initialization
943 }
944}
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
index d4fe5e0..cbc538e 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
@@ -84,8 +84,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
84 84
85 Region = scene.RegionInfo.RegionName; 85 Region = scene.RegionInfo.RegionName;
86 Host = scene.RegionInfo.ExternalHostName; 86 Host = scene.RegionInfo.ExternalHostName;
87 LocX = Convert.ToString(scene.RegionInfo.RegionLocX); 87 LocX = Convert.ToString(scene.RegionInfo.LegacyRegionLocX);
88 LocY = Convert.ToString(scene.RegionInfo.RegionLocY); 88 LocY = Convert.ToString(scene.RegionInfo.LegacyRegionLocY);
89 IDK = Convert.ToString(_idk_++); 89 IDK = Convert.ToString(_idk_++);
90 90
91 showAlert = config.GetBoolean("alert_show", false); 91 showAlert = config.GetBoolean("alert_show", false);
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index c717128..c6e4a7b 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -170,7 +170,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
170 c.Channel = m_channelNotify; 170 c.Channel = m_channelNotify;
171 c.Message += numScriptsFailed.ToString() + "," + message; 171 c.Message += numScriptsFailed.ToString() + "," + message;
172 c.Type = ChatTypeEnum.Region; 172 c.Type = ChatTypeEnum.Region;
173 c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); 173 if (m_scene != null)
174 c.Position = new Vector3((m_scene.RegionInfo.RegionSizeX * 0.5f), (m_scene.RegionInfo.RegionSizeY * 0.5f), 30);
175 else
176 c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30);
174 c.Sender = null; 177 c.Sender = null;
175 c.SenderUUID = UUID.Zero; 178 c.SenderUUID = UUID.Zero;
176 c.Scene = m_scene; 179 c.Scene = m_scene;
diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
index 8144870..e4a3382 100644
--- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
+++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
@@ -748,8 +748,8 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
748 position.X = s_tree.AbsolutePosition.X + (float)randX; 748 position.X = s_tree.AbsolutePosition.X + (float)randX;
749 position.Y = s_tree.AbsolutePosition.Y + (float)randY; 749 position.Y = s_tree.AbsolutePosition.Y + (float)randY;
750 750
751 if (position.X <= ((int)Constants.RegionSize - 1) && position.X >= 0 && 751 if (position.X <= (m_scene.RegionInfo.RegionSizeX - 1) && position.X >= 0 &&
752 position.Y <= ((int)Constants.RegionSize - 1) && position.Y >= 0 && 752 position.Y <= (m_scene.RegionInfo.RegionSizeY - 1) && position.Y >= 0 &&
753 Util.GetDistanceTo(position, copse.m_seed_point) <= copse.m_range) 753 Util.GetDistanceTo(position, copse.m_seed_point) <= copse.m_range)
754 { 754 {
755 UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner; 755 UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 15b7090..edec949 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -376,18 +376,19 @@ public class BSPrim : BSPhysObject
376 { 376 {
377 bool ret = false; 377 bool ret = false;
378 378
379 uint wayOutThere = Constants.RegionSize * Constants.RegionSize; 379 int wayOverThere = -1000;
380 int wayOutThere = 10000;
380 // There have been instances of objects getting thrown way out of bounds and crashing 381 // There have been instances of objects getting thrown way out of bounds and crashing
381 // the border crossing code. 382 // the border crossing code.
382 if ( RawPosition.X < -Constants.RegionSize || RawPosition.X > wayOutThere 383 if ( RawPosition.X < wayOverThere || RawPosition.X > wayOutThere
383 || RawPosition.Y < -Constants.RegionSize || RawPosition.Y > wayOutThere 384 || RawPosition.Y < wayOverThere || RawPosition.X > wayOutThere
384 || RawPosition.Z < -Constants.RegionSize || RawPosition.Z > wayOutThere) 385 || RawPosition.Z < wayOverThere || RawPosition.X > wayOutThere)
385 { 386 {
386 RawPosition = new OMV.Vector3(10, 10, 50); 387 RawPosition = new OMV.Vector3(10, 10, 50);
387 ZeroMotion(inTaintTime); 388 ZeroMotion(inTaintTime);
388 ret = true; 389 ret = true;
389 } 390 }
390 if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocity) 391 if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocitySquared)
391 { 392 {
392 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity); 393 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
393 ret = true; 394 ret = true;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index b3dfa41..83ef1f6 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -210,6 +210,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
210 210
211 public override void Initialise(IMesher meshmerizer, IConfigSource config) 211 public override void Initialise(IMesher meshmerizer, IConfigSource config)
212 { 212 {
213 m_log.ErrorFormat("{0} WARNING WARNING WARNING! BulletSim initialized without region extent specification. Terrain will be messed up.");
214 Vector3 regionExtent = new Vector3( Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
215 Initialise(meshmerizer, config, regionExtent);
216
217 }
218
219 public override void Initialise(IMesher meshmerizer, IConfigSource config, Vector3 regionExtent)
220 {
213 mesher = meshmerizer; 221 mesher = meshmerizer;
214 _taintOperations = new List<TaintCallbackEntry>(); 222 _taintOperations = new List<TaintCallbackEntry>();
215 _postTaintOperations = new Dictionary<string, TaintCallbackEntry>(); 223 _postTaintOperations = new Dictionary<string, TaintCallbackEntry>();
@@ -250,13 +258,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
250 // a child in a mega-region. 258 // a child in a mega-region.
251 // Bullet actually doesn't care about the extents of the simulated 259 // Bullet actually doesn't care about the extents of the simulated
252 // area. It tracks active objects no matter where they are. 260 // area. It tracks active objects no matter where they are.
253 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 261 Vector3 worldExtent = regionExtent;
254 262
255 World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray); 263 World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray);
256 264
257 Constraints = new BSConstraintCollection(World); 265 Constraints = new BSConstraintCollection(World);
258 266
259 TerrainManager = new BSTerrainManager(this); 267 TerrainManager = new BSTerrainManager(this, worldExtent);
260 TerrainManager.CreateInitialGroundPlaneAndTerrain(); 268 TerrainManager.CreateInitialGroundPlaneAndTerrain();
261 269
262 // Put some informational messages into the log file. 270 // Put some informational messages into the log file.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
index 8888d6d..d70b2fb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
@@ -58,7 +58,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
58 { 58 {
59 initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; 59 initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION;
60 } 60 }
61 m_mapInfo = new BulletHMapInfo(id, initialMap); 61 m_mapInfo = new BulletHMapInfo(id, initialMap, regionSize.X, regionSize.Y);
62 m_mapInfo.minCoords = minTerrainCoords; 62 m_mapInfo.minCoords = minTerrainCoords;
63 m_mapInfo.maxCoords = maxTerrainCoords; 63 m_mapInfo.maxCoords = maxTerrainCoords;
64 m_mapInfo.terrainRegionBase = TerrainBase; 64 m_mapInfo.terrainRegionBase = TerrainBase;
@@ -72,7 +72,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
72 Vector3 minCoords, Vector3 maxCoords) 72 Vector3 minCoords, Vector3 maxCoords)
73 : base(physicsScene, regionBase, id) 73 : base(physicsScene, regionBase, id)
74 { 74 {
75 m_mapInfo = new BulletHMapInfo(id, initialMap); 75 m_mapInfo = new BulletHMapInfo(id, initialMap, maxCoords.X - minCoords.X, maxCoords.Y - minCoords.Y);
76 m_mapInfo.minCoords = minCoords; 76 m_mapInfo.minCoords = minCoords;
77 m_mapInfo.maxCoords = maxCoords; 77 m_mapInfo.maxCoords = maxCoords;
78 m_mapInfo.minZ = minCoords.Z; 78 m_mapInfo.minZ = minCoords.Z;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 441d2d3..3013077 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -111,9 +111,11 @@ public sealed class BSTerrainManager : IDisposable
111 private Vector3 m_worldMax; 111 private Vector3 m_worldMax;
112 private PhysicsScene MegaRegionParentPhysicsScene { get; set; } 112 private PhysicsScene MegaRegionParentPhysicsScene { get; set; }
113 113
114 public BSTerrainManager(BSScene physicsScene) 114 public BSTerrainManager(BSScene physicsScene, Vector3 regionSize)
115 { 115 {
116 m_physicsScene = physicsScene; 116 m_physicsScene = physicsScene;
117 DefaultRegionSize = regionSize;
118
117 m_terrains = new Dictionary<Vector3,BSTerrainPhys>(); 119 m_terrains = new Dictionary<Vector3,BSTerrainPhys>();
118 120
119 // Assume one region of default size 121 // Assume one region of default size
@@ -268,7 +270,7 @@ public sealed class BSTerrainManager : IDisposable
268 { 270 {
269 // There is already a terrain in this spot. Free the old and build the new. 271 // There is already a terrain in this spot. Free the old and build the new.
270 DetailLog("{0},BSTErrainManager.UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", 272 DetailLog("{0},BSTErrainManager.UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
271 BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); 273 BSScene.DetailLogZero, id, terrainRegionBase, minCoords, maxCoords);
272 274
273 // Remove old terrain from the collection 275 // Remove old terrain from the collection
274 m_terrains.Remove(terrainRegionBase); 276 m_terrains.Remove(terrainRegionBase);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
index 971ff9f..3425d9e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
@@ -165,14 +165,15 @@ public class BulletConstraint
165// than making copies. 165// than making copies.
166public class BulletHMapInfo 166public class BulletHMapInfo
167{ 167{
168 public BulletHMapInfo(uint id, float[] hm) { 168 public BulletHMapInfo(uint id, float[] hm, float pSizeX, float pSizeY) {
169 ID = id; 169 ID = id;
170 heightMap = hm; 170 heightMap = hm;
171 terrainRegionBase = OMV.Vector3.Zero; 171 terrainRegionBase = OMV.Vector3.Zero;
172 minCoords = new OMV.Vector3(100f, 100f, 25f); 172 minCoords = new OMV.Vector3(100f, 100f, 25f);
173 maxCoords = new OMV.Vector3(101f, 101f, 26f); 173 maxCoords = new OMV.Vector3(101f, 101f, 26f);
174 minZ = maxZ = 0f; 174 minZ = maxZ = 0f;
175 sizeX = sizeY = 256f; 175 sizeX = pSizeX;
176 sizeY = pSizeY;
176 } 177 }
177 public uint ID; 178 public uint ID;
178 public float[] heightMap; 179 public float[] heightMap;
diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
index 8ccfda5..9b06353 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
@@ -32,6 +32,7 @@ using System.Reflection;
32using Nini.Config; 32using Nini.Config;
33using log4net; 33using log4net;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenMetaverse;
35 36
36namespace OpenSim.Region.Physics.Manager 37namespace OpenSim.Region.Physics.Manager
37{ 38{
@@ -66,7 +67,8 @@ namespace OpenSim.Region.Physics.Manager
66 /// <param name="meshEngineName"></param> 67 /// <param name="meshEngineName"></param>
67 /// <param name="config"></param> 68 /// <param name="config"></param>
68 /// <returns></returns> 69 /// <returns></returns>
69 public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName, IConfigSource config, string regionName) 70 public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName,
71 IConfigSource config, string regionName, Vector3 regionExtent)
70 { 72 {
71 if (String.IsNullOrEmpty(physEngineName)) 73 if (String.IsNullOrEmpty(physEngineName))
72 { 74 {
@@ -94,7 +96,7 @@ namespace OpenSim.Region.Physics.Manager
94 { 96 {
95 m_log.Info("[PHYSICS]: creating " + physEngineName); 97 m_log.Info("[PHYSICS]: creating " + physEngineName);
96 PhysicsScene result = _PhysPlugins[physEngineName].GetScene(regionName); 98 PhysicsScene result = _PhysPlugins[physEngineName].GetScene(regionName);
97 result.Initialise(meshEngine, config); 99 result.Initialise(meshEngine, config, regionExtent);
98 return result; 100 return result;
99 } 101 }
100 else 102 else
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index c93206d..71ad795 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -126,8 +126,17 @@ namespace OpenSim.Region.Physics.Manager
126 } 126 }
127 } 127 }
128 128
129 // Deprecated. Do not use this for new physics engines.
129 public abstract void Initialise(IMesher meshmerizer, IConfigSource config); 130 public abstract void Initialise(IMesher meshmerizer, IConfigSource config);
130 131
132 // For older physics engines that do not implement non-legacy region sizes.
133 // If the physics engine handles the region extent feature, it overrides this function.
134 public virtual void Initialise(IMesher meshmerizer, IConfigSource config, Vector3 regionExtent)
135 {
136 // If not overridden, call the old initialization entry.
137 Initialise(meshmerizer, config);
138 }
139
131 /// <summary> 140 /// <summary>
132 /// Add an avatar 141 /// Add an avatar
133 /// </summary> 142 /// </summary>
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs
index 83732e2..7f616bb 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs
@@ -100,8 +100,8 @@ namespace OpenSim.Region.RegionCombinerModule
100 UUID raytargetid, byte bypassraycast, bool rayendisintersection, bool rezselected, bool removeitem, 100 UUID raytargetid, byte bypassraycast, bool rayendisintersection, bool rezselected, bool removeitem,
101 UUID fromtaskid) 101 UUID fromtaskid)
102 { 102 {
103 int differenceX = (int)m_virtScene.RegionInfo.RegionLocX - (int)m_rootScene.RegionInfo.RegionLocX; 103 int differenceX = (int)m_virtScene.RegionInfo.LegacyRegionLocX - (int)m_rootScene.RegionInfo.LegacyRegionLocX;
104 int differenceY = (int)m_virtScene.RegionInfo.RegionLocY - (int)m_rootScene.RegionInfo.RegionLocY; 104 int differenceY = (int)m_virtScene.RegionInfo.LegacyRegionLocY - (int)m_rootScene.RegionInfo.LegacyRegionLocY;
105 rayend.X += differenceX * (int)Constants.RegionSize; 105 rayend.X += differenceX * (int)Constants.RegionSize;
106 rayend.Y += differenceY * (int)Constants.RegionSize; 106 rayend.Y += differenceY * (int)Constants.RegionSize;
107 raystart.X += differenceX * (int)Constants.RegionSize; 107 raystart.X += differenceX * (int)Constants.RegionSize;
@@ -126,8 +126,8 @@ namespace OpenSim.Region.RegionCombinerModule
126 PrimitiveBaseShape shape, byte bypassraycast, Vector3 raystart, UUID raytargetid, 126 PrimitiveBaseShape shape, byte bypassraycast, Vector3 raystart, UUID raytargetid,
127 byte rayendisintersection) 127 byte rayendisintersection)
128 { 128 {
129 int differenceX = (int)m_virtScene.RegionInfo.RegionLocX - (int)m_rootScene.RegionInfo.RegionLocX; 129 int differenceX = (int)m_virtScene.RegionInfo.LegacyRegionLocX - (int)m_rootScene.RegionInfo.LegacyRegionLocX;
130 int differenceY = (int)m_virtScene.RegionInfo.RegionLocY - (int)m_rootScene.RegionInfo.RegionLocY; 130 int differenceY = (int)m_virtScene.RegionInfo.LegacyRegionLocY - (int)m_rootScene.RegionInfo.LegacyRegionLocY;
131 rayend.X += differenceX * (int)Constants.RegionSize; 131 rayend.X += differenceX * (int)Constants.RegionSize;
132 rayend.Y += differenceY * (int)Constants.RegionSize; 132 rayend.Y += differenceY * (int)Constants.RegionSize;
133 raystart.X += differenceX * (int)Constants.RegionSize; 133 raystart.X += differenceX * (int)Constants.RegionSize;
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
index 7127c73..3f835a4 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -246,8 +246,8 @@ namespace OpenSim.Region.RegionCombinerModule
246 newConn.RegionScene = scene; 246 newConn.RegionScene = scene;
247 newConn.RegionLandChannel = scene.LandChannel; 247 newConn.RegionLandChannel = scene.LandChannel;
248 newConn.RegionId = scene.RegionInfo.originRegionID; 248 newConn.RegionId = scene.RegionInfo.originRegionID;
249 newConn.X = scene.RegionInfo.RegionLocX; 249 newConn.X = scene.RegionInfo.LegacyRegionLocX;
250 newConn.Y = scene.RegionInfo.RegionLocY; 250 newConn.Y = scene.RegionInfo.LegacyRegionLocY;
251 newConn.XEnd = (int)Constants.RegionSize; 251 newConn.XEnd = (int)Constants.RegionSize;
252 newConn.YEnd = (int)Constants.RegionSize; 252 newConn.YEnd = (int)Constants.RegionSize;
253 253
@@ -502,11 +502,11 @@ namespace OpenSim.Region.RegionCombinerModule
502 502
503 lock (scene.WestBorders) 503 lock (scene.WestBorders)
504 { 504 {
505 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West 505 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.LegacyRegionLocX - rootConn.RegionScene.RegionInfo.LegacyRegionLocX) * (int)Constants.RegionSize); //auto teleport West
506 506
507 // Trigger auto teleport to root region 507 // Trigger auto teleport to root region
508 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; 508 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.LegacyRegionLocX;
509 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; 509 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.LegacyRegionLocY;
510 } 510 }
511 511
512 // Reset Terrain.. since terrain loads before we get here, we need to load 512 // Reset Terrain.. since terrain loads before we get here, we need to load
@@ -564,9 +564,9 @@ namespace OpenSim.Region.RegionCombinerModule
564 564
565 lock (scene.SouthBorders) 565 lock (scene.SouthBorders)
566 { 566 {
567 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south 567 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.LegacyRegionLocY - rootConn.RegionScene.RegionInfo.LegacyRegionLocY) * (int)Constants.RegionSize); //auto teleport south
568 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; 568 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.LegacyRegionLocX;
569 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; 569 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.LegacyRegionLocY;
570 } 570 }
571 571
572 // Reset Terrain.. since terrain normally loads first. 572 // Reset Terrain.. since terrain normally loads first.
@@ -636,9 +636,9 @@ namespace OpenSim.Region.RegionCombinerModule
636 636
637 lock (scene.SouthBorders) 637 lock (scene.SouthBorders)
638 { 638 {
639 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south 639 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.LegacyRegionLocY - rootConn.RegionScene.RegionInfo.LegacyRegionLocY) * (int)Constants.RegionSize); //auto teleport south
640 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; 640 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.LegacyRegionLocX;
641 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; 641 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.LegacyRegionLocY;
642 } 642 }
643 643
644 lock (rootConn.RegionScene.EastBorders) 644 lock (rootConn.RegionScene.EastBorders)
@@ -657,9 +657,9 @@ namespace OpenSim.Region.RegionCombinerModule
657 657
658 lock (scene.WestBorders) 658 lock (scene.WestBorders)
659 { 659 {
660 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West 660 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.LegacyRegionLocX - rootConn.RegionScene.RegionInfo.LegacyRegionLocX) * (int)Constants.RegionSize); //auto teleport West
661 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; 661 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.LegacyRegionLocX;
662 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; 662 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.LegacyRegionLocY;
663 } 663 }
664 664
665 /* 665 /*
diff --git a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
index fba51d2..62a3a91 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
@@ -64,12 +64,12 @@ namespace OpenSim.Region.RegionCombinerModule
64 /// <summary> 64 /// <summary>
65 /// The X meters position of this connection. 65 /// The X meters position of this connection.
66 /// </summary> 66 /// </summary>
67 public uint PosX { get { return X * Constants.RegionSize; } } 67 public uint PosX { get { return Util.RegionToWorldLoc(X); } }
68 68
69 /// <summary> 69 /// <summary>
70 /// The Y meters co-ordinate of this connection. 70 /// The Y meters co-ordinate of this connection.
71 /// </summary> 71 /// </summary>
72 public uint PosY { get { return Y * Constants.RegionSize; } } 72 public uint PosY { get { return Util.RegionToWorldLoc(Y); } }
73 73
74 /// <summary> 74 /// <summary>
75 /// The size of the megaregion in meters. 75 /// The size of the megaregion in meters.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 5663048..f46bdf3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2107,7 +2107,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2107 // 2107 //
2108 // This workaround is to prevent silent failure of this function. 2108 // This workaround is to prevent silent failure of this function.
2109 // According to the specification on the SL Wiki, providing a position outside of the 2109 // According to the specification on the SL Wiki, providing a position outside of the
2110 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) 2110 if (pos.x < 0 || pos.x > World.RegionInfo.RegionSizeX || pos.y < 0 || pos.y > World.RegionInfo.RegionSizeY)
2111 { 2111 {
2112 return 0; 2112 return 0;
2113 } 2113 }
@@ -2117,9 +2117,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2117 m_host.ParentGroup.IsAttachment || // return FALSE if attachment 2117 m_host.ParentGroup.IsAttachment || // return FALSE if attachment
2118 ( 2118 (
2119 pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. 2119 pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region.
2120 pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. 2120 pos.x > (World.RegionInfo.RegionSizeX + 10) || // return FALSE if more than 10 meters into a east-adjacent region.
2121 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. 2121 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region.
2122 pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. 2122 pos.y > (World.RegionInfo.RegionSizeY + 10) || // return FALSE if more than 10 meters into a north-adjacent region.
2123 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m 2123 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m
2124 ) 2124 )
2125 ) 2125 )
@@ -4244,10 +4244,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4244 DataserverPlugin.RegisterRequest(m_host.LocalId, 4244 DataserverPlugin.RegisterRequest(m_host.LocalId,
4245 m_item.ItemID, item.AssetID.ToString()); 4245 m_item.ItemID, item.AssetID.ToString());
4246 4246
4247 Vector3 region = new Vector3( 4247 Vector3 region = new Vector3(World.RegionInfo.RegionWorldLocX, World.RegionInfo.RegionWorldLocY, 0);
4248 World.RegionInfo.RegionLocX * Constants.RegionSize,
4249 World.RegionInfo.RegionLocY * Constants.RegionSize,
4250 0);
4251 4248
4252 World.AssetService.Get(item.AssetID.ToString(), this, 4249 World.AssetService.Get(item.AssetID.ToString(), this,
4253 delegate(string i, object sender, AssetBase a) 4250 delegate(string i, object sender, AssetBase a)
@@ -5481,7 +5478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5481 public LSL_Vector llGetRegionCorner() 5478 public LSL_Vector llGetRegionCorner()
5482 { 5479 {
5483 m_host.AddScriptLPS(1); 5480 m_host.AddScriptLPS(1);
5484 return new LSL_Vector(World.RegionInfo.RegionLocX * Constants.RegionSize, World.RegionInfo.RegionLocY * Constants.RegionSize, 0); 5481 return new LSL_Vector(World.RegionInfo.RegionWorldLocX, World.RegionInfo.RegionWorldLocY, 0);
5485 } 5482 }
5486 5483
5487 /// <summary> 5484 /// <summary>
@@ -5628,7 +5625,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5628 LSL_Float mag; 5625 LSL_Float mag;
5629 if (dir.x > 0) 5626 if (dir.x > 0)
5630 { 5627 {
5631 mag = (Constants.RegionSize - pos.x) / dir.x; 5628 mag = (World.RegionInfo.RegionSizeX - pos.x) / dir.x;
5632 } 5629 }
5633 else 5630 else
5634 { 5631 {
@@ -5639,7 +5636,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5639 5636
5640 edge.y = pos.y + (dir.y * mag); 5637 edge.y = pos.y + (dir.y * mag);
5641 5638
5642 if (edge.y > Constants.RegionSize || edge.y < 0) 5639 if (edge.y > World.RegionInfo.RegionSizeY || edge.y < 0)
5643 { 5640 {
5644 // Y goes out of bounds first 5641 // Y goes out of bounds first
5645 edge.y = dir.y / Math.Abs(dir.y); 5642 edge.y = dir.y / Math.Abs(dir.y);
@@ -5654,8 +5651,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5654 5651
5655 List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID); 5652 List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID);
5656 5653
5657 uint neighborX = World.RegionInfo.RegionLocX + (uint)dir.x; 5654 uint neighborX = World.RegionInfo.LegacyRegionLocX + (uint)dir.x;
5658 uint neighborY = World.RegionInfo.RegionLocY + (uint)dir.y; 5655 uint neighborY = World.RegionInfo.LegacyRegionLocY + (uint)dir.y;
5659 5656
5660 foreach (GridRegion sri in neighbors) 5657 foreach (GridRegion sri in neighbors)
5661 { 5658 {
@@ -10770,7 +10767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10770 httpHeaders["X-SecondLife-Shard"] = shard; 10767 httpHeaders["X-SecondLife-Shard"] = shard;
10771 httpHeaders["X-SecondLife-Object-Name"] = m_host.Name; 10768 httpHeaders["X-SecondLife-Object-Name"] = m_host.Name;
10772 httpHeaders["X-SecondLife-Object-Key"] = m_host.UUID.ToString(); 10769 httpHeaders["X-SecondLife-Object-Key"] = m_host.UUID.ToString();
10773 httpHeaders["X-SecondLife-Region"] = string.Format("{0} ({1}, {2})", regionInfo.RegionName, regionInfo.RegionLocX, regionInfo.RegionLocY); 10770 httpHeaders["X-SecondLife-Region"] = string.Format("{0} ({1}, {2})", regionInfo.RegionName, regionInfo.LegacyRegionLocX, regionInfo.LegacyRegionLocY);
10774 httpHeaders["X-SecondLife-Local-Position"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", position.X, position.Y, position.Z); 10771 httpHeaders["X-SecondLife-Local-Position"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", position.X, position.Y, position.Z);
10775 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); 10772 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z);
10776 httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W); 10773 httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index f4d5562..4fb0856 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -450,7 +450,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
450 { 450 {
451 m_host.AddScriptLPS(1); 451 m_host.AddScriptLPS(1);
452 452
453 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0) 453 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0)
454 OSSLError("osSetTerrainHeight: Coordinate out of bounds"); 454 OSSLError("osSetTerrainHeight: Coordinate out of bounds");
455 455
456 if (World.Permissions.CanTerraformLand(m_host.OwnerID, new Vector3(x, y, 0))) 456 if (World.Permissions.CanTerraformLand(m_host.OwnerID, new Vector3(x, y, 0)))
@@ -480,7 +480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
480 private LSL_Float GetTerrainHeight(int x, int y) 480 private LSL_Float GetTerrainHeight(int x, int y)
481 { 481 {
482 m_host.AddScriptLPS(1); 482 m_host.AddScriptLPS(1);
483 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0) 483 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0)
484 OSSLError("osGetTerrainHeight: Coordinate out of bounds"); 484 OSSLError("osGetTerrainHeight: Coordinate out of bounds");
485 485
486 return World.Heightmap[x, y]; 486 return World.Heightmap[x, y];
@@ -814,7 +814,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
814 private void TeleportAgent(string agent, int regionX, int regionY, 814 private void TeleportAgent(string agent, int regionX, int regionY,
815 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) 815 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions)
816 { 816 {
817 ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize)); 817 // ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize));
818 ulong regionHandle = Util.RegionWorldLocToHandle(Util.RegionToWorldLoc((uint)regionX), Util.RegionToWorldLoc((uint)regionY));
818 819
819 m_host.AddScriptLPS(1); 820 m_host.AddScriptLPS(1);
820 UUID agentId = new UUID(); 821 UUID agentId = new UUID();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index c9902e4..e3f3fc7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -721,8 +721,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
721 Position.y = ((int)Constants.RegionSize - 1); 721 Position.y = ((int)Constants.RegionSize - 1);
722 if (Position.y < 0) 722 if (Position.y < 0)
723 Position.y = 0; 723 Position.y = 0;
724 if (Position.z > 768) 724 if (Position.z > Constants.RegionHeight)
725 Position.z = 768; 725 Position.z = Constants.RegionHeight;
726 if (Position.z < 0) 726 if (Position.z < 0)
727 Position.z = 0; 727 Position.z = 0;
728 prim.OSSL.llSetPos(Position); 728 prim.OSSL.llSetPos(Position);
diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs
index d438fc7..4d1729e 100644
--- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs
+++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs
@@ -116,9 +116,9 @@ namespace OpenSim.Server.Handlers.MapImage
116 httpResponse.StatusCode = (int)OSHttpStatusCode.ClientErrorBadRequest; 116 httpResponse.StatusCode = (int)OSHttpStatusCode.ClientErrorBadRequest;
117 return FailureResult("Bad request."); 117 return FailureResult("Bad request.");
118 } 118 }
119 int x = 0, y = 0; 119 uint x = 0, y = 0;
120 Int32.TryParse(request["X"].ToString(), out x); 120 UInt32.TryParse(request["X"].ToString(), out x);
121 Int32.TryParse(request["Y"].ToString(), out y); 121 UInt32.TryParse(request["Y"].ToString(), out y);
122 122
123 m_log.DebugFormat("[MAP ADD SERVER CONNECTOR]: Received map data for region at {0}-{1}", x, y); 123 m_log.DebugFormat("[MAP ADD SERVER CONNECTOR]: Received map data for region at {0}-{1}", x, y);
124 124
@@ -130,7 +130,7 @@ namespace OpenSim.Server.Handlers.MapImage
130 if (m_GridService != null) 130 if (m_GridService != null)
131 { 131 {
132 System.Net.IPAddress ipAddr = GetCallerIP(httpRequest); 132 System.Net.IPAddress ipAddr = GetCallerIP(httpRequest);
133 GridRegion r = m_GridService.GetRegionByPosition(UUID.Zero, x * (int)Constants.RegionSize, y * (int)Constants.RegionSize); 133 GridRegion r = m_GridService.GetRegionByPosition(UUID.Zero, (int)Util.RegionToWorldLoc(x), (int)Util.RegionToWorldLoc(y));
134 if (r != null) 134 if (r != null)
135 { 135 {
136 if (r.ExternalEndPoint.Address.ToString() != ipAddr.ToString()) 136 if (r.ExternalEndPoint.Address.ToString() != ipAddr.ToString())
@@ -151,7 +151,7 @@ namespace OpenSim.Server.Handlers.MapImage
151 byte[] data = Convert.FromBase64String(request["DATA"].ToString()); 151 byte[] data = Convert.FromBase64String(request["DATA"].ToString());
152 152
153 string reason = string.Empty; 153 string reason = string.Empty;
154 bool result = m_MapService.AddMapTile(x, y, data, out reason); 154 bool result = m_MapService.AddMapTile((int)x, (int)y, data, out reason);
155 155
156 if (result) 156 if (result)
157 return SuccessResult(); 157 return SuccessResult();
diff --git a/OpenSim/Services/Connectors/Land/LandServicesConnector.cs b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs
index 30a73a4..644331a 100644
--- a/OpenSim/Services/Connectors/Land/LandServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs
@@ -78,7 +78,7 @@ namespace OpenSim.Services.Connectors
78 try 78 try
79 { 79 {
80 uint xpos = 0, ypos = 0; 80 uint xpos = 0, ypos = 0;
81 Utils.LongToUInts(regionHandle, out xpos, out ypos); 81 Util.RegionHandleToWorldLoc(regionHandle, out xpos, out ypos);
82 GridRegion info = m_GridService.GetRegionByPosition(scopeID, (int)xpos, (int)ypos); 82 GridRegion info = m_GridService.GetRegionByPosition(scopeID, (int)xpos, (int)ypos);
83 if (info != null) // just to be sure 83 if (info != null) // just to be sure
84 { 84 {
diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
index 774fe2a..beead97 100644
--- a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
@@ -69,7 +69,7 @@ namespace OpenSim.Services.Connectors
69 public virtual GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) 69 public virtual GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
70 { 70 {
71 uint x = 0, y = 0; 71 uint x = 0, y = 0;
72 Utils.LongToUInts(regionHandle, out x, out y); 72 Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
73 GridRegion regInfo = m_GridService.GetRegionByPosition(thisRegion.ScopeID, (int)x, (int)y); 73 GridRegion regInfo = m_GridService.GetRegionByPosition(thisRegion.ScopeID, (int)x, (int)y);
74 if ((regInfo != null) && 74 if ((regInfo != null) &&
75 // Don't remote-call this instance; that's a startup hickup 75 // Don't remote-call this instance; that's a startup hickup
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
index b999509..71334ee 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
@@ -201,8 +201,8 @@ namespace OpenSim.Services.Connectors.SimianGrid
201 NameValueCollection requestArgs = new NameValueCollection 201 NameValueCollection requestArgs = new NameValueCollection
202 { 202 {
203 { "RequestMethod", "xAddMapTile" }, 203 { "RequestMethod", "xAddMapTile" },
204 { "X", scene.RegionInfo.RegionLocX.ToString() }, 204 { "X", scene.RegionInfo.LegacyRegionLocX.ToString() },
205 { "Y", scene.RegionInfo.RegionLocY.ToString() }, 205 { "Y", scene.RegionInfo.LegacyRegionLocY.ToString() },
206 { "ContentType", "image/png" }, 206 { "ContentType", "image/png" },
207 { "EncodedData", System.Convert.ToBase64String(pngData) } 207 { "EncodedData", System.Convert.ToBase64String(pngData) }
208 }; 208 };
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs b/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs
index 504fcaf..2cbf967 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs
@@ -100,6 +100,11 @@ namespace OpenSim.Services.Connectors
100 return m_database.LoadObjects(regionUUID); 100 return m_database.LoadObjects(regionUUID);
101 } 101 }
102 102
103 public void StoreTerrain(TerrainData terrain, UUID regionID)
104 {
105 m_database.StoreTerrain(terrain, regionID);
106 }
107
103 public void StoreTerrain(double[,] terrain, UUID regionID) 108 public void StoreTerrain(double[,] terrain, UUID regionID)
104 { 109 {
105 m_database.StoreTerrain(terrain, regionID); 110 m_database.StoreTerrain(terrain, regionID);
@@ -110,6 +115,11 @@ namespace OpenSim.Services.Connectors
110 return m_database.LoadTerrain(regionID); 115 return m_database.LoadTerrain(regionID);
111 } 116 }
112 117
118 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
119 {
120 return m_database.LoadTerrain(regionID, pSizeX, pSizeY, pSizeZ);
121 }
122
113 public void StoreLandObject(ILandObject Parcel) 123 public void StoreLandObject(ILandObject Parcel)
114 { 124 {
115 m_database.StoreLandObject(Parcel); 125 m_database.StoreLandObject(Parcel);
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index e72b7f9..aa7ffc1 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -347,6 +347,11 @@ namespace OpenSim.Services.GridService
347 return null; 347 return null;
348 } 348 }
349 349
350 // Get a region given its base coordinates.
351 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
352 // be the base coordinate of the region.
353 // The snapping is technically unnecessary but is harmless because regions are always
354 // multiples of the legacy region size (256).
350 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 355 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
351 { 356 {
352 int snapX = (int)(x / Constants.RegionSize) * (int)Constants.RegionSize; 357 int snapX = (int)(x / Constants.RegionSize) * (int)Constants.RegionSize;
@@ -441,6 +446,8 @@ namespace OpenSim.Services.GridService
441 RegionData rdata = new RegionData(); 446 RegionData rdata = new RegionData();
442 rdata.posX = (int)rinfo.RegionLocX; 447 rdata.posX = (int)rinfo.RegionLocX;
443 rdata.posY = (int)rinfo.RegionLocY; 448 rdata.posY = (int)rinfo.RegionLocY;
449 rdata.sizeX = rinfo.RegionSizeX;
450 rdata.sizeY = rinfo.RegionSizeY;
444 rdata.RegionID = rinfo.RegionID; 451 rdata.RegionID = rinfo.RegionID;
445 rdata.RegionName = rinfo.RegionName; 452 rdata.RegionName = rinfo.RegionName;
446 rdata.Data = rinfo.ToKeyValuePairs(); 453 rdata.Data = rinfo.ToKeyValuePairs();
@@ -454,6 +461,8 @@ namespace OpenSim.Services.GridService
454 GridRegion rinfo = new GridRegion(rdata.Data); 461 GridRegion rinfo = new GridRegion(rdata.Data);
455 rinfo.RegionLocX = rdata.posX; 462 rinfo.RegionLocX = rdata.posX;
456 rinfo.RegionLocY = rdata.posY; 463 rinfo.RegionLocY = rdata.posY;
464 rinfo.RegionSizeX = rdata.sizeX;
465 rinfo.RegionSizeY = rdata.sizeY;
457 rinfo.RegionID = rdata.RegionID; 466 rinfo.RegionID = rdata.RegionID;
458 rinfo.RegionName = rdata.RegionName; 467 rinfo.RegionName = rdata.RegionName;
459 rinfo.ScopeID = rdata.ScopeID; 468 rinfo.ScopeID = rdata.ScopeID;
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs
index 88ac5b3..e1a3cef 100644
--- a/OpenSim/Services/Interfaces/IGridService.cs
+++ b/OpenSim/Services/Interfaces/IGridService.cs
@@ -168,12 +168,12 @@ namespace OpenSim.Services.Interfaces
168 /// <summary> 168 /// <summary>
169 /// The co-ordinate of this region. 169 /// The co-ordinate of this region.
170 /// </summary> 170 /// </summary>
171 public int RegionCoordX { get { return RegionLocX / (int)Constants.RegionSize; } } 171 public int RegionCoordX { get { return (int)Util.WorldToRegionLoc((uint)RegionLocX); } }
172 172
173 /// <summary> 173 /// <summary>
174 /// The co-ordinate of this region 174 /// The co-ordinate of this region
175 /// </summary> 175 /// </summary>
176 public int RegionCoordY { get { return RegionLocY / (int)Constants.RegionSize; } } 176 public int RegionCoordY { get { return (int)Util.WorldToRegionLoc((uint)RegionLocY); } }
177 177
178 /// <summary> 178 /// <summary>
179 /// The location of this region in meters. 179 /// The location of this region in meters.
@@ -185,6 +185,9 @@ namespace OpenSim.Services.Interfaces
185 } 185 }
186 protected int m_regionLocX; 186 protected int m_regionLocX;
187 187
188 public int RegionSizeX { get; set; }
189 public int RegionSizeY { get; set; }
190
188 /// <summary> 191 /// <summary>
189 /// The location of this region in meters. 192 /// The location of this region in meters.
190 /// </summary> 193 /// </summary>
@@ -222,6 +225,8 @@ namespace OpenSim.Services.Interfaces
222 { 225 {
223 m_regionLocX = regionLocX; 226 m_regionLocX = regionLocX;
224 m_regionLocY = regionLocY; 227 m_regionLocY = regionLocY;
228 RegionSizeX = (int)Constants.RegionSize;
229 RegionSizeY = (int)Constants.RegionSize;
225 230
226 m_internalEndPoint = internalEndPoint; 231 m_internalEndPoint = internalEndPoint;
227 m_externalHostName = externalUri; 232 m_externalHostName = externalUri;
@@ -231,6 +236,8 @@ namespace OpenSim.Services.Interfaces
231 { 236 {
232 m_regionLocX = regionLocX; 237 m_regionLocX = regionLocX;
233 m_regionLocY = regionLocY; 238 m_regionLocY = regionLocY;
239 RegionSizeX = (int)Constants.RegionSize;
240 RegionSizeY = (int)Constants.RegionSize;
234 241
235 m_externalHostName = externalUri; 242 m_externalHostName = externalUri;
236 243
@@ -239,15 +246,19 @@ namespace OpenSim.Services.Interfaces
239 246
240 public GridRegion(uint xcell, uint ycell) 247 public GridRegion(uint xcell, uint ycell)
241 { 248 {
242 m_regionLocX = (int)(xcell * Constants.RegionSize); 249 m_regionLocX = (int)Util.RegionToWorldLoc(xcell);
243 m_regionLocY = (int)(ycell * Constants.RegionSize); 250 m_regionLocY = (int)Util.RegionToWorldLoc(ycell);
251 RegionSizeX = (int)Constants.RegionSize;
252 RegionSizeY = (int)Constants.RegionSize;
244 } 253 }
245 254
246 public GridRegion(RegionInfo ConvertFrom) 255 public GridRegion(RegionInfo ConvertFrom)
247 { 256 {
248 m_regionName = ConvertFrom.RegionName; 257 m_regionName = ConvertFrom.RegionName;
249 m_regionLocX = (int)(ConvertFrom.RegionLocX * Constants.RegionSize); 258 m_regionLocX = (int)(ConvertFrom.RegionWorldLocX);
250 m_regionLocY = (int)(ConvertFrom.RegionLocY * Constants.RegionSize); 259 m_regionLocY = (int)(ConvertFrom.RegionWorldLocY);
260 RegionSizeX = (int)ConvertFrom.RegionSizeX;
261 RegionSizeY = (int)ConvertFrom.RegionSizeY;
251 m_internalEndPoint = ConvertFrom.InternalEndPoint; 262 m_internalEndPoint = ConvertFrom.InternalEndPoint;
252 m_externalHostName = ConvertFrom.ExternalHostName; 263 m_externalHostName = ConvertFrom.ExternalHostName;
253 m_httpPort = ConvertFrom.HttpPort; 264 m_httpPort = ConvertFrom.HttpPort;
@@ -266,6 +277,8 @@ namespace OpenSim.Services.Interfaces
266 m_regionName = ConvertFrom.RegionName; 277 m_regionName = ConvertFrom.RegionName;
267 m_regionLocX = ConvertFrom.RegionLocX; 278 m_regionLocX = ConvertFrom.RegionLocX;
268 m_regionLocY = ConvertFrom.RegionLocY; 279 m_regionLocY = ConvertFrom.RegionLocY;
280 RegionSizeX = ConvertFrom.RegionSizeX;
281 RegionSizeY = ConvertFrom.RegionSizeY;
269 m_internalEndPoint = ConvertFrom.InternalEndPoint; 282 m_internalEndPoint = ConvertFrom.InternalEndPoint;
270 m_externalHostName = ConvertFrom.ExternalHostName; 283 m_externalHostName = ConvertFrom.ExternalHostName;
271 m_httpPort = ConvertFrom.HttpPort; 284 m_httpPort = ConvertFrom.HttpPort;
@@ -373,6 +386,8 @@ namespace OpenSim.Services.Interfaces
373 kvp["uuid"] = RegionID.ToString(); 386 kvp["uuid"] = RegionID.ToString();
374 kvp["locX"] = RegionLocX.ToString(); 387 kvp["locX"] = RegionLocX.ToString();
375 kvp["locY"] = RegionLocY.ToString(); 388 kvp["locY"] = RegionLocY.ToString();
389 kvp["sizeX"] = RegionSizeX.ToString();
390 kvp["sizeY"] = RegionSizeY.ToString();
376 kvp["regionName"] = RegionName; 391 kvp["regionName"] = RegionName;
377 kvp["serverIP"] = ExternalHostName; //ExternalEndPoint.Address.ToString(); 392 kvp["serverIP"] = ExternalHostName; //ExternalEndPoint.Address.ToString();
378 kvp["serverHttpPort"] = HttpPort.ToString(); 393 kvp["serverHttpPort"] = HttpPort.ToString();
@@ -399,6 +414,12 @@ namespace OpenSim.Services.Interfaces
399 if (kvp.ContainsKey("locY")) 414 if (kvp.ContainsKey("locY"))
400 RegionLocY = Convert.ToInt32((string)kvp["locY"]); 415 RegionLocY = Convert.ToInt32((string)kvp["locY"]);
401 416
417 if (kvp.ContainsKey("sizeX"))
418 RegionSizeX = Convert.ToInt32((string)kvp["sizeX"]);
419
420 if (kvp.ContainsKey("sizeY"))
421 RegionSizeY = Convert.ToInt32((string)kvp["sizeY"]);
422
402 if (kvp.ContainsKey("regionName")) 423 if (kvp.ContainsKey("regionName"))
403 RegionName = (string)kvp["regionName"]; 424 RegionName = (string)kvp["regionName"];
404 425
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index 6ab5258..ff51f09 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -254,11 +254,12 @@ namespace OpenSim.Services.LLLoginService
254 Currency = currency; 254 Currency = currency;
255 ClassifiedFee = classifiedFee; 255 ClassifiedFee = classifiedFee;
256 256
257
258 FillOutHomeData(pinfo, home); 257 FillOutHomeData(pinfo, home);
259 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); 258 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z);
260 259
261 FillOutRegionData(destination); 260 FillOutRegionData(destination);
261 m_log.DebugFormat("[LOGIN RESPONSE] LLLoginResponse create. sizeX={0}, sizeY={1}", RegionSizeX, RegionSizeY);
262 Util.PrintCallStack();
262 263
263 FillOutSeedCap(aCircuit, destination, clientIP); 264 FillOutSeedCap(aCircuit, destination, clientIP);
264 265
@@ -361,7 +362,9 @@ namespace OpenSim.Services.LLLoginService
361 362
362 private void FillOutHomeData(GridUserInfo pinfo, GridRegion home) 363 private void FillOutHomeData(GridUserInfo pinfo, GridRegion home)
363 { 364 {
364 int x = 1000 * (int)Constants.RegionSize, y = 1000 * (int)Constants.RegionSize; 365 // int x = 1000 * (int)Constants.RegionSize, y = 1000 * (int)Constants.RegionSize;
366 int x = (int)Util.RegionToWorldLoc(1000);
367 int y = (int)Util.RegionToWorldLoc(1000);
365 if (home != null) 368 if (home != null)
366 { 369 {
367 x = home.RegionLocX; 370 x = home.RegionLocX;
@@ -384,6 +387,8 @@ namespace OpenSim.Services.LLLoginService
384 SimPort = (uint)endPoint.Port; 387 SimPort = (uint)endPoint.Port;
385 RegionX = (uint)destination.RegionLocX; 388 RegionX = (uint)destination.RegionLocX;
386 RegionY = (uint)destination.RegionLocY; 389 RegionY = (uint)destination.RegionLocY;
390 RegionSizeX = destination.RegionSizeX;
391 RegionSizeY = destination.RegionSizeY;
387 } 392 }
388 393
389 private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient) 394 private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient)
@@ -433,10 +438,23 @@ namespace OpenSim.Services.LLLoginService
433 ErrorReason = "key"; 438 ErrorReason = "key";
434 welcomeMessage = "Welcome to OpenSim!"; 439 welcomeMessage = "Welcome to OpenSim!";
435 seedCapability = String.Empty; 440 seedCapability = String.Empty;
436 home = "{'region_handle':[r" + (1000*Constants.RegionSize).ToString() + ",r" + (1000*Constants.RegionSize).ToString() + "], 'position':[r" + 441 home = "{'region_handle':[r"
437 userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" + 442 + Util.RegionToWorldLoc(1000).ToString()
438 userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" + 443 + ",r"
439 userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}"; 444 + Util.RegionToWorldLoc(1000).ToString()
445 + "], 'position':[r"
446 + userProfile.homepos.X.ToString()
447 + ",r"
448 + userProfile.homepos.Y.ToString()
449 + ",r"
450 + userProfile.homepos.Z.ToString()
451 + "], 'look_at':[r"
452 + userProfile.homelookat.X.ToString()
453 + ",r"
454 + userProfile.homelookat.Y.ToString()
455 + ",r"
456 + userProfile.homelookat.Z.ToString()
457 + "]}";
440 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]"; 458 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]";
441 RegionX = (uint) 255232; 459 RegionX = (uint) 255232;
442 RegionY = (uint) 254976; 460 RegionY = (uint) 254976;
@@ -529,6 +547,9 @@ namespace OpenSim.Services.LLLoginService
529 responseData["message"] = welcomeMessage; 547 responseData["message"] = welcomeMessage;
530 responseData["region_x"] = (Int32)(RegionX); 548 responseData["region_x"] = (Int32)(RegionX);
531 responseData["region_y"] = (Int32)(RegionY); 549 responseData["region_y"] = (Int32)(RegionY);
550 responseData["region_size_x"] = (Int32)RegionSizeX;
551 responseData["region_size_y"] = (Int32)RegionSizeY;
552 m_log.DebugFormat("[LOGIN RESPONSE] returning sizeX={0}, sizeY={1}", RegionSizeX, RegionSizeY);
532 553
533 if (searchURL != String.Empty) 554 if (searchURL != String.Empty)
534 responseData["search"] = searchURL; 555 responseData["search"] = searchURL;
@@ -918,6 +939,9 @@ namespace OpenSim.Services.LLLoginService
918 set { regionY = value; } 939 set { regionY = value; }
919 } 940 }
920 941
942 public int RegionSizeX { get; private set; }
943 public int RegionSizeY { get; private set; }
944
921 public string SunTexture 945 public string SunTexture
922 { 946 {
923 get { return sunTexture; } 947 get { return sunTexture; }
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index fe43582..150c2c0 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -50,6 +50,8 @@ namespace OpenSim.Services.LLLoginService
50 public class LLLoginService : ILoginService 50 public class LLLoginService : ILoginService
51 { 51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 private static readonly string LogHeader = "[LLOGIN SERVICE]";
54
53 private static bool Initialized = false; 55 private static bool Initialized = false;
54 56
55 protected IUserAccountService m_UserAccountService; 57 protected IUserAccountService m_UserAccountService;
@@ -389,6 +391,7 @@ namespace OpenSim.Services.LLLoginService
389 if (guinfo == null) 391 if (guinfo == null)
390 { 392 {
391 // something went wrong, make something up, so that we don't have to test this anywhere else 393 // something went wrong, make something up, so that we don't have to test this anywhere else
394 m_log.DebugFormat("{0} Failed to fetch GridUserInfo. Creating empty GridUserInfo as home", LogHeader);
392 guinfo = new GridUserInfo(); 395 guinfo = new GridUserInfo();
393 guinfo.LastPosition = guinfo.HomePosition = new Vector3(128, 128, 30); 396 guinfo.LastPosition = guinfo.HomePosition = new Vector3(128, 128, 30);
394 } 397 }
@@ -681,7 +684,7 @@ namespace OpenSim.Services.LLLoginService
681 private GridRegion FindAlternativeRegion(UUID scopeID) 684 private GridRegion FindAlternativeRegion(UUID scopeID)
682 { 685 {
683 List<GridRegion> hyperlinks = null; 686 List<GridRegion> hyperlinks = null;
684 List<GridRegion> regions = m_GridService.GetFallbackRegions(scopeID, 1000 * (int)Constants.RegionSize, 1000 * (int)Constants.RegionSize); 687 List<GridRegion> regions = m_GridService.GetFallbackRegions(scopeID, (int)Util.RegionToWorldLoc(1000), (int)Util.RegionToWorldLoc(1000));
685 if (regions != null && regions.Count > 0) 688 if (regions != null && regions.Count > 0)
686 { 689 {
687 hyperlinks = m_GridService.GetHyperlinks(scopeID); 690 hyperlinks = m_GridService.GetHyperlinks(scopeID);
diff --git a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
index 52a17e7..049200c 100644
--- a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
@@ -69,9 +69,7 @@ namespace OpenSim.Tests.Common
69 tc.OnTestClientInformClientOfNeighbour += (neighbourHandle, neighbourExternalEndPoint) => 69 tc.OnTestClientInformClientOfNeighbour += (neighbourHandle, neighbourExternalEndPoint) =>
70 { 70 {
71 uint x, y; 71 uint x, y;
72 Utils.LongToUInts(neighbourHandle, out x, out y); 72 Util.RegionHandleToRegionLoc(neighbourHandle, out x, out y);
73 x /= Constants.RegionSize;
74 y /= Constants.RegionSize;
75 73
76 m_log.DebugFormat( 74 m_log.DebugFormat(
77 "[TEST CLIENT]: Processing inform client of neighbour located at {0},{1} at {2}", 75 "[TEST CLIENT]: Processing inform client of neighbour located at {0},{1} at {2}",
@@ -104,9 +102,7 @@ namespace OpenSim.Tests.Common
104 += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) => 102 += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) =>
105 { 103 {
106 uint x, y; 104 uint x, y;
107 Utils.LongToUInts(regionHandle, out x, out y); 105 Util.RegionHandleToRegionLoc(regionHandle, out x, out y);
108 x /= Constants.RegionSize;
109 y /= Constants.RegionSize;
110 106
111 m_log.DebugFormat( 107 m_log.DebugFormat(
112 "[TEST CLIENT]: Processing send region teleport for destination at {0},{1} at {2}", 108 "[TEST CLIENT]: Processing send region teleport for destination at {0},{1} at {2}",
diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
index 4cdfe98..008f2d0 100644
--- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
@@ -186,8 +186,9 @@ namespace OpenSim.Tests.Common
186 186
187 PhysicsPluginManager physicsPluginManager = new PhysicsPluginManager(); 187 PhysicsPluginManager physicsPluginManager = new PhysicsPluginManager();
188 physicsPluginManager.LoadPluginsFromAssembly("Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll"); 188 physicsPluginManager.LoadPluginsFromAssembly("Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll");
189 Vector3 regionExtent = new Vector3( regInfo.RegionSizeX, regInfo.RegionSizeY, regInfo.RegionSizeZ);
189 testScene.PhysicsScene 190 testScene.PhysicsScene
190 = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test"); 191 = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test", regionExtent);
191 192
192 testScene.RegionInfo.EstateSettings = new EstateSettings(); 193 testScene.RegionInfo.EstateSettings = new EstateSettings();
193 testScene.LoginsEnabled = true; 194 testScene.LoginsEnabled = true;
diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
index ed29c39..5df8e04 100644
--- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
+++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
@@ -69,11 +69,21 @@ namespace OpenSim.Data.Null
69 m_store.StoreTerrain(terrain, regionID); 69 m_store.StoreTerrain(terrain, regionID);
70 } 70 }
71 71
72 public void StoreTerrain(TerrainData terrain, UUID regionID)
73 {
74 m_store.StoreTerrain(terrain, regionID);
75 }
76
72 public double[,] LoadTerrain(UUID regionID) 77 public double[,] LoadTerrain(UUID regionID)
73 { 78 {
74 return m_store.LoadTerrain(regionID); 79 return m_store.LoadTerrain(regionID);
75 } 80 }
76 81
82 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
83 {
84 return m_store.LoadTerrain(regionID, pSizeX, pSizeY, pSizeZ);
85 }
86
77 public void StoreLandObject(ILandObject Parcel) 87 public void StoreLandObject(ILandObject Parcel)
78 { 88 {
79 m_store.StoreLandObject(Parcel); 89 m_store.StoreLandObject(Parcel);
@@ -154,7 +164,7 @@ namespace OpenSim.Data.Null
154 protected Dictionary<UUID, SceneObjectPart> m_sceneObjectParts = new Dictionary<UUID, SceneObjectPart>(); 164 protected Dictionary<UUID, SceneObjectPart> m_sceneObjectParts = new Dictionary<UUID, SceneObjectPart>();
155 protected Dictionary<UUID, ICollection<TaskInventoryItem>> m_primItems 165 protected Dictionary<UUID, ICollection<TaskInventoryItem>> m_primItems
156 = new Dictionary<UUID, ICollection<TaskInventoryItem>>(); 166 = new Dictionary<UUID, ICollection<TaskInventoryItem>>();
157 protected Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>(); 167 protected Dictionary<UUID, TerrainData> m_terrains = new Dictionary<UUID, TerrainData>();
158 protected Dictionary<UUID, LandData> m_landData = new Dictionary<UUID, LandData>(); 168 protected Dictionary<UUID, LandData> m_landData = new Dictionary<UUID, LandData>();
159 169
160 public void Initialise(string dbfile) 170 public void Initialise(string dbfile)
@@ -299,12 +309,17 @@ namespace OpenSim.Data.Null
299 return new List<SceneObjectGroup>(objects.Values); 309 return new List<SceneObjectGroup>(objects.Values);
300 } 310 }
301 311
302 public void StoreTerrain(double[,] ter, UUID regionID) 312 public void StoreTerrain(TerrainData ter, UUID regionID)
303 { 313 {
304 m_terrains[regionID] = ter; 314 m_terrains[regionID] = ter;
305 } 315 }
306 316
307 public double[,] LoadTerrain(UUID regionID) 317 public void StoreTerrain(double[,] ter, UUID regionID)
318 {
319 m_terrains[regionID] = new HeightmapTerrainData(ter);
320 }
321
322 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
308 { 323 {
309 if (m_terrains.ContainsKey(regionID)) 324 if (m_terrains.ContainsKey(regionID))
310 return m_terrains[regionID]; 325 return m_terrains[regionID];
@@ -312,6 +327,14 @@ namespace OpenSim.Data.Null
312 return null; 327 return null;
313 } 328 }
314 329
330 public double[,] LoadTerrain(UUID regionID)
331 {
332 if (m_terrains.ContainsKey(regionID))
333 return m_terrains[regionID].GetDoubles();
334 else
335 return null;
336 }
337
315 public void RemoveLandObject(UUID globalID) 338 public void RemoveLandObject(UUID globalID)
316 { 339 {
317 if (m_landData.ContainsKey(globalID)) 340 if (m_landData.ContainsKey(globalID))