aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/TerrainData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/TerrainData.cs')
-rw-r--r--OpenSim/Framework/TerrainData.cs113
1 files changed, 102 insertions, 11 deletions
diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs
index 8cb1aef..bee6814 100644
--- a/OpenSim/Framework/TerrainData.cs
+++ b/OpenSim/Framework/TerrainData.cs
@@ -44,9 +44,19 @@ namespace OpenSim.Framework
44 // Someday terrain will have caves 44 // Someday terrain will have caves
45 public abstract float this[int x, int y, int z] { get; set; } 45 public abstract float this[int x, int y, int z] { get; set; }
46 46
47 public bool IsTainted { get; protected set; }
48 public abstract bool IsTaintedAt(int xx, int yy);
49 public abstract void ClearTaint();
50
47 // Return a representation of this terrain for storing as a blob in the database. 51 // Return a representation of this terrain for storing as a blob in the database.
48 // Returns 'true' to say blob was stored in the 'out' locations. 52 // Returns 'true' to say blob was stored in the 'out' locations.
49 public abstract bool GetDatabaseBlob(out int DBFormatRevisionCode, out Array blob); 53 public abstract bool GetDatabaseBlob(out int DBFormatRevisionCode, out Array blob);
54
55 // return a special compressed representation of the heightmap in shorts
56 public abstract short[] GetCompressedMap();
57 public abstract void SetCompressedMap(short[] cmap);
58
59 public abstract TerrainData Clone();
50 } 60 }
51 61
52 // The terrain is stored as a blob in the database with a 'revision' field. 62 // The terrain is stored as a blob in the database with a 'revision' field.
@@ -72,13 +82,23 @@ namespace OpenSim.Framework
72 // Version of terrain that is a heightmap. 82 // Version of terrain that is a heightmap.
73 // This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge 83 // This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge
74 // of 'patches' which are 16x16 terrain areas which can be sent separately to the viewer. 84 // of 'patches' which are 16x16 terrain areas which can be sent separately to the viewer.
85 // The heighmap is kept as an array of short integers. The integer values are converted to
86 // and from floats by TerrainCompressionFactor.
75 public class HeightmapTerrainData : TerrainData 87 public class HeightmapTerrainData : TerrainData
76 { 88 {
77 // TerrainData.this[x, y] 89 // TerrainData.this[x, y]
78 public override float this[int x, int y] 90 public override float this[int x, int y]
79 { 91 {
80 get { return m_heightmap[x * SizeX + y]; } 92 get { return FromCompressedHeight(m_heightmap[x, y]); }
81 set { m_heightmap[x * SizeX + y] = value; } 93 set {
94 short newVal = ToCompressedHeight(value);
95 if (m_heightmap[x, y] != newVal)
96 {
97 m_heightmap[x, y] = newVal;
98 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
99
100 }
101 }
82 } 102 }
83 103
84 // TerrainData.this[x, y, z] 104 // TerrainData.this[x, y, z]
@@ -88,6 +108,20 @@ namespace OpenSim.Framework
88 set { this[x, y] = value; } 108 set { this[x, y] = value; }
89 } 109 }
90 110
111 // TerrainData.ClearTaint
112 public override void ClearTaint()
113 {
114 IsTainted = false;
115 for (int ii = 0; ii < m_taint.GetLength(0); ii++)
116 for (int jj = 0; jj < m_taint.GetLength(1); jj++)
117 m_taint[ii, jj] = false;
118 }
119
120 public override bool IsTaintedAt(int xx, int yy)
121 {
122 return m_taint[xx / Constants.TerrainPatchSize, yy / Constants.TerrainPatchSize];
123 }
124
91 // TerrainData.GetDatabaseBlob 125 // TerrainData.GetDatabaseBlob
92 // The user wants something to store in the database. 126 // The user wants something to store in the database.
93 public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob) 127 public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob)
@@ -96,7 +130,53 @@ namespace OpenSim.Framework
96 blob = LegacyTerrainSerialization(); 130 blob = LegacyTerrainSerialization();
97 return false; 131 return false;
98 } 132 }
99 private float[] m_heightmap; 133
134 public override short[] GetCompressedMap()
135 {
136 short[] newMap = new short[SizeX * SizeY];
137
138 int ind = 0;
139 for (int xx = 0; xx < SizeX; xx++)
140 for (int yy = 0; yy < SizeY; yy++)
141 newMap[ind++] = m_heightmap[xx, yy];
142
143 return newMap;
144
145 }
146 public override void SetCompressedMap(short[] cmap)
147 {
148 int ind = 0;
149 for (int xx = 0; xx < SizeX; xx++)
150 for (int yy = 0; yy < SizeY; yy++)
151 m_heightmap[xx, yy] = cmap[ind++];
152 }
153
154 // TerrainData.Clone
155 public override TerrainData Clone()
156 {
157 HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ);
158 ret.m_heightmap = (short[,])this.m_heightmap.Clone();
159 return ret;
160 }
161
162 // =============================================================
163
164 private short[,] m_heightmap;
165 // Remember subregions of the heightmap that has changed.
166 private bool[,] m_taint;
167
168 // To save space (especially for large regions), keep the height as a short integer
169 // that is coded as the float height times the compression factor (usually '100'
170 // to make for two decimal points).
171 public static short ToCompressedHeight(double pHeight)
172 {
173 return (short)(pHeight * Constants.TerrainCompression);
174 }
175
176 public static float FromCompressedHeight(short pHeight)
177 {
178 return ((float)pHeight) / Constants.TerrainCompression;
179 }
100 180
101 // To keep with the legacy theme, this can be created with the way terrain 181 // To keep with the legacy theme, this can be created with the way terrain
102 // used to passed around as. 182 // used to passed around as.
@@ -106,26 +186,37 @@ namespace OpenSim.Framework
106 SizeY = pTerrain.GetLength(1); 186 SizeY = pTerrain.GetLength(1);
107 SizeZ = (int)Constants.RegionHeight; 187 SizeZ = (int)Constants.RegionHeight;
108 188
109 int idx = 0; 189 m_heightmap = new short[SizeX, SizeY];
110 m_heightmap = new float[SizeX * SizeY];
111 for (int ii = 0; ii < SizeX; ii++) 190 for (int ii = 0; ii < SizeX; ii++)
112 { 191 {
113 for (int jj = 0; jj < SizeY; jj++) 192 for (int jj = 0; jj < SizeY; jj++)
114 { 193 {
115 m_heightmap[idx++] = (float)pTerrain[ii, jj]; 194 m_heightmap[ii, jj] = ToCompressedHeight(pTerrain[ii, jj]);
116 195
117 } 196 }
118 } 197 }
198
199 m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
200 ClearTaint();
119 } 201 }
120 202
121 public HeightmapTerrainData(float[] pHeightmap, int pX, int pY, int pZ) 203 // Create underlying structures but don't initialize the heightmap assuming the caller will immediately do that
204 public HeightmapTerrainData(int pX, int pY, int pZ)
122 { 205 {
123 m_heightmap = pHeightmap;
124 SizeX = pX; 206 SizeX = pX;
125 SizeY = pY; 207 SizeY = pY;
126 SizeZ = pZ; 208 SizeZ = pZ;
209 m_heightmap = new short[SizeX, SizeY];
210 m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
211 ClearTaint();
127 } 212 }
128 213
214 public HeightmapTerrainData(short[] cmap, int pX, int pY, int pZ) : this(pX, pY, pZ)
215 {
216 SetCompressedMap(cmap);
217 }
218
219
129 // Just create an array of doubles. Presumes the caller implicitly knows the size. 220 // Just create an array of doubles. Presumes the caller implicitly knows the size.
130 public Array LegacyTerrainSerialization() 221 public Array LegacyTerrainSerialization()
131 { 222 {
@@ -135,12 +226,12 @@ namespace OpenSim.Framework
135 using (BinaryWriter bw = new BinaryWriter(str)) 226 using (BinaryWriter bw = new BinaryWriter(str))
136 { 227 {
137 // TODO: COMPATIBILITY - Add byte-order conversions 228 // TODO: COMPATIBILITY - Add byte-order conversions
138 for (int ii = 0; ii < m_heightmap.Length; ii++) 229 for (int ii = 0; ii < SizeX; ii++)
230 for (int jj = 0; jj < SizeY; jj++)
139 { 231 {
140 double height = (double)m_heightmap[ii]; 232 double height = this[ii, jj];
141 if (height == 0.0) 233 if (height == 0.0)
142 height = double.Epsilon; 234 height = double.Epsilon;
143
144 bw.Write(height); 235 bw.Write(height);
145 } 236 }
146 } 237 }