aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/TerrainChannel.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs242
1 files changed, 242 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
new file mode 100644
index 0000000..55c5181
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -0,0 +1,242 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Framework;
29using OpenSim.Region.Framework.Interfaces;
30using System;
31using System.Text;
32using System.Xml;
33using System.IO;
34using System.Xml.Serialization;
35
36namespace OpenSim.Region.Framework.Scenes
37{
38 /// <summary>
39 /// A new version of the old Channel class, simplified
40 /// </summary>
41 public class TerrainChannel : ITerrainChannel
42 {
43 private readonly bool[,] taint;
44 private double[,] map;
45
46 public TerrainChannel()
47 {
48 map = new double[Constants.RegionSize, Constants.RegionSize];
49 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
50
51 int x;
52 for (x = 0; x < Constants.RegionSize; x++)
53 {
54 int y;
55 for (y = 0; y < Constants.RegionSize; y++)
56 {
57 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10;
58 double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01;
59 double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001;
60 if (map[x, y] < spherFacA)
61 map[x, y] = spherFacA;
62 if (map[x, y] < spherFacB)
63 map[x, y] = spherFacB;
64 }
65 }
66 }
67
68 public TerrainChannel(double[,] import)
69 {
70 map = import;
71 taint = new bool[import.GetLength(0),import.GetLength(1)];
72 }
73
74 public TerrainChannel(bool createMap)
75 {
76 if (createMap)
77 {
78 map = new double[Constants.RegionSize,Constants.RegionSize];
79 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
80 }
81 }
82
83 public TerrainChannel(int w, int h)
84 {
85 map = new double[w,h];
86 taint = new bool[w / 16,h / 16];
87 }
88
89 #region ITerrainChannel Members
90
91 public int Width
92 {
93 get { return map.GetLength(0); }
94 }
95
96 public int Height
97 {
98 get { return map.GetLength(1); }
99 }
100
101 public ITerrainChannel MakeCopy()
102 {
103 TerrainChannel copy = new TerrainChannel(false);
104 copy.map = (double[,]) map.Clone();
105
106 return copy;
107 }
108
109 public float[] GetFloatsSerialised()
110 {
111 // Move the member variables into local variables, calling
112 // member variables 256*256 times gets expensive
113 int w = Width;
114 int h = Height;
115 float[] heights = new float[w * h];
116
117 int i, j; // map coordinates
118 int idx = 0; // index into serialized array
119 for (i = 0; i < h; i++)
120 {
121 for (j = 0; j < w; j++)
122 {
123 heights[idx++] = (float)map[j, i];
124 }
125 }
126
127 return heights;
128 }
129
130 public double[,] GetDoubles()
131 {
132 return map;
133 }
134
135 public double this[int x, int y]
136 {
137 get { return map[x, y]; }
138 set
139 {
140 // Will "fix" terrain hole problems. Although not fantastically.
141 if (Double.IsNaN(value) || Double.IsInfinity(value))
142 return;
143
144 if (map[x, y] != value)
145 {
146 taint[x / 16, y / 16] = true;
147 map[x, y] = value;
148 }
149 }
150 }
151
152 public bool Tainted(int x, int y)
153 {
154 if (taint[x / 16, y / 16])
155 {
156 taint[x / 16, y / 16] = false;
157 return true;
158 }
159 return false;
160 }
161
162 #endregion
163
164 public TerrainChannel Copy()
165 {
166 TerrainChannel copy = new TerrainChannel(false);
167 copy.map = (double[,]) map.Clone();
168
169 return copy;
170 }
171
172 public string SaveToXmlString()
173 {
174 XmlWriterSettings settings = new XmlWriterSettings();
175 settings.Encoding = Encoding.UTF8;
176 using (StringWriter sw = new StringWriter())
177 {
178 using (XmlWriter writer = XmlWriter.Create(sw, settings))
179 {
180 WriteXml(writer);
181 }
182 string output = sw.ToString();
183 return output;
184 }
185 }
186
187 private void WriteXml(XmlWriter writer)
188 {
189 writer.WriteStartElement(String.Empty, "TerrainMap", String.Empty);
190 ToXml(writer);
191 writer.WriteEndElement();
192 }
193
194 public void LoadFromXmlString(string data)
195 {
196 StringReader sr = new StringReader(data);
197 XmlTextReader reader = new XmlTextReader(sr);
198 reader.Read();
199
200 ReadXml(reader);
201 reader.Close();
202 sr.Close();
203 }
204
205 private void ReadXml(XmlReader reader)
206 {
207 reader.ReadStartElement("TerrainMap");
208 FromXml(reader);
209 }
210
211 private void ToXml(XmlWriter xmlWriter)
212 {
213 float[] mapData = GetFloatsSerialised();
214 byte[] buffer = new byte[mapData.Length * 4];
215 for (int i = 0; i < mapData.Length; i++)
216 {
217 byte[] value = BitConverter.GetBytes(mapData[i]);
218 Array.Copy(value, 0, buffer, (i * 4), 4);
219 }
220 XmlSerializer serializer = new XmlSerializer(typeof(byte[]));
221 serializer.Serialize(xmlWriter, buffer);
222 }
223
224 private void FromXml(XmlReader xmlReader)
225 {
226 XmlSerializer serializer = new XmlSerializer(typeof(byte[]));
227 byte[] dataArray = (byte[])serializer.Deserialize(xmlReader);
228 int index = 0;
229
230 for (int y = 0; y < Height; y++)
231 {
232 for (int x = 0; x < Width; x++)
233 {
234 float value;
235 value = BitConverter.ToSingle(dataArray, index);
236 index += 4;
237 this[x, y] = (double)value;
238 }
239 }
240 }
241 }
242}