29 using System.Collections.Generic;
31 using System.IO.Compression;
32 using System.Reflection;
38 namespace OpenSim.Framework
43 public int SizeX {
get;
protected set; }
44 public int SizeY {
get;
protected set; }
45 public int SizeZ {
get;
protected set; }
48 public const float DefaultTerrainHeight = 21f;
50 public abstract float this[
int x,
int y] {
get; set; }
53 public abstract float this[
int x,
int y,
int z] {
get; set; }
55 public abstract bool IsTaintedAt(
int xx,
int yy);
56 public abstract bool IsTaintedAt(
int xx,
int yy,
bool clearOnTest);
57 public abstract void TaintAllTerrain();
58 public abstract void ClearTaint();
60 public abstract void ClearLand();
61 public abstract void ClearLand(
float height);
65 public abstract bool GetDatabaseBlob(out
int DBFormatRevisionCode, out Array blob);
78 public abstract float[] GetCompressedMap();
79 public abstract float CompressionFactor {
get; }
81 public abstract float[] GetFloatsSerialized();
82 public abstract double[,] GetDoubles();
122 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
123 private static string LogHeader =
"[HEIGHTMAP TERRAIN DATA]";
126 public override float this[
int x,
int y]
128 get {
return m_heightmap[x, y]; }
131 if (m_heightmap[x, y] != value)
133 m_heightmap[x, y] = value;
134 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] =
true;
140 public override float this[
int x,
int y,
int z]
142 get {
return this[x, y]; }
143 set {
this[x, y] = value; }
158 private void SetAllTaint(
bool setting)
160 for (
int ii = 0; ii < m_taint.GetLength(0); ii++)
161 for (
int jj = 0; jj < m_taint.GetLength(1); jj++)
162 m_taint[ii, jj] = setting;
168 ClearLand(DefaultTerrainHeight);
173 for (
int xx = 0; xx < SizeX; xx++)
174 for (
int yy = 0; yy < SizeY; yy++)
175 m_heightmap[xx, yy] = pHeight;
181 public override bool IsTaintedAt(
int xx,
int yy,
bool clearOnTest)
183 int tx = xx / Constants.TerrainPatchSize;
184 int ty = yy / Constants.TerrainPatchSize;
185 bool ret = m_taint[tx, ty];
186 if (ret && clearOnTest)
187 m_taint[tx, ty] =
false;
196 return IsTaintedAt(xx, yy,
true );
207 blob = ToLegacyTerrainSerialization();
214 blob = ToCompressedTerrainSerializationV2DGzip();
222 private float m_compressionFactor = 100.0f;
223 public override float CompressionFactor {
get {
return m_compressionFactor; } }
228 float[] newMap =
new float[SizeX * SizeY];
231 for (
int xx = 0; xx < SizeX; xx++)
232 for (
int yy = 0; yy < SizeY; yy++)
233 newMap[ind++] = m_heightmap[xx, yy];
242 ret.m_heightmap = (
float[,])this.m_heightmap.Clone();
252 int points = SizeX * SizeY;
253 float[] heights =
new float[points];
256 for (
int jj = 0; jj < SizeY; jj++)
257 for (
int ii = 0; ii < SizeX; ii++)
259 heights[idx++] = m_heightmap[ii, jj];
268 double[,] ret =
new double[SizeX, SizeY];
269 for (
int xx = 0; xx < SizeX; xx++)
270 for (
int yy = 0; yy < SizeY; yy++)
271 ret[xx, yy] = (
double)m_heightmap[xx, yy];
279 private float[,] m_heightmap;
281 private bool[,] m_taint;
288 pHeight *= CompressionFactor;
289 if (pHeight <
short.MinValue)
290 return short.MinValue;
291 else if (pHeight >
short.MaxValue)
292 return short.MaxValue;
293 return (
short)pHeight;
299 pHeight *= CompressionFactor;
300 if (pHeight < ushort.MinValue)
301 return ushort.MinValue;
302 else if (pHeight > ushort.MaxValue)
303 return ushort.MaxValue;
304 return (ushort)pHeight;
309 return ((
float)pHeight) / CompressionFactor;
314 return ((
float)pHeight) / CompressionFactor;
321 SizeX = pTerrain.GetLength(0);
322 SizeY = pTerrain.GetLength(1);
324 m_compressionFactor = 100.0f;
326 m_heightmap =
new float[SizeX, SizeY];
327 for (
int ii = 0; ii < SizeX; ii++)
329 for (
int jj = 0; jj < SizeY; jj++)
331 m_heightmap[ii, jj] = (float)pTerrain[ii, jj];
337 m_taint =
new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
347 m_compressionFactor = 100.0f;
348 m_heightmap =
new float[SizeX, SizeY];
349 m_taint =
new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
358 m_compressionFactor = pCompressionFactor;
360 for (
int xx = 0; xx < SizeX; xx++)
361 for (
int yy = 0; yy < SizeY; yy++)
362 m_heightmap[xx, yy] = cmap[ind++];
368 : this(pSizeX, pSizeY, pSizeZ)
372 case DBTerrainRevision.Variable2DGzip:
373 FromCompressedTerrainSerializationV2DGZip(pBlob);
374 m_log.DebugFormat(
"{0} HeightmapTerrainData create from Variable2DGzip serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
377 case DBTerrainRevision.Variable2D:
378 FromCompressedTerrainSerializationV2D(pBlob);
379 m_log.DebugFormat(
"{0} HeightmapTerrainData create from Variable2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
381 case DBTerrainRevision.Compressed2D:
382 FromCompressedTerrainSerialization2D(pBlob);
383 m_log.DebugFormat(
"{0} HeightmapTerrainData create from Compressed2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
386 FromLegacyTerrainSerialization(pBlob);
387 m_log.DebugFormat(
"{0} HeightmapTerrainData create from legacy serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
399 using (BinaryWriter bw =
new BinaryWriter(str))
401 for (
int xx = 0; xx < Constants.RegionSize; xx++)
403 for (
int yy = 0; yy < Constants.RegionSize; yy++)
405 double height =
this[xx, yy];
407 height = double.Epsilon;
425 using (MemoryStream mstr =
new MemoryStream(pBlob))
427 using (BinaryReader br =
new BinaryReader(mstr))
433 float val = (float)br.ReadDouble();
435 if (xx < SizeX && yy < SizeY)
436 m_heightmap[xx, yy] = val;
460 using (MemoryStream str =
new MemoryStream((2 *
sizeof(Int32)) + (SizeX * SizeY *
sizeof(
float))))
462 using (BinaryWriter bw =
new BinaryWriter(str))
464 bw.Write((Int32)SizeX);
465 bw.Write((Int32)SizeY);
466 for (
int yy = 0; yy < SizeY; yy++)
467 for (
int xx = 0; xx < SizeX; xx++)
470 float val = (float)Math.Round(m_heightmap[xx, yy],2,MidpointRounding.ToEven);
482 m_log.DebugFormat(
"{0} V2D {1} bytes",
483 LogHeader, ret.Length);
494 using (MemoryStream inp =
new MemoryStream((2 *
sizeof(Int32)) + (SizeX * SizeY *
sizeof(
float))))
496 using (BinaryWriter bw =
new BinaryWriter(inp))
498 bw.Write((Int32)SizeX);
499 bw.Write((Int32)SizeY);
500 for (
int yy = 0; yy < SizeY; yy++)
501 for (
int xx = 0; xx < SizeX; xx++)
503 bw.Write((float)m_heightmap[xx, yy]);
507 inp.Seek(0, SeekOrigin.Begin);
509 using (MemoryStream outputStream =
new MemoryStream())
513 inp.CopyStream(compressionStream, int.MaxValue);
514 compressionStream.Close();
515 ret = outputStream.ToArray();
525 m_log.DebugFormat(
"{0} V2DGzip {1} bytes",
526 LogHeader, ret.Length);
538 Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
540 using (MemoryStream mstr =
new MemoryStream(pBlob))
542 using (BinaryReader br =
new BinaryReader(mstr))
544 hmFormatCode = br.ReadInt32();
545 hmSizeX = br.ReadInt32();
546 hmSizeY = br.ReadInt32();
547 hmCompressionFactor = br.ReadInt32();
549 m_compressionFactor = hmCompressionFactor;
554 for (
int yy = 0; yy < hmSizeY; yy++)
556 for (
int xx = 0; xx < hmSizeX; xx++)
558 float val = FromCompressedHeight(br.ReadInt16());
559 if (xx < SizeX && yy < SizeY)
560 m_heightmap[xx, yy] = val;
566 m_log.DebugFormat(
"{0} Read (compressed2D) heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}",
567 LogHeader, hmSizeX, hmSizeY, SizeX, SizeY, hmCompressionFactor);
578 Int32 hmSizeX, hmSizeY;
581 using (MemoryStream mstr =
new MemoryStream(pBlob))
583 using (BinaryReader br =
new BinaryReader(mstr))
585 hmSizeX = br.ReadInt32();
586 hmSizeY = br.ReadInt32();
591 for (
int yy = 0; yy < hmSizeY; yy++)
593 for (
int xx = 0; xx < hmSizeX; xx++)
595 float val = br.ReadSingle();
596 if (xx < SizeX && yy < SizeY)
597 m_heightmap[xx, yy] = val;
606 m_log.ErrorFormat(
"{0} 2D error: {1} - terrain may be damaged",
607 LogHeader, e.Message);
612 m_log.DebugFormat(
"{0} V2D Heightmap size=<{1},{2}>. Region size=<{3},{4}>",
613 LogHeader, hmSizeX, hmSizeY, SizeX, SizeY);
620 m_log.InfoFormat(
"{0} VD2Gzip {1} bytes input",
621 LogHeader, pBlob.Length);
623 Int32 hmSizeX, hmSizeY;
627 using (MemoryStream outputStream =
new MemoryStream())
629 using (MemoryStream inputStream =
new MemoryStream(pBlob))
633 decompressionStream.Flush();
634 decompressionStream.CopyTo(outputStream);
638 outputStream.Seek(0, SeekOrigin.Begin);
640 using (BinaryReader br =
new BinaryReader(outputStream))
642 hmSizeX = br.ReadInt32();
643 hmSizeY = br.ReadInt32();
648 for (
int yy = 0; yy < hmSizeY; yy++)
650 for (
int xx = 0; xx < hmSizeX; xx++)
652 float val = br.ReadSingle();
653 if (xx < SizeX && yy < SizeY)
654 m_heightmap[xx, yy] = val;
663 m_log.ErrorFormat(
"{0} V2DGzip error: {1} - terrain may be damaged",
664 LogHeader, e.Message);
669 m_log.DebugFormat(
"{0} V2DGzip. Heightmap size=<{1},{2}>. Region size=<{3},{4}>",
670 LogHeader, hmSizeX, hmSizeY, SizeX, SizeY);
override double[,] GetDoubles()
override void ClearTaint()
HeightmapTerrainData(double[,] pTerrain)
override bool IsTaintedAt(int xx, int yy)
HeightmapTerrainData(float[] cmap, float pCompressionFactor, int pX, int pY, int pZ)
short ToCompressedHeightshort(float pHeight)
HeightmapTerrainData(int pX, int pY, int pZ)
void FromCompressedTerrainSerialization2D(byte[] pBlob)
float FromCompressedHeight(short pHeight)
Ionic.Zlib.GZipStream GZipStream
ushort ToCompressedHeightushort(float pHeight)
HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob)
Array ToCompressedTerrainSerializationV2DGzip()
override TerrainData Clone()
void FromCompressedTerrainSerializationV2D(byte[] pBlob)
Array ToLegacyTerrainSerialization()
override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob)
float FromCompressedHeight(ushort pHeight)
void FromCompressedTerrainSerializationV2DGZip(byte[] pBlob)
override void ClearLand()
void FromLegacyTerrainSerialization(byte[] pBlob)
override bool IsTaintedAt(int xx, int yy, bool clearOnTest)
Ionic.Zlib.CompressionMode CompressionMode
override float[] GetCompressedMap()
override float[] GetFloatsSerialized()
static TerrainData CreateFromDatabaseBlobFactory(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob)
override void ClearLand(float pHeight)
Array ToCompressedTerrainSerializationV2D()
override void TaintAllTerrain()