aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/TerrainCompressor.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainCompressor.cs59
1 files changed, 25 insertions, 34 deletions
diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
index 2e856bc..511745d 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
@@ -113,22 +113,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
113 // routines (like IClientAPI) only pass the float array of heights around. This entry 113 // routines (like IClientAPI) only pass the float array of heights around. This entry
114 // converts that legacy representation into the more compact represenation used in 114 // converts that legacy representation into the more compact represenation used in
115 // TerrainChannel. Someday fix the plumbing between here and the scene. 115 // TerrainChannel. Someday fix the plumbing between here and the scene.
116 public static LayerDataPacket CreateLandPacket(float[] heightmap, int patchX, int patchY, uint sizeX, uint sizeY) 116 public static LayerDataPacket CreateLandPacket(TerrainData terrData, int patchX, int patchY)
117 { 117 {
118 int[] xPieces = new int[1]; 118 int[] xPieces = new int[1];
119 int[] yPieces = new int[1]; 119 int[] yPieces = new int[1];
120
121 short[] newmap = new short[heightmap.Length];
122 for (int ii = 0; ii < heightmap.Length; ii++)
123 newmap[ii] = TerrainChannel.ToCompressedHeight(heightmap[ii]);
124
125 xPieces[0] = patchX; // patch X dimension 120 xPieces[0] = patchX; // patch X dimension
126 yPieces[0] = patchY; 121 yPieces[0] = patchY;
127 122
128 m_log.DebugFormat("{0} CreateLandPacket. patchX={1}, patchY={2}, sizeX={3}, sizeY={4}", 123 m_log.DebugFormat("{0} CreateLandPacket. patchX={1}, patchY={2}, sizeX={3}, sizeY={4}",
129 LogHeader, patchX, patchY, sizeX, sizeY); 124 LogHeader, patchX, patchY, terrData.SizeX, terrData.SizeY);
130 125
131 return CreateLandPacket(newmap, xPieces, yPieces, (int)TerrainPatch.LayerType.Land, sizeX, sizeY); 126 return CreateLandPacket(terrData, xPieces, yPieces, (int)TerrainPatch.LayerType.Land);
132 } 127 }
133 128
134 /// <summary> 129 /// <summary>
@@ -153,8 +148,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
153 /// <param name="pRegionSizeX"></param> 148 /// <param name="pRegionSizeX"></param>
154 /// <param name="pRegionSizeY"></param> 149 /// <param name="pRegionSizeY"></param>
155 /// <returns></returns> 150 /// <returns></returns>
156 public static LayerDataPacket CreateLandPacket(short[] heightmap, int[] x, int[] y, byte type, 151 public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] x, int[] y, byte type)
157 uint pRegionSizeX, uint pRegionSizeY)
158 { 152 {
159 LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}}; 153 LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}};
160 154
@@ -168,7 +162,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
168 bitpack.PackBits(type, 8); 162 bitpack.PackBits(type, 8);
169 163
170 for (int i = 0; i < x.Length; i++) 164 for (int i = 0; i < x.Length; i++)
171 CreatePatchFromHeightmap(bitpack, heightmap, x[i], y[i], pRegionSizeX, pRegionSizeY); 165 CreatePatchFromHeightmap(bitpack, terrData, x[i], y[i]);
172 166
173 bitpack.PackBits(END_OF_PATCHES, 8); 167 bitpack.PackBits(END_OF_PATCHES, 8);
174 168
@@ -217,14 +211,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
217 /// </param> 211 /// </param>
218 /// <param name="pRegionSizeX"></param> 212 /// <param name="pRegionSizeX"></param>
219 /// <param name="pRegionSizeY"></param> 213 /// <param name="pRegionSizeY"></param>
220 public static void CreatePatchFromHeightmap(BitPack output, short[] heightmap, int patchX, int patchY, 214 public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY)
221 uint pRegionSizeX, uint pRegionSizeY)
222 { 215 {
223 TerrainPatch.Header header = PrescanPatch(heightmap, patchX, patchY, pRegionSizeX, pRegionSizeY); 216 TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY);
224 header.QuantWBits = 136; 217 header.QuantWBits = 136;
225 218
226 // If larger than legacy region size, pack patch X and Y info differently. 219 // If larger than legacy region size, pack patch X and Y info differently.
227 if (pRegionSizeX > Constants.RegionSize || pRegionSizeY > Constants.RegionSize) 220 if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
228 { 221 {
229 header.PatchIDs = (patchY & 0xFFFF); 222 header.PatchIDs = (patchY & 0xFFFF);
230 header.PatchIDs += (patchX << 16); 223 header.PatchIDs += (patchX << 16);
@@ -237,8 +230,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
237 230
238 // NOTE: No idea what prequant and postquant should be or what they do 231 // NOTE: No idea what prequant and postquant should be or what they do
239 int wbits; 232 int wbits;
240 int[] patch = CompressPatch(heightmap, patchX, patchY, header, 10, pRegionSizeX, pRegionSizeY, out wbits); 233 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
241 wbits = EncodePatchHeader(output, header, patch, pRegionSizeX, pRegionSizeY, wbits); 234 wbits = EncodePatchHeader(output, header, patch, (uint)terrData.SizeX, (uint)terrData.SizeY, wbits);
242 EncodePatch(output, patch, 0, wbits); 235 EncodePatch(output, patch, 0, wbits);
243 } 236 }
244 237
@@ -262,19 +255,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
262 } 255 }
263 256
264 // Scan the height info we're returning and return a patch packet header for this patch. 257 // Scan the height info we're returning and return a patch packet header for this patch.
265 // TODO. Why are patches ordered Y,X rather than X,Y? 258 private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY)
266 private static TerrainPatch.Header PrescanPatch(short[] heightmap, int patchX, int patchY,
267 uint pRegionSizeX, uint pRegionSizeY)
268 { 259 {
269 TerrainPatch.Header header = new TerrainPatch.Header(); 260 TerrainPatch.Header header = new TerrainPatch.Header();
270 short zmax = -32767; 261 float zmax = -99999999.0f;
271 short zmin = 32767; 262 float zmin = 99999999.0f;
272 263
273 for (int j = patchY*16; j < (patchY + 1)*16; j++) 264 for (int j = patchY*16; j < (patchY + 1)*16; j++)
274 { 265 {
275 for (int i = patchX*16; i < (patchX + 1)*16; i++) 266 for (int i = patchX*16; i < (patchX + 1)*16; i++)
276 { 267 {
277 short val = heightmap[j*pRegionSizeX + i]; 268 // short val = heightmap[j*pRegionSizeX + i];
269 float val = terrData[j, i];
278 if (val > zmax) zmax = val; 270 if (val > zmax) zmax = val;
279 if (val < zmin) zmin = val; 271 if (val < zmin) zmin = val;
280 } 272 }
@@ -282,8 +274,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
282 274
283 // Since the the min and max values are the shorts, rescale to be real values. 275 // Since the the min and max values are the shorts, rescale to be real values.
284 // TODO: all this logic should go into the class wrapping the short values. 276 // TODO: all this logic should go into the class wrapping the short values.
285 header.DCOffset = TerrainChannel.FromCompressedHeight(zmin); 277 header.DCOffset = zmin;
286 header.Range = (int)(TerrainChannel.FromCompressedHeight(zmax) - TerrainChannel.FromCompressedHeight(zmin) + 1.0f); 278 header.Range = (int)(zmax - zmin + 1.0f);
287 279
288 return header; 280 return header;
289 } 281 }
@@ -812,8 +804,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
812 return itemp; 804 return itemp;
813 } 805 }
814 806
815 private static int[] CompressPatch(short[] heightmap, int patchX, int patchY, TerrainPatch.Header header, 807 private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
816 int prequant, uint pRegionSizeX, uint pRegionSizeY, out int wbits) 808 int prequant, out int wbits)
817 { 809 {
818 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 810 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
819 int wordsize = prequant; 811 int wordsize = prequant;
@@ -827,19 +819,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
827 819
828 int k = 0; 820 int k = 0;
829 821
830 premult /= Constants.TerrainCompression; // put here short to float factor
831
832 int jPatchLimit = patchY; 822 int jPatchLimit = patchY;
833 if (patchY >= (pRegionSizeY / Constants.TerrainPatchSize)) 823 if (patchY >= (terrData.SizeY / Constants.TerrainPatchSize))
834 { 824 {
835 jPatchLimit = (int)(pRegionSizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize; 825 jPatchLimit = (int)(terrData.SizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize;
836 } 826 }
837 jPatchLimit = (jPatchLimit + 1) * Constants.TerrainPatchSize; 827 jPatchLimit = (jPatchLimit + 1) * Constants.TerrainPatchSize;
838 828
839 int iPatchLimit = patchX; 829 int iPatchLimit = patchX;
840 if (patchX >= (pRegionSizeX / Constants.TerrainPatchSize)) 830 if (patchX >= (terrData.SizeX / Constants.TerrainPatchSize))
841 { 831 {
842 iPatchLimit = (int)(pRegionSizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize; 832 iPatchLimit = (int)(terrData.SizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize;
843 } 833 }
844 iPatchLimit = (iPatchLimit + 1) * Constants.TerrainPatchSize; 834 iPatchLimit = (iPatchLimit + 1) * Constants.TerrainPatchSize;
845 835
@@ -847,7 +837,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
847 { 837 {
848 for (int i = patchX * Constants.TerrainPatchSize; i < iPatchLimit; i++) 838 for (int i = patchX * Constants.TerrainPatchSize; i < iPatchLimit; i++)
849 { 839 {
850 block[k++] = (heightmap[j*pRegionSizeX + i])*premult - sub; 840 // block[k++] = (heightmap[j*pRegionSizeX + i])*premult - sub;
841 block[k++] = terrData[j, i] - sub;
851 } 842 }
852 } 843 }
853 844