From 2a354f6c286b4b70e2768d9b267f53c3d391a10b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 14 Dec 2015 11:57:24 +0000 Subject: [PATCH] calculate land startpoint, endpoint and center estimate when it is updated, it not every time they are needed --- OpenSim/Framework/ILandObject.cs | 15 ++-- .../CoreModules/World/Land/LandObject.cs | 82 ++++++++++++------- OpenSim/Region/Framework/Scenes/Scene.cs | 47 +---------- 3 files changed, 65 insertions(+), 79 deletions(-) diff --git a/OpenSim/Framework/ILandObject.cs b/OpenSim/Framework/ILandObject.cs index ef7a9e69a9..7a50c2a5f7 100644 --- a/OpenSim/Framework/ILandObject.cs +++ b/OpenSim/Framework/ILandObject.cs @@ -50,16 +50,19 @@ namespace OpenSim.Framework IPrimCounts PrimCounts { get; set; } /// - /// The start point for the land object. This is the western-most point as one scans land working from - /// north to south. + /// The start point for the land object. This is the northern-most point as one scans land working from + /// west to east. /// - Vector3 StartPoint { get; } + Vector2 StartPoint { get; } /// - /// The end point for the land object. This is the eastern-most point as one scans land working from - /// south to north. + /// The end point for the land object. This is the southern-most point as one scans land working from + /// west to east. /// - Vector3 EndPoint { get; } + Vector2 EndPoint { get; } + + // a estimation of a parcel center. + Vector2 CenterPoint { get; } bool ContainsPoint(int x, int y); diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 28652d78f4..e1cd28365a 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -90,43 +90,32 @@ namespace OpenSim.Region.CoreModules.World.Land get { return m_scene.RegionInfo.RegionID; } } - public Vector3 StartPoint + private Vector2 m_startPoint = Vector2.Zero; + private Vector2 m_endPoint = Vector2.Zero; + private Vector2 m_centerPoint = Vector2.Zero; + + public Vector2 StartPoint { get { - for (int y = 0; y < LandBitmap.GetLength(1); y++) - { - for (int x = 0; x < LandBitmap.GetLength(0); x++) - { - if (LandBitmap[x, y]) - return new Vector3(x * landUnit, y * landUnit, 0); - } - } - - m_log.ErrorFormat("{0} StartPoint. No start point found. bitmapSize=<{1},{2}>", - LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); - return new Vector3(-1, -1, -1); + return m_startPoint; } } - public Vector3 EndPoint + public Vector2 EndPoint { get { - for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--) - { - for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--) - { - if (LandBitmap[x, y]) - { - return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0); - } - } - } + return m_endPoint; + } + } - m_log.ErrorFormat("{0} EndPoint. No end point found. bitmapSize=<{1},{2}>", - LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); - return new Vector3(-1, -1, -1); + //estimate a center point of a parcel + public Vector2 CenterPoint + { + get + { + return m_centerPoint; } } @@ -789,6 +778,14 @@ namespace OpenSim.Region.CoreModules.World.Land int max_y = Int32.MinValue; int tempArea = 0; int x, y; + + int lastX = 0; + int lastY = 0; + float avgx = 0f; + float avgy = 0f; + + bool needStart = true; + for (x = 0; x < LandBitmap.GetLength(0); x++) { for (y = 0; y < LandBitmap.GetLength(1); y++) @@ -803,10 +800,37 @@ namespace OpenSim.Region.CoreModules.World.Land max_x = x; if (max_y < y) max_y = y; - tempArea += landUnit * landUnit; //16sqm peice of land + + if(needStart) + { + avgx = x; + avgy = y; + m_startPoint.X = x * landUnit; + m_startPoint.Y = y * landUnit; + needStart = false; + } + else + { + avgx = (avgx * tempArea + x) / (tempArea + 1); + avgy = (avgy * tempArea + y) / (tempArea + 1); + } + + tempArea++; + + lastX = x; + lastY = y; } } } + + int halfunit = landUnit/2; + + m_centerPoint.X = avgx * landUnit + halfunit; + m_centerPoint.Y = avgy * landUnit + halfunit; + + m_endPoint.X = lastX * landUnit + landUnit; + m_endPoint.Y = lastY * landUnit + landUnit; + int tx = min_x * landUnit; if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); @@ -847,7 +871,7 @@ namespace OpenSim.Region.CoreModules.World.Land = new Vector3( (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0); - LandData.Area = tempArea; + LandData.Area = tempArea * landUnit * landUnit; } #endregion diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4d2cdd99f2..1857fd8a1b 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5827,7 +5827,7 @@ Environment.Exit(1); private Vector3 GetParcelCenterAtGround(ILandObject parcel) { - Vector2 center = GetParcelCenter(parcel); + Vector2 center = parcel.CenterPoint; return GetPositionAtGround(center.X, center.Y); } @@ -5880,53 +5880,12 @@ Environment.Exit(1); private Vector2 GetParcelSafeCorner(ILandObject parcel) { - Vector3 start = parcel.StartPoint; - float x = start.X + 2.0f; - float y = start.Y + 2.0f; - return new Vector2(x, y); + return parcel.StartPoint; } private float GetParcelDistancefromPoint(ILandObject parcel, float x, float y) { - return Vector2.Distance(new Vector2(x, y), GetParcelCenter(parcel)); - } - - //calculate the average center point of a parcel - private Vector2 GetParcelCenter(ILandObject parcel) - { - int count = 0; - int avgx = 0; - int avgy = 0; - Vector3 start = parcel.StartPoint; - Vector3 end = parcel.EndPoint; - int startX = (int) start.X; - int startY = (int) start.Y; - int endX = (int) end.X; - int endY = (int) end.Y; - - for (int x = startX; x < endX; x += 4) - { - for (int y = startY; y < endY; y += 4) - { - //Just keep a running average as we check if all the points are inside or not - if (parcel.ContainsPoint(x, y)) - { - if (count == 0) - { - avgx = x; - avgy = y; - } - else - { - avgx = (avgx * count + x) / (count + 1); - avgy = (avgy * count + y) / (count + 1); - } - count += 1; - } - } - } - - return new Vector2(avgx, avgy); + return Vector2.Distance(new Vector2(x, y), parcel.CenterPoint); } private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar)