diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World')
14 files changed, 614 insertions, 285 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index 7a844f4..cd95ee9 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs | |||
@@ -533,7 +533,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
533 | if (isMegaregion) | 533 | if (isMegaregion) |
534 | size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID); | 534 | size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID); |
535 | else | 535 | else |
536 | size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize); | 536 | size = new Vector2((float)scene.RegionInfo.RegionSizeX, (float)scene.RegionInfo.RegionSizeY); |
537 | 537 | ||
538 | xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); | 538 | xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); |
539 | xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); | 539 | xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 9279066..4aee6a5 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -64,6 +64,12 @@ 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]"; | ||
68 | |||
69 | /// <summary> | ||
70 | /// Minimum land unit size in region co-ordinates. | ||
71 | /// </summary> | ||
72 | public const int landUnit = 4; | ||
67 | 73 | ||
68 | private static readonly string remoteParcelRequestPath = "0009/"; | 74 | private static readonly string remoteParcelRequestPath = "0009/"; |
69 | 75 | ||
@@ -74,15 +80,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
74 | protected IPrimCountModule m_primCountModule; | 80 | protected IPrimCountModule m_primCountModule; |
75 | protected IDialogModule m_Dialog; | 81 | protected IDialogModule m_Dialog; |
76 | 82 | ||
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> | 83 | /// <value> |
83 | /// Local land ids at specified region co-ordinates (region size / 4) | 84 | /// Local land ids at specified region co-ordinates (region size / 4) |
84 | /// </value> | 85 | /// </value> |
85 | private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax]; | 86 | private int[,] m_landIDList; |
86 | 87 | ||
87 | /// <value> | 88 | /// <value> |
88 | /// Land objects keyed by local id | 89 | /// Land objects keyed by local id |
@@ -123,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
123 | public void AddRegion(Scene scene) | 124 | public void AddRegion(Scene scene) |
124 | { | 125 | { |
125 | m_scene = scene; | 126 | m_scene = scene; |
126 | m_landIDList.Initialize(); | 127 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; |
127 | landChannel = new LandChannel(scene, this); | 128 | landChannel = new LandChannel(scene, this); |
128 | 129 | ||
129 | parcelInfoCache = new Cache(); | 130 | parcelInfoCache = new Cache(); |
@@ -235,7 +236,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
235 | public void UpdateLandObject(int local_id, LandData data) | 236 | public void UpdateLandObject(int local_id, LandData data) |
236 | { | 237 | { |
237 | LandData newData = data.Copy(); | 238 | LandData newData = data.Copy(); |
238 | newData.LocalID = local_id; | 239 | newData.LocalID = local_id; |
239 | 240 | ||
240 | ILandObject land; | 241 | ILandObject land; |
241 | lock (m_landList) | 242 | lock (m_landList) |
@@ -264,7 +265,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
264 | { | 265 | { |
265 | m_landList.Clear(); | 266 | m_landList.Clear(); |
266 | m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | 267 | m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; |
267 | m_landIDList.Initialize(); | 268 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; |
268 | } | 269 | } |
269 | } | 270 | } |
270 | 271 | ||
@@ -274,11 +275,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
274 | /// <returns>The parcel created.</returns> | 275 | /// <returns>The parcel created.</returns> |
275 | protected ILandObject CreateDefaultParcel() | 276 | protected ILandObject CreateDefaultParcel() |
276 | { | 277 | { |
277 | m_log.DebugFormat( | 278 | m_log.DebugFormat("{0} Creating default parcel for region {1}", LogHeader, m_scene.RegionInfo.RegionName); |
278 | "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); | ||
279 | 279 | ||
280 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); | 280 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); |
281 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); | 281 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, |
282 | (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY)); | ||
282 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 283 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
283 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 284 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
284 | 285 | ||
@@ -569,9 +570,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
569 | new_land.LandData.LocalID = newLandLocalID; | 570 | new_land.LandData.LocalID = newLandLocalID; |
570 | 571 | ||
571 | bool[,] landBitmap = new_land.GetLandBitmap(); | 572 | bool[,] landBitmap = new_land.GetLandBitmap(); |
572 | for (int x = 0; x < landArrayMax; x++) | 573 | for (int x = 0; x < landBitmap.GetLength(0); x++) |
573 | { | 574 | { |
574 | for (int y = 0; y < landArrayMax; y++) | 575 | for (int y = 0; y < landBitmap.GetLength(1); y++) |
575 | { | 576 | { |
576 | if (landBitmap[x, y]) | 577 | if (landBitmap[x, y]) |
577 | { | 578 | { |
@@ -601,9 +602,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
601 | ILandObject land; | 602 | ILandObject land; |
602 | lock (m_landList) | 603 | lock (m_landList) |
603 | { | 604 | { |
604 | for (int x = 0; x < 64; x++) | 605 | for (int x = 0; x < m_landIDList.GetLength(0); x++) |
605 | { | 606 | { |
606 | for (int y = 0; y < 64; y++) | 607 | for (int y = 0; y < m_landIDList.GetLength(1); y++) |
607 | { | 608 | { |
608 | if (m_landIDList[x, y] == local_id) | 609 | if (m_landIDList[x, y] == local_id) |
609 | { | 610 | { |
@@ -656,9 +657,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
656 | bool[,] landBitmapSlave = slave.GetLandBitmap(); | 657 | bool[,] landBitmapSlave = slave.GetLandBitmap(); |
657 | lock (m_landList) | 658 | lock (m_landList) |
658 | { | 659 | { |
659 | for (int x = 0; x < 64; x++) | 660 | for (int x = 0; x < landBitmapSlave.GetLength(0); x++) |
660 | { | 661 | { |
661 | for (int y = 0; y < 64; y++) | 662 | for (int y = 0; y < landBitmapSlave.GetLength(1); y++) |
662 | { | 663 | { |
663 | if (landBitmapSlave[x, y]) | 664 | if (landBitmapSlave[x, y]) |
664 | { | 665 | { |
@@ -695,20 +696,23 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
695 | int x; | 696 | int x; |
696 | int y; | 697 | int y; |
697 | 698 | ||
698 | if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0) | 699 | if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0) |
699 | return null; | 700 | return null; |
700 | 701 | ||
701 | try | 702 | try |
702 | { | 703 | { |
703 | x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0)); | 704 | x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit)); |
704 | y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0)); | 705 | y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit)); |
705 | } | 706 | } |
706 | catch (OverflowException) | 707 | catch (OverflowException) |
707 | { | 708 | { |
708 | return null; | 709 | return null; |
709 | } | 710 | } |
710 | 711 | ||
711 | if (x >= 64 || y >= 64 || x < 0 || y < 0) | 712 | if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit) |
713 | || y >= (m_scene.RegionInfo.RegionSizeY / landUnit) | ||
714 | || x < 0 | ||
715 | || y < 0) | ||
712 | { | 716 | { |
713 | return null; | 717 | return null; |
714 | } | 718 | } |
@@ -740,20 +744,20 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
740 | int avx = (int)x; | 744 | int avx = (int)x; |
741 | if (avx < 0) | 745 | if (avx < 0) |
742 | avx = 0; | 746 | avx = 0; |
743 | else if (avx >= (int)Constants.RegionSize) | 747 | else if (avx >= m_scene.RegionInfo.RegionSizeX) |
744 | avx = (int)Constants.RegionSize - 1; | 748 | avx = (int)Constants.RegionSize - 1; |
745 | 749 | ||
746 | int avy = (int)y; | 750 | int avy = (int)y; |
747 | if (avy < 0) | 751 | if (avy < 0) |
748 | avy = 0; | 752 | avy = 0; |
749 | else if (avy >= (int)Constants.RegionSize) | 753 | else if (avy >= m_scene.RegionInfo.RegionSizeY) |
750 | avy = (int)Constants.RegionSize - 1; | 754 | avy = (int)Constants.RegionSize - 1; |
751 | 755 | ||
752 | lock (m_landIDList) | 756 | lock (m_landIDList) |
753 | { | 757 | { |
754 | try | 758 | try |
755 | { | 759 | { |
756 | return m_landList[m_landIDList[avx / 4, avy / 4]]; | 760 | return m_landList[m_landIDList[avx / landUnit, avy / landUnit]]; |
757 | } | 761 | } |
758 | catch (IndexOutOfRangeException) | 762 | catch (IndexOutOfRangeException) |
759 | { | 763 | { |
@@ -764,7 +768,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
764 | 768 | ||
765 | public ILandObject GetLandObject(int x, int y) | 769 | public ILandObject GetLandObject(int x, int y) |
766 | { | 770 | { |
767 | if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) | 771 | if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0) |
768 | { | 772 | { |
769 | // These exceptions here will cause a lot of complaints from the users specifically because | 773 | // These exceptions here will cause a lot of complaints from the users specifically because |
770 | // they happen every time at border crossings | 774 | // they happen every time at border crossings |
@@ -1057,9 +1061,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1057 | int byteArrayCount = 0; | 1061 | int byteArrayCount = 0; |
1058 | int sequenceID = 0; | 1062 | int sequenceID = 0; |
1059 | 1063 | ||
1060 | for (int y = 0; y < Constants.RegionSize; y += 4) | 1064 | // Layer data is in landUnit (4m) chunks |
1065 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += landUnit) | ||
1061 | { | 1066 | { |
1062 | for (int x = 0; x < Constants.RegionSize; x += 4) | 1067 | for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += landUnit) |
1063 | { | 1068 | { |
1064 | byte tempByte = 0; //This represents the byte for the current 4x4 | 1069 | byte tempByte = 0; //This represents the byte for the current 4x4 |
1065 | 1070 | ||
@@ -1769,7 +1774,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1769 | { | 1774 | { |
1770 | // most likely still cached from building the extLandData entry | 1775 | // most likely still cached from building the extLandData entry |
1771 | uint x = 0, y = 0; | 1776 | uint x = 0, y = 0; |
1772 | Utils.LongToUInts(data.RegionHandle, out x, out y); | 1777 | Util.RegionHandleToWorldLoc(data.RegionHandle, out x, out y); |
1773 | info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); | 1778 | info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); |
1774 | } | 1779 | } |
1775 | // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. | 1780 | // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index a3cd4a5..5858d6c 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -45,15 +45,13 @@ 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 readonly int landUnit = 4; |
51 | private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; | ||
52 | 51 | ||
53 | private int m_lastSeqId = 0; | 52 | private int m_lastSeqId = 0; |
54 | private int m_expiryCounter = 0; | 53 | private int m_expiryCounter = 0; |
55 | 54 | ||
56 | protected LandData m_landData = new LandData(); | ||
57 | protected Scene m_scene; | 55 | protected Scene m_scene; |
58 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); | 56 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); |
59 | protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); | 57 | protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); |
@@ -61,6 +59,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
61 | protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); | 59 | protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); |
62 | protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds | 60 | protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds |
63 | 61 | ||
62 | private bool[,] m_landBitmap; | ||
64 | public bool[,] LandBitmap | 63 | public bool[,] LandBitmap |
65 | { | 64 | { |
66 | get { return m_landBitmap; } | 65 | get { return m_landBitmap; } |
@@ -76,6 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
76 | return free; | 75 | return free; |
77 | } | 76 | } |
78 | 77 | ||
78 | protected LandData m_landData; | ||
79 | public LandData LandData | 79 | public LandData LandData |
80 | { | 80 | { |
81 | get { return m_landData; } | 81 | get { return m_landData; } |
@@ -94,12 +94,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
94 | { | 94 | { |
95 | get | 95 | get |
96 | { | 96 | { |
97 | for (int y = 0; y < landArrayMax; y++) | 97 | for (int y = 0; y < LandBitmap.GetLength(1); y++) |
98 | { | 98 | { |
99 | for (int x = 0; x < landArrayMax; x++) | 99 | for (int x = 0; x < LandBitmap.GetLength(0); x++) |
100 | { | 100 | { |
101 | if (LandBitmap[x, y]) | 101 | if (LandBitmap[x, y]) |
102 | return new Vector3(x * 4, y * 4, 0); | 102 | return new Vector3(x * landUnit, y * landUnit, 0); |
103 | } | 103 | } |
104 | } | 104 | } |
105 | 105 | ||
@@ -111,13 +111,13 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
111 | { | 111 | { |
112 | get | 112 | get |
113 | { | 113 | { |
114 | for (int y = landArrayMax - 1; y >= 0; y--) | 114 | for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--) |
115 | { | 115 | { |
116 | for (int x = landArrayMax - 1; x >= 0; x--) | 116 | for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--) |
117 | { | 117 | { |
118 | if (LandBitmap[x, y]) | 118 | if (LandBitmap[x, y]) |
119 | { | 119 | { |
120 | return new Vector3(x * 4 + 4, y * 4 + 4, 0); | 120 | return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0); |
121 | } | 121 | } |
122 | } | 122 | } |
123 | } | 123 | } |
@@ -128,9 +128,21 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
128 | 128 | ||
129 | #region Constructors | 129 | #region Constructors |
130 | 130 | ||
131 | public LandObject(LandData landData, Scene scene) | ||
132 | { | ||
133 | LandData = landData.Copy(); | ||
134 | m_scene = scene; | ||
135 | } | ||
136 | |||
131 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) | 137 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) |
132 | { | 138 | { |
133 | m_scene = scene; | 139 | m_scene = scene; |
140 | if (m_scene == null) | ||
141 | LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit]; | ||
142 | else | ||
143 | LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; | ||
144 | |||
145 | LandData = new LandData(); | ||
134 | LandData.OwnerID = owner_id; | 146 | LandData.OwnerID = owner_id; |
135 | if (is_group_owned) | 147 | if (is_group_owned) |
136 | LandData.GroupID = owner_id; | 148 | LandData.GroupID = owner_id; |
@@ -155,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
155 | /// <returns>Returns true if the piece of land contains the specified point</returns> | 167 | /// <returns>Returns true if the piece of land contains the specified point</returns> |
156 | public bool ContainsPoint(int x, int y) | 168 | public bool ContainsPoint(int x, int y) |
157 | { | 169 | { |
158 | if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize) | 170 | if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY) |
159 | { | 171 | { |
160 | return (LandBitmap[x / 4, y / 4] == true); | 172 | return LandBitmap[x / landUnit, y / landUnit]; |
161 | } | 173 | } |
162 | else | 174 | else |
163 | { | 175 | { |
@@ -197,10 +209,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
197 | else | 209 | else |
198 | { | 210 | { |
199 | // Normal Calculations | 211 | // Normal Calculations |
200 | int parcelMax = (int)((long)LandData.Area | 212 | int parcelMax = (int)( (long)LandData.Area |
201 | * (long)m_scene.RegionInfo.ObjectCapacity | 213 | * (long)m_scene.RegionInfo.ObjectCapacity |
202 | * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus | 214 | * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus |
203 | / 65536L); | 215 | / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) ); |
204 | //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); | 216 | //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); |
205 | return parcelMax; | 217 | return parcelMax; |
206 | } | 218 | } |
@@ -231,8 +243,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
231 | else | 243 | else |
232 | { | 244 | { |
233 | //Normal Calculations | 245 | //Normal Calculations |
234 | int simMax = (int)((long)LandData.SimwideArea | 246 | int simMax = (int)( (long)LandData.SimwideArea |
235 | * (long)m_scene.RegionInfo.ObjectCapacity / 65536L); | 247 | * (long)m_scene.RegionInfo.ObjectCapacity |
248 | / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) ); | ||
236 | // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax); | 249 | // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax); |
237 | return simMax; | 250 | return simMax; |
238 | } | 251 | } |
@@ -597,8 +610,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
597 | try | 610 | try |
598 | { | 611 | { |
599 | over = | 612 | over = |
600 | m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), | 613 | m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)), |
601 | Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); | 614 | Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1))); |
602 | } | 615 | } |
603 | catch (Exception) | 616 | catch (Exception) |
604 | { | 617 | { |
@@ -752,9 +765,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
752 | int max_y = Int32.MinValue; | 765 | int max_y = Int32.MinValue; |
753 | int tempArea = 0; | 766 | int tempArea = 0; |
754 | int x, y; | 767 | int x, y; |
755 | for (x = 0; x < 64; x++) | 768 | for (x = 0; x < LandBitmap.GetLength(0); x++) |
756 | { | 769 | { |
757 | for (y = 0; y < 64; y++) | 770 | for (y = 0; y < LandBitmap.GetLength(1); y++) |
758 | { | 771 | { |
759 | if (LandBitmap[x, y] == true) | 772 | if (LandBitmap[x, y] == true) |
760 | { | 773 | { |
@@ -766,23 +779,25 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
766 | max_x = x; | 779 | max_x = x; |
767 | if (max_y < y) | 780 | if (max_y < y) |
768 | max_y = y; | 781 | max_y = y; |
769 | tempArea += 16; //16sqm peice of land | 782 | tempArea += landUnit * landUnit; //16sqm peice of land |
770 | } | 783 | } |
771 | } | 784 | } |
772 | } | 785 | } |
786 | int tx = min_x * landUnit; | ||
787 | if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) | ||
788 | tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); | ||
773 | 789 | ||
774 | int tx = min_x * 4; | ||
775 | int htx; | 790 | int htx; |
776 | if (tx == ((int)Constants.RegionSize)) | 791 | if (tx >= ((int)m_scene.RegionInfo.RegionSizeX)) |
777 | htx = tx - 1; | 792 | htx = (int)m_scene.RegionInfo.RegionSizeX - 1; |
778 | else | 793 | else |
779 | htx = tx; | 794 | htx = tx; |
780 | 795 | ||
781 | int ty = min_y * 4; | 796 | int ty = min_y * landUnit; |
782 | int hty; | 797 | int hty; |
783 | 798 | ||
784 | if (ty == ((int)Constants.RegionSize)) | 799 | if (ty >= ((int)m_scene.RegionInfo.RegionSizeY)) |
785 | hty = ty - 1; | 800 | hty = (int)m_scene.RegionInfo.RegionSizeY - 1; |
786 | else | 801 | else |
787 | hty = ty; | 802 | hty = ty; |
788 | 803 | ||
@@ -791,17 +806,17 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
791 | (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0); | 806 | (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0); |
792 | 807 | ||
793 | max_x++; | 808 | max_x++; |
794 | tx = max_x * 4; | 809 | tx = max_x * landUnit; |
795 | if (tx == ((int)Constants.RegionSize)) | 810 | if (tx >= ((int)m_scene.RegionInfo.RegionSizeX)) |
796 | htx = tx - 1; | 811 | htx = (int)m_scene.RegionInfo.RegionSizeX - 1; |
797 | else | 812 | else |
798 | htx = tx; | 813 | htx = tx; |
799 | 814 | ||
800 | max_y++; | 815 | max_y++; |
801 | ty = max_y * 4; | 816 | ty = max_y * 4; |
802 | 817 | ||
803 | if (ty == ((int)Constants.RegionSize)) | 818 | if (ty >= ((int)m_scene.RegionInfo.RegionSizeY)) |
804 | hty = ty - 1; | 819 | hty = (int)m_scene.RegionInfo.RegionSizeY - 1; |
805 | else | 820 | else |
806 | hty = ty; | 821 | hty = ty; |
807 | 822 | ||
@@ -819,20 +834,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
819 | /// <summary> | 834 | /// <summary> |
820 | /// Sets the land's bitmap manually | 835 | /// Sets the land's bitmap manually |
821 | /// </summary> | 836 | /// </summary> |
822 | /// <param name="bitmap">64x64 block representing where this land is on a map</param> | 837 | /// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param> |
823 | public void SetLandBitmap(bool[,] bitmap) | 838 | public void SetLandBitmap(bool[,] bitmap) |
824 | { | 839 | { |
825 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) | 840 | LandBitmap = bitmap; |
826 | { | 841 | ForceUpdateLandInfo(); |
827 | //Throw an exception - The bitmap is not 64x64 | ||
828 | //throw new Exception("Error: Invalid Parcel Bitmap"); | ||
829 | } | ||
830 | else | ||
831 | { | ||
832 | //Valid: Lets set it | ||
833 | LandBitmap = bitmap; | ||
834 | ForceUpdateLandInfo(); | ||
835 | } | ||
836 | } | 842 | } |
837 | 843 | ||
838 | /// <summary> | 844 | /// <summary> |
@@ -846,14 +852,16 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
846 | 852 | ||
847 | public bool[,] BasicFullRegionLandBitmap() | 853 | public bool[,] BasicFullRegionLandBitmap() |
848 | { | 854 | { |
849 | return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); | 855 | return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY); |
850 | } | 856 | } |
851 | 857 | ||
852 | public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) | 858 | public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) |
853 | { | 859 | { |
854 | bool[,] tempBitmap = new bool[64,64]; | 860 | // Empty bitmap for the whole region |
861 | bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; | ||
855 | tempBitmap.Initialize(); | 862 | tempBitmap.Initialize(); |
856 | 863 | ||
864 | // Fill the bitmap square area specified by state and end | ||
857 | tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); | 865 | tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); |
858 | return tempBitmap; | 866 | return tempBitmap; |
859 | } | 867 | } |
@@ -871,19 +879,13 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
871 | public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, | 879 | public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, |
872 | bool set_value) | 880 | bool set_value) |
873 | { | 881 | { |
874 | if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) | ||
875 | { | ||
876 | //Throw an exception - The bitmap is not 64x64 | ||
877 | //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); | ||
878 | } | ||
879 | |||
880 | int x, y; | 882 | int x, y; |
881 | for (y = 0; y < 64; y++) | 883 | for (y = 0; y < land_bitmap.GetLength(1); y++) |
882 | { | 884 | { |
883 | for (x = 0; x < 64; x++) | 885 | for (x = 0; x < land_bitmap.GetLength(0); x++) |
884 | { | 886 | { |
885 | if (x >= start_x / 4 && x < end_x / 4 | 887 | if (x >= start_x / landUnit && x < end_x / landUnit |
886 | && y >= start_y / 4 && y < end_y / 4) | 888 | && y >= start_y / landUnit && y < end_y / landUnit) |
887 | { | 889 | { |
888 | land_bitmap[x, y] = set_value; | 890 | land_bitmap[x, y] = set_value; |
889 | } | 891 | } |
@@ -900,21 +902,21 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
900 | /// <returns></returns> | 902 | /// <returns></returns> |
901 | public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) | 903 | public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) |
902 | { | 904 | { |
903 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) | 905 | if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0) |
904 | { | 906 | || bitmap_base.GetLength(1) != bitmap_add.GetLength(1) |
905 | //Throw an exception - The bitmap is not 64x64 | 907 | || bitmap_add.Rank != 2 |
906 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); | 908 | || bitmap_base.Rank != 2) |
907 | } | ||
908 | if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) | ||
909 | { | 909 | { |
910 | //Throw an exception - The bitmap is not 64x64 | 910 | throw new Exception( |
911 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); | 911 | String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>", |
912 | LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1)) | ||
913 | ); | ||
912 | } | 914 | } |
913 | 915 | ||
914 | int x, y; | 916 | int x, y; |
915 | for (y = 0; y < 64; y++) | 917 | for (y = 0; y < bitmap_base.GetLength(1); y++) |
916 | { | 918 | { |
917 | for (x = 0; x < 64; x++) | 919 | for (x = 0; x < bitmap_add.GetLength(0); x++) |
918 | { | 920 | { |
919 | if (bitmap_add[x, y]) | 921 | if (bitmap_add[x, y]) |
920 | { | 922 | { |
@@ -931,14 +933,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
931 | /// <returns></returns> | 933 | /// <returns></returns> |
932 | private byte[] ConvertLandBitmapToBytes() | 934 | private byte[] ConvertLandBitmapToBytes() |
933 | { | 935 | { |
934 | byte[] tempConvertArr = new byte[512]; | 936 | byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8]; |
935 | int tempByte = 0; | 937 | int tempByte = 0; |
936 | int x, y, i, byteNum = 0; | 938 | int i, byteNum = 0; |
937 | int mask = 1; | 939 | int mask = 1; |
938 | i = 0; | 940 | i = 0; |
939 | for (y = 0; y < 64; y++) | 941 | for (int y = 0; y < LandBitmap.GetLength(1); y++) |
940 | { | 942 | { |
941 | for (x = 0; x < 64; x++) | 943 | for (int x = 0; x < LandBitmap.GetLength(0); x++) |
942 | { | 944 | { |
943 | if (LandBitmap[x, y]) | 945 | if (LandBitmap[x, y]) |
944 | tempByte |= mask; | 946 | tempByte |= mask; |
@@ -971,25 +973,45 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
971 | 973 | ||
972 | private bool[,] ConvertBytesToLandBitmap() | 974 | private bool[,] ConvertBytesToLandBitmap() |
973 | { | 975 | { |
974 | bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; | 976 | bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; |
975 | tempConvertMap.Initialize(); | 977 | tempConvertMap.Initialize(); |
976 | byte tempByte = 0; | 978 | byte tempByte = 0; |
977 | int x = 0, y = 0, i = 0, bitNum = 0; | 979 | // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap. |
978 | for (i = 0; i < 512; i++) | 980 | int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8); |
981 | int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit); | ||
982 | |||
983 | if (bitmapLen == 512) | ||
984 | { | ||
985 | // Legacy bitmap being passed in. Use the legacy region size | ||
986 | // and only set the lower area of the larger region. | ||
987 | xLen = (int)(Constants.RegionSize / landUnit); | ||
988 | } | ||
989 | // m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen); | ||
990 | |||
991 | int x = 0, y = 0; | ||
992 | for (int i = 0; i < bitmapLen; i++) | ||
979 | { | 993 | { |
980 | tempByte = LandData.Bitmap[i]; | 994 | tempByte = LandData.Bitmap[i]; |
981 | for (bitNum = 0; bitNum < 8; bitNum++) | 995 | for (int bitNum = 0; bitNum < 8; bitNum++) |
982 | { | 996 | { |
983 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); | 997 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); |
984 | tempConvertMap[x, y] = bit; | 998 | try |
999 | { | ||
1000 | tempConvertMap[x, y] = bit; | ||
1001 | } | ||
1002 | catch (Exception) | ||
1003 | { | ||
1004 | m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y); | ||
1005 | } | ||
985 | x++; | 1006 | x++; |
986 | if (x > 63) | 1007 | if (x >= xLen) |
987 | { | 1008 | { |
988 | x = 0; | 1009 | x = 0; |
989 | y++; | 1010 | y++; |
990 | } | 1011 | } |
991 | } | 1012 | } |
992 | } | 1013 | } |
1014 | |||
993 | return tempConvertMap; | 1015 | return tempConvertMap; |
994 | } | 1016 | } |
995 | 1017 | ||
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index bc52a43..c7ffeaf 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs | |||
@@ -102,7 +102,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
102 | 102 | ||
103 | terrainRenderer.Initialise(m_scene, m_config); | 103 | terrainRenderer.Initialise(m_scene, m_config); |
104 | 104 | ||
105 | mapbmp = new Bitmap((int)Constants.RegionSize, (int)Constants.RegionSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb); | 105 | mapbmp = new Bitmap((int)m_scene.Heightmap.Width, (int)m_scene.Heightmap.Height, |
106 | System.Drawing.Imaging.PixelFormat.Format24bppRgb); | ||
106 | //long t = System.Environment.TickCount; | 107 | //long t = System.Environment.TickCount; |
107 | //for (int i = 0; i < 10; ++i) { | 108 | //for (int i = 0; i < 10; ++i) { |
108 | terrainRenderer.TerrainToBitmap(mapbmp); | 109 | terrainRenderer.TerrainToBitmap(mapbmp); |
@@ -277,7 +278,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
277 | private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp) | 278 | private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp) |
278 | { | 279 | { |
279 | int tc = 0; | 280 | int tc = 0; |
280 | double[,] hm = whichScene.Heightmap.GetDoubles(); | 281 | ITerrainChannel hm = whichScene.Heightmap; |
281 | tc = Environment.TickCount; | 282 | tc = Environment.TickCount; |
282 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); | 283 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); |
283 | EntityBase[] objs = whichScene.GetEntities(); | 284 | EntityBase[] objs = whichScene.GetEntities(); |
@@ -363,7 +364,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
363 | Vector3 pos = part.GetWorldPosition(); | 364 | Vector3 pos = part.GetWorldPosition(); |
364 | 365 | ||
365 | // skip prim outside of retion | 366 | // skip prim outside of retion |
366 | if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) | 367 | if (!m_scene.PositionIsInCurrentRegion(pos)) |
367 | continue; | 368 | continue; |
368 | 369 | ||
369 | // skip prim in non-finite position | 370 | // skip prim in non-finite position |
@@ -388,7 +389,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
388 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); | 389 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); |
389 | Vector3 scale = new Vector3(); | 390 | Vector3 scale = new Vector3(); |
390 | Vector3 tScale = new Vector3(); | 391 | Vector3 tScale = new Vector3(); |
391 | Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | 392 | Vector3 axPos = new Vector3(pos.X, pos.Y, pos.Z); |
392 | 393 | ||
393 | Quaternion llrot = part.GetWorldRotation(); | 394 | Quaternion llrot = part.GetWorldRotation(); |
394 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | 395 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); |
@@ -406,9 +407,14 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
406 | int mapdrawendY = (int)(pos.Y + scale.Y); | 407 | int mapdrawendY = (int)(pos.Y + scale.Y); |
407 | 408 | ||
408 | // If object is beyond the edge of the map, don't draw it to avoid errors | 409 | // If object is beyond the edge of the map, don't draw it to avoid errors |
409 | if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | 410 | if (mapdrawstartX < 0 |
410 | || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | 411 | || mapdrawstartX > (hm.Width - 1) |
411 | || mapdrawendY > ((int)Constants.RegionSize - 1)) | 412 | || mapdrawendX < 0 |
413 | || mapdrawendX > (hm.Width - 1) | ||
414 | || mapdrawstartY < 0 | ||
415 | || mapdrawstartY > (hm.Height - 1) | ||
416 | || mapdrawendY < 0 | ||
417 | || mapdrawendY > (hm.Height - 1)) | ||
412 | continue; | 418 | continue; |
413 | 419 | ||
414 | #region obb face reconstruction part duex | 420 | #region obb face reconstruction part duex |
@@ -530,11 +536,11 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
530 | for (int i = 0; i < FaceA.Length; i++) | 536 | for (int i = 0; i < FaceA.Length; i++) |
531 | { | 537 | { |
532 | Point[] working = new Point[5]; | 538 | Point[] working = new Point[5]; |
533 | working[0] = project(FaceA[i], axPos); | 539 | working[0] = project(hm, FaceA[i], axPos); |
534 | working[1] = project(FaceB[i], axPos); | 540 | working[1] = project(hm, FaceB[i], axPos); |
535 | working[2] = project(FaceD[i], axPos); | 541 | working[2] = project(hm, FaceD[i], axPos); |
536 | working[3] = project(FaceC[i], axPos); | 542 | working[3] = project(hm, FaceC[i], axPos); |
537 | working[4] = project(FaceA[i], axPos); | 543 | working[4] = project(hm, FaceA[i], axPos); |
538 | 544 | ||
539 | face workingface = new face(); | 545 | face workingface = new face(); |
540 | workingface.pts = working; | 546 | workingface.pts = working; |
@@ -609,17 +615,17 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
609 | return mapbmp; | 615 | return mapbmp; |
610 | } | 616 | } |
611 | 617 | ||
612 | private Point project(Vector3 point3d, Vector3 originpos) | 618 | private Point project(ITerrainChannel hm, Vector3 point3d, Vector3 originpos) |
613 | { | 619 | { |
614 | Point returnpt = new Point(); | 620 | Point returnpt = new Point(); |
615 | //originpos = point3d; | 621 | //originpos = point3d; |
616 | //int d = (int)(256f / 1.5f); | 622 | //int d = (int)(256f / 1.5f); |
617 | 623 | ||
618 | //Vector3 topos = new Vector3(0, 0, 0); | 624 | //Vector3 topos = new Vector3(0, 0, 0); |
619 | // float z = -point3d.z - topos.z; | 625 | // float z = -point3d.z - topos.z; |
620 | 626 | ||
621 | returnpt.X = (int)point3d.X;//(int)((topos.x - point3d.x) / z * d); | 627 | returnpt.X = (int)point3d.X;//(int)((topos.x - point3d.x) / z * d); |
622 | returnpt.Y = (int)(((int)Constants.RegionSize - 1) - point3d.Y);//(int)(255 - (((topos.y - point3d.y) / z * d))); | 628 | returnpt.Y = (int)((hm.Width - 1) - point3d.Y);//(int)(255 - (((topos.y - point3d.y) / z * d))); |
623 | 629 | ||
624 | return returnpt; | 630 | return returnpt; |
625 | } | 631 | } |
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs index cb06fd4..708286c 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs | |||
@@ -31,6 +31,7 @@ using System.Reflection; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Framework.Interfaces; | ||
34 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
35 | 36 | ||
36 | namespace OpenSim.Region.CoreModules.World.LegacyMap | 37 | namespace OpenSim.Region.CoreModules.World.LegacyMap |
@@ -39,8 +40,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
39 | { | 40 | { |
40 | private static readonly Color WATER_COLOR = Color.FromArgb(29, 71, 95); | 41 | private static readonly Color WATER_COLOR = Color.FromArgb(29, 71, 95); |
41 | 42 | ||
42 | private static readonly ILog m_log = | 43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly string LogHeader = "[SHADED MAPTILE RENDERER]"; |
44 | 45 | ||
45 | private Scene m_scene; | 46 | private Scene m_scene; |
46 | //private IConfigSource m_config; // not used currently | 47 | //private IConfigSource m_config; // not used currently |
@@ -53,19 +54,26 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
53 | 54 | ||
54 | public void TerrainToBitmap(Bitmap mapbmp) | 55 | public void TerrainToBitmap(Bitmap mapbmp) |
55 | { | 56 | { |
57 | m_log.DebugFormat("{0} Generating Maptile Step 1: Terrain", LogHeader); | ||
56 | int tc = Environment.TickCount; | 58 | int tc = Environment.TickCount; |
57 | m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Terrain"); | ||
58 | 59 | ||
59 | double[,] hm = m_scene.Heightmap.GetDoubles(); | 60 | ITerrainChannel hm = m_scene.Heightmap; |
61 | |||
62 | if (mapbmp.Width != hm.Width || mapbmp.Height != hm.Height) | ||
63 | { | ||
64 | m_log.ErrorFormat("{0} TerrainToBitmap. Passed bitmap wrong dimensions. passed=<{1},{2}>, size=<{3},{4}>", | ||
65 | LogHeader, mapbmp.Width, mapbmp.Height, hm.Width, hm.Height); | ||
66 | } | ||
67 | |||
60 | bool ShadowDebugContinue = true; | 68 | bool ShadowDebugContinue = true; |
61 | 69 | ||
62 | bool terraincorruptedwarningsaid = false; | 70 | bool terraincorruptedwarningsaid = false; |
63 | 71 | ||
64 | float low = 255; | 72 | float low = 255; |
65 | float high = 0; | 73 | float high = 0; |
66 | for (int x = 0; x < (int)Constants.RegionSize; x++) | 74 | for (int x = 0; x < hm.Width; x++) |
67 | { | 75 | { |
68 | for (int y = 0; y < (int)Constants.RegionSize; y++) | 76 | for (int y = 0; y < hm.Height; y++) |
69 | { | 77 | { |
70 | float hmval = (float)hm[x, y]; | 78 | float hmval = (float)hm[x, y]; |
71 | if (hmval < low) | 79 | if (hmval < low) |
@@ -77,12 +85,12 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
77 | 85 | ||
78 | float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; | 86 | float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; |
79 | 87 | ||
80 | for (int x = 0; x < (int)Constants.RegionSize; x++) | 88 | for (int x = 0; x < hm.Width; x++) |
81 | { | 89 | { |
82 | for (int y = 0; y < (int)Constants.RegionSize; y++) | 90 | for (int y = 0; y < hm.Height; y++) |
83 | { | 91 | { |
84 | // Y flip the cordinates for the bitmap: hf origin is lower left, bm origin is upper left | 92 | // Y flip the cordinates for the bitmap: hf origin is lower left, bm origin is upper left |
85 | int yr = ((int)Constants.RegionSize - 1) - y; | 93 | int yr = ((int)hm.Height - 1) - y; |
86 | 94 | ||
87 | float heightvalue = (float)hm[x, y]; | 95 | float heightvalue = (float)hm[x, y]; |
88 | 96 | ||
@@ -109,12 +117,12 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
109 | // . | 117 | // . |
110 | // | 118 | // |
111 | // Shade the terrain for shadows | 119 | // Shade the terrain for shadows |
112 | if (x < ((int)Constants.RegionSize - 1) && yr < ((int)Constants.RegionSize - 1)) | 120 | if (x < (hm.Width - 1) && yr < (hm.Height - 1)) |
113 | { | 121 | { |
114 | float hfvalue = (float)hm[x, y]; | 122 | float hfvalue = (float)hm[x, y]; |
115 | float hfvaluecompare = 0f; | 123 | float hfvaluecompare = 0f; |
116 | 124 | ||
117 | if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize)) | 125 | if ((x + 1 < hm.Width) && (y + 1 < hm.Height)) |
118 | { | 126 | { |
119 | hfvaluecompare = (float)hm[x + 1, y + 1]; // light from north-east => look at land height there | 127 | hfvaluecompare = (float)hm[x + 1, y + 1]; // light from north-east => look at land height there |
120 | } | 128 | } |
@@ -179,7 +187,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
179 | 187 | ||
180 | if (ShadowDebugContinue) | 188 | if (ShadowDebugContinue) |
181 | { | 189 | { |
182 | if ((x - 1 > 0) && (yr + 1 < (int)Constants.RegionSize)) | 190 | if ((x - 1 > 0) && (yr + 1 < hm.Height)) |
183 | { | 191 | { |
184 | color = mapbmp.GetPixel(x - 1, yr + 1); | 192 | color = mapbmp.GetPixel(x - 1, yr + 1); |
185 | int r = color.R; | 193 | int r = color.R; |
@@ -233,7 +241,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
233 | terraincorruptedwarningsaid = true; | 241 | terraincorruptedwarningsaid = true; |
234 | } | 242 | } |
235 | Color black = Color.Black; | 243 | Color black = Color.Black; |
236 | mapbmp.SetPixel(x, ((int)Constants.RegionSize - y) - 1, black); | 244 | mapbmp.SetPixel(x, (hm.Width - y) - 1, black); |
237 | } | 245 | } |
238 | } | 246 | } |
239 | } | 247 | } |
@@ -242,4 +250,4 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
242 | m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 250 | m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); |
243 | } | 251 | } |
244 | } | 252 | } |
245 | } \ No newline at end of file | 253 | } |
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index d4e4c25..014c845 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | |||
@@ -151,14 +151,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell | |||
151 | break; | 151 | break; |
152 | 152 | ||
153 | case 2: // Sell a copy | 153 | case 2: // Sell a copy |
154 | Vector3 inventoryStoredPosition = new Vector3 | 154 | Vector3 inventoryStoredPosition = new Vector3( |
155 | (((group.AbsolutePosition.X > (int)Constants.RegionSize) | 155 | Math.Min(group.AbsolutePosition.X, m_scene.RegionInfo.RegionSizeX - 6), |
156 | ? 250 | 156 | Math.Min(group.AbsolutePosition.Y, m_scene.RegionInfo.RegionSizeY - 6), |
157 | : group.AbsolutePosition.X) | ||
158 | , | ||
159 | (group.AbsolutePosition.X > (int)Constants.RegionSize) | ||
160 | ? 250 | ||
161 | : group.AbsolutePosition.X, | ||
162 | group.AbsolutePosition.Z); | 157 | group.AbsolutePosition.Z); |
163 | 158 | ||
164 | Vector3 originalPosition = group.AbsolutePosition; | 159 | Vector3 originalPosition = group.AbsolutePosition; |
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 616fe98..928755d 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..80396c4 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; |
@@ -53,4 +53,4 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects | |||
53 | 53 | ||
54 | #endregion | 54 | #endregion |
55 | } | 55 | } |
56 | } \ No newline at end of file | 56 | } |
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/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index b5c7d33..a7e4d9f 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs | |||
@@ -154,10 +154,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
154 | 154 | ||
155 | public ITerrainChannel LoadStream(Stream s) | 155 | public ITerrainChannel LoadStream(Stream s) |
156 | { | 156 | { |
157 | 157 | // Set to default size | |
158 | int w = (int)Constants.RegionSize; | 158 | int w = (int)Constants.RegionSize; |
159 | int h = (int)Constants.RegionSize; | 159 | int h = (int)Constants.RegionSize; |
160 | 160 | ||
161 | // create a dummy channel (in case data is bad) | ||
161 | TerrainChannel retval = new TerrainChannel(w, h); | 162 | TerrainChannel retval = new TerrainChannel(w, h); |
162 | 163 | ||
163 | BinaryReader bs = new BinaryReader(s); | 164 | BinaryReader bs = new BinaryReader(s); |
@@ -165,8 +166,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
165 | bool eof = false; | 166 | bool eof = false; |
166 | if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") | 167 | if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") |
167 | { | 168 | { |
168 | // int fileWidth = w; | ||
169 | // int fileHeight = h; | ||
170 | 169 | ||
171 | // Terragen file | 170 | // Terragen file |
172 | while (eof == false) | 171 | while (eof == false) |
@@ -175,31 +174,29 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
175 | switch (tmp) | 174 | switch (tmp) |
176 | { | 175 | { |
177 | case "SIZE": | 176 | case "SIZE": |
178 | // int sztmp = bs.ReadInt16() + 1; | 177 | w = bs.ReadInt16() + 1; |
179 | // fileWidth = sztmp; | 178 | h = w; |
180 | // fileHeight = sztmp; | ||
181 | bs.ReadInt16(); | ||
182 | bs.ReadInt16(); | 179 | bs.ReadInt16(); |
183 | break; | 180 | break; |
184 | case "XPTS": | 181 | case "XPTS": |
185 | // fileWidth = bs.ReadInt16(); | 182 | w = bs.ReadInt16(); |
186 | bs.ReadInt16(); | ||
187 | bs.ReadInt16(); | 183 | bs.ReadInt16(); |
188 | break; | 184 | break; |
189 | case "YPTS": | 185 | case "YPTS": |
190 | // fileHeight = bs.ReadInt16(); | 186 | h = bs.ReadInt16(); |
191 | bs.ReadInt16(); | ||
192 | bs.ReadInt16(); | 187 | bs.ReadInt16(); |
193 | break; | 188 | break; |
194 | case "ALTW": | 189 | case "ALTW": |
195 | eof = true; | 190 | eof = true; |
196 | Int16 heightScale = bs.ReadInt16(); | 191 | // create new channel of proper size (now that we know it) |
197 | Int16 baseHeight = bs.ReadInt16(); | 192 | retval = new TerrainChannel(w, h); |
193 | double heightScale = (double)bs.ReadInt16() / 65536.0; | ||
194 | double baseHeight = (double)bs.ReadInt16(); | ||
198 | for (int y = 0; y < h; y++) | 195 | for (int y = 0; y < h; y++) |
199 | { | 196 | { |
200 | for (int x = 0; x < w; x++) | 197 | for (int x = 0; x < w; x++) |
201 | { | 198 | { |
202 | retval[x, y] = baseHeight + bs.ReadInt16() * (double)heightScale / 65536.0; | 199 | retval[x, y] = baseHeight + (double)bs.ReadInt16() * heightScale; |
203 | } | 200 | } |
204 | } | 201 | } |
205 | break; | 202 | break; |
@@ -257,17 +254,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
257 | bs.Write(enc.GetBytes("TERRAGENTERRAIN ")); | 254 | bs.Write(enc.GetBytes("TERRAGENTERRAIN ")); |
258 | 255 | ||
259 | bs.Write(enc.GetBytes("SIZE")); | 256 | bs.Write(enc.GetBytes("SIZE")); |
260 | bs.Write(Convert.ToInt16(Constants.RegionSize)); | 257 | bs.Write(Convert.ToInt16(map.Width)); |
261 | bs.Write(Convert.ToInt16(0)); // necessary padding | 258 | bs.Write(Convert.ToInt16(0)); // necessary padding |
262 | 259 | ||
263 | //The XPTS and YPTS chunks are not needed for square regions | 260 | //The XPTS and YPTS chunks are not needed for square regions |
264 | //but L3DT won't load the terrain file properly without them. | 261 | //but L3DT won't load the terrain file properly without them. |
265 | bs.Write(enc.GetBytes("XPTS")); | 262 | bs.Write(enc.GetBytes("XPTS")); |
266 | bs.Write(Convert.ToInt16(Constants.RegionSize)); | 263 | bs.Write(Convert.ToInt16(map.Width)); |
267 | bs.Write(Convert.ToInt16(0)); // necessary padding | 264 | bs.Write(Convert.ToInt16(0)); // necessary padding |
268 | 265 | ||
269 | bs.Write(enc.GetBytes("YPTS")); | 266 | bs.Write(enc.GetBytes("YPTS")); |
270 | bs.Write(Convert.ToInt16(Constants.RegionSize)); | 267 | bs.Write(Convert.ToInt16(map.Height)); |
271 | bs.Write(Convert.ToInt16(0)); // necessary padding | 268 | bs.Write(Convert.ToInt16(0)); // necessary padding |
272 | 269 | ||
273 | bs.Write(enc.GetBytes("SCAL")); | 270 | bs.Write(enc.GetBytes("SCAL")); |
@@ -283,11 +280,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
283 | bs.Write(Convert.ToInt16(horizontalScale)); // range between max and min | 280 | bs.Write(Convert.ToInt16(horizontalScale)); // range between max and min |
284 | bs.Write(Convert.ToInt16(baseHeight)); // base height or mid point | 281 | bs.Write(Convert.ToInt16(baseHeight)); // base height or mid point |
285 | 282 | ||
283 | double factor = 65536.0 / horizontalScale; // avoid computing this on each iteration | ||
284 | |||
286 | for (int y = 0; y < map.Height; y++) | 285 | for (int y = 0; y < map.Height; y++) |
287 | { | 286 | { |
288 | for (int x = 0; x < map.Width; x++) | 287 | for (int x = 0; x < map.Width; x++) |
289 | { | 288 | { |
290 | float elevation = (float)((map[x,y] - baseHeight) * 65536 ) / (float)horizontalScale; // see LoadStream for inverse | 289 | float elevation = (float)((map[x,y] - baseHeight) * factor); // see LoadStream for inverse |
291 | 290 | ||
292 | // clamp rounding issues | 291 | // clamp rounding issues |
293 | if (elevation > Int16.MaxValue) | 292 | if (elevation > Int16.MaxValue) |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs index 630473e..d3e2533 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs | |||
@@ -45,7 +45,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes | |||
45 | { | 45 | { |
46 | if (fillArea[x, y]) | 46 | if (fillArea[x, y]) |
47 | { | 47 | { |
48 | double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0); | 48 | double noise = TerrainUtil.PerlinNoise2D((double) x / map.Width, (double) y / map.Height, 8, 1.0); |
49 | 49 | ||
50 | map[x, y] += noise * strength; | 50 | map[x, y] += noise * strength; |
51 | } | 51 | } |
@@ -55,4 +55,4 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes | |||
55 | 55 | ||
56 | #endregion | 56 | #endregion |
57 | } | 57 | } |
58 | } \ No newline at end of file | 58 | } |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs index 989b7d8..e7df3f8 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs | |||
@@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes | |||
53 | z *= z; | 53 | z *= z; |
54 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); | 54 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); |
55 | 55 | ||
56 | double noise = TerrainUtil.PerlinNoise2D(x / (double) Constants.RegionSize, y / (double) Constants.RegionSize, 8, 1.0); | 56 | double noise = TerrainUtil.PerlinNoise2D(x / (double) map.Width, y / (double) map.Height, 8, 1.0); |
57 | 57 | ||
58 | if (z > 0.0) | 58 | if (z > 0.0) |
59 | map[x, y] += noise * z * duration; | 59 | map[x, y] += noise * z * duration; |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 4d738a5..9a88804 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -71,6 +71,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
71 | 71 | ||
72 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 72 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
73 | 73 | ||
74 | #pragma warning disable 414 | ||
75 | private static readonly string LogHeader = "[TERRAIN MODULE]"; | ||
76 | #pragma warning restore 414 | ||
77 | |||
74 | private readonly Commander m_commander = new Commander("terrain"); | 78 | private readonly Commander m_commander = new Commander("terrain"); |
75 | 79 | ||
76 | private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = | 80 | private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = |
@@ -81,8 +85,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
81 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = | 85 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = |
82 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); | 86 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); |
83 | 87 | ||
84 | private ITerrainChannel m_channel; | ||
85 | private Dictionary<string, ITerrainEffect> m_plugineffects; | 88 | private Dictionary<string, ITerrainEffect> m_plugineffects; |
89 | private ITerrainChannel m_channel; | ||
86 | private ITerrainChannel m_revert; | 90 | private ITerrainChannel m_revert; |
87 | private Scene m_scene; | 91 | private Scene m_scene; |
88 | private volatile bool m_tainted; | 92 | private volatile bool m_tainted; |
@@ -90,6 +94,85 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
90 | 94 | ||
91 | private String m_InitialTerrain = "pinhead-island"; | 95 | private String m_InitialTerrain = "pinhead-island"; |
92 | 96 | ||
97 | // If true, send terrain patch updates to clients based on their view distance | ||
98 | private bool m_sendTerrainUpdatesByViewDistance = true; | ||
99 | |||
100 | // Class to keep the per client collection of terrain patches that must be sent. | ||
101 | // A patch is set to 'true' meaning it should be sent to the client. Once the | ||
102 | // patch packet is queued to the client, the bit for that patch is set to 'false'. | ||
103 | private class PatchUpdates | ||
104 | { | ||
105 | private bool[,] updated; // for each patch, whether it needs to be sent to this client | ||
106 | private int updateCount; // number of patches that need to be sent | ||
107 | public ScenePresence Presence; // a reference to the client to send to | ||
108 | public PatchUpdates(TerrainData terrData, ScenePresence pPresence) | ||
109 | { | ||
110 | updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize]; | ||
111 | updateCount = 0; | ||
112 | Presence = pPresence; | ||
113 | // Initially, send all patches to the client | ||
114 | SetAll(true); | ||
115 | } | ||
116 | // Returns 'true' if there are any patches marked for sending | ||
117 | public bool HasUpdates() | ||
118 | { | ||
119 | return (updateCount > 0); | ||
120 | } | ||
121 | public void SetByXY(int x, int y, bool state) | ||
122 | { | ||
123 | this.SetByPatch(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, state); | ||
124 | } | ||
125 | public bool GetByPatch(int patchX, int patchY) | ||
126 | { | ||
127 | return updated[patchX, patchY]; | ||
128 | } | ||
129 | public void SetByPatch(int patchX, int patchY, bool state) | ||
130 | { | ||
131 | bool prevState = updated[patchX, patchY]; | ||
132 | if (!prevState && state) | ||
133 | updateCount++; | ||
134 | if (prevState && !state) | ||
135 | updateCount--; | ||
136 | updated[patchX, patchY] = state; | ||
137 | } | ||
138 | public void SetAll(bool state) | ||
139 | { | ||
140 | updateCount = 0; | ||
141 | for (int xx = 0; xx < updated.GetLength(0); xx++) | ||
142 | for (int yy = 0; yy < updated.GetLength(1); yy++) | ||
143 | updated[xx, yy] = state; | ||
144 | if (state) | ||
145 | updateCount = updated.GetLength(0) * updated.GetLength(1); | ||
146 | } | ||
147 | // Logically OR's the terrain data's patch taint map into this client's update map. | ||
148 | public void SetAll(TerrainData terrData) | ||
149 | { | ||
150 | if (updated.GetLength(0) != (terrData.SizeX / Constants.TerrainPatchSize) | ||
151 | || updated.GetLength(1) != (terrData.SizeY / Constants.TerrainPatchSize)) | ||
152 | { | ||
153 | throw new Exception( | ||
154 | String.Format("{0} PatchUpdates.SetAll: patch array not same size as terrain. arr=<{1},{2}>, terr=<{3},{4}>", | ||
155 | LogHeader, updated.GetLength(0), updated.GetLength(1), | ||
156 | terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize) | ||
157 | ); | ||
158 | } | ||
159 | for (int xx = 0; xx < terrData.SizeX; xx += Constants.TerrainPatchSize) | ||
160 | { | ||
161 | for (int yy = 0; yy < terrData.SizeY; yy += Constants.TerrainPatchSize) | ||
162 | { | ||
163 | // Only set tainted. The patch bit may be set if the patch was to be sent later. | ||
164 | if (terrData.IsTaintedAt(xx, yy, false)) | ||
165 | { | ||
166 | this.SetByXY(xx, yy, true); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | |||
173 | // The flags of which terrain patches to send for each of the ScenePresence's | ||
174 | private Dictionary<UUID, PatchUpdates> m_perClientPatchUpdates = new Dictionary<UUID, PatchUpdates>(); | ||
175 | |||
93 | /// <summary> | 176 | /// <summary> |
94 | /// Human readable list of terrain file extensions that are supported. | 177 | /// Human readable list of terrain file extensions that are supported. |
95 | /// </summary> | 178 | /// </summary> |
@@ -118,7 +201,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
118 | { | 201 | { |
119 | IConfig terrainConfig = config.Configs["Terrain"]; | 202 | IConfig terrainConfig = config.Configs["Terrain"]; |
120 | if (terrainConfig != null) | 203 | if (terrainConfig != null) |
204 | { | ||
121 | m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); | 205 | m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); |
206 | m_sendTerrainUpdatesByViewDistance = terrainConfig.GetBoolean("SendTerrainUpdatesByViewDistance", m_sendTerrainUpdatesByViewDistance); | ||
207 | } | ||
122 | } | 208 | } |
123 | 209 | ||
124 | public void AddRegion(Scene scene) | 210 | public void AddRegion(Scene scene) |
@@ -130,22 +216,24 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
130 | { | 216 | { |
131 | if (m_scene.Heightmap == null) | 217 | if (m_scene.Heightmap == null) |
132 | { | 218 | { |
133 | m_channel = new TerrainChannel(m_InitialTerrain); | 219 | m_channel = new TerrainChannel(m_InitialTerrain, (int)m_scene.RegionInfo.RegionSizeX, |
220 | (int)m_scene.RegionInfo.RegionSizeY, | ||
221 | (int)m_scene.RegionInfo.RegionSizeZ); | ||
134 | m_scene.Heightmap = m_channel; | 222 | m_scene.Heightmap = m_channel; |
135 | m_revert = new TerrainChannel(); | ||
136 | UpdateRevertMap(); | 223 | UpdateRevertMap(); |
137 | } | 224 | } |
138 | else | 225 | else |
139 | { | 226 | { |
140 | m_channel = m_scene.Heightmap; | 227 | m_channel = m_scene.Heightmap; |
141 | m_revert = new TerrainChannel(); | ||
142 | UpdateRevertMap(); | 228 | UpdateRevertMap(); |
143 | } | 229 | } |
144 | 230 | ||
145 | m_scene.RegisterModuleInterface<ITerrainModule>(this); | 231 | m_scene.RegisterModuleInterface<ITerrainModule>(this); |
146 | m_scene.EventManager.OnNewClient += EventManager_OnNewClient; | 232 | m_scene.EventManager.OnNewClient += EventManager_OnNewClient; |
233 | m_scene.EventManager.OnClientClosed += EventManager_OnClientClosed; | ||
147 | m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; | 234 | m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; |
148 | m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; | 235 | m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; |
236 | m_scene.EventManager.OnFrame += EventManager_OnFrame; | ||
149 | } | 237 | } |
150 | 238 | ||
151 | InstallDefaultEffects(); | 239 | InstallDefaultEffects(); |
@@ -184,8 +272,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
184 | // remove the commands | 272 | // remove the commands |
185 | m_scene.UnregisterModuleCommander(m_commander.Name); | 273 | m_scene.UnregisterModuleCommander(m_commander.Name); |
186 | // remove the event-handlers | 274 | // remove the event-handlers |
275 | m_scene.EventManager.OnFrame -= EventManager_OnFrame; | ||
187 | m_scene.EventManager.OnTerrainTick -= EventManager_OnTerrainTick; | 276 | m_scene.EventManager.OnTerrainTick -= EventManager_OnTerrainTick; |
188 | m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; | 277 | m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; |
278 | m_scene.EventManager.OnClientClosed -= EventManager_OnClientClosed; | ||
189 | m_scene.EventManager.OnNewClient -= EventManager_OnNewClient; | 279 | m_scene.EventManager.OnNewClient -= EventManager_OnNewClient; |
190 | // remove the interface | 280 | // remove the interface |
191 | m_scene.UnregisterModuleInterface<ITerrainModule>(this); | 281 | m_scene.UnregisterModuleInterface<ITerrainModule>(this); |
@@ -230,11 +320,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
230 | try | 320 | try |
231 | { | 321 | { |
232 | ITerrainChannel channel = loader.Value.LoadFile(filename); | 322 | ITerrainChannel channel = loader.Value.LoadFile(filename); |
233 | if (channel.Width != Constants.RegionSize || channel.Height != Constants.RegionSize) | 323 | if (channel.Width != m_scene.RegionInfo.RegionSizeX || channel.Height != m_scene.RegionInfo.RegionSizeY) |
234 | { | 324 | { |
235 | // TerrainChannel expects a RegionSize x RegionSize map, currently | 325 | // TerrainChannel expects a RegionSize x RegionSize map, currently |
236 | throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}", | 326 | throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}", |
237 | Constants.RegionSize, Constants.RegionSize)); | 327 | m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY)); |
238 | } | 328 | } |
239 | m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height); | 329 | m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height); |
240 | m_scene.Heightmap = channel; | 330 | m_scene.Heightmap = channel; |
@@ -261,7 +351,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
261 | String.Format("Unable to load heightmap: {0}", e.Message)); | 351 | String.Format("Unable to load heightmap: {0}", e.Message)); |
262 | } | 352 | } |
263 | } | 353 | } |
264 | CheckForTerrainUpdates(); | ||
265 | m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); | 354 | m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); |
266 | return; | 355 | return; |
267 | } | 356 | } |
@@ -309,12 +398,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
309 | LoadFromStream(filename, URIFetch(pathToTerrainHeightmap)); | 398 | LoadFromStream(filename, URIFetch(pathToTerrainHeightmap)); |
310 | } | 399 | } |
311 | 400 | ||
401 | public void LoadFromStream(string filename, Stream stream) | ||
402 | { | ||
403 | LoadFromStream(filename, Vector3.Zero, 0f, Vector2.Zero, stream); | ||
404 | } | ||
405 | |||
312 | /// <summary> | 406 | /// <summary> |
313 | /// Loads a terrain file from a stream and installs it in the scene. | 407 | /// Loads a terrain file from a stream and installs it in the scene. |
314 | /// </summary> | 408 | /// </summary> |
315 | /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> | 409 | /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> |
316 | /// <param name="stream"></param> | 410 | /// <param name="stream"></param> |
317 | public void LoadFromStream(string filename, Stream stream) | 411 | public void LoadFromStream(string filename, Vector3 displacement, |
412 | float radianRotation, Vector2 rotationDisplacement, Stream stream) | ||
318 | { | 413 | { |
319 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 414 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
320 | { | 415 | { |
@@ -325,8 +420,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
325 | try | 420 | try |
326 | { | 421 | { |
327 | ITerrainChannel channel = loader.Value.LoadStream(stream); | 422 | ITerrainChannel channel = loader.Value.LoadStream(stream); |
328 | m_scene.Heightmap = channel; | 423 | m_channel.Merge(channel, displacement, radianRotation, rotationDisplacement); |
329 | m_channel = channel; | ||
330 | UpdateRevertMap(); | 424 | UpdateRevertMap(); |
331 | } | 425 | } |
332 | catch (NotImplementedException) | 426 | catch (NotImplementedException) |
@@ -337,7 +431,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
337 | } | 431 | } |
338 | } | 432 | } |
339 | 433 | ||
340 | CheckForTerrainUpdates(); | ||
341 | m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); | 434 | m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); |
342 | return; | 435 | return; |
343 | } | 436 | } |
@@ -406,9 +499,46 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
406 | } | 499 | } |
407 | } | 500 | } |
408 | 501 | ||
502 | // Someone diddled terrain outside the normal code paths. Set the taintedness for all clients. | ||
503 | // ITerrainModule.TaintTerrain() | ||
409 | public void TaintTerrain () | 504 | public void TaintTerrain () |
410 | { | 505 | { |
411 | CheckForTerrainUpdates(); | 506 | lock (m_perClientPatchUpdates) |
507 | { | ||
508 | // Set the flags for all clients so the tainted patches will be sent out | ||
509 | foreach (PatchUpdates pups in m_perClientPatchUpdates.Values) | ||
510 | { | ||
511 | pups.SetAll(m_scene.Heightmap.GetTerrainData()); | ||
512 | } | ||
513 | } | ||
514 | } | ||
515 | |||
516 | // ITerrainModule.PushTerrain() | ||
517 | public void PushTerrain(IClientAPI pClient) | ||
518 | { | ||
519 | if (m_sendTerrainUpdatesByViewDistance) | ||
520 | { | ||
521 | ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); | ||
522 | if (presence != null) | ||
523 | { | ||
524 | lock (m_perClientPatchUpdates) | ||
525 | { | ||
526 | PatchUpdates pups; | ||
527 | if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups)) | ||
528 | { | ||
529 | // There is a ScenePresence without a send patch map. Create one. | ||
530 | pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence); | ||
531 | m_perClientPatchUpdates.Add(presence.UUID, pups); | ||
532 | } | ||
533 | pups.SetAll(true); | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | else | ||
538 | { | ||
539 | // The traditional way is to call into the protocol stack to send them all. | ||
540 | pClient.SendLayerData(new float[10]); | ||
541 | } | ||
412 | } | 542 | } |
413 | 543 | ||
414 | #region Plugin Loading Methods | 544 | #region Plugin Loading Methods |
@@ -532,6 +662,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
532 | /// </summary> | 662 | /// </summary> |
533 | public void UpdateRevertMap() | 663 | public void UpdateRevertMap() |
534 | { | 664 | { |
665 | /* | ||
535 | int x; | 666 | int x; |
536 | for (x = 0; x < m_channel.Width; x++) | 667 | for (x = 0; x < m_channel.Width; x++) |
537 | { | 668 | { |
@@ -541,6 +672,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
541 | m_revert[x, y] = m_channel[x, y]; | 672 | m_revert[x, y] = m_channel[x, y]; |
542 | } | 673 | } |
543 | } | 674 | } |
675 | */ | ||
676 | m_revert = m_channel.MakeCopy(); | ||
544 | } | 677 | } |
545 | 678 | ||
546 | /// <summary> | 679 | /// <summary> |
@@ -567,8 +700,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
567 | { | 700 | { |
568 | ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, | 701 | ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, |
569 | fileWidth, fileHeight, | 702 | fileWidth, fileHeight, |
570 | (int) Constants.RegionSize, | 703 | (int) m_scene.RegionInfo.RegionSizeX, |
571 | (int) Constants.RegionSize); | 704 | (int) m_scene.RegionInfo.RegionSizeY); |
572 | m_scene.Heightmap = channel; | 705 | m_scene.Heightmap = channel; |
573 | m_channel = channel; | 706 | m_channel = channel; |
574 | UpdateRevertMap(); | 707 | UpdateRevertMap(); |
@@ -615,8 +748,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
615 | { | 748 | { |
616 | loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, | 749 | loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, |
617 | fileWidth, fileHeight, | 750 | fileWidth, fileHeight, |
618 | (int)Constants.RegionSize, | 751 | (int)m_scene.RegionInfo.RegionSizeX, |
619 | (int)Constants.RegionSize); | 752 | (int)m_scene.RegionInfo.RegionSizeY); |
620 | 753 | ||
621 | MainConsole.Instance.OutputFormat( | 754 | MainConsole.Instance.OutputFormat( |
622 | "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}", | 755 | "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}", |
@@ -634,7 +767,44 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
634 | } | 767 | } |
635 | 768 | ||
636 | /// <summary> | 769 | /// <summary> |
770 | /// Called before processing of every simulation frame. | ||
771 | /// This is used to check to see of any of the terrain is tainted and, if so, schedule | ||
772 | /// updates for all the presences. | ||
773 | /// This also checks to see if there are updates that need to be sent for each presence. | ||
774 | /// This is where the logic is to send terrain updates to clients. | ||
775 | /// </summary> | ||
776 | private void EventManager_OnFrame() | ||
777 | { | ||
778 | TerrainData terrData = m_channel.GetTerrainData(); | ||
779 | |||
780 | bool shouldTaint = false; | ||
781 | for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) | ||
782 | { | ||
783 | for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) | ||
784 | { | ||
785 | if (terrData.IsTaintedAt(x, y)) | ||
786 | { | ||
787 | // Found a patch that was modified. Push this flag into the clients. | ||
788 | SendToClients(terrData, x, y); | ||
789 | shouldTaint = true; | ||
790 | } | ||
791 | } | ||
792 | } | ||
793 | |||
794 | // This event also causes changes to be sent to the clients | ||
795 | CheckSendingPatchesToClients(); | ||
796 | |||
797 | // If things changes, generate some events | ||
798 | if (shouldTaint) | ||
799 | { | ||
800 | m_scene.EventManager.TriggerTerrainTainted(); | ||
801 | m_tainted = true; | ||
802 | } | ||
803 | } | ||
804 | |||
805 | /// <summary> | ||
637 | /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections | 806 | /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections |
807 | /// Called infrequently (like every 5 seconds or so). Best used for storing terrain. | ||
638 | /// </summary> | 808 | /// </summary> |
639 | private void EventManager_OnTerrainTick() | 809 | private void EventManager_OnTerrainTick() |
640 | { | 810 | { |
@@ -644,8 +814,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
644 | m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); | 814 | m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); |
645 | m_scene.SaveTerrain(); | 815 | m_scene.SaveTerrain(); |
646 | 816 | ||
647 | m_scene.EventManager.TriggerTerrainUpdate(); | ||
648 | |||
649 | // Clients who look at the map will never see changes after they looked at the map, so i've commented this out. | 817 | // Clients who look at the map will never see changes after they looked at the map, so i've commented this out. |
650 | //m_scene.CreateTerrainTexture(true); | 818 | //m_scene.CreateTerrainTexture(true); |
651 | } | 819 | } |
@@ -687,54 +855,48 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
687 | } | 855 | } |
688 | 856 | ||
689 | /// <summary> | 857 | /// <summary> |
690 | /// Checks to see if the terrain has been modified since last check | 858 | /// Installs terrain brush hook to IClientAPI |
691 | /// but won't attempt to limit those changes to the limits specified in the estate settings | ||
692 | /// currently invoked by the command line operations in the region server only | ||
693 | /// </summary> | 859 | /// </summary> |
694 | private void CheckForTerrainUpdates() | 860 | /// <param name="client"></param> |
861 | private void EventManager_OnClientClosed(UUID client, Scene scene) | ||
695 | { | 862 | { |
696 | CheckForTerrainUpdates(false); | 863 | ScenePresence presence = scene.GetScenePresence(client); |
697 | } | 864 | if (presence != null) |
865 | { | ||
866 | presence.ControllingClient.OnModifyTerrain -= client_OnModifyTerrain; | ||
867 | presence.ControllingClient.OnBakeTerrain -= client_OnBakeTerrain; | ||
868 | presence.ControllingClient.OnLandUndo -= client_OnLandUndo; | ||
869 | presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain; | ||
870 | } | ||
698 | 871 | ||
872 | lock (m_perClientPatchUpdates) | ||
873 | m_perClientPatchUpdates.Remove(client); | ||
874 | } | ||
875 | |||
699 | /// <summary> | 876 | /// <summary> |
700 | /// Checks to see if the terrain has been modified since last check. | 877 | /// Scan over changes in the terrain and limit height changes. This enforces the |
701 | /// If it has been modified, every all the terrain patches are sent to the client. | 878 | /// non-estate owner limits on rate of terrain editting. |
702 | /// If the call is asked to respect the estate settings for terrain_raise_limit and | 879 | /// Returns 'true' if any heights were limited. |
703 | /// terrain_lower_limit, it will clamp terrain updates between these values | ||
704 | /// currently invoked by client_OnModifyTerrain only and not the Commander interfaces | ||
705 | /// <param name="respectEstateSettings">should height map deltas be limited to the estate settings limits</param> | ||
706 | /// </summary> | 880 | /// </summary> |
707 | private void CheckForTerrainUpdates(bool respectEstateSettings) | 881 | private bool EnforceEstateLimits() |
708 | { | 882 | { |
709 | bool shouldTaint = false; | 883 | TerrainData terrData = m_channel.GetTerrainData(); |
710 | float[] serialised = m_channel.GetFloatsSerialised(); | 884 | |
711 | int x; | 885 | bool wasLimited = false; |
712 | for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) | 886 | for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) |
713 | { | 887 | { |
714 | int y; | 888 | for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) |
715 | for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize) | ||
716 | { | 889 | { |
717 | if (m_channel.Tainted(x, y)) | 890 | if (terrData.IsTaintedAt(x, y, false /* clearOnTest */)) |
718 | { | 891 | { |
719 | // if we should respect the estate settings then | 892 | // If we should respect the estate settings then |
720 | // fixup and height deltas that don't respect them | 893 | // fixup and height deltas that don't respect them. |
721 | if (respectEstateSettings && LimitChannelChanges(x, y)) | 894 | // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values. |
722 | { | 895 | wasLimited |= LimitChannelChanges(terrData, x, y); |
723 | // this has been vetoed, so update | ||
724 | // what we are going to send to the client | ||
725 | serialised = m_channel.GetFloatsSerialised(); | ||
726 | } | ||
727 | |||
728 | SendToClients(serialised, x, y); | ||
729 | shouldTaint = true; | ||
730 | } | 896 | } |
731 | } | 897 | } |
732 | } | 898 | } |
733 | if (shouldTaint) | 899 | return wasLimited; |
734 | { | ||
735 | m_scene.EventManager.TriggerTerrainTainted(); | ||
736 | m_tainted = true; | ||
737 | } | ||
738 | } | 900 | } |
739 | 901 | ||
740 | /// <summary> | 902 | /// <summary> |
@@ -742,11 +904,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
742 | /// are all within the current estate limits | 904 | /// are all within the current estate limits |
743 | /// <returns>true if changes were limited, false otherwise</returns> | 905 | /// <returns>true if changes were limited, false otherwise</returns> |
744 | /// </summary> | 906 | /// </summary> |
745 | private bool LimitChannelChanges(int xStart, int yStart) | 907 | private bool LimitChannelChanges(TerrainData terrData, int xStart, int yStart) |
746 | { | 908 | { |
747 | bool changesLimited = false; | 909 | bool changesLimited = false; |
748 | double minDelta = m_scene.RegionInfo.RegionSettings.TerrainLowerLimit; | 910 | float minDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainLowerLimit; |
749 | double maxDelta = m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit; | 911 | float maxDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit; |
750 | 912 | ||
751 | // loop through the height map for this patch and compare it against | 913 | // loop through the height map for this patch and compare it against |
752 | // the revert map | 914 | // the revert map |
@@ -754,19 +916,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
754 | { | 916 | { |
755 | for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++) | 917 | for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++) |
756 | { | 918 | { |
757 | 919 | float requestedHeight = terrData[x, y]; | |
758 | double requestedHeight = m_channel[x, y]; | 920 | float bakedHeight = (float)m_revert[x, y]; |
759 | double bakedHeight = m_revert[x, y]; | 921 | float requestedDelta = requestedHeight - bakedHeight; |
760 | double requestedDelta = requestedHeight - bakedHeight; | ||
761 | 922 | ||
762 | if (requestedDelta > maxDelta) | 923 | if (requestedDelta > maxDelta) |
763 | { | 924 | { |
764 | m_channel[x, y] = bakedHeight + maxDelta; | 925 | terrData[x, y] = bakedHeight + maxDelta; |
765 | changesLimited = true; | 926 | changesLimited = true; |
766 | } | 927 | } |
767 | else if (requestedDelta < minDelta) | 928 | else if (requestedDelta < minDelta) |
768 | { | 929 | { |
769 | m_channel[x, y] = bakedHeight + minDelta; //as lower is a -ve delta | 930 | terrData[x, y] = bakedHeight + minDelta; //as lower is a -ve delta |
770 | changesLimited = true; | 931 | changesLimited = true; |
771 | } | 932 | } |
772 | } | 933 | } |
@@ -794,14 +955,154 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
794 | /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> | 955 | /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> |
795 | /// <param name="x">The patch corner to send</param> | 956 | /// <param name="x">The patch corner to send</param> |
796 | /// <param name="y">The patch corner to send</param> | 957 | /// <param name="y">The patch corner to send</param> |
797 | private void SendToClients(float[] serialised, int x, int y) | 958 | private void SendToClients(TerrainData terrData, int x, int y) |
959 | { | ||
960 | if (m_sendTerrainUpdatesByViewDistance) | ||
961 | { | ||
962 | // Add that this patch needs to be sent to the accounting for each client. | ||
963 | lock (m_perClientPatchUpdates) | ||
964 | { | ||
965 | m_scene.ForEachScenePresence(presence => | ||
966 | { | ||
967 | PatchUpdates thisClientUpdates; | ||
968 | if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates)) | ||
969 | { | ||
970 | // There is a ScenePresence without a send patch map. Create one. | ||
971 | thisClientUpdates = new PatchUpdates(terrData, presence); | ||
972 | m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates); | ||
973 | } | ||
974 | thisClientUpdates.SetByXY(x, y, true); | ||
975 | } | ||
976 | ); | ||
977 | } | ||
978 | } | ||
979 | else | ||
980 | { | ||
981 | // Legacy update sending where the update is sent out as soon as noticed | ||
982 | // We know the actual terrain data passed is ignored. This kludge saves changing IClientAPI. | ||
983 | //float[] heightMap = terrData.GetFloatsSerialized(); | ||
984 | float[] heightMap = new float[10]; | ||
985 | m_scene.ForEachClient( | ||
986 | delegate(IClientAPI controller) | ||
987 | { | ||
988 | controller.SendLayerData(x / Constants.TerrainPatchSize, | ||
989 | y / Constants.TerrainPatchSize, | ||
990 | heightMap); | ||
991 | } | ||
992 | ); | ||
993 | } | ||
994 | } | ||
995 | |||
996 | private class PatchesToSend : IComparable<PatchesToSend> | ||
798 | { | 997 | { |
799 | m_scene.ForEachClient( | 998 | public int PatchX; |
800 | delegate(IClientAPI controller) | 999 | public int PatchY; |
801 | { controller.SendLayerData( | 1000 | public float Dist; |
802 | x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); | 1001 | public PatchesToSend(int pX, int pY, float pDist) |
1002 | { | ||
1003 | PatchX = pX; | ||
1004 | PatchY = pY; | ||
1005 | Dist = pDist; | ||
1006 | } | ||
1007 | public int CompareTo(PatchesToSend other) | ||
1008 | { | ||
1009 | return Dist.CompareTo(other.Dist); | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | // Called each frame time to see if there are any patches to send to any of the | ||
1014 | // ScenePresences. | ||
1015 | // Loop through all the per-client info and send any patches necessary. | ||
1016 | private void CheckSendingPatchesToClients() | ||
1017 | { | ||
1018 | lock (m_perClientPatchUpdates) | ||
1019 | { | ||
1020 | foreach (PatchUpdates pups in m_perClientPatchUpdates.Values) | ||
1021 | { | ||
1022 | if (pups.HasUpdates()) | ||
1023 | { | ||
1024 | // There is something that could be sent to this client. | ||
1025 | List<PatchesToSend> toSend = GetModifiedPatchesInViewDistance(pups); | ||
1026 | if (toSend.Count > 0) | ||
1027 | { | ||
1028 | // m_log.DebugFormat("{0} CheckSendingPatchesToClient: sending {1} patches to {2} in region {3}", | ||
1029 | // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); | ||
1030 | // Sort the patches to send by the distance from the presence | ||
1031 | toSend.Sort(); | ||
1032 | /* | ||
1033 | foreach (PatchesToSend pts in toSend) | ||
1034 | { | ||
1035 | pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); | ||
1036 | // presence.ControllingClient.SendLayerData(xs.ToArray(), ys.ToArray(), null, TerrainPatch.LayerType.Land); | ||
1037 | } | ||
1038 | */ | ||
1039 | |||
1040 | int[] xPieces = new int[toSend.Count]; | ||
1041 | int[] yPieces = new int[toSend.Count]; | ||
1042 | float[] patchPieces = new float[toSend.Count * 2]; | ||
1043 | int pieceIndex = 0; | ||
1044 | foreach (PatchesToSend pts in toSend) | ||
1045 | { | ||
1046 | patchPieces[pieceIndex++] = pts.PatchX; | ||
1047 | patchPieces[pieceIndex++] = pts.PatchY; | ||
1048 | } | ||
1049 | pups.Presence.ControllingClient.SendLayerData(-toSend.Count, 0, patchPieces); | ||
1050 | } | ||
1051 | } | ||
1052 | } | ||
1053 | } | ||
1054 | } | ||
1055 | |||
1056 | private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups) | ||
1057 | { | ||
1058 | List<PatchesToSend> ret = new List<PatchesToSend>(); | ||
1059 | |||
1060 | ScenePresence presence = pups.Presence; | ||
1061 | if (presence == null) | ||
1062 | return ret; | ||
1063 | |||
1064 | // Compute the area of patches within our draw distance | ||
1065 | int startX = (((int) (presence.AbsolutePosition.X - presence.DrawDistance))/Constants.TerrainPatchSize) - 2; | ||
1066 | startX = Math.Max(startX, 0); | ||
1067 | startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX/Constants.TerrainPatchSize); | ||
1068 | int startY = (((int) (presence.AbsolutePosition.Y - presence.DrawDistance))/Constants.TerrainPatchSize) - 2; | ||
1069 | startY = Math.Max(startY, 0); | ||
1070 | startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY/Constants.TerrainPatchSize); | ||
1071 | int endX = (((int) (presence.AbsolutePosition.X + presence.DrawDistance))/Constants.TerrainPatchSize) + 2; | ||
1072 | endX = Math.Max(endX, 0); | ||
1073 | endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX/Constants.TerrainPatchSize); | ||
1074 | int endY = (((int) (presence.AbsolutePosition.Y + presence.DrawDistance))/Constants.TerrainPatchSize) + 2; | ||
1075 | endY = Math.Max(endY, 0); | ||
1076 | endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY/Constants.TerrainPatchSize); | ||
1077 | // m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, start=<{4},{5}>, end=<{6},{7}>", | ||
1078 | // LogHeader, m_scene.RegionInfo.RegionName, | ||
1079 | // presence.DrawDistance, presence.AbsolutePosition, | ||
1080 | // startX, startY, endX, endY); | ||
1081 | for (int x = startX; x < endX; x++) | ||
1082 | { | ||
1083 | for (int y = startY; y < endY; y++) | ||
1084 | { | ||
1085 | //Need to make sure we don't send the same ones over and over | ||
1086 | Vector3 presencePos = presence.AbsolutePosition; | ||
1087 | Vector3 patchPos = new Vector3(x * Constants.TerrainPatchSize, y * Constants.TerrainPatchSize, presencePos.Z); | ||
1088 | if (pups.GetByPatch(x, y)) | ||
1089 | { | ||
1090 | //Check which has less distance, camera or avatar position, both have to be done. | ||
1091 | //Its not a radius, its a diameter and we add 50 so that it doesn't look like it cuts off | ||
1092 | if (Util.DistanceLessThan(presencePos, patchPos, presence.DrawDistance + 50) | ||
1093 | || Util.DistanceLessThan(presence.CameraPosition, patchPos, presence.DrawDistance + 50)) | ||
1094 | { | ||
1095 | //They can see it, send it to them | ||
1096 | pups.SetByPatch(x, y, false); | ||
1097 | float dist = Vector3.DistanceSquared(presencePos, patchPos); | ||
1098 | ret.Add(new PatchesToSend(x, y, dist)); | ||
1099 | //Wait and send them all at once | ||
1100 | // pups.client.SendLayerData(x, y, null); | ||
1101 | } | ||
803 | } | 1102 | } |
804 | ); | 1103 | } |
1104 | } | ||
1105 | return ret; | ||
805 | } | 1106 | } |
806 | 1107 | ||
807 | private void client_OnModifyTerrain(UUID user, float height, float seconds, byte size, byte action, | 1108 | private void client_OnModifyTerrain(UUID user, float height, float seconds, byte size, byte action, |
@@ -846,7 +1147,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
846 | m_painteffects[(StandardTerrainEffects) action].PaintEffect( | 1147 | m_painteffects[(StandardTerrainEffects) action].PaintEffect( |
847 | m_channel, allowMask, west, south, height, size, seconds); | 1148 | m_channel, allowMask, west, south, height, size, seconds); |
848 | 1149 | ||
849 | CheckForTerrainUpdates(!god); //revert changes outside estate limits | 1150 | //revert changes outside estate limits |
1151 | if (!god) | ||
1152 | EnforceEstateLimits(); | ||
850 | } | 1153 | } |
851 | } | 1154 | } |
852 | else | 1155 | else |
@@ -884,10 +1187,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
884 | if (allowed) | 1187 | if (allowed) |
885 | { | 1188 | { |
886 | StoreUndoState(); | 1189 | StoreUndoState(); |
887 | m_floodeffects[(StandardTerrainEffects) action].FloodEffect( | 1190 | m_floodeffects[(StandardTerrainEffects) action].FloodEffect(m_channel, fillArea, size); |
888 | m_channel, fillArea, size); | ||
889 | 1191 | ||
890 | CheckForTerrainUpdates(!god); //revert changes outside estate limits | 1192 | //revert changes outside estate limits |
1193 | if (!god) | ||
1194 | EnforceEstateLimits(); | ||
891 | } | 1195 | } |
892 | } | 1196 | } |
893 | else | 1197 | else |
@@ -911,7 +1215,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
911 | protected void client_OnUnackedTerrain(IClientAPI client, int patchX, int patchY) | 1215 | protected void client_OnUnackedTerrain(IClientAPI client, int patchX, int patchY) |
912 | { | 1216 | { |
913 | //m_log.Debug("Terrain packet unacked, resending patch: " + patchX + " , " + patchY); | 1217 | //m_log.Debug("Terrain packet unacked, resending patch: " + patchX + " , " + patchY); |
914 | client.SendLayerData(patchX, patchY, m_scene.Heightmap.GetFloatsSerialised()); | 1218 | // SendLayerData does not use the heightmap parameter. This kludge is so as to not change IClientAPI. |
1219 | float[] heightMap = new float[10]; | ||
1220 | client.SendLayerData(patchX, patchY, heightMap); | ||
915 | } | 1221 | } |
916 | 1222 | ||
917 | private void StoreUndoState() | 1223 | private void StoreUndoState() |
@@ -938,7 +1244,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
938 | private void InterfaceLoadFile(Object[] args) | 1244 | private void InterfaceLoadFile(Object[] args) |
939 | { | 1245 | { |
940 | LoadFromFile((string) args[0]); | 1246 | LoadFromFile((string) args[0]); |
941 | CheckForTerrainUpdates(); | ||
942 | } | 1247 | } |
943 | 1248 | ||
944 | private void InterfaceLoadTileFile(Object[] args) | 1249 | private void InterfaceLoadTileFile(Object[] args) |
@@ -948,7 +1253,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
948 | (int) args[2], | 1253 | (int) args[2], |
949 | (int) args[3], | 1254 | (int) args[3], |
950 | (int) args[4]); | 1255 | (int) args[4]); |
951 | CheckForTerrainUpdates(); | ||
952 | } | 1256 | } |
953 | 1257 | ||
954 | private void InterfaceSaveFile(Object[] args) | 1258 | private void InterfaceSaveFile(Object[] args) |
@@ -977,7 +1281,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
977 | for (y = 0; y < m_channel.Height; y++) | 1281 | for (y = 0; y < m_channel.Height; y++) |
978 | m_channel[x, y] = m_revert[x, y]; | 1282 | m_channel[x, y] = m_revert[x, y]; |
979 | 1283 | ||
980 | CheckForTerrainUpdates(); | ||
981 | } | 1284 | } |
982 | 1285 | ||
983 | private void InterfaceFlipTerrain(Object[] args) | 1286 | private void InterfaceFlipTerrain(Object[] args) |
@@ -986,28 +1289,28 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
986 | 1289 | ||
987 | if (direction.ToLower().StartsWith("y")) | 1290 | if (direction.ToLower().StartsWith("y")) |
988 | { | 1291 | { |
989 | for (int x = 0; x < Constants.RegionSize; x++) | 1292 | for (int x = 0; x < m_channel.Width; x++) |
990 | { | 1293 | { |
991 | for (int y = 0; y < Constants.RegionSize / 2; y++) | 1294 | for (int y = 0; y < m_channel.Height / 2; y++) |
992 | { | 1295 | { |
993 | double height = m_channel[x, y]; | 1296 | double height = m_channel[x, y]; |
994 | double flippedHeight = m_channel[x, (int)Constants.RegionSize - 1 - y]; | 1297 | double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y]; |
995 | m_channel[x, y] = flippedHeight; | 1298 | m_channel[x, y] = flippedHeight; |
996 | m_channel[x, (int)Constants.RegionSize - 1 - y] = height; | 1299 | m_channel[x, (int)m_channel.Height - 1 - y] = height; |
997 | 1300 | ||
998 | } | 1301 | } |
999 | } | 1302 | } |
1000 | } | 1303 | } |
1001 | else if (direction.ToLower().StartsWith("x")) | 1304 | else if (direction.ToLower().StartsWith("x")) |
1002 | { | 1305 | { |
1003 | for (int y = 0; y < Constants.RegionSize; y++) | 1306 | for (int y = 0; y < m_channel.Height; y++) |
1004 | { | 1307 | { |
1005 | for (int x = 0; x < Constants.RegionSize / 2; x++) | 1308 | for (int x = 0; x < m_channel.Width / 2; x++) |
1006 | { | 1309 | { |
1007 | double height = m_channel[x, y]; | 1310 | double height = m_channel[x, y]; |
1008 | double flippedHeight = m_channel[(int)Constants.RegionSize - 1 - x, y]; | 1311 | double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y]; |
1009 | m_channel[x, y] = flippedHeight; | 1312 | m_channel[x, y] = flippedHeight; |
1010 | m_channel[(int)Constants.RegionSize - 1 - x, y] = height; | 1313 | m_channel[(int)m_channel.Width - 1 - x, y] = height; |
1011 | 1314 | ||
1012 | } | 1315 | } |
1013 | } | 1316 | } |
@@ -1016,9 +1319,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1016 | { | 1319 | { |
1017 | m_log.Error("Unrecognised direction - need x or y"); | 1320 | m_log.Error("Unrecognised direction - need x or y"); |
1018 | } | 1321 | } |
1019 | |||
1020 | |||
1021 | CheckForTerrainUpdates(); | ||
1022 | } | 1322 | } |
1023 | 1323 | ||
1024 | private void InterfaceRescaleTerrain(Object[] args) | 1324 | private void InterfaceRescaleTerrain(Object[] args) |
@@ -1076,7 +1376,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1076 | } | 1376 | } |
1077 | } | 1377 | } |
1078 | 1378 | ||
1079 | CheckForTerrainUpdates(); | ||
1080 | } | 1379 | } |
1081 | 1380 | ||
1082 | } | 1381 | } |
@@ -1087,7 +1386,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1087 | for (x = 0; x < m_channel.Width; x++) | 1386 | for (x = 0; x < m_channel.Width; x++) |
1088 | for (y = 0; y < m_channel.Height; y++) | 1387 | for (y = 0; y < m_channel.Height; y++) |
1089 | m_channel[x, y] += (double) args[0]; | 1388 | m_channel[x, y] += (double) args[0]; |
1090 | CheckForTerrainUpdates(); | ||
1091 | } | 1389 | } |
1092 | 1390 | ||
1093 | private void InterfaceMultiplyTerrain(Object[] args) | 1391 | private void InterfaceMultiplyTerrain(Object[] args) |
@@ -1096,7 +1394,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1096 | for (x = 0; x < m_channel.Width; x++) | 1394 | for (x = 0; x < m_channel.Width; x++) |
1097 | for (y = 0; y < m_channel.Height; y++) | 1395 | for (y = 0; y < m_channel.Height; y++) |
1098 | m_channel[x, y] *= (double) args[0]; | 1396 | m_channel[x, y] *= (double) args[0]; |
1099 | CheckForTerrainUpdates(); | ||
1100 | } | 1397 | } |
1101 | 1398 | ||
1102 | private void InterfaceLowerTerrain(Object[] args) | 1399 | private void InterfaceLowerTerrain(Object[] args) |
@@ -1105,17 +1402,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1105 | for (x = 0; x < m_channel.Width; x++) | 1402 | for (x = 0; x < m_channel.Width; x++) |
1106 | for (y = 0; y < m_channel.Height; y++) | 1403 | for (y = 0; y < m_channel.Height; y++) |
1107 | m_channel[x, y] -= (double) args[0]; | 1404 | m_channel[x, y] -= (double) args[0]; |
1108 | CheckForTerrainUpdates(); | ||
1109 | } | 1405 | } |
1110 | 1406 | ||
1111 | private void InterfaceFillTerrain(Object[] args) | 1407 | public void InterfaceFillTerrain(Object[] args) |
1112 | { | 1408 | { |
1113 | int x, y; | 1409 | int x, y; |
1114 | 1410 | ||
1115 | for (x = 0; x < m_channel.Width; x++) | 1411 | for (x = 0; x < m_channel.Width; x++) |
1116 | for (y = 0; y < m_channel.Height; y++) | 1412 | for (y = 0; y < m_channel.Height; y++) |
1117 | m_channel[x, y] = (double) args[0]; | 1413 | m_channel[x, y] = (double) args[0]; |
1118 | CheckForTerrainUpdates(); | ||
1119 | } | 1414 | } |
1120 | 1415 | ||
1121 | private void InterfaceMinTerrain(Object[] args) | 1416 | private void InterfaceMinTerrain(Object[] args) |
@@ -1128,7 +1423,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1128 | m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); | 1423 | m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); |
1129 | } | 1424 | } |
1130 | } | 1425 | } |
1131 | CheckForTerrainUpdates(); | ||
1132 | } | 1426 | } |
1133 | 1427 | ||
1134 | private void InterfaceMaxTerrain(Object[] args) | 1428 | private void InterfaceMaxTerrain(Object[] args) |
@@ -1141,7 +1435,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1141 | m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); | 1435 | m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); |
1142 | } | 1436 | } |
1143 | } | 1437 | } |
1144 | CheckForTerrainUpdates(); | ||
1145 | } | 1438 | } |
1146 | 1439 | ||
1147 | private void InterfaceShowDebugStats(Object[] args) | 1440 | private void InterfaceShowDebugStats(Object[] args) |
@@ -1204,7 +1497,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1204 | if (m_plugineffects.ContainsKey(firstArg)) | 1497 | if (m_plugineffects.ContainsKey(firstArg)) |
1205 | { | 1498 | { |
1206 | m_plugineffects[firstArg].RunEffect(m_channel); | 1499 | m_plugineffects[firstArg].RunEffect(m_channel); |
1207 | CheckForTerrainUpdates(); | ||
1208 | } | 1500 | } |
1209 | else | 1501 | else |
1210 | { | 1502 | { |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs index be719ea..062d7ff 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs | |||
@@ -40,10 +40,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests | |||
40 | [Test] | 40 | [Test] |
41 | public void BrushTest() | 41 | public void BrushTest() |
42 | { | 42 | { |
43 | int midRegion = (int)Constants.RegionSize / 2; | ||
44 | |||
45 | // Create a mask that covers only the left half of the region | ||
43 | bool[,] allowMask = new bool[(int)Constants.RegionSize, 256]; | 46 | bool[,] allowMask = new bool[(int)Constants.RegionSize, 256]; |
44 | int x; | 47 | int x; |
45 | int y; | 48 | int y; |
46 | for (x = 0; x < (int)((int)Constants.RegionSize * 0.5f); x++) | 49 | for (x = 0; x < midRegion; x++) |
47 | { | 50 | { |
48 | for (y = 0; y < (int)Constants.RegionSize; y++) | 51 | for (y = 0; y < (int)Constants.RegionSize; y++) |
49 | { | 52 | { |
@@ -57,13 +60,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests | |||
57 | TerrainChannel map = new TerrainChannel((int)Constants.RegionSize, (int)Constants.RegionSize); | 60 | TerrainChannel map = new TerrainChannel((int)Constants.RegionSize, (int)Constants.RegionSize); |
58 | ITerrainPaintableEffect effect = new RaiseSphere(); | 61 | ITerrainPaintableEffect effect = new RaiseSphere(); |
59 | 62 | ||
60 | effect.PaintEffect(map, allowMask, (int)Constants.RegionSize * 0.5f, (int)Constants.RegionSize * 0.5f, -1.0, 2, 0.1); | 63 | effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0); |
61 | Assert.That(map[127, (int)((int)Constants.RegionSize * 0.5f)] > 0.0, "Raise brush should raising value at this point (127,128)."); | 64 | Assert.That(map[127, midRegion] > 0.0, "Raise brush should raising value at this point (127,128)."); |
62 | Assert.That(map[124, (int)((int)Constants.RegionSize * 0.5f)] > 0.0, "Raise brush should raising value at this point (124,128)."); | 65 | Assert.That(map[125, midRegion] > 0.0, "Raise brush should raising value at this point (124,128)."); |
63 | Assert.That(map[123, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Raise brush should not change value at this point (123,128)."); | 66 | Assert.That(map[120, midRegion] == 0.0, "Raise brush should not change value at this point (120,128)."); |
64 | Assert.That(map[128, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Raise brush should not change value at this point (128,128)."); | 67 | Assert.That(map[128, midRegion] == 0.0, "Raise brush should not change value at this point (128,128)."); |
65 | Assert.That(map[0, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Raise brush should not change value at this point (0,128)."); | 68 | Assert.That(map[0, midRegion] == 0.0, "Raise brush should not change value at this point (0,128)."); |
66 | |||
67 | // | 69 | // |
68 | // Test LowerSphere | 70 | // Test LowerSphere |
69 | // | 71 | // |
@@ -77,13 +79,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests | |||
77 | } | 79 | } |
78 | effect = new LowerSphere(); | 80 | effect = new LowerSphere(); |
79 | 81 | ||
80 | effect.PaintEffect(map, allowMask, ((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), -1.0, 2, 6.0); | 82 | effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0); |
81 | Assert.That(map[127, (int)((int)Constants.RegionSize * 0.5f)] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128)."); | 83 | Assert.That(map[127, midRegion] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128)."); |
82 | Assert.That(map[127, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128)."); | 84 | Assert.That(map[127, midRegion] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128)."); |
83 | Assert.That(map[124, (int)((int)Constants.RegionSize * 0.5f)] < 1.0, "Lower brush should lowering value at this point (124,128)."); | 85 | Assert.That(map[125, midRegion] < 1.0, "Lower brush should lowering value at this point (124,128)."); |
84 | Assert.That(map[123, (int)((int)Constants.RegionSize * 0.5f)] == 1.0, "Lower brush should not change value at this point (123,128)."); | 86 | Assert.That(map[120, midRegion] == 1.0, "Lower brush should not change value at this point (120,128)."); |
85 | Assert.That(map[128, (int)((int)Constants.RegionSize * 0.5f)] == 1.0, "Lower brush should not change value at this point (128,128)."); | 87 | Assert.That(map[128, midRegion] == 1.0, "Lower brush should not change value at this point (128,128)."); |
86 | Assert.That(map[0, (int)((int)Constants.RegionSize * 0.5f)] == 1.0, "Lower brush should not change value at this point (0,128)."); | 88 | Assert.That(map[0, midRegion] == 1.0, "Lower brush should not change value at this point (0,128)."); |
87 | } | 89 | } |
88 | 90 | ||
89 | [Test] | 91 | [Test] |