aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
authorUbitUmarov2015-08-25 16:51:48 +0100
committerUbitUmarov2015-08-25 16:51:48 +0100
commit244f0c6352a920b8bba5e13fadda49cb5b368e06 (patch)
tree92d97bde9369dd1e7541f9b6e44d770b429fe503 /OpenSim/Framework
parent terrain stored as ushorts with gzip compression (diff)
downloadopensim-SC_OLD-244f0c6352a920b8bba5e13fadda49cb5b368e06.zip
opensim-SC_OLD-244f0c6352a920b8bba5e13fadda49cb5b368e06.tar.gz
opensim-SC_OLD-244f0c6352a920b8bba5e13fadda49cb5b368e06.tar.bz2
opensim-SC_OLD-244f0c6352a920b8bba5e13fadda49cb5b368e06.tar.xz
change terrain internal representation to float. ushort work with legal
sl terrain, but may break existent terrain and that may cost a lot more than the cost of memory
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/TerrainData.cs241
1 files changed, 162 insertions, 79 deletions
diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs
index cc5b8f5..976c1f0 100644
--- a/OpenSim/Framework/TerrainData.cs
+++ b/OpenSim/Framework/TerrainData.cs
@@ -49,6 +49,7 @@ namespace OpenSim.Framework
49 49
50 public abstract float this[int x, int y] { get; set; } 50 public abstract float this[int x, int y] { get; set; }
51 // Someday terrain will have caves 51 // Someday terrain will have caves
52 // at most holes :p
52 public abstract float this[int x, int y, int z] { get; set; } 53 public abstract float this[int x, int y, int z] { get; set; }
53 54
54 public abstract bool IsTaintedAt(int xx, int yy); 55 public abstract bool IsTaintedAt(int xx, int yy);
@@ -74,7 +75,7 @@ namespace OpenSim.Framework
74 } 75 }
75 76
76 // return a special compressed representation of the heightmap in ushort 77 // return a special compressed representation of the heightmap in ushort
77 public abstract ushort[] GetCompressedMap(); 78 public abstract float[] GetCompressedMap();
78 public abstract float CompressionFactor { get; } 79 public abstract float CompressionFactor { get; }
79 80
80 public abstract float[] GetFloatsSerialized(); 81 public abstract float[] GetFloatsSerialized();
@@ -95,16 +96,21 @@ namespace OpenSim.Framework
95 { 96 {
96 // Terrain is 'double[256,256]' 97 // Terrain is 'double[256,256]'
97 Legacy256 = 11, 98 Legacy256 = 11,
99
98 // Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions 100 // Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions
99 // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256. 101 // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
100 Variable2D = 22, 102 Variable2D = 22,
103 Variable2DGzip = 23,
104
101 // Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions 105 // Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions
102 // and third int is the 'compression factor'. The heights are compressed as 106 // and third int is the 'compression factor'. The heights are compressed as
103 // "ushort compressedHeight = (ushort)(height * compressionFactor);" 107 // "ushort compressedHeight = (ushort)(height * compressionFactor);"
104 // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256. 108 // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
105 Compressed2D = 27, 109 Compressed2D = 27,
110
106 // as Compressed2D but using ushort[] in place of int16[] 111 // as Compressed2D but using ushort[] in place of int16[]
107 Compressed2Du = 28, 112 Compressed2Du = 28,
113
108 // as Compressed2D but using ushort[] in place of int16[] with Gzip compression 114 // as Compressed2D but using ushort[] in place of int16[] with Gzip compression
109 Compressed2DuGzip = 29, 115 Compressed2DuGzip = 29,
110 116
@@ -125,13 +131,12 @@ namespace OpenSim.Framework
125 // TerrainData.this[x, y] 131 // TerrainData.this[x, y]
126 public override float this[int x, int y] 132 public override float this[int x, int y]
127 { 133 {
128 get { return FromCompressedHeight(m_heightmap[x, y]); } 134 get { return m_heightmap[x, y]; }
129 set 135 set
130 { 136 {
131 ushort newVal = ToCompressedHeight(value); 137 if (m_heightmap[x, y] != value)
132 if (m_heightmap[x, y] != newVal)
133 { 138 {
134 m_heightmap[x, y] = newVal; 139 m_heightmap[x, y] = value;
135 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true; 140 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
136 } 141 }
137 } 142 }
@@ -171,10 +176,9 @@ namespace OpenSim.Framework
171 // TerrainData.ClearLand(float) 176 // TerrainData.ClearLand(float)
172 public override void ClearLand(float pHeight) 177 public override void ClearLand(float pHeight)
173 { 178 {
174 ushort flatHeight = ToCompressedHeight(pHeight);
175 for (int xx = 0; xx < SizeX; xx++) 179 for (int xx = 0; xx < SizeX; xx++)
176 for (int yy = 0; yy < SizeY; yy++) 180 for (int yy = 0; yy < SizeY; yy++)
177 m_heightmap[xx, yy] = flatHeight; 181 m_heightmap[xx, yy] = pHeight;
178 } 182 }
179 183
180 // Return 'true' of the patch that contains these region coordinates has been modified. 184 // Return 'true' of the patch that contains these region coordinates has been modified.
@@ -209,8 +213,8 @@ namespace OpenSim.Framework
209 } 213 }
210 else 214 else
211 { 215 {
212 DBRevisionCode = (int)DBTerrainRevision.Compressed2DuGzip; 216 DBRevisionCode = (int)DBTerrainRevision.Variable2DGzip;
213 blob = ToCompressedTerrainSerializationGzip(); 217 blob = ToCompressedTerrainSerializationV2DGzip();
214 ret = true; 218 ret = true;
215 } 219 }
216 return ret; 220 return ret;
@@ -221,9 +225,9 @@ namespace OpenSim.Framework
221 public override float CompressionFactor { get { return m_compressionFactor; } } 225 public override float CompressionFactor { get { return m_compressionFactor; } }
222 226
223 // TerrainData.GetCompressedMap 227 // TerrainData.GetCompressedMap
224 public override ushort[] GetCompressedMap() 228 public override float[] GetCompressedMap()
225 { 229 {
226 ushort[] newMap = new ushort[SizeX * SizeY]; 230 float[] newMap = new float[SizeX * SizeY];
227 231
228 int ind = 0; 232 int ind = 0;
229 for (int xx = 0; xx < SizeX; xx++) 233 for (int xx = 0; xx < SizeX; xx++)
@@ -237,7 +241,7 @@ namespace OpenSim.Framework
237 public override TerrainData Clone() 241 public override TerrainData Clone()
238 { 242 {
239 HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ); 243 HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ);
240 ret.m_heightmap = (ushort[,])this.m_heightmap.Clone(); 244 ret.m_heightmap = (float[,])this.m_heightmap.Clone();
241 return ret; 245 return ret;
242 } 246 }
243 247
@@ -254,7 +258,7 @@ namespace OpenSim.Framework
254 for (int jj = 0; jj < SizeY; jj++) 258 for (int jj = 0; jj < SizeY; jj++)
255 for (int ii = 0; ii < SizeX; ii++) 259 for (int ii = 0; ii < SizeX; ii++)
256 { 260 {
257 heights[idx++] = FromCompressedHeight(m_heightmap[ii, jj]); 261 heights[idx++] = m_heightmap[ii, jj];
258 } 262 }
259 263
260 return heights; 264 return heights;
@@ -266,7 +270,7 @@ namespace OpenSim.Framework
266 double[,] ret = new double[SizeX, SizeY]; 270 double[,] ret = new double[SizeX, SizeY];
267 for (int xx = 0; xx < SizeX; xx++) 271 for (int xx = 0; xx < SizeX; xx++)
268 for (int yy = 0; yy < SizeY; yy++) 272 for (int yy = 0; yy < SizeY; yy++)
269 ret[xx, yy] = FromCompressedHeight(m_heightmap[xx, yy]); 273 ret[xx, yy] = (double)m_heightmap[xx, yy];
270 274
271 return ret; 275 return ret;
272 } 276 }
@@ -274,21 +278,37 @@ namespace OpenSim.Framework
274 278
275 // ============================================================= 279 // =============================================================
276 280
277 private ushort[,] m_heightmap; 281 private float[,] m_heightmap;
278 // Remember subregions of the heightmap that has changed. 282 // Remember subregions of the heightmap that has changed.
279 private bool[,] m_taint; 283 private bool[,] m_taint;
280 284
281 // To save space (especially for large regions), keep the height as a short integer
282 // that is coded as the float height times the compression factor (usually '100' 285 // that is coded as the float height times the compression factor (usually '100'
283 // to make for two decimal points). 286 // to make for two decimal points).
284 public ushort ToCompressedHeight(double pHeight) 287 public short ToCompressedHeightshort(float pHeight)
288 {
289 // clamp into valid range
290 pHeight *= CompressionFactor;
291 if (pHeight < short.MinValue)
292 return short.MinValue;
293 else if (pHeight > short.MaxValue)
294 return short.MaxValue;
295 return (short)pHeight;
296 }
297
298 public ushort ToCompressedHeightushort(float pHeight)
285 { 299 {
286 // clamp into valid range 300 // clamp into valid range
287 if (pHeight < 0) 301 pHeight *= CompressionFactor;
288 pHeight = 0; 302 if (pHeight < ushort.MinValue)
289 else if (pHeight > 655.35f) 303 return ushort.MinValue;
290 pHeight = 655.35f; 304 else if (pHeight > ushort.MaxValue)
291 return (ushort)(pHeight * CompressionFactor); 305 return ushort.MaxValue;
306 return (ushort)pHeight;
307 }
308
309 public float FromCompressedHeight(short pHeight)
310 {
311 return ((float)pHeight) / CompressionFactor;
292 } 312 }
293 313
294 public float FromCompressedHeight(ushort pHeight) 314 public float FromCompressedHeight(ushort pHeight)
@@ -305,12 +325,12 @@ namespace OpenSim.Framework
305 SizeZ = (int)Constants.RegionHeight; 325 SizeZ = (int)Constants.RegionHeight;
306 m_compressionFactor = 100.0f; 326 m_compressionFactor = 100.0f;
307 327
308 m_heightmap = new ushort[SizeX, SizeY]; 328 m_heightmap = new float[SizeX, SizeY];
309 for (int ii = 0; ii < SizeX; ii++) 329 for (int ii = 0; ii < SizeX; ii++)
310 { 330 {
311 for (int jj = 0; jj < SizeY; jj++) 331 for (int jj = 0; jj < SizeY; jj++)
312 { 332 {
313 m_heightmap[ii, jj] = ToCompressedHeight(pTerrain[ii, jj]); 333 m_heightmap[ii, jj] = (float)pTerrain[ii, jj];
314 334
315 } 335 }
316 } 336 }
@@ -327,14 +347,14 @@ namespace OpenSim.Framework
327 SizeY = pY; 347 SizeY = pY;
328 SizeZ = pZ; 348 SizeZ = pZ;
329 m_compressionFactor = 100.0f; 349 m_compressionFactor = 100.0f;
330 m_heightmap = new ushort[SizeX, SizeY]; 350 m_heightmap = new float[SizeX, SizeY];
331 m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize]; 351 m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
332 // m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ); 352 // m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
333 ClearTaint(); 353 ClearTaint();
334 ClearLand(0f); 354 ClearLand(0f);
335 } 355 }
336 356
337 public HeightmapTerrainData(ushort[] cmap, float pCompressionFactor, int pX, int pY, int pZ) 357 public HeightmapTerrainData(float[] cmap, float pCompressionFactor, int pX, int pY, int pZ)
338 : this(pX, pY, pZ) 358 : this(pX, pY, pZ)
339 { 359 {
340 m_compressionFactor = pCompressionFactor; 360 m_compressionFactor = pCompressionFactor;
@@ -351,12 +371,22 @@ namespace OpenSim.Framework
351 { 371 {
352 switch ((DBTerrainRevision)pFormatCode) 372 switch ((DBTerrainRevision)pFormatCode)
353 { 373 {
374 case DBTerrainRevision.Variable2DGzip:
375 FromCompressedTerrainSerializationV2DGZip(pBlob);
376 m_log.DebugFormat("{0} HeightmapTerrainData create from Gzip Compressed2D (unsigned shorts) serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
377 break;
378
379 case DBTerrainRevision.Variable2D:
380 FromCompressedTerrainSerializationV2D(pBlob);
381 m_log.DebugFormat("{0} HeightmapTerrainData create from Gzip Compressed2D (unsigned shorts) serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
382 break;
383
354 case DBTerrainRevision.Compressed2DuGzip: 384 case DBTerrainRevision.Compressed2DuGzip:
355 FromCompressedTerrainSerializationGZip(pBlob); 385 FromCompressedTerrainSerialization2DuGZip(pBlob);
356 m_log.DebugFormat("{0} HeightmapTerrainData create from Gzip Compressed2D (unsigned shorts) serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY); 386 m_log.DebugFormat("{0} HeightmapTerrainData create from Gzip Compressed2D (unsigned shorts) serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
357 break; 387 break;
358 case DBTerrainRevision.Compressed2Du: 388 case DBTerrainRevision.Compressed2Du:
359 FromCompressedTerrainSerialization(pBlob); 389 FromCompressedTerrainSerialization2D(pBlob);
360 m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D (unsigned shorts) serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY); 390 m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D (unsigned shorts) serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
361 break; 391 break;
362 case DBTerrainRevision.Compressed2D: 392 case DBTerrainRevision.Compressed2D:
@@ -414,7 +444,7 @@ namespace OpenSim.Framework
414 float val = (float)br.ReadDouble(); 444 float val = (float)br.ReadDouble();
415 445
416 if (xx < SizeX && yy < SizeY) 446 if (xx < SizeX && yy < SizeY)
417 m_heightmap[xx, yy] = ToCompressedHeight(val); 447 m_heightmap[xx, yy] = val;
418 } 448 }
419 } 449 }
420 } 450 }
@@ -427,53 +457,33 @@ namespace OpenSim.Framework
427 ClearTaint(); 457 ClearTaint();
428 } 458 }
429 459
430 public Array ToCompressedTerrainSerialization2D()
431 {
432 Array ret = null;
433 try
434 {
435 using (MemoryStream str = new MemoryStream((4 * sizeof(Int32)) + (SizeX * SizeY * sizeof(ushort))))
436 {
437 using (BinaryWriter bw = new BinaryWriter(str))
438 {
439 bw.Write((Int32)DBTerrainRevision.Compressed2D);
440 bw.Write((Int32)SizeX);
441 bw.Write((Int32)SizeY);
442 bw.Write((Int32)CompressionFactor);
443 for (int yy = 0; yy < SizeY; yy++)
444 for (int xx = 0; xx < SizeX; xx++)
445 {
446 bw.Write((Int16)m_heightmap[xx, yy]);
447 }
448 }
449 ret = str.ToArray();
450 }
451 }
452 catch
453 {
454 460
455 } 461 // stores as variable2D
456 return ret; 462 // int32 format
457 } 463 // int32 sizeX
464 // int32 sizeY
465 // float[,] array
458 466
459 // See the reader below. 467 // may have endian issues like older
460 public Array ToCompressedTerrainSerialization() 468
469 public Array ToCompressedTerrainSerializationV2D()
461 { 470 {
462 Array ret = null; 471 Array ret = null;
463 try 472 try
464 { 473 {
465 using (MemoryStream str = new MemoryStream((4 * sizeof(Int32)) + (SizeX * SizeY * sizeof(ushort)))) 474 using (MemoryStream str = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float))))
466 { 475 {
467 using (BinaryWriter bw = new BinaryWriter(str)) 476 using (BinaryWriter bw = new BinaryWriter(str))
468 { 477 {
469 bw.Write((Int32)DBTerrainRevision.Compressed2Du); 478 bw.Write((Int32)DBTerrainRevision.Variable2D);
470 bw.Write((Int32)SizeX); 479 bw.Write((Int32)SizeX);
471 bw.Write((Int32)SizeY); 480 bw.Write((Int32)SizeY);
472 bw.Write((Int32)CompressionFactor);
473 for (int yy = 0; yy < SizeY; yy++) 481 for (int yy = 0; yy < SizeY; yy++)
474 for (int xx = 0; xx < SizeX; xx++) 482 for (int xx = 0; xx < SizeX; xx++)
475 { 483 {
476 bw.Write((ushort)m_heightmap[xx, yy]); 484 // reduce to 1cm resolution
485 float val = (float)Math.Round(m_heightmap[xx, yy],2,MidpointRounding.ToEven);
486 bw.Write(val);
477 } 487 }
478 } 488 }
479 ret = str.ToArray(); 489 ret = str.ToArray();
@@ -487,27 +497,26 @@ namespace OpenSim.Framework
487 } 497 }
488 498
489 // as above with Gzip compression 499 // as above with Gzip compression
490 public Array ToCompressedTerrainSerializationGzip() 500 public Array ToCompressedTerrainSerializationV2DGzip()
491 { 501 {
492 Array ret = null; 502 Array ret = null;
493 try 503 try
494 { 504 {
495 using (MemoryStream inp = new MemoryStream((4 * sizeof(Int32)) + (SizeX * SizeY * sizeof(ushort)))) 505 using (MemoryStream inp = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float))))
496 { 506 {
497 using (BinaryWriter bw = new BinaryWriter(inp)) 507 using (BinaryWriter bw = new BinaryWriter(inp))
498 { 508 {
499 bw.Write((Int32)DBTerrainRevision.Compressed2DuGzip); 509 bw.Write((Int32)DBTerrainRevision.Variable2DGzip);
500 bw.Write((Int32)SizeX); 510 bw.Write((Int32)SizeX);
501 bw.Write((Int32)SizeY); 511 bw.Write((Int32)SizeY);
502 bw.Write((Int32)CompressionFactor);
503 for (int yy = 0; yy < SizeY; yy++) 512 for (int yy = 0; yy < SizeY; yy++)
504 for (int xx = 0; xx < SizeX; xx++) 513 for (int xx = 0; xx < SizeX; xx++)
505 { 514 {
506 bw.Write((ushort)m_heightmap[xx, yy]); 515 bw.Write((float)m_heightmap[xx, yy]);
507 } 516 }
508 517
509 bw.Flush(); 518 bw.Flush();
510 inp.Seek(0,SeekOrigin.Begin); 519 inp.Seek(0, SeekOrigin.Begin);
511 520
512 using (MemoryStream outputStream = new MemoryStream()) 521 using (MemoryStream outputStream = new MemoryStream())
513 { 522 {
@@ -525,7 +534,7 @@ namespace OpenSim.Framework
525 { 534 {
526 535
527 } 536 }
528 m_log.InfoFormat("{0} terrain GZiped to {1} bytes (compressed2Dus)", 537 m_log.InfoFormat("{0} terrain GZiped to {1} bytes (V2DGzip)",
529 LogHeader, ret.Length); 538 LogHeader, ret.Length);
530 return ret; 539 return ret;
531 } 540 }
@@ -558,11 +567,9 @@ namespace OpenSim.Framework
558 { 567 {
559 for (int xx = 0; xx < hmSizeX; xx++) 568 for (int xx = 0; xx < hmSizeX; xx++)
560 { 569 {
561 short val = br.ReadInt16(); 570 float val = FromCompressedHeight(br.ReadInt16());
562 if (val < 0)
563 val = 0;
564 if (xx < SizeX && yy < SizeY) 571 if (xx < SizeX && yy < SizeY)
565 m_heightmap[xx, yy] = (ushort)val; 572 m_heightmap[xx, yy] = val;
566 } 573 }
567 } 574 }
568 } 575 }
@@ -579,7 +586,7 @@ namespace OpenSim.Framework
579 // the forth int is the compression factor for the following int16s 586 // the forth int is the compression factor for the following int16s
580 // This is just sets heightmap info. The actual size of the region was set on this instance's 587 // This is just sets heightmap info. The actual size of the region was set on this instance's
581 // creation and any heights not initialized by theis blob are set to the default height. 588 // creation and any heights not initialized by theis blob are set to the default height.
582 public void FromCompressedTerrainSerialization(byte[] pBlob) 589 public void FromCompressedTerrainSerialization2Du(byte[] pBlob)
583 { 590 {
584 Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor; 591 Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
585 try 592 try
@@ -602,7 +609,7 @@ namespace OpenSim.Framework
602 { 609 {
603 for (int xx = 0; xx < hmSizeX; xx++) 610 for (int xx = 0; xx < hmSizeX; xx++)
604 { 611 {
605 ushort val = br.ReadUInt16(); 612 float val = FromCompressedHeight(br.ReadUInt16());
606 if (xx < SizeX && yy < SizeY) 613 if (xx < SizeX && yy < SizeY)
607 m_heightmap[xx, yy] = val; 614 m_heightmap[xx, yy] = val;
608 } 615 }
@@ -614,7 +621,7 @@ namespace OpenSim.Framework
614 { 621 {
615 ClearTaint(); 622 ClearTaint();
616 m_log.ErrorFormat("{0} Read (compressed2Dus) terrain error: {1} - terrain may be damaged", 623 m_log.ErrorFormat("{0} Read (compressed2Dus) terrain error: {1} - terrain may be damaged",
617 LogHeader,e.Message); 624 LogHeader, e.Message);
618 return; 625 return;
619 } 626 }
620 ClearTaint(); 627 ClearTaint();
@@ -625,10 +632,86 @@ namespace OpenSim.Framework
625 } 632 }
626 633
627 // as above but Gzip compressed 634 // as above but Gzip compressed
628 public void FromCompressedTerrainSerializationGZip(byte[] pBlob) 635 public void FromCompressedTerrainSerialization2DuGZip(byte[] pBlob)
636 {
637 m_log.InfoFormat("{0} GZip {1} bytes for terrain",
638 LogHeader, pBlob.Length);
639 byte[] gzipout = null;
640 try
641 {
642 using (MemoryStream inputStream = new MemoryStream(pBlob))
643 {
644 using (GZipStream decompressionStream = new GZipStream(inputStream, CompressionMode.Decompress))
645 {
646 using (MemoryStream outputStream = new MemoryStream())
647 {
648 decompressionStream.Flush();
649 decompressionStream.CopyTo(outputStream);
650 gzipout = outputStream.ToArray();
651 }
652 }
653 }
654 }
655 catch
656 {
657 }
658
659 FromCompressedTerrainSerialization2Du(gzipout);
660 }
661
662 // Initialize heightmap from blob consisting of:
663 // int32, int32, int32, int32, ushort[]
664 // where the first int32 is format code, next two int32s are the X and y of heightmap data and
665 // the forth int is the compression factor for the following int16s
666 // This is just sets heightmap info. The actual size of the region was set on this instance's
667 // creation and any heights not initialized by theis blob are set to the default height.
668 public void FromCompressedTerrainSerializationV2D(byte[] pBlob)
669 {
670 Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
671 try
672 {
673 using (MemoryStream mstr = new MemoryStream(pBlob))
674 {
675 using (BinaryReader br = new BinaryReader(mstr))
676 {
677 hmFormatCode = br.ReadInt32();
678 hmSizeX = br.ReadInt32();
679 hmSizeY = br.ReadInt32();
680
681 // In case database info doesn't match real terrain size, initialize the whole terrain.
682 ClearLand();
683
684 for (int yy = 0; yy < hmSizeY; yy++)
685 {
686 for (int xx = 0; xx < hmSizeX; xx++)
687 {
688 float val = br.ReadSingle();
689 if (xx < SizeX && yy < SizeY)
690 m_heightmap[xx, yy] = val;
691 }
692 }
693 }
694 }
695 }
696 catch (Exception e)
697 {
698 ClearTaint();
699 m_log.ErrorFormat("{0} Read (Variable size format) terrain error: {1} - terrain may be damaged",
700 LogHeader, e.Message);
701 return;
702 }
703 ClearTaint();
704
705 m_log.InfoFormat("{0} Read Variable size format terrain. Heightmap size=<{1},{2}>. Region size=<{3},{4}>",
706 LogHeader, hmSizeX, hmSizeY, SizeX, SizeY);
707
708 }
709 // as above but Gzip compressed
710 public void FromCompressedTerrainSerializationV2DGZip(byte[] pBlob)
629 { 711 {
630 m_log.InfoFormat("{0} GZip {1} bytes for terrain", 712 m_log.InfoFormat("{0} GZip {1} bytes for terrain",
631 LogHeader,pBlob.Length); 713 LogHeader, pBlob.Length);
714
632 byte[] gzipout = null; 715 byte[] gzipout = null;
633 try 716 try
634 { 717 {
@@ -649,7 +732,7 @@ namespace OpenSim.Framework
649 { 732 {
650 } 733 }
651 734
652 FromCompressedTerrainSerialization(gzipout); 735 FromCompressedTerrainSerializationV2D(gzipout);
653 } 736 }
654 } 737 }
655} 738}