aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainCompressor.cs235
1 files changed, 62 insertions, 173 deletions
diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
index beca578..d77e1d7 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
@@ -248,9 +248,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
248 header.PatchIDs = (y & 0x1F); 248 header.PatchIDs = (y & 0x1F);
249 header.PatchIDs += (x << 5); 249 header.PatchIDs += (x << 5);
250 } 250 }
251 251
252 // NOTE: No idea what prequant and postquant should be or what they do
253
254 int wbits; 252 int wbits;
255 int[] patch = CompressPatch(patchData, header, 10, out wbits); 253 int[] patch = CompressPatch(patchData, header, 10, out wbits);
256 wbits = EncodePatchHeader(output, header, patch, Constants.RegionSize, Constants.RegionSize, wbits); 254 wbits = EncodePatchHeader(output, header, patch, Constants.RegionSize, Constants.RegionSize, wbits);
@@ -274,8 +272,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
274 /// <param name="pRegionSizeY"></param> 272 /// <param name="pRegionSizeY"></param>
275 public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY) 273 public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY)
276 { 274 {
277 TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY); 275 float frange;
278 header.QuantWBits = 136; 276 TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY, out frange);
277 header.QuantWBits = 130;
279 278
280 // If larger than legacy region size, pack patch X and Y info differently. 279 // If larger than legacy region size, pack patch X and Y info differently.
281 if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) 280 if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
@@ -289,10 +288,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
289 header.PatchIDs += (patchX << 5); 288 header.PatchIDs += (patchX << 5);
290 } 289 }
291 290
292 // m_log.DebugFormat("{0} CreatePatchFromHeightmap. patchX={1}, patchY={2}, DCOffset={3}, range={4}", 291 if(Math.Round((double)frange,2) == 1.0)
293 // LogHeader, patchX, patchY, header.DCOffset, header.Range); 292 {
293 // flat terrain spead up things
294 294
295 // NOTE: No idea what prequant and postquant should be or what they do 295 // prequant and quant 2 bits both
296 header.QuantWBits = 0x00;
297 output.PackBits(header.QuantWBits, 8);
298 output.PackFloat(header.DCOffset);
299 output.PackBits(1, 16);
300 if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
301 output.PackBits(header.PatchIDs, 32);
302 else
303 output.PackBits(header.PatchIDs, 10);
304 // dc term is - max quant value
305 output.PackBits(NEGATIVE_VALUE, 3);
306 output.PackBits(3, 2);
307 // and thats all
308 output.PackBits(ZERO_EOB, 2);
309 return;
310 }
311
296 int wbits; 312 int wbits;
297 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits); 313 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
298 wbits = EncodePatchHeader(output, header, patch, (uint)terrData.SizeX, (uint)terrData.SizeY, wbits); 314 wbits = EncodePatchHeader(output, header, patch, (uint)terrData.SizeX, (uint)terrData.SizeY, wbits);
@@ -319,15 +335,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
319 } 335 }
320 336
321 // Scan the height info we're returning and return a patch packet header for this patch. 337 // Scan the height info we're returning and return a patch packet header for this patch.
322 private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY) 338 private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY, out float frange)
323 { 339 {
324 TerrainPatch.Header header = new TerrainPatch.Header(); 340 TerrainPatch.Header header = new TerrainPatch.Header();
325 float zmax = -99999999.0f; 341 float zmax = -99999999.0f;
326 float zmin = 99999999.0f; 342 float zmin = 99999999.0f;
343 int startx = patchX * Constants.TerrainPatchSize;
344 int starty = patchY * Constants.TerrainPatchSize;
327 345
328 for (int j = patchY*Constants.TerrainPatchSize; j < (patchY + 1)*Constants.TerrainPatchSize; j++) 346 for (int j = starty; j < starty + Constants.TerrainPatchSize; j++)
329 { 347 {
330 for (int i = patchX*Constants.TerrainPatchSize; i < (patchX + 1)*Constants.TerrainPatchSize; i++) 348 for (int i = startx; i < startx + Constants.TerrainPatchSize; i++)
331 { 349 {
332 float val = terrData[i, j]; 350 float val = terrData[i, j];
333 if (val > zmax) zmax = val; 351 if (val > zmax) zmax = val;
@@ -336,7 +354,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 } 354 }
337 355
338 header.DCOffset = zmin; 356 header.DCOffset = zmin;
339 header.Range = (int)((zmax - zmin) + 1.0f); 357 frange = ((zmax - zmin) + 1.0f);
358 header.Range = (int)frange;
340 359
341 return header; 360 return header;
342 } 361 }
@@ -367,59 +386,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
367 private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, uint pRegionSizeX, 386 private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, uint pRegionSizeX,
368 uint pRegionSizeY, int wbits) 387 uint pRegionSizeY, int wbits)
369 { 388 {
370 /*
371 int temp;
372 int wbits = (header.QuantWBits & 0x0f) + 2;
373 uint maxWbits = (uint)wbits + 5;
374 uint minWbits = ((uint)wbits >> 1);
375 int wbitsMaxValue;
376 */
377 // goal is to determ minimum number of bits to use so all data fits
378 /*
379 wbits = (int)minWbits;
380 wbitsMaxValue = (1 << wbits);
381
382 for (int i = 0; i < patch.Length; i++)
383 {
384 temp = patch[i];
385 if (temp != 0)
386 {
387 // Get the absolute value
388 if (temp < 0) temp *= -1;
389
390 no coments..
391
392 for (int j = (int)maxWbits; j > (int)minWbits; j--)
393 {
394 if ((temp & (1 << j)) != 0)
395 {
396 if (j > wbits) wbits = j;
397 break;
398 }
399 }
400
401 while (temp > wbitsMaxValue)
402 {
403 wbits++;
404 if (wbits == maxWbits)
405 goto Done;
406 wbitsMaxValue = 1 << wbits;
407 }
408 }
409 }
410
411 Done:
412
413 // wbits += 1;
414 */
415 // better check
416 if (wbits > 17) 389 if (wbits > 17)
417 wbits = 16; 390 wbits = 17;
418 else if (wbits < 3) 391 else if (wbits < 2)
419 wbits = 3; 392 wbits = 2;
420 393
421 header.QuantWBits &= 0xf0; 394 header.QuantWBits &= 0xf0;
422
423 header.QuantWBits |= (wbits - 2); 395 header.QuantWBits |= (wbits - 2);
424 396
425 output.PackBits(header.QuantWBits, 8); 397 output.PackBits(header.QuantWBits, 8);
@@ -467,39 +439,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
467 } 439 }
468 } 440 }
469 441
470/*
471 private static void DCTLine16(float[] linein, float[] lineout, int line) 442 private static void DCTLine16(float[] linein, float[] lineout, int line)
472 { 443 {
473 float total = 0.0f; 444 // outputs transpose data
474 int lineSize = line * Constants.TerrainPatchSize;
475
476 for (int n = 0; n < Constants.TerrainPatchSize; n++)
477 {
478 total += linein[lineSize + n];
479 }
480
481 lineout[lineSize] = OO_SQRT2 * total;
482
483 int uptr = 0;
484 for (int u = 1; u < Constants.TerrainPatchSize; u++)
485 {
486 total = 0.0f;
487 uptr += Constants.TerrainPatchSize;
488
489 for (int n = 0; n < Constants.TerrainPatchSize; n++)
490 {
491 total += linein[lineSize + n] * CosineTable16[uptr + n];
492 }
493
494 lineout[lineSize + u] = total;
495 }
496 }
497*/
498 445
499 private static void DCTLine16(float[] linein, float[] lineout, int line)
500 {
501 // outputs transpose data (lines exchanged with coluns )
502 // so to save a bit of cpu when doing coluns
503 float total = 0.0f; 446 float total = 0.0f;
504 int lineSize = line*Constants.TerrainPatchSize; 447 int lineSize = line*Constants.TerrainPatchSize;
505 448
@@ -524,68 +467,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
524 } 467 }
525 } 468 }
526 469
527
528 /*
529 private static void DCTColumn16(float[] linein, int[] lineout, int column)
530 {
531 float total = 0.0f;
532 // const float oosob = 2.0f / Constants.TerrainPatchSize;
533
534 for (int n = 0; n < Constants.TerrainPatchSize; n++)
535 {
536 total += linein[Constants.TerrainPatchSize * n + column];
537 }
538
539 // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]);
540 lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * QuantizeTable16[column]);
541
542 for (int uptr = Constants.TerrainPatchSize; uptr < Constants.TerrainPatchSize * Constants.TerrainPatchSize; uptr += Constants.TerrainPatchSize)
543 {
544 total = 0.0f;
545
546 for (int n = 0; n < Constants.TerrainPatchSize; n++)
547 {
548 total += linein[Constants.TerrainPatchSize * n + column] * CosineTable16[uptr + n];
549 }
550
551 // lineout[CopyMatrix16[Constants.TerrainPatchSize * u + column]] = (int)(total * oosob * QuantizeTable16[Constants.TerrainPatchSize * u + column]);
552 lineout[CopyMatrix16[uptr + column]] = (int)(total * QuantizeTable16[uptr + column]);
553 }
554 }
555
556 private static void DCTColumn16(float[] linein, int[] lineout, int column)
557 {
558 // input columns are in fact stored in lines now
559
560 float total = 0.0f;
561// const float oosob = 2.0f / Constants.TerrainPatchSize;
562 int inlinesptr = Constants.TerrainPatchSize*column;
563
564 for (int n = 0; n < Constants.TerrainPatchSize; n++)
565 {
566 total += linein[inlinesptr + n];
567 }
568
569 // lineout[CopyMatrix16[column]] = (int)(OO_SQRT2 * total * oosob * QuantizeTable16[column]);
570 lineout[CopyMatrix16[column]] = (int) (OO_SQRT2*total*QuantizeTable16[column]);
571
572 for (int uptr = Constants.TerrainPatchSize;
573 uptr < Constants.TerrainPatchSize*Constants.TerrainPatchSize;
574 uptr += Constants.TerrainPatchSize)
575 {
576 total = 0.0f;
577
578 for (int n = inlinesptr, ptru = uptr; n < inlinesptr + Constants.TerrainPatchSize; n++, ptru++)
579 {
580 total += linein[n]*CosineTable16[ptru];
581 }
582
583// lineout[CopyMatrix16[Constants.TerrainPatchSize * u + column]] = (int)(total * oosob * QuantizeTable16[Constants.TerrainPatchSize * u + column]);
584 lineout[CopyMatrix16[uptr + column]] = (int) (total*QuantizeTable16[uptr + column]);
585 }
586 }
587 */
588
589 private static int DCTColumn16Wbits(float[] linein, int[] lineout, int column, int wbits, int maxwbits) 470 private static int DCTColumn16Wbits(float[] linein, int[] lineout, int column, int wbits, int maxwbits)
590 { 471 {
591 // input columns are in fact stored in lines now 472 // input columns are in fact stored in lines now
@@ -701,16 +582,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
701 private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits) 582 private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits)
702 { 583 {
703 int maxwbitssize = (1 << wbits) - 1; 584 int maxwbitssize = (1 << wbits) - 1;
585 int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize;
704 586
705 if (postquant > Constants.TerrainPatchSize*Constants.TerrainPatchSize || postquant < 0) 587 if (postquant > fullSize || postquant < 0)
706 { 588 {
707 Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error); 589 Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error);
708 return; 590 return;
709 } 591 }
710 592
711 if (postquant != 0) patch[Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant] = 0; 593 if (postquant != 0)
594 patch[fullSize - postquant] = 0;
712 595
713 for (int i = 0; i < Constants.TerrainPatchSize*Constants.TerrainPatchSize; i++) 596 int lastZeroindx = fullSize - postquant;
597
598 for (int i = 0; i < fullSize; i++)
714 { 599 {
715 int temp = patch[i]; 600 int temp = patch[i];
716 601
@@ -718,7 +603,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
718 { 603 {
719 bool eob = true; 604 bool eob = true;
720 605
721 for (int j = i; j < Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant; j++) 606 for (int j = i; j < lastZeroindx ; j++)
722 { 607 {
723 if (patch[j] != 0) 608 if (patch[j] != 0)
724 { 609 {
@@ -800,13 +685,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
800 685
801 private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits) 686 private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits)
802 { 687 {
803 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 688 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
804 int wordsize = (prequant - 2) & 0x0f;
805 float oozrange = 1.0f/header.Range; 689 float oozrange = 1.0f/header.Range;
806 float range = (1 << prequant); 690 float range = (1 << prequant);
807 float premult = oozrange*range; 691 float premult = oozrange*range;
808 float sub = (1 << (prequant - 1)) + header.DCOffset*premult;
809 692
693
694 float sub = 0.5f * header.Range + header.DCOffset;
695
696 int wordsize = (prequant - 2) & 0x0f;
810 header.QuantWBits = wordsize; 697 header.QuantWBits = wordsize;
811 header.QuantWBits |= wordsize << 4; 698 header.QuantWBits |= wordsize << 4;
812 699
@@ -814,7 +701,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
814 for (int j = 0; j < Constants.TerrainPatchSize; j++) 701 for (int j = 0; j < Constants.TerrainPatchSize; j++)
815 { 702 {
816 for (int i = 0; i < Constants.TerrainPatchSize; i++) 703 for (int i = 0; i < Constants.TerrainPatchSize; i++)
817 block[k++] = patchData[j*Constants.TerrainPatchSize + i]*premult - sub; 704 block[k++] = (patchData[j*Constants.TerrainPatchSize + i] - sub) * premult;
818 } 705 }
819 706
820 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 707 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
@@ -838,9 +725,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
838 float oozrange = 1.0f/header.Range; 725 float oozrange = 1.0f/header.Range;
839 float range = (1 << prequant); 726 float range = (1 << prequant);
840 float premult = oozrange*range; 727 float premult = oozrange*range;
841 float sub = (1 << (prequant - 1)) + header.DCOffset*premult;
842 int wordsize = (prequant - 2) & 0x0f;
843 728
729 float sub = 0.5f * header.Range + header.DCOffset;
730
731 int wordsize = (prequant - 2) & 0x0f;
844 header.QuantWBits = wordsize; 732 header.QuantWBits = wordsize;
845 header.QuantWBits |= wordsize << 4; 733 header.QuantWBits |= wordsize << 4;
846 734
@@ -848,7 +736,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
848 for (int j = 0; j < Constants.TerrainPatchSize; j++) 736 for (int j = 0; j < Constants.TerrainPatchSize; j++)
849 { 737 {
850 for (int i = 0; i < Constants.TerrainPatchSize; i++) 738 for (int i = 0; i < Constants.TerrainPatchSize; i++)
851 block[k++] = patchData[j, i]*premult - sub; 739 block[k++] = (patchData[j, i] - sub) * premult;
852 } 740 }
853 741
854 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 742 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
@@ -869,14 +757,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
869 int prequant, out int wbits) 757 int prequant, out int wbits)
870 { 758 {
871 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 759 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
872 int wordsize = prequant; 760
873 float oozrange = 1.0f/header.Range; 761 float oozrange = 1.0f/header.Range;
874 float range = (1 << prequant); 762 float invprequat = (1 << prequant);
875 float premult = oozrange*range; 763 float premult = oozrange* invprequat;
876 float sub = (1 << (prequant - 1)) + header.DCOffset*premult; 764
765 float sub = 0.5f * header.Range + header.DCOffset;
877 766
878 header.QuantWBits = wordsize - 2; 767 int wordsize = (prequant -2 ) & 0x0f;
879 header.QuantWBits |= (prequant - 2) << 4; 768 header.QuantWBits = wordsize;
769 header.QuantWBits |= wordsize << 4;
880 770
881 int k = 0; 771 int k = 0;
882 772
@@ -892,7 +782,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
892 { 782 {
893 for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++) 783 for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++)
894 { 784 {
895 block[k++] = terrData[xx, yy] * premult - sub; 785 block[k++] = (terrData[xx, yy] - sub) * premult;
896 } 786 }
897 } 787 }
898 788
@@ -930,7 +820,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
930 { 820 {
931 for (int i = 0; i < Constants.TerrainPatchSize; i++) 821 for (int i = 0; i < Constants.TerrainPatchSize; i++)
932 { 822 {
933// QuantizeTable16[j * Constants.TerrainPatchSize + i] = 1.0f / (1.0f + 2.0f * ((float)i + (float)j));
934 QuantizeTable16[j*Constants.TerrainPatchSize + i] = oosob/(1.0f + 2.0f*(i + (float) j)); 823 QuantizeTable16[j*Constants.TerrainPatchSize + i] = oosob/(1.0f + 2.0f*(i + (float) j));
935 } 824 }
936 } 825 }