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()