aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
diff options
context:
space:
mode:
authorRobert Adams2013-10-02 16:59:37 -0700
committerRobert Adams2013-10-07 13:57:40 -0700
commit7416809077227f35ab70ed44060e51f2bcf66937 (patch)
tree7578cbfed07777d5c60af986791dc7d8b09b2cd5 /OpenSim/Region/Framework/Scenes/TerrainChannel.cs
parentvarregion: remove scattered use of Constants.RegionSize by having routines re... (diff)
downloadopensim-SC-7416809077227f35ab70ed44060e51f2bcf66937.zip
opensim-SC-7416809077227f35ab70ed44060e51f2bcf66937.tar.gz
opensim-SC-7416809077227f35ab70ed44060e51f2bcf66937.tar.bz2
opensim-SC-7416809077227f35ab70ed44060e51f2bcf66937.tar.xz
varregion: plug in TerrainData class and modify TerrainModule and LLClientView to use same. This passes a terrain info class around rather than passing a one dimensional array thus allowing variable regions. Update the database storage for variable region sizes. This should be downward compatible (same format for 256x256 regions).
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/TerrainChannel.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs145
1 files changed, 56 insertions, 89 deletions
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index fef93bf..65e890f 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -25,14 +25,19 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using OpenSim.Framework;
29using OpenSim.Region.Framework.Interfaces;
30using System; 28using System;
29using System.IO;
31using System.Text; 30using System.Text;
31using System.Reflection;
32using System.Xml; 32using System.Xml;
33using System.IO;
34using System.Xml.Serialization; 33using System.Xml.Serialization;
35 34
35using OpenSim.Data;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38
39using log4net;
40
36namespace OpenSim.Region.Framework.Scenes 41namespace OpenSim.Region.Framework.Scenes
37{ 42{
38 /// <summary> 43 /// <summary>
@@ -40,18 +45,20 @@ namespace OpenSim.Region.Framework.Scenes
40 /// </summary> 45 /// </summary>
41 public class TerrainChannel : ITerrainChannel 46 public class TerrainChannel : ITerrainChannel
42 { 47 {
43 protected bool[,] m_taint; 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 protected short[] m_map; 49 private static string LogHeader = "[TERRAIN CHANNEL]";
45 50
46 public int Width { get; private set; } // X dimension 51 protected TerrainData m_terrainData;
52
53 public int Width { get { return m_terrainData.SizeX; } } // X dimension
47 // Unfortunately, for historical reasons, in this module 'Width' is X and 'Height' is Y 54 // Unfortunately, for historical reasons, in this module 'Width' is X and 'Height' is Y
48 public int Height { get; private set; } // Y dimension 55 public int Height { get { return m_terrainData.SizeY; } } // Y dimension
49 public int Altitude { get; private set; } // Y dimension 56 public int Altitude { get { return m_terrainData.SizeZ; } } // Y dimension
50 57
51 // Default, not-often-used builder 58 // Default, not-often-used builder
52 public TerrainChannel() 59 public TerrainChannel()
53 { 60 {
54 InitializeStructures(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight, false); 61 m_terrainData = new HeightmapTerrainData((int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
55 FlatLand(); 62 FlatLand();
56 // PinHeadIsland(); 63 // PinHeadIsland();
57 } 64 }
@@ -59,27 +66,23 @@ namespace OpenSim.Region.Framework.Scenes
59 // Create terrain of given size 66 // Create terrain of given size
60 public TerrainChannel(int pX, int pY) 67 public TerrainChannel(int pX, int pY)
61 { 68 {
62 InitializeStructures((uint)pX, (uint)pY, Constants.RegionHeight, true); 69 m_terrainData = new HeightmapTerrainData(pX, pY, (int)Constants.RegionHeight);
63 } 70 }
64 71
65 // Create terrain of specified size and initialize with specified terrain. 72 // Create terrain of specified size and initialize with specified terrain.
66 // TODO: join this with the terrain initializers. 73 // TODO: join this with the terrain initializers.
67 public TerrainChannel(String type, uint pX, uint pY, uint pZ) 74 public TerrainChannel(String type, int pX, int pY, int pZ)
68 { 75 {
69 InitializeStructures(pX, pY, pZ, false); 76 m_terrainData = new HeightmapTerrainData(pX, pY, pZ);
70 if (type.Equals("flat")) 77 if (type.Equals("flat"))
71 FlatLand(); 78 FlatLand();
72 else 79 else
73 PinHeadIsland(); 80 PinHeadIsland();
74 } 81 }
75 82
76 public TerrainChannel(double[,] pM, uint pH) 83 public TerrainChannel(double[,] pM, uint pAltitude)
77 { 84 {
78 InitializeStructures((uint)pM.GetLength(0), (uint)pM.GetLength(1), pH, false); 85 m_terrainData = new HeightmapTerrainData(pM);
79 int idx = 0;
80 for (int ii = 0; ii < Height; ii++)
81 for (int jj = 0; jj < Width; jj++)
82 m_map[idx++] = ToCompressedHeight(pM[ii, jj]);
83 } 86 }
84 87
85 #region ITerrainChannel Members 88 #region ITerrainChannel Members
@@ -90,20 +93,23 @@ namespace OpenSim.Region.Framework.Scenes
90 return this.Copy(); 93 return this.Copy();
91 } 94 }
92 95
93 // ITerrainChannel.GetCompressedMap() 96 // ITerrainChannel.GetTerrainData()
94 public short[] GetCompressedMap() 97 public TerrainData GetTerrainData()
95 { 98 {
96 return m_map; 99 return m_terrainData;
97 } 100 }
98 101
99 // ITerrainChannel.GetFloatsSerialized() 102 // ITerrainChannel.GetFloatsSerialized()
103 // NOTICE that the one dimensional form is ordered by Y!!
100 public float[] GetFloatsSerialised() 104 public float[] GetFloatsSerialised()
101 { 105 {
102 int points = Width * Height; 106 int points = Width * Height;
103 float[] heights = new float[points]; 107 float[] heights = new float[points];
104 108
105 for (int ii = 0; ii < points; ii++) 109 int idx = 0;
106 heights[ii] = FromCompressedHeight(m_map[ii]); 110 for (int ii = 0; ii < Height; ii++)
111 for (int jj = 0; jj < Width; jj++)
112 heights[idx++] = m_terrainData[jj, ii];
107 113
108 return heights; 114 return heights;
109 } 115 }
@@ -116,11 +122,11 @@ namespace OpenSim.Region.Framework.Scenes
116 double[,] heights = new double[w, l]; 122 double[,] heights = new double[w, l];
117 123
118 int idx = 0; // index into serialized array 124 int idx = 0; // index into serialized array
119 for (int ii = 0; ii < l; ii++) 125 for (int ii = 0; ii < w; ii++)
120 { 126 {
121 for (int jj = 0; jj < w; jj++) 127 for (int jj = 0; jj < l; jj++)
122 { 128 {
123 heights[ii, jj] = (double)FromCompressedHeight(m_map[idx]); 129 heights[ii, jj] = (double)m_terrainData[ii, jj];
124 idx++; 130 idx++;
125 } 131 }
126 } 132 }
@@ -131,31 +137,20 @@ namespace OpenSim.Region.Framework.Scenes
131 // ITerrainChannel.this[x,y] 137 // ITerrainChannel.this[x,y]
132 public double this[int x, int y] 138 public double this[int x, int y]
133 { 139 {
134 get { return m_map[x * Width + y]; } 140 get { return (double)m_terrainData[x, y]; }
135 set 141 set
136 { 142 {
137 // Will "fix" terrain hole problems. Although not fantastically.
138 if (Double.IsNaN(value) || Double.IsInfinity(value)) 143 if (Double.IsNaN(value) || Double.IsInfinity(value))
139 return; 144 return;
140 145
141 int idx = x * Width + y; 146 m_terrainData[x, y] = (float)value;
142 if (m_map[idx] != value)
143 {
144 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
145 m_map[idx] = ToCompressedHeight(value);
146 }
147 } 147 }
148 } 148 }
149 149
150 // ITerrainChannel.Tainted() 150 // ITerrainChannel.Tainted()
151 public bool Tainted(int x, int y) 151 public bool Tainted(int x, int y)
152 { 152 {
153 if (m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize]) 153 return m_terrainData.IsTaintedAt(x, y);
154 {
155 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = false;
156 return true;
157 }
158 return false;
159 } 154 }
160 155
161 // ITerrainChannel.SaveToXmlString() 156 // ITerrainChannel.SaveToXmlString()
@@ -188,49 +183,25 @@ namespace OpenSim.Region.Framework.Scenes
188 183
189 #endregion 184 #endregion
190 185
191 private void InitializeStructures(uint pX, uint pY, uint pZ, bool shouldInitializeHeightmap) 186 /*
192 {
193 Width = (int)pX;
194 Height = (int)pY;
195 Altitude = (int)pZ;
196 m_map = new short[Width * Height];
197 m_taint = new bool[Width / Constants.TerrainPatchSize, Height / Constants.TerrainPatchSize];
198 ClearTaint();
199 if (shouldInitializeHeightmap)
200 {
201 FlatLand();
202 }
203 }
204
205 public void ClearTaint()
206 {
207 for (int ii = 0; ii < Width / Constants.TerrainPatchSize; ii++)
208 for (int jj = 0; jj < Height / Constants.TerrainPatchSize; jj++)
209 m_taint[ii, jj] = false;
210 }
211
212 // To save space (especially for large regions), keep the height as a short integer 187 // To save space (especially for large regions), keep the height as a short integer
213 // that is coded as the float height times the compression factor (usually '100' 188 // that is coded as the float height times the compression factor (usually '100'
214 // to make for two decimal points). 189 // to make for two decimal points).
215 public short ToCompressedHeight(double pHeight) 190 public static short ToCompressedHeight(double pHeight)
216 { 191 {
217 return (short)(pHeight * Constants.TerrainCompression); 192 return (short)(pHeight * Constants.TerrainCompression);
218 } 193 }
219 194
220 public float FromCompressedHeight(short pHeight) 195 public static float FromCompressedHeight(short pHeight)
221 { 196 {
222 return ((float)pHeight) / Constants.TerrainCompression; 197 return ((float)pHeight) / Constants.TerrainCompression;
223 } 198 }
199 */
224 200
225 public TerrainChannel Copy() 201 public TerrainChannel Copy()
226 { 202 {
227 TerrainChannel copy = new TerrainChannel(); 203 TerrainChannel copy = new TerrainChannel();
228 copy.m_map = (short[])m_map.Clone(); 204 copy.m_terrainData = m_terrainData.Clone();
229 copy.m_taint = (bool[,])m_taint.Clone();
230 copy.Width = Width;
231 copy.Height = Height;
232 copy.Altitude = Altitude;
233
234 return copy; 205 return copy;
235 } 206 }
236 207
@@ -289,6 +260,8 @@ namespace OpenSim.Region.Framework.Scenes
289 byte[] dataArray = (byte[])serializer.Deserialize(xmlReader); 260 byte[] dataArray = (byte[])serializer.Deserialize(xmlReader);
290 int index = 0; 261 int index = 0;
291 262
263 m_terrainData = new HeightmapTerrainData(Width, Height, Altitude);
264
292 for (int y = 0; y < Height; y++) 265 for (int y = 0; y < Height; y++)
293 { 266 {
294 for (int x = 0; x < Width; x++) 267 for (int x = 0; x < Width; x++)
@@ -321,7 +294,7 @@ namespace OpenSim.Region.Framework.Scenes
321 // New terrain serialization format that includes the width and length. 294 // New terrain serialization format that includes the width and length.
322 private void ToXml2(XmlWriter xmlWriter) 295 private void ToXml2(XmlWriter xmlWriter)
323 { 296 {
324 TerrainChannelXMLPackage package = new TerrainChannelXMLPackage(Width, Height, Altitude, m_map); 297 TerrainChannelXMLPackage package = new TerrainChannelXMLPackage(Width, Height, Altitude, m_terrainData.GetCompressedMap());
325 XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage)); 298 XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage));
326 serializer.Serialize(xmlWriter, package); 299 serializer.Serialize(xmlWriter, package);
327 } 300 }
@@ -331,38 +304,32 @@ namespace OpenSim.Region.Framework.Scenes
331 { 304 {
332 XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage)); 305 XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage));
333 TerrainChannelXMLPackage package = (TerrainChannelXMLPackage)serializer.Deserialize(xmlReader); 306 TerrainChannelXMLPackage package = (TerrainChannelXMLPackage)serializer.Deserialize(xmlReader);
334 Width = package.SizeX; 307 m_terrainData = new HeightmapTerrainData(package.Map, package.SizeX, package.SizeY, package.SizeZ);
335 Height = package.SizeY;
336 Altitude = package.SizeZ;
337 m_map = package.Map;
338 } 308 }
339 309
340 // Fill the heightmap with the center bump terrain 310 // Fill the heightmap with the center bump terrain
341 private void PinHeadIsland() 311 private void PinHeadIsland()
342 { 312 {
343 int x; 313 for (int x = 0; x < Width; x++)
344 for (x = 0; x < Width; x++)
345 { 314 {
346 int y; 315 for (int y = 0; y < Height; y++)
347 for (y = 0; y < Height; y++)
348 { 316 {
349 int idx = x * (int)Width + y; 317 m_terrainData[x, y] = (float)TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10;
350 m_map[idx] = ToCompressedHeight(TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10); 318 float spherFacA = (float)(TerrainUtil.SphericalFactor(x, y, m_terrainData.SizeX / 2.0, m_terrainData.SizeY / 2.0, 50) * 0.01d);
351 short spherFacA = ToCompressedHeight(TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01); 319 float spherFacB = (float)(TerrainUtil.SphericalFactor(x, y, m_terrainData.SizeX / 2.0, m_terrainData.SizeY / 2.0, 100) * 0.001d);
352 short spherFacB = ToCompressedHeight(TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001); 320 if (m_terrainData[x, y]< spherFacA)
353 if (m_map[idx] < spherFacA) 321 m_terrainData[x, y]= spherFacA;
354 m_map[idx] = spherFacA; 322 if (m_terrainData[x, y]< spherFacB)
355 if (m_map[idx] < spherFacB) 323 m_terrainData[x, y] = spherFacB;
356 m_map[idx] = spherFacB;
357 } 324 }
358 } 325 }
359 } 326 }
360 327
361 private void FlatLand() 328 private void FlatLand()
362 { 329 {
363 short flatHeight = ToCompressedHeight(21); 330 for (int xx = 0; xx < Width; xx++)
364 for (int ii = 0; ii < m_map.Length; ii++) 331 for (int yy = 0; yy < Height; yy++)
365 m_map[ii] = flatHeight; 332 m_terrainData[xx, yy] = 21;
366 } 333 }
367 } 334 }
368} 335}