From 9f18e3ba80a6469b7ff03c7cca595a0a3b999592 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 22 Mar 2015 21:53:02 -0700 Subject: Varregion: first cut at removing Border class checks for region crossings. Added Scene.PositionIsInCurrentRegion(pos) to sense when new position needs some crossing work. Many changes made to EntityTransferModule to accomodate new crossing sense logic. --- .../Framework/Interfaces/IRegionCombinerModule.cs | 5 + OpenSim/Region/Framework/Scenes/Scene.cs | 325 ++------------------- .../Region/Framework/Scenes/SceneObjectGroup.cs | 10 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 60 ++-- 5 files changed, 56 insertions(+), 349 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs index e03ac5a..c6f531e 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -55,5 +55,10 @@ namespace OpenSim.Region.Framework.Interfaces /// Currently, will throw an exception if this does not match a root region. /// Vector2 GetSizeOfMegaregion(UUID regionId); + + /// + /// Tests to see of position (relative to the region) is within the megaregion + /// + bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index eb34f55..03270d7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -160,11 +160,6 @@ namespace OpenSim.Region.Framework.Scenes /// public SimStatsReporter StatsReporter { get; private set; } - public List NorthBorders = new List(); - public List EastBorders = new List(); - public List SouthBorders = new List(); - public List WestBorders = new List(); - /// /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a /// PhysicsScene in order to perform collision detection @@ -364,7 +359,6 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Possibly stop other classes being able to manipulate this directly. private SceneGraph m_sceneGraph; - private volatile int m_bordersLocked; private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private volatile bool m_backingup; private Dictionary m_returns = new Dictionary(); @@ -446,18 +440,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_splitRegionID = value; } } - public bool BordersLocked - { - get { return m_bordersLocked == 1; } - set - { - if (value == true) - m_bordersLocked = 1; - else - m_bordersLocked = 0; - } - } - public new float TimeDilation { get { return m_sceneGraph.PhysicsScene.TimeDilation; } @@ -1075,28 +1057,6 @@ namespace OpenSim.Region.Framework.Scenes PeriodicBackup = true; UseBackup = true; - BordersLocked = true; - Border northBorder = new Border(); - northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, RegionInfo.RegionSizeY); //<--- - northBorder.CrossDirection = Cardinals.N; - NorthBorders.Add(northBorder); - - Border southBorder = new Border(); - southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> - southBorder.CrossDirection = Cardinals.S; - SouthBorders.Add(southBorder); - - Border eastBorder = new Border(); - eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, RegionInfo.RegionSizeX); //<--- - eastBorder.CrossDirection = Cardinals.E; - EastBorders.Add(eastBorder); - - Border westBorder = new Border(); - westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> - westBorder.CrossDirection = Cardinals.W; - WestBorders.Add(westBorder); - BordersLocked = false; - m_eventManager = new EventManager(); m_permissions = new ScenePermissions(this); @@ -2611,185 +2571,35 @@ namespace OpenSim.Region.Framework.Scenes EntityTransferModule.Cross(grp, attemptedPosition, silent); } - public Border GetCrossedBorder(Vector3 position, Cardinals gridline) + // Simple test to see if a position is in the current region. + // This test is mostly used to see if a region crossing is necessary. + // Assuming the position is relative to the region so anything outside its bounds. + // Return 'true' if position inside region. + public bool PositionIsInCurrentRegion(Vector3 pos) { - if (BordersLocked) - { - switch (gridline) - { - case Cardinals.N: - lock (NorthBorders) - { - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return b; - } - } - break; - case Cardinals.S: - lock (SouthBorders) - { - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return b; - } - } - - break; - case Cardinals.E: - lock (EastBorders) - { - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return b; - } - } - - break; - case Cardinals.W: - - lock (WestBorders) - { - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return b; - } - } - break; + bool ret = false; + int xx = (int)Math.Floor(pos.X); + int yy = (int)Math.Floor(pos.Y); + if (xx < 0 || yy < 0) + return false; - } + IRegionCombinerModule regionCombinerModule = RequestModuleInterface(); + if (regionCombinerModule == null) + { + // Regular region. Just check for region size + if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) + ret = true; } else { - switch (gridline) - { - case Cardinals.N: - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return b; - } - - break; - case Cardinals.S: - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return b; - } - break; - case Cardinals.E: - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return b; - } - - break; - case Cardinals.W: - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return b; - } - break; - - } + // We're in a mega-region so see if we are still in that larger region + ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); } - return null; - } + return ret; - public bool TestBorderCross(Vector3 position, Cardinals border) - { - if (BordersLocked) - { - switch (border) - { - case Cardinals.N: - lock (NorthBorders) - { - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.E: - lock (EastBorders) - { - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.S: - lock (SouthBorders) - { - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.W: - lock (WestBorders) - { - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - } - } - else - { - switch (border) - { - case Cardinals.N: - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.E: - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.S: - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.W: - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return true; - } - break; - } - } - return false; } - /// /// Called when objects or attachments cross the border, or teleport, between regions. /// @@ -4116,60 +3926,11 @@ namespace OpenSim.Region.Framework.Scenes { // CleanDroppedAttachments(); - if (TestBorderCross(acd.startpos, Cardinals.E)) - { - Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); - acd.startpos.X = crossedBorder.BorderLine.Z - 1; - } - - if (TestBorderCross(acd.startpos, Cardinals.N)) - { - Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N); - acd.startpos.Y = crossedBorder.BorderLine.Z - 1; - } - - //Mitigate http://opensimulator.org/mantis/view.php?id=3522 - // Check if start position is outside of region - // If it is, check the Z start position also.. if not, leave it alone. - if (BordersLocked) - { - lock (EastBorders) - { - if (acd.startpos.X > EastBorders[0].BorderLine.Z) - { - m_log.Warn("FIX AGENT POSITION"); - acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } - lock (NorthBorders) - { - if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) - { - m_log.Warn("FIX Agent POSITION"); - acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } - } else - { - if (acd.startpos.X > EastBorders[0].BorderLine.Z) - { - m_log.Warn("FIX AGENT POSITION"); - acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) - { - m_log.Warn("FIX Agent POSITION"); - acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } + // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking) + if (acd.startpos.X < 0) acd.startpos.X = 1f; + if (acd.startpos.X >= RegionInfo.RegionSizeX) acd.startpos.X = RegionInfo.RegionSizeX - 1f; + if (acd.startpos.Y < 0) acd.startpos.Y = 1f; + if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f; // m_log.DebugFormat( // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", @@ -4883,44 +4644,6 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence sp = GetScenePresence(remoteClient.AgentId); if (sp != null) { - uint regionX = RegionInfo.RegionLocX; - uint regionY = RegionInfo.RegionLocY; - - Utils.LongToUInts(regionHandle, out regionX, out regionY); - - int shiftx = (int) regionX - (int) RegionInfo.RegionLocX * (int)Constants.RegionSize; - int shifty = (int) regionY - (int) RegionInfo.RegionLocY * (int)Constants.RegionSize; - - position.X += shiftx; - position.Y += shifty; - - bool result = false; - - if (TestBorderCross(position,Cardinals.N)) - result = true; - - if (TestBorderCross(position, Cardinals.S)) - result = true; - - if (TestBorderCross(position, Cardinals.E)) - result = true; - - if (TestBorderCross(position, Cardinals.W)) - result = true; - - // bordercross if position is outside of region - - if (!result) - { - regionHandle = RegionInfo.RegionHandle; - } - else - { - // not in this region, undo the shift! - position.X -= shiftx; - position.Y -= shifty; - } - if (EntityTransferModule != null) { EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 89c7a1a..a99e469 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -529,12 +529,10 @@ namespace OpenSim.Region.Framework.Scenes set { Vector3 val = value; - if (Scene != null && !IsAttachmentCheckFull() - && !Scene.LoadingPrims && - (Scene.TestBorderCross(val, Cardinals.E) || - Scene.TestBorderCross(val, Cardinals.W) || - Scene.TestBorderCross(val, Cardinals.N) || - Scene.TestBorderCross(val, Cardinals.S)) + if (Scene != null + && Scene.PositionIsInCurrentRegion(val) + && !IsAttachmentCheckFull() + && !Scene.LoadingPrims ) { if (!inTransit) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 91293c4..8979659 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2979,10 +2979,7 @@ namespace OpenSim.Region.Framework.Scenes { Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); - if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) - || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) - || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) - || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) + if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos)) { ParentGroup.AbsolutePosition = newpos; return; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cd9dcf5..2965903 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1170,18 +1170,6 @@ namespace OpenSim.Region.Framework.Scenes if (ParentID == 0) { - if (m_scene.TestBorderCross(pos, Cardinals.E)) - { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); - pos.X = crossedBorder.BorderLine.Z - 1; - } - - if (m_scene.TestBorderCross(pos, Cardinals.N)) - { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); - pos.Y = crossedBorder.BorderLine.Z - 1; - } - CheckAndAdjustLandingPoint(ref pos); if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) @@ -3867,32 +3855,28 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", // pos2, Name, Scene.Name); - - if( Scene.TestBorderCross(pos2, Cardinals.E) || - Scene.TestBorderCross(pos2, Cardinals.W) || - Scene.TestBorderCross(pos2, Cardinals.N) || - Scene.TestBorderCross(pos2, Cardinals.S) - ) - { - if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero) - { - // we don't have entity transfer module - Vector3 pos = AbsolutePosition; - float px = pos.X; - if (px < 0) - pos.X += Velocity.X * 2; - else if (px > m_scene.RegionInfo.RegionSizeX) - pos.X -= Velocity.X * 2; - - float py = pos.Y; - if (py < 0) - pos.Y += Velocity.Y * 2; - else if (py > m_scene.RegionInfo.RegionSizeY) - pos.Y -= Velocity.Y * 2; - - Velocity = Vector3.Zero; - AbsolutePosition = pos; - } + + if (Scene.PositionIsInCurrentRegion(pos2)) + return; + + if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero) + { + // we don't have entity transfer module + Vector3 pos = AbsolutePosition; + float px = pos.X; + if (px < 0) + pos.X += Velocity.X * 2; + else if (px > m_scene.RegionInfo.RegionSizeX) + pos.X -= Velocity.X * 2; + + float py = pos.Y; + if (py < 0) + pos.Y += Velocity.Y * 2; + else if (py > m_scene.RegionInfo.RegionSizeY) + pos.Y -= Velocity.Y * 2; + + Velocity = Vector3.Zero; + AbsolutePosition = pos; } } -- cgit v1.1 From bedafb8fae9898ef0c5fc6470236ee7244e616a9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 27 Mar 2015 19:32:50 -0700 Subject: varregion: refactor use of 'double heightmap[,]' into references to new class TerrainData and push the implementation from Scene into the database readers and writers. --- .../Framework/Interfaces/ISimulationDataService.cs | 9 + .../Framework/Interfaces/ISimulationDataStore.cs | 10 + .../Region/Framework/Interfaces/ITerrainChannel.cs | 19 +- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- OpenSim/Region/Framework/Scenes/TerrainChannel.cs | 352 ++++++++++++++------- 5 files changed, 284 insertions(+), 110 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index 3e97a7a..13358cb 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs @@ -68,13 +68,22 @@ namespace OpenSim.Region.Framework.Interfaces /// /// HeightField data /// region UUID + void StoreTerrain(TerrainData terrain, UUID regionID); + + // Legacy version kept for downward compabibility void StoreTerrain(double[,] terrain, UUID regionID); /// /// Load the latest terrain revision from region storage /// /// the region UUID + /// the X dimension of the region being filled + /// the Y dimension of the region being filled + /// the Z dimension of the region being filled /// Heightfield data + TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ); + + // Legacy version kept for downward compabibility double[,] LoadTerrain(UUID regionID); void StoreLandObject(ILandObject Parcel); diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index 17bd48b..e09f775 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -79,13 +79,22 @@ namespace OpenSim.Region.Framework.Interfaces /// /// HeightField data /// region UUID + void StoreTerrain(TerrainData terrain, UUID regionID); + + // Legacy version kept for downward compabibility void StoreTerrain(double[,] terrain, UUID regionID); /// /// Load the latest terrain revision from region storage /// /// the region UUID + /// the X dimension of the terrain being filled + /// the Y dimension of the terrain being filled + /// the Z dimension of the terrain being filled /// Heightfield data + TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ); + + // Legacy version kept for downward compabibility double[,] LoadTerrain(UUID regionID); void StoreLandObject(ILandObject Parcel); @@ -136,4 +145,5 @@ namespace OpenSim.Region.Framework.Interfaces void Shutdown(); } + } diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs index e467701..f660b8d 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs @@ -25,13 +25,23 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using OpenSim.Framework; +using OpenMetaverse; + namespace OpenSim.Region.Framework.Interfaces { public interface ITerrainChannel { - int Height { get; } + int Width { get;} // X dimension + int Height { get;} // Y dimension + int Altitude { get;} // Z dimension + double this[int x, int y] { get; set; } - int Width { get; } + + float GetHeightAtXYZ(float x, float y, float z); + + // Return the packaged terrain data for passing into lower levels of communication + TerrainData GetTerrainData(); /// /// Squash the entire heightmap into a single dimensioned array @@ -40,9 +50,14 @@ namespace OpenSim.Region.Framework.Interfaces float[] GetFloatsSerialised(); double[,] GetDoubles(); + + // Check if a location has been updated. Clears the taint flag as a side effect. bool Tainted(int x, int y); + ITerrainChannel MakeCopy(); string SaveToXmlString(); void LoadFromXmlString(string data); + // Merge some terrain into this channel + void Merge(ITerrainChannel newTerrain, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 03270d7..f5458c1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1935,7 +1935,7 @@ namespace OpenSim.Region.Framework.Scenes { try { - double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID); + TerrainData map = SimulationDataService.LoadTerrain(RegionInfo.RegionID, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); if (map == null) { // This should be in the Terrain module, but it isn't because @@ -1946,7 +1946,7 @@ namespace OpenSim.Region.Framework.Scenes m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain); - Heightmap = new TerrainChannel(m_InitialTerrain); + Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); } diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs index b6e0a97..3d563a6 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs @@ -25,14 +25,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; using System; +using System.IO; using System.Text; +using System.Reflection; using System.Xml; -using System.IO; using System.Xml.Serialization; +using OpenSim.Data; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; + +using OpenMetaverse; + +using log4net; + namespace OpenSim.Region.Framework.Scenes { /// @@ -40,140 +47,136 @@ namespace OpenSim.Region.Framework.Scenes /// public class TerrainChannel : ITerrainChannel { - private readonly bool[,] taint; - private double[,] map; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[TERRAIN CHANNEL]"; + protected TerrainData m_terrainData; + + public int Width { get { return m_terrainData.SizeX; } } // X dimension + // Unfortunately, for historical reasons, in this module 'Width' is X and 'Height' is Y + public int Height { get { return m_terrainData.SizeY; } } // Y dimension + public int Altitude { get { return m_terrainData.SizeZ; } } // Y dimension + + // Default, not-often-used builder public TerrainChannel() { - map = new double[Constants.RegionSize, Constants.RegionSize]; - taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; - - PinHeadIsland(); + m_terrainData = new HeightmapTerrainData((int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); + FlatLand(); + // PinHeadIsland(); } - public TerrainChannel(String type) + // Create terrain of given size + public TerrainChannel(int pX, int pY) { - map = new double[Constants.RegionSize, Constants.RegionSize]; - taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; + m_terrainData = new HeightmapTerrainData(pX, pY, (int)Constants.RegionHeight); + } + // Create terrain of specified size and initialize with specified terrain. + // TODO: join this with the terrain initializers. + public TerrainChannel(String type, int pX, int pY, int pZ) + { + m_terrainData = new HeightmapTerrainData(pX, pY, pZ); if (type.Equals("flat")) FlatLand(); else PinHeadIsland(); } - public TerrainChannel(double[,] import) + // Create channel passed a heightmap and expected dimensions of the region. + // The heightmap might not fit the passed size so accomodations must be made. + public TerrainChannel(double[,] pM, int pSizeX, int pSizeY, int pAltitude) { - map = import; - taint = new bool[import.GetLength(0),import.GetLength(1)]; - } + int hmSizeX = pM.GetLength(0); + int hmSizeY = pM.GetLength(1); - public TerrainChannel(bool createMap) - { - if (createMap) - { - map = new double[Constants.RegionSize,Constants.RegionSize]; - taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; - } + m_terrainData = new HeightmapTerrainData(pSizeX, pSizeY, pAltitude); + + for (int xx = 0; xx < pSizeX; xx++) + for (int yy = 0; yy < pSizeY; yy++) + if (xx > hmSizeX || yy > hmSizeY) + m_terrainData[xx, yy] = TerrainData.DefaultTerrainHeight; + else + m_terrainData[xx, yy] = (float)pM[xx, yy]; } - public TerrainChannel(int w, int h) + public TerrainChannel(TerrainData pTerrData) { - map = new double[w,h]; - taint = new bool[w / 16,h / 16]; + m_terrainData = pTerrData; } #region ITerrainChannel Members - public int Width + // ITerrainChannel.MakeCopy() + public ITerrainChannel MakeCopy() { - get { return map.GetLength(0); } + return this.Copy(); } - public int Height + // ITerrainChannel.GetTerrainData() + public TerrainData GetTerrainData() { - get { return map.GetLength(1); } + return m_terrainData; } - public ITerrainChannel MakeCopy() + // ITerrainChannel.GetFloatsSerialized() + // This one dimensional version is ordered so height = map[y*sizeX+x]; + // DEPRECATED: don't use this function as it does not retain the dimensions of the terrain + // and the caller will probably do the wrong thing if the terrain is not the legacy 256x256. + public float[] GetFloatsSerialised() { - TerrainChannel copy = new TerrainChannel(false); - copy.map = (double[,]) map.Clone(); - - return copy; + return m_terrainData.GetFloatsSerialized(); } - public float[] GetFloatsSerialised() + // ITerrainChannel.GetDoubles() + public double[,] GetDoubles() { - // Move the member variables into local variables, calling - // member variables 256*256 times gets expensive - int w = Width; - int h = Height; - float[] heights = new float[w * h]; + double[,] heights = new double[Width, Height]; - int i, j; // map coordinates int idx = 0; // index into serialized array - for (i = 0; i < h; i++) + for (int ii = 0; ii < Width; ii++) { - for (j = 0; j < w; j++) + for (int jj = 0; jj < Height; jj++) { - heights[idx++] = (float)map[j, i]; + heights[ii, jj] = (double)m_terrainData[ii, jj]; + idx++; } } return heights; } - public double[,] GetDoubles() - { - return map; - } - + // ITerrainChannel.this[x,y] public double this[int x, int y] { - get - { - if (x < 0) x = 0; - if (y < 0) y = 0; - if (x >= (int)Constants.RegionSize) x = (int)Constants.RegionSize - 1; - if (y >= (int)Constants.RegionSize) y = (int)Constants.RegionSize - 1; - - return map[x, y]; + get { + if (x < 0 || x >= Width || y < 0 || y >= Height) + return 0; + return (double)m_terrainData[x, y]; } set { - // Will "fix" terrain hole problems. Although not fantastically. if (Double.IsNaN(value) || Double.IsInfinity(value)) return; - if (map[x, y] != value) - { - taint[x / 16, y / 16] = true; - map[x, y] = value; - } + m_terrainData[x, y] = (float)value; } } - public bool Tainted(int x, int y) + // ITerrainChannel.GetHieghtAtXYZ(x, y, z) + public float GetHeightAtXYZ(float x, float y, float z) { - if (taint[x / 16, y / 16]) - { - taint[x / 16, y / 16] = false; - return true; - } - return false; + if (x < 0 || x >= Width || y < 0 || y >= Height) + return 0; + return m_terrainData[(int)x, (int)y]; } - #endregion - - public TerrainChannel Copy() + // ITerrainChannel.Tainted() + public bool Tainted(int x, int y) { - TerrainChannel copy = new TerrainChannel(false); - copy.map = (double[,]) map.Clone(); - - return copy; + return m_terrainData.IsTaintedAt(x, y); } + // ITerrainChannel.SaveToXmlString() public string SaveToXmlString() { XmlWriterSettings settings = new XmlWriterSettings(); @@ -189,13 +192,7 @@ namespace OpenSim.Region.Framework.Scenes } } - private void WriteXml(XmlWriter writer) - { - writer.WriteStartElement(String.Empty, "TerrainMap", String.Empty); - ToXml(writer); - writer.WriteEndElement(); - } - + // ITerrainChannel.LoadFromXmlString() public void LoadFromXmlString(string data) { StringReader sr = new StringReader(data); @@ -207,12 +204,124 @@ namespace OpenSim.Region.Framework.Scenes sr.Close(); } + // ITerrainChannel.Merge + public void Merge(ITerrainChannel newTerrain, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement) + { + m_log.DebugFormat("{0} Merge. inSize=<{1},{2}>, disp={3}, rot={4}, rotDisp={5}, outSize=<{6},{7}>", LogHeader, + newTerrain.Width, newTerrain.Height, + displacement, radianRotation, rotationDisplacement, + m_terrainData.SizeX, m_terrainData.SizeY); + for (int xx = 0; xx < newTerrain.Width; xx++) + { + for (int yy = 0; yy < newTerrain.Height; yy++) + { + int dispX = (int)displacement.X; + int dispY = (int)displacement.Y; + float newHeight = (float)newTerrain[xx, yy] + displacement.Z; + if (radianRotation == 0) + { + // If no rotation, place the new height in the specified location + dispX += xx; + dispY += yy; + if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY) + { + m_terrainData[dispX, dispY] = newHeight; + } + } + else + { + // If rotating, we have to smooth the result because the conversion + // to ints will mean heightmap entries will not get changed + // First compute the rotation location for the new height. + dispX += (int)(rotationDisplacement.X + + ((float)xx - rotationDisplacement.X) * Math.Cos(radianRotation) + - ((float)yy - rotationDisplacement.Y) * Math.Sin(radianRotation) ); + + dispY += (int)(rotationDisplacement.Y + + ((float)xx - rotationDisplacement.X) * Math.Sin(radianRotation) + + ((float)yy - rotationDisplacement.Y) * Math.Cos(radianRotation) ); + + if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY) + { + float oldHeight = m_terrainData[dispX, dispY]; + // Smooth the heights around this location if the old height is far from this one + for (int sxx = dispX - 2; sxx < dispX + 2; sxx++) + { + for (int syy = dispY - 2; syy < dispY + 2; syy++) + { + if (sxx >= 0 && sxx < m_terrainData.SizeX && syy >= 0 && syy < m_terrainData.SizeY) + { + if (sxx == dispX && syy == dispY) + { + // Set height for the exact rotated point + m_terrainData[dispX, dispY] = newHeight; + } + else + { + if (Math.Abs(m_terrainData[sxx, syy] - newHeight) > 1f) + { + // If the adjacent height is far off, force it to this height + m_terrainData[sxx, syy] = newHeight; + } + } + } + } + } + } + + if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY) + { + m_terrainData[dispX, dispY] = (float)newTerrain[xx, yy]; + } + } + } + } + } + + #endregion + + public TerrainChannel Copy() + { + TerrainChannel copy = new TerrainChannel(); + copy.m_terrainData = m_terrainData.Clone(); + return copy; + } + + private void WriteXml(XmlWriter writer) + { + if (Width == Constants.RegionSize && Height == Constants.RegionSize) + { + // Downward compatibility for legacy region terrain maps. + // If region is exactly legacy size, return the old format XML. + writer.WriteStartElement(String.Empty, "TerrainMap", String.Empty); + ToXml(writer); + writer.WriteEndElement(); + } + else + { + // New format XML that includes width and length. + writer.WriteStartElement(String.Empty, "TerrainMap2", String.Empty); + ToXml2(writer); + writer.WriteEndElement(); + } + } + private void ReadXml(XmlReader reader) { - reader.ReadStartElement("TerrainMap"); - FromXml(reader); + // Check the first element. If legacy element, use the legacy reader. + if (reader.IsStartElement("TerrainMap")) + { + reader.ReadStartElement("TerrainMap"); + FromXml(reader); + } + else + { + reader.ReadStartElement("TerrainMap2"); + FromXml2(reader); + } } + // Write legacy terrain map. Presumed to be 256x256 of data encoded as floats in a byte array. private void ToXml(XmlWriter xmlWriter) { float[] mapData = GetFloatsSerialised(); @@ -226,12 +335,15 @@ namespace OpenSim.Region.Framework.Scenes serializer.Serialize(xmlWriter, buffer); } + // Read legacy terrain map. Presumed to be 256x256 of data encoded as floats in a byte array. private void FromXml(XmlReader xmlReader) { XmlSerializer serializer = new XmlSerializer(typeof(byte[])); byte[] dataArray = (byte[])serializer.Deserialize(xmlReader); int index = 0; + m_terrainData = new HeightmapTerrainData(Height, Width, (int)Constants.RegionHeight); + for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) @@ -244,35 +356,63 @@ namespace OpenSim.Region.Framework.Scenes } } + private class TerrainChannelXMLPackage + { + public int Version; + public int SizeX; + public int SizeY; + public int SizeZ; + public float CompressionFactor; + public int[] Map; + public TerrainChannelXMLPackage(int pX, int pY, int pZ, float pCompressionFactor, int[] pMap) + { + Version = 1; + SizeX = pX; + SizeY = pY; + SizeZ = pZ; + CompressionFactor = pCompressionFactor; + Map = pMap; + } + } + + // New terrain serialization format that includes the width and length. + private void ToXml2(XmlWriter xmlWriter) + { + TerrainChannelXMLPackage package = new TerrainChannelXMLPackage(Width, Height, Altitude, m_terrainData.CompressionFactor, + m_terrainData.GetCompressedMap()); + XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage)); + serializer.Serialize(xmlWriter, package); + } + + // New terrain serialization format that includes the width and length. + private void FromXml2(XmlReader xmlReader) + { + XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage)); + TerrainChannelXMLPackage package = (TerrainChannelXMLPackage)serializer.Deserialize(xmlReader); + m_terrainData = new HeightmapTerrainData(package.Map, package.CompressionFactor, package.SizeX, package.SizeY, package.SizeZ); + } + + // Fill the heightmap with the center bump terrain private void PinHeadIsland() { - int x; - for (x = 0; x < Constants.RegionSize; x++) + for (int x = 0; x < Width; x++) { - int y; - for (y = 0; y < Constants.RegionSize; y++) + for (int y = 0; y < Height; y++) { - map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; - double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01; - double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001; - if (map[x, y] < spherFacA) - map[x, y] = spherFacA; - if (map[x, y] < spherFacB) - map[x, y] = spherFacB; + m_terrainData[x, y] = (float)TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; + float spherFacA = (float)(TerrainUtil.SphericalFactor(x, y, m_terrainData.SizeX / 2.0, m_terrainData.SizeY / 2.0, 50) * 0.01d); + float spherFacB = (float)(TerrainUtil.SphericalFactor(x, y, m_terrainData.SizeX / 2.0, m_terrainData.SizeY / 2.0, 100) * 0.001d); + if (m_terrainData[x, y]< spherFacA) + m_terrainData[x, y]= spherFacA; + if (m_terrainData[x, y]< spherFacB) + m_terrainData[x, y] = spherFacB; } } } private void FlatLand() { - int x; - for (x = 0; x < Constants.RegionSize; x++) - { - int y; - for (y = 0; y < Constants.RegionSize; y++) - map[x, y] = 21; - } + m_terrainData.ClearLand(); } - } } -- cgit v1.1 From c5a7bf6601dfde518a008d45b4e4a8dc8de698bf Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 28 Mar 2015 08:30:52 -0700 Subject: varregion: add varregion and TerrainData use in LLClientView. Add sending multiple parcel patches and sending patches by avatar view distance. --- .../Region/Framework/Scenes/TerrainCompressor.cs | 948 +++++++++++++++++++++ 1 file changed, 948 insertions(+) create mode 100644 OpenSim/Region/Framework/Scenes/TerrainCompressor.cs (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs new file mode 100644 index 0000000..fc8f8cd --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs @@ -0,0 +1,948 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Freely adapted from the Aurora version of the terrain compressor. + * Copyright (c) Contributors, http://aurora-sim.org/, http://opensimulator.org/ + */ + +using System; +using System.Reflection; + +using log4net; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Scenes; + +using OpenMetaverse; +using OpenMetaverse.Packets; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public static class OpenSimTerrainCompressor + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + +#pragma warning disable 414 + private static string LogHeader = "[TERRAIN COMPRESSOR]"; +#pragma warning restore 414 + + public const int END_OF_PATCHES = 97; + + private const float OO_SQRT2 = 0.7071067811865475244008443621049f; + private const int STRIDE = 264; + + private const int ZERO_CODE = 0x0; + private const int ZERO_EOB = 0x2; + private const int POSITIVE_VALUE = 0x6; + private const int NEGATIVE_VALUE = 0x7; + + private static readonly float[] DequantizeTable16 = + new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + private static readonly float[] DequantizeTable32 = + new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + private static readonly float[] CosineTable16 = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + //private static readonly float[] CosineTable32 = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; + private static readonly int[] CopyMatrix16 = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + private static readonly int[] CopyMatrix32 = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + private static readonly float[] QuantizeTable16 = + new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + static OpenSimTerrainCompressor() + { + // Initialize the decompression tables + BuildDequantizeTable16(); + SetupCosines16(); + BuildCopyMatrix16(); + BuildQuantizeTable16(); + } + + // Used to send cloud and wind patches + public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, byte type, int pRegionSizeX, + int pRegionSizeY) + { + LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}}; + + TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader + {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize}; + + // Should be enough to fit even the most poorly packed data + byte[] data = new byte[patches.Length*Constants.TerrainPatchSize*Constants.TerrainPatchSize*2]; + BitPack bitpack = new BitPack(data, 0); + bitpack.PackBits(header.Stride, 16); + bitpack.PackBits(header.PatchSize, 8); + bitpack.PackBits(type, 8); + + foreach (TerrainPatch t in patches) + CreatePatch(bitpack, t.Data, t.X, t.Y, pRegionSizeX, pRegionSizeY); + + bitpack.PackBits(END_OF_PATCHES, 8); + + layer.LayerData.Data = new byte[bitpack.BytePos + 1]; + Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1); + + return layer; + } + + // Create a land packet for a single patch. + public static LayerDataPacket CreateLandPacket(TerrainData terrData, int patchX, int patchY) + { + int[] xPieces = new int[1]; + int[] yPieces = new int[1]; + xPieces[0] = patchX; // patch X dimension + yPieces[0] = patchY; + + return CreateLandPacket(terrData, xPieces, yPieces); + } + + public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] xPieces, int[] yPieces) + { + byte landPacketType = (byte)TerrainPatch.LayerType.Land; + if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) + { + landPacketType = (byte)TerrainPatch.LayerType.LandExtended; + } + + return CreateLandPacket(terrData, xPieces, yPieces, landPacketType); + } + + /// + /// Creates a LayerData packet for compressed land data given a full + /// simulator heightmap and an array of indices of patches to compress + /// + /// + /// Terrain data that can result in a meter square heightmap. + /// + /// + /// Array of indexes in the grid of patches + /// for this simulator. + /// If creating a packet for multiple patches, there will be entries in + /// both the X and Y arrays for each of the patches. + /// For example if patches 1 and 17 are to be sent, + /// x[] = {1,1} and y[] = {0,1} which specifies the patches at + /// indexes <1,0> and <1,1> (presuming the terrain size is 16x16 patches). + /// + /// + /// Array of indexes in the grid of patches. + /// + /// + /// + public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] x, int[] y, byte type) + { + LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}}; + + TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader + {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize}; + + byte[] data = new byte[x.Length * Constants.TerrainPatchSize * Constants.TerrainPatchSize * 2]; + BitPack bitpack = new BitPack(data, 0); + bitpack.PackBits(header.Stride, 16); + bitpack.PackBits(header.PatchSize, 8); + bitpack.PackBits(type, 8); + + for (int i = 0; i < x.Length; i++) + CreatePatchFromHeightmap(bitpack, terrData, x[i], y[i]); + + bitpack.PackBits(END_OF_PATCHES, 8); + + layer.LayerData.Data = new byte[bitpack.BytePos + 1]; + Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1); + + return layer; + } + + // Unused: left for historical reference. + public static void CreatePatch(BitPack output, float[] patchData, int x, int y, int pRegionSizeX, int pRegionSizeY) + { + TerrainPatch.Header header = PrescanPatch(patchData); + header.QuantWBits = 136; + if (pRegionSizeX > Constants.RegionSize || pRegionSizeY > Constants.RegionSize) + { + header.PatchIDs = (y & 0xFFFF); + header.PatchIDs += (x << 16); + } + else + { + header.PatchIDs = (y & 0x1F); + header.PatchIDs += (x << 5); + } + + // NOTE: No idea what prequant and postquant should be or what they do + + int wbits; + int[] patch = CompressPatch(patchData, header, 10, out wbits); + wbits = EncodePatchHeader(output, header, patch, Constants.RegionSize, Constants.RegionSize, wbits); + EncodePatch(output, patch, 0, wbits); + } + + /// + /// Add a patch of terrain to a BitPacker + /// + /// BitPacker to write the patch to + /// + /// Heightmap of the simulator. Presumed to be an sizeX*sizeY array. + /// + /// + /// X offset of the patch to create. + /// + /// + /// Y offset of the patch to create. + /// + /// + /// + public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY) + { + TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY); + header.QuantWBits = 136; + + // If larger than legacy region size, pack patch X and Y info differently. + if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) + { + header.PatchIDs = (patchY & 0xFFFF); + header.PatchIDs += (patchX << 16); + } + else + { + header.PatchIDs = (patchY & 0x1F); + header.PatchIDs += (patchX << 5); + } + + // m_log.DebugFormat("{0} CreatePatchFromHeightmap. patchX={1}, patchY={2}, DCOffset={3}, range={4}", + // LogHeader, patchX, patchY, header.DCOffset, header.Range); + + // NOTE: No idea what prequant and postquant should be or what they do + int wbits; + int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits); + wbits = EncodePatchHeader(output, header, patch, (uint)terrData.SizeX, (uint)terrData.SizeY, wbits); + EncodePatch(output, patch, 0, wbits); + } + + private static TerrainPatch.Header PrescanPatch(float[] patch) + { + TerrainPatch.Header header = new TerrainPatch.Header(); + float zmax = -99999999.0f; + float zmin = 99999999.0f; + + for (int i = 0; i < Constants.TerrainPatchSize*Constants.TerrainPatchSize; i++) + { + float val = patch[i]; + if (val > zmax) zmax = val; + if (val < zmin) zmin = val; + } + + header.DCOffset = zmin; + header.Range = (int) ((zmax - zmin) + 1.0f); + + return header; + } + + // Scan the height info we're returning and return a patch packet header for this patch. + private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY) + { + TerrainPatch.Header header = new TerrainPatch.Header(); + float zmax = -99999999.0f; + float zmin = 99999999.0f; + + for (int j = patchY*Constants.TerrainPatchSize; j < (patchY + 1)*Constants.TerrainPatchSize; j++) + { + for (int i = patchX*Constants.TerrainPatchSize; i < (patchX + 1)*Constants.TerrainPatchSize; i++) + { + float val = terrData[i, j]; + if (val > zmax) zmax = val; + if (val < zmin) zmin = val; + } + } + + header.DCOffset = zmin; + header.Range = (int)((zmax - zmin) + 1.0f); + + return header; + } + + public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack) + { + TerrainPatch.Header header = new TerrainPatch.Header {QuantWBits = bitpack.UnpackBits(8)}; + + // Quantized word bits + if (header.QuantWBits == END_OF_PATCHES) + return header; + + // DC offset + header.DCOffset = bitpack.UnpackFloat(); + + // Range + header.Range = bitpack.UnpackBits(16); + + // Patch IDs (10 bits) + header.PatchIDs = bitpack.UnpackBits(10); + + // Word bits + header.WordBits = (uint) ((header.QuantWBits & 0x0f) + 2); + + return header; + } + + private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, uint pRegionSizeX, + uint pRegionSizeY, int wbits) + { + /* + int temp; + int wbits = (header.QuantWBits & 0x0f) + 2; + uint maxWbits = (uint)wbits + 5; + uint minWbits = ((uint)wbits >> 1); + int wbitsMaxValue; + */ + // goal is to determ minimum number of bits to use so all data fits + /* + wbits = (int)minWbits; + wbitsMaxValue = (1 << wbits); + + for (int i = 0; i < patch.Length; i++) + { + temp = patch[i]; + if (temp != 0) + { + // Get the absolute value + if (temp < 0) temp *= -1; + + no coments.. + + for (int j = (int)maxWbits; j > (int)minWbits; j--) + { + if ((temp & (1 << j)) != 0) + { + if (j > wbits) wbits = j; + break; + } + } + + while (temp > wbitsMaxValue) + { + wbits++; + if (wbits == maxWbits) + goto Done; + wbitsMaxValue = 1 << wbits; + } + } + } + + Done: + + // wbits += 1; + */ + // better check + if (wbits > 17) + wbits = 16; + else if (wbits < 3) + wbits = 3; + + header.QuantWBits &= 0xf0; + + header.QuantWBits |= (wbits - 2); + + output.PackBits(header.QuantWBits, 8); + output.PackFloat(header.DCOffset); + output.PackBits(header.Range, 16); + if (pRegionSizeX > Constants.RegionSize || pRegionSizeY > Constants.RegionSize) + output.PackBits(header.PatchIDs, 32); + else + output.PackBits(header.PatchIDs, 10); + + return wbits; + } + + private static void IDCTColumn16(float[] linein, float[] lineout, int column) + { + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + float total = OO_SQRT2*linein[column]; + + for (int u = 1; u < Constants.TerrainPatchSize; u++) + { + int usize = u*Constants.TerrainPatchSize; + total += linein[usize + column]*CosineTable16[usize + n]; + } + + lineout[Constants.TerrainPatchSize*n + column] = total; + } + } + + private static void IDCTLine16(float[] linein, float[] lineout, int line) + { + const float oosob = 2.0f/Constants.TerrainPatchSize; + int lineSize = line*Constants.TerrainPatchSize; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + float total = OO_SQRT2*linein[lineSize]; + + for (int u = 1; u < Constants.TerrainPatchSize; u++) + { + total += linein[lineSize + u]*CosineTable16[u*Constants.TerrainPatchSize + n]; + } + + lineout[lineSize + n] = total*oosob; + } + } + +/* + private static void DCTLine16(float[] linein, float[] lineout, int line) + { + float total = 0.0f; + int lineSize = line * Constants.TerrainPatchSize; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + total += linein[lineSize + n]; + } + + lineout[lineSize] = OO_SQRT2 * total; + + int uptr = 0; + for (int u = 1; u < Constants.TerrainPatchSize; u++) + { + total = 0.0f; + uptr += Constants.TerrainPatchSize; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + total += linein[lineSize + n] * CosineTable16[uptr + n]; + } + + lineout[lineSize + u] = total; + } + } +*/ + + private static void DCTLine16(float[] linein, float[] lineout, int line) + { + // outputs transpose data (lines exchanged with coluns ) + // so to save a bit of cpu when doing coluns + float total = 0.0f; + int lineSize = line*Constants.TerrainPatchSize; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + total += linein[lineSize + n]; + } + + lineout[line] = OO_SQRT2*total; + + for (int u = Constants.TerrainPatchSize; + u < Constants.TerrainPatchSize*Constants.TerrainPatchSize; + u += Constants.TerrainPatchSize) + { + total = 0.0f; + for (int ptrn = lineSize, ptru = u; ptrn < lineSize + Constants.TerrainPatchSize; ptrn++,ptru++) + { + total += linein[ptrn]*CosineTable16[ptru]; + } + + lineout[line + u] = total; + } + } + + + /* + private static void DCTColumn16(float[] linein, int[] lineout, int column) + { + float total = 0.0f; + // const float oosob = 2.0f / Constants.TerrainPatchSize; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + total += linein[Constants.TerrainPatchSize * n + column]; + } + + // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]); + lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * QuantizeTable16[column]); + + for (int uptr = Constants.TerrainPatchSize; uptr < Constants.TerrainPatchSize * Constants.TerrainPatchSize; uptr += Constants.TerrainPatchSize) + { + total = 0.0f; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + total += linein[Constants.TerrainPatchSize * n + column] * CosineTable16[uptr + n]; + } + + // lineout[CopyMatrix16[Constants.TerrainPatchSize * u + column]] = (int)(total * oosob * QuantizeTable16[Constants.TerrainPatchSize * u + column]); + lineout[CopyMatrix16[uptr + column]] = (int)(total * QuantizeTable16[uptr + column]); + } + } + + private static void DCTColumn16(float[] linein, int[] lineout, int column) + { + // input columns are in fact stored in lines now + + float total = 0.0f; +// const float oosob = 2.0f / Constants.TerrainPatchSize; + int inlinesptr = Constants.TerrainPatchSize*column; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + total += linein[inlinesptr + n]; + } + + // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]); + lineout[CopyMatrix16[column]] = (int) (OO_SQRT2*total*QuantizeTable16[column]); + + for (int uptr = Constants.TerrainPatchSize; + uptr < Constants.TerrainPatchSize*Constants.TerrainPatchSize; + uptr += Constants.TerrainPatchSize) + { + total = 0.0f; + + for (int n = inlinesptr, ptru = uptr; n < inlinesptr + Constants.TerrainPatchSize; n++, ptru++) + { + total += linein[n]*CosineTable16[ptru]; + } + +// lineout[CopyMatrix16[Constants.TerrainPatchSize * u + column]] = (int)(total * oosob * QuantizeTable16[Constants.TerrainPatchSize * u + column]); + lineout[CopyMatrix16[uptr + column]] = (int) (total*QuantizeTable16[uptr + column]); + } + } + */ + + private static int DCTColumn16Wbits(float[] linein, int[] lineout, int column, int wbits, int maxwbits) + { + // input columns are in fact stored in lines now + + bool dowbits = wbits != maxwbits; + int wbitsMaxValue = 1 << wbits; + + float total = 0.0f; + // const float oosob = 2.0f / Constants.TerrainPatchSize; + int inlinesptr = Constants.TerrainPatchSize*column; + + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + total += linein[inlinesptr + n]; + } + + // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]); + int tmp = (int) (OO_SQRT2*total*QuantizeTable16[column]); + lineout[CopyMatrix16[column]] = tmp; + + if (dowbits) + { + if (tmp < 0) tmp *= -1; + while (tmp > wbitsMaxValue) + { + wbits++; + wbitsMaxValue = 1 << wbits; + if (wbits == maxwbits) + { + dowbits = false; + break; + } + } + } + + for (int uptr = Constants.TerrainPatchSize; + uptr < Constants.TerrainPatchSize*Constants.TerrainPatchSize; + uptr += Constants.TerrainPatchSize) + { + total = 0.0f; + + for (int n = inlinesptr, ptru = uptr; n < inlinesptr + Constants.TerrainPatchSize; n++, ptru++) + { + total += linein[n]*CosineTable16[ptru]; + } + + tmp = (int) (total*QuantizeTable16[uptr + column]); + lineout[CopyMatrix16[uptr + column]] = tmp; + + if (dowbits) + { + if (tmp < 0) tmp *= -1; + while (tmp > wbitsMaxValue) + { + wbits++; + wbitsMaxValue = 1 << wbits; + if (wbits == maxwbits) + { + dowbits = false; + break; + } + } + } + } + return wbits; + } + + public static void DecodePatch(int[] patches, BitPack bitpack, TerrainPatch.Header header, int size) + { + for (int n = 0; n < size*size; n++) + { + // ? + int temp = bitpack.UnpackBits(1); + if (temp != 0) + { + // Value or EOB + temp = bitpack.UnpackBits(1); + if (temp != 0) + { + // Value + temp = bitpack.UnpackBits(1); + if (temp != 0) + { + // Negative + temp = bitpack.UnpackBits((int) header.WordBits); + patches[n] = temp*-1; + } + else + { + // Positive + temp = bitpack.UnpackBits((int) header.WordBits); + patches[n] = temp; + } + } + else + { + // Set the rest to zero + // TODO: This might not be necessary + for (int o = n; o < size*size; o++) + { + patches[o] = 0; + } + break; + } + } + else + { + patches[n] = 0; + } + } + } + + private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits) + { + int maxwbitssize = (1 << wbits) - 1; + + if (postquant > Constants.TerrainPatchSize*Constants.TerrainPatchSize || postquant < 0) + { + Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error); + return; + } + + if (postquant != 0) patch[Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant] = 0; + + for (int i = 0; i < Constants.TerrainPatchSize*Constants.TerrainPatchSize; i++) + { + int temp = patch[i]; + + if (temp == 0) + { + bool eob = true; + + for (int j = i; j < Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant; j++) + { + if (patch[j] != 0) + { + eob = false; + break; + } + } + + if (eob) + { + output.PackBits(ZERO_EOB, 2); + return; + } + output.PackBits(ZERO_CODE, 1); + } + else + { + if (temp < 0) + { + temp *= -1; + + if (temp > maxwbitssize) temp = maxwbitssize; + + output.PackBits(NEGATIVE_VALUE, 3); + output.PackBits(temp, wbits); + } + else + { + if (temp > maxwbitssize) temp = maxwbitssize; + + output.PackBits(POSITIVE_VALUE, 3); + output.PackBits(temp, wbits); + } + } + } + } + + public static float[] DecompressPatch(int[] patches, TerrainPatch.Header header, TerrainPatch.GroupHeader group) + { + float[] block = new float[group.PatchSize*group.PatchSize]; + float[] output = new float[group.PatchSize*group.PatchSize]; + int prequant = (header.QuantWBits >> 4) + 2; + int quantize = 1 << prequant; + float ooq = 1.0f/quantize; + float mult = ooq*header.Range; + float addval = mult*(1 << (prequant - 1)) + header.DCOffset; + + if (group.PatchSize == Constants.TerrainPatchSize) + { + for (int n = 0; n < Constants.TerrainPatchSize*Constants.TerrainPatchSize; n++) + { + block[n] = patches[CopyMatrix16[n]]*DequantizeTable16[n]; + } + + float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + for (int o = 0; o < Constants.TerrainPatchSize; o++) + IDCTColumn16(block, ftemp, o); + for (int o = 0; o < Constants.TerrainPatchSize; o++) + IDCTLine16(ftemp, block, o); + } + else + { + for (int n = 0; n < Constants.TerrainPatchSize*2*Constants.TerrainPatchSize*2; n++) + { + block[n] = patches[CopyMatrix32[n]]*DequantizeTable32[n]; + } + + Logger.Log("Implement IDCTPatchLarge", Helpers.LogLevel.Error); + } + + for (int j = 0; j < block.Length; j++) + { + output[j] = block[j]*mult + addval; + } + + return output; + } + + private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits) + { + float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + int wordsize = (prequant - 2) & 0x0f; + float oozrange = 1.0f/header.Range; + float range = (1 << prequant); + float premult = oozrange*range; + float sub = (1 << (prequant - 1)) + header.DCOffset*premult; + + header.QuantWBits = wordsize; + header.QuantWBits |= wordsize << 4; + + int k = 0; + for (int j = 0; j < Constants.TerrainPatchSize; j++) + { + for (int i = 0; i < Constants.TerrainPatchSize; i++) + block[k++] = patchData[j*Constants.TerrainPatchSize + i]*premult - sub; + } + + float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + + int maxWbits = prequant + 5; + wbits = (prequant >> 1); + + for (int o = 0; o < Constants.TerrainPatchSize; o++) + DCTLine16(block, ftemp, o); + for (int o = 0; o < Constants.TerrainPatchSize; o++) + wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits); + + return itemp; + } + + private static int[] CompressPatch(float[,] patchData, TerrainPatch.Header header, int prequant, out int wbits) + { + float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + float oozrange = 1.0f/header.Range; + float range = (1 << prequant); + float premult = oozrange*range; + float sub = (1 << (prequant - 1)) + header.DCOffset*premult; + int wordsize = (prequant - 2) & 0x0f; + + header.QuantWBits = wordsize; + header.QuantWBits |= wordsize << 4; + + int k = 0; + for (int j = 0; j < Constants.TerrainPatchSize; j++) + { + for (int i = 0; i < Constants.TerrainPatchSize; i++) + block[k++] = patchData[j, i]*premult - sub; + } + + float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + int maxWbits = prequant + 5; + wbits = (prequant >> 1); + + for (int o = 0; o < Constants.TerrainPatchSize; o++) + DCTLine16(block, ftemp, o); + for (int o = 0; o < Constants.TerrainPatchSize; o++) + wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits); + + return itemp; + } + + private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header, + int prequant, out int wbits) + { + float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + int wordsize = prequant; + float oozrange = 1.0f/header.Range; + float range = (1 << prequant); + float premult = oozrange*range; + float sub = (1 << (prequant - 1)) + header.DCOffset*premult; + + header.QuantWBits = wordsize - 2; + header.QuantWBits |= (prequant - 2) << 4; + + int k = 0; + + int yPatchLimit = patchY >= (terrData.SizeY / Constants.TerrainPatchSize) ? + (terrData.SizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchY; + yPatchLimit = (yPatchLimit + 1) * Constants.TerrainPatchSize; + + int xPatchLimit = patchX >= (terrData.SizeX / Constants.TerrainPatchSize) ? + (terrData.SizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchX; + xPatchLimit = (xPatchLimit + 1) * Constants.TerrainPatchSize; + + for (int yy = patchY * Constants.TerrainPatchSize; yy < yPatchLimit; yy++) + { + for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++) + { + block[k++] = terrData[xx, yy] * premult - sub; + } + } + + float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; + + int maxWbits = prequant + 5; + wbits = (prequant >> 1); + + for (int o = 0; o < Constants.TerrainPatchSize; o++) + DCTLine16(block, ftemp, o); + for (int o = 0; o < Constants.TerrainPatchSize; o++) + wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits); + + return itemp; + } + + #region Initialization + + private static void BuildDequantizeTable16() + { + for (int j = 0; j < Constants.TerrainPatchSize; j++) + { + for (int i = 0; i < Constants.TerrainPatchSize; i++) + { + DequantizeTable16[j*Constants.TerrainPatchSize + i] = 1.0f + 2.0f*(i + j); + } + } + } + + private static void BuildQuantizeTable16() + { + const float oosob = 2.0f/Constants.TerrainPatchSize; + for (int j = 0; j < Constants.TerrainPatchSize; j++) + { + for (int i = 0; i < Constants.TerrainPatchSize; i++) + { +// QuantizeTable16[j * Constants.TerrainPatchSize + i] = 1.0f / (1.0f + 2.0f * ((float)i + (float)j)); + QuantizeTable16[j*Constants.TerrainPatchSize + i] = oosob/(1.0f + 2.0f*(i + (float) j)); + } + } + } + + private static void SetupCosines16() + { + const float hposz = (float) Math.PI*0.5f/Constants.TerrainPatchSize; + + for (int u = 0; u < Constants.TerrainPatchSize; u++) + { + for (int n = 0; n < Constants.TerrainPatchSize; n++) + { + CosineTable16[u*Constants.TerrainPatchSize + n] = (float) Math.Cos((2.0f*n + 1.0f)*u*hposz); + } + } + } + + private static void BuildCopyMatrix16() + { + bool diag = false; + bool right = true; + int i = 0; + int j = 0; + int count = 0; + + while (i < Constants.TerrainPatchSize && j < Constants.TerrainPatchSize) + { + CopyMatrix16[j*Constants.TerrainPatchSize + i] = count++; + + if (!diag) + { + if (right) + { + if (i < Constants.TerrainPatchSize - 1) i++; + else j++; + + right = false; + diag = true; + } + else + { + if (j < Constants.TerrainPatchSize - 1) j++; + else i++; + + right = true; + diag = true; + } + } + else + { + if (right) + { + i++; + j--; + if (i == Constants.TerrainPatchSize - 1 || j == 0) diag = false; + } + else + { + i--; + j++; + if (j == Constants.TerrainPatchSize - 1 || i == 0) diag = false; + } + } + } + } + + #endregion Initialization + } +} -- cgit v1.1 From 07dead7dcb8b0f2a27a50748e4a460d9669903fc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 29 Mar 2015 14:25:12 -0700 Subject: varregion: any conversions of use of Constants.RegionSize converted into Util.cs routines to convert region coords to and from world coords or handles. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 11 ++------ OpenSim/Region/Framework/Scenes/Scene.cs | 33 ++++++++++++++++++---- .../Framework/Scenes/SceneCommunicationService.cs | 9 ++++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 25 +++++++--------- 5 files changed, 48 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b45cc4d..4ab5a4a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2221,14 +2221,9 @@ namespace OpenSim.Region.Framework.Scenes itemID = UUID.Zero; if (grp != null) { - Vector3 inventoryStoredPosition = new Vector3 - (((grp.AbsolutePosition.X > (int)Constants.RegionSize) - ? 250 - : grp.AbsolutePosition.X) - , - (grp.AbsolutePosition.X > (int)Constants.RegionSize) - ? 250 - : grp.AbsolutePosition.X, + Vector3 inventoryStoredPosition = new Vector3( + Math.Min(grp.AbsolutePosition.X, RegionInfo.RegionSizeX - 6), + Math.Min(grp.AbsolutePosition.Y, RegionInfo.RegionSizeY - 6), grp.AbsolutePosition.Z); Vector3 originalPosition = grp.AbsolutePosition; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f5458c1..46c9048 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -6,7 +6,7 @@ * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD + * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the OpenSimulator Project nor the @@ -103,7 +103,29 @@ namespace OpenSim.Region.Framework.Scenes /// /// If false then physical objects are disabled, though collisions will continue as normal. /// - public bool PhysicsEnabled { get; set; } + public bool PhysicsEnabled + { + get + { + return m_physicsEnabled; + } + + set + { + m_physicsEnabled = value; + + if (PhysicsScene != null) + { + IPhysicsParameters physScene = PhysicsScene as IPhysicsParameters; + + if (physScene != null) + physScene.SetPhysicsParameter( + "Active", m_physicsEnabled.ToString(), PhysParameterEntry.APPLY_TO_NONE); + } + } + } + + private bool m_physicsEnabled; /// /// If false then scripts are not enabled on the smiulator @@ -199,15 +221,16 @@ namespace OpenSim.Region.Framework.Scenes /// public int m_linksetCapacity = 0; + public bool m_clampPrimSize; + public bool m_trustBinaries; + public bool m_allowScriptCrossings = true; + /// /// Max prims an Physical object will hold /// /// public int m_linksetPhysCapacity = 0; - public bool m_clampPrimSize; - public bool m_trustBinaries; - public bool m_allowScriptCrossings; public bool m_useFlySlow; public bool m_useTrashOnDelete = true; diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 52f46f2..a2625c4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -52,6 +52,7 @@ namespace OpenSim.Region.Framework.Scenes public class SceneCommunicationService //one instance per region { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[SCENE COMMUNICATION SERVICE]"; protected RegionInfo m_regionInfo; protected Scene m_scene; @@ -100,7 +101,7 @@ namespace OpenSim.Region.Framework.Scenes { m_log.WarnFormat( "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.", - m_scene.Name, x / Constants.RegionSize, y / Constants.RegionSize); + m_scene.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y)); } } @@ -166,7 +167,7 @@ namespace OpenSim.Region.Framework.Scenes // we only want to send one update to each simulator; the simulator will // hand it off to the regions where a child agent exists, this does assume // that the region position is cached or performance will degrade - Utils.LongToUInts(regionHandle, out x, out y); + Util.RegionHandleToWorldLoc(regionHandle, out x, out y); GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); if (dest == null) continue; @@ -206,7 +207,7 @@ namespace OpenSim.Region.Framework.Scenes //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); uint x = 0, y = 0; - Utils.LongToUInts(regionHandle, out x, out y); + Util.RegionHandleToWorldLoc(regionHandle, out x, out y); GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y); @@ -226,6 +227,8 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ulong handle in regionslst) { + // We must take a copy here since handle acts like a reference when used in an iterator. + // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. ulong handleCopy = handle; Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); }); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a99e469..cb2f377 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -412,7 +412,7 @@ namespace OpenSim.Region.Framework.Scenes { get { - Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); + Vector3 minScale = new Vector3(Constants.MaximumRegionSize, Constants.MaximumRegionSize, Constants.MaximumRegionSize); Vector3 maxScale = Vector3.Zero; Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2965903..82508ad 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -842,9 +842,8 @@ namespace OpenSim.Region.Framework.Scenes foreach (ulong handle in seeds.Keys) { uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; + Util.RegionHandleToRegionLoc(handle, out x, out y); + if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) { old.Add(handle); @@ -866,9 +865,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (KeyValuePair kvp in KnownRegions) { uint x, y; - Utils.LongToUInts(kvp.Key, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; + Util.RegionHandleToRegionLoc(kvp.Key, out x, out y); m_log.Info(" >> "+x+", "+y+": "+kvp.Value); } } @@ -1189,7 +1186,7 @@ namespace OpenSim.Region.Framework.Scenes float posZLimit = 0; - if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) + if (pos.X < m_scene.RegionInfo.RegionSizeX && pos.Y < m_scene.RegionInfo.RegionSizeY) posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; float newPosZ = posZLimit + localAVHeight / 2; @@ -2595,7 +2592,7 @@ namespace OpenSim.Region.Framework.Scenes if (regionCombinerModule != null) regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); else - regionSize = new Vector2(Constants.RegionSize); + regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY); if (pos.X < 0 || pos.X >= regionSize.X || pos.Y < 0 || pos.Y >= regionSize.Y @@ -2613,8 +2610,8 @@ namespace OpenSim.Region.Framework.Scenes // } // Get terrain height for sub-region in a megaregion if necessary - int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X); - int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y); + int X = (int)((m_scene.RegionInfo.WorldLocX) + pos.X); + int Y = (int)((m_scene.RegionInfo.WorldLocY) + pos.Y); GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y); // If X and Y is NaN, target_region will be null if (target_region == null) @@ -2625,7 +2622,7 @@ namespace OpenSim.Region.Framework.Scenes if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) targetScene = m_scene; - float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; + float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % regionSize.X), (int)(pos.Y % regionSize.Y)]; // dont try to land underground terrainHeight += Appearance.AvatarHeight / 2; pos.Z = Math.Max(terrainHeight, pos.Z); @@ -3941,7 +3938,7 @@ namespace OpenSim.Region.Framework.Scenes // Put the child agent back at the center AbsolutePosition - = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); + = new Vector3(((float)m_scene.RegionInfo.RegionSizeX * 0.5f), ((float)m_scene.RegionInfo.RegionSizeY * 0.5f), 70); Animator.ResetAnimations(); } @@ -3968,9 +3965,7 @@ namespace OpenSim.Region.Framework.Scenes if (handle != Scene.RegionInfo.RegionHandle) { uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; + Util.RegionHandleToRegionLoc(handle, out x, out y); // m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); // m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); -- cgit v1.1