aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2013-10-31 09:24:06 -0700
committerRobert Adams2013-10-31 09:24:06 -0700
commit39777db8ef0604ad228854ce226bb530c2d27239 (patch)
treee351cd0c09bb9af6c10776a494f53563b0ec480c
parentMerge branch 'master' into varregion (diff)
downloadopensim-SC_OLD-39777db8ef0604ad228854ce226bb530c2d27239.zip
opensim-SC_OLD-39777db8ef0604ad228854ce226bb530c2d27239.tar.gz
opensim-SC_OLD-39777db8ef0604ad228854ce226bb530c2d27239.tar.bz2
opensim-SC_OLD-39777db8ef0604ad228854ce226bb530c2d27239.tar.xz
varregion: fix problem of X/Y dimensions swapped and incorrect terrain
compression base computation. Complete replacement of float[] for terrain heightmap with TerrainData instance.
-rw-r--r--OpenSim/Framework/TerrainData.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs25
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainCompressor.cs35
4 files changed, 42 insertions, 40 deletions
diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs
index 103359b..d7f1655 100644
--- a/OpenSim/Framework/TerrainData.cs
+++ b/OpenSim/Framework/TerrainData.cs
@@ -103,7 +103,7 @@ namespace OpenSim.Framework
103 { 103 {
104 m_heightmap[x, y] = newVal; 104 m_heightmap[x, y] = newVal;
105 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true; 105 m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
106 m_log.DebugFormat("{0} set[{1},{2}] to {3} ({4})", LogHeader, x, y, value, newVal); 106 // m_log.DebugFormat("{0} set[{1},{2}] to {3} ({4})", LogHeader, x, y, value, newVal);
107 } 107 }
108 } 108 }
109 } 109 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 2b8a04f..c8e7eb5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1154,7 +1154,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1154 /// <param name="map">heightmap</param> 1154 /// <param name="map">heightmap</param>
1155 public virtual void SendLayerData(float[] map) 1155 public virtual void SendLayerData(float[] map)
1156 { 1156 {
1157 Util.FireAndForget(DoSendLayerData, map); 1157 Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData());
1158 } 1158 }
1159 1159
1160 /// <summary> 1160 /// <summary>
@@ -1163,7 +1163,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1163 /// <param name="o"></param> 1163 /// <param name="o"></param>
1164 private void DoSendLayerData(object o) 1164 private void DoSendLayerData(object o)
1165 { 1165 {
1166 float[] map = (float[])o; 1166 TerrainData map = (TerrainData)o;
1167 1167
1168 try 1168 try
1169 { 1169 {
@@ -1177,7 +1177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1177 //} 1177 //}
1178 1178
1179 // Send LayerData in a spiral pattern. Fun! 1179 // Send LayerData in a spiral pattern. Fun!
1180 SendLayerTopRight(map, 0, 0, 15, 15); 1180 SendLayerTopRight(map, 0, 0, map.SizeX/Constants.TerrainPatchSize-1, map.SizeY/Constants.TerrainPatchSize-1);
1181 } 1181 }
1182 catch (Exception e) 1182 catch (Exception e)
1183 { 1183 {
@@ -1185,7 +1185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1185 } 1185 }
1186 } 1186 }
1187 1187
1188 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2) 1188 private void SendLayerTopRight(TerrainData map, int x1, int y1, int x2, int y2)
1189 { 1189 {
1190 // Row 1190 // Row
1191 for (int i = x1; i <= x2; i++) 1191 for (int i = x1; i <= x2; i++)
@@ -1199,7 +1199,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1199 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2); 1199 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1200 } 1200 }
1201 1201
1202 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2) 1202 void SendLayerBottomLeft(TerrainData map, int x1, int y1, int x2, int y2)
1203 { 1203 {
1204 // Row in reverse 1204 // Row in reverse
1205 for (int i = x2; i >= x1; i--) 1205 for (int i = x2; i >= x1; i--)
@@ -1231,6 +1231,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1231 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1231 // OutPacket(layerpack, ThrottleOutPacketType.Land);
1232 // } 1232 // }
1233 1233
1234 // Legacy form of invocation that passes around a bare data array.
1235 // Just ignore what was passed and use the real terrain info that is part of the scene.
1236 public void SendLayerData(int px, int py, float[] map)
1237 {
1238 SendLayerData(px, py, m_scene.Heightmap.GetTerrainData());
1239 }
1240
1234 /// <summary> 1241 /// <summary>
1235 /// Sends a terrain packet for the point specified. 1242 /// Sends a terrain packet for the point specified.
1236 /// This is a legacy call that has refarbed the terrain into a flat map of floats. 1243 /// This is a legacy call that has refarbed the terrain into a flat map of floats.
@@ -1239,15 +1246,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1239 /// <param name="px">Patch coordinate (x) 0..15</param> 1246 /// <param name="px">Patch coordinate (x) 0..15</param>
1240 /// <param name="py">Patch coordinate (y) 0..15</param> 1247 /// <param name="py">Patch coordinate (y) 0..15</param>
1241 /// <param name="map">heightmap</param> 1248 /// <param name="map">heightmap</param>
1242 public void SendLayerData(int px, int py, float[] map) 1249 public void SendLayerData(int px, int py, TerrainData terrData)
1243 { 1250 {
1244 try 1251 try
1245 { 1252 {
1246 // For unknown reasons, after this point, patch numbers are swapped X for y. 1253 LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, px, py);
1247 // That means, that for <patchNumX, patchNumY, the array location is computed as map[patchNumY * 16 + patchNumX].
1248 // TODO: someday straighten the below implementation to keep the X row order for patch numbers.
1249 // Since this is passing only one patch, we just swap the patch numbers.
1250 LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(m_scene.Heightmap.GetTerrainData(), px, py);
1251 1254
1252 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience. 1255 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience.
1253 // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain. 1256 // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain.
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index 6d245cb..d641c87 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -100,16 +100,20 @@ namespace OpenSim.Region.Framework.Scenes
100 } 100 }
101 101
102 // ITerrainChannel.GetFloatsSerialized() 102 // ITerrainChannel.GetFloatsSerialized()
103 // NOTICE that the one dimensional form is ordered by Y!! 103 // This one dimensional version is ordered so height = map[y*sizeX+x];
104 // DEPRECATED: don't use this function as it does not retain the dimensions of the terrain
105 // and the caller will probably do the wrong thing if the terrain is not the legacy 256x256.
104 public float[] GetFloatsSerialised() 106 public float[] GetFloatsSerialised()
105 { 107 {
106 int points = Width * Height; 108 int points = Width * Height;
107 float[] heights = new float[points]; 109 float[] heights = new float[points];
108 110
109 int idx = 0; 111 int idx = 0;
110 for (int ii = 0; ii < Height; ii++) 112 for (int jj = 0; jj < Height; jj++)
111 for (int jj = 0; jj < Width; jj++) 113 for (int ii = 0; ii < Width; ii++)
112 heights[idx++] = m_terrainData[jj, ii]; 114 {
115 heights[idx++] = m_terrainData[ii, jj];
116 }
113 117
114 return heights; 118 return heights;
115 } 119 }
@@ -117,14 +121,12 @@ namespace OpenSim.Region.Framework.Scenes
117 // ITerrainChannel.GetDoubles() 121 // ITerrainChannel.GetDoubles()
118 public double[,] GetDoubles() 122 public double[,] GetDoubles()
119 { 123 {
120 int w = Width; 124 double[,] heights = new double[Width, Height];
121 int l = Height;
122 double[,] heights = new double[w, l];
123 125
124 int idx = 0; // index into serialized array 126 int idx = 0; // index into serialized array
125 for (int ii = 0; ii < w; ii++) 127 for (int ii = 0; ii < Width; ii++)
126 { 128 {
127 for (int jj = 0; jj < l; jj++) 129 for (int jj = 0; jj < Height; jj++)
128 { 130 {
129 heights[ii, jj] = (double)m_terrainData[ii, jj]; 131 heights[ii, jj] = (double)m_terrainData[ii, jj];
130 idx++; 132 idx++;
diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
index e91c959..e4513ad 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
@@ -108,11 +108,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
108 return layer; 108 return layer;
109 } 109 }
110 110
111 // Legacy land packet generation gluing old land representation (heights) to compressed representation. 111 // Create a land packet for a single patch.
112 // This is an intermediate step in converting terrain into a variable sized heightmap. Some of the
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
115 // TerrainData. Someday fix the plumbing between here and the scene.
116 public static LayerDataPacket CreateLandPacket(TerrainData terrData, int patchX, int patchY) 112 public static LayerDataPacket CreateLandPacket(TerrainData terrData, int patchX, int patchY)
117 { 113 {
118 int[] xPieces = new int[1]; 114 int[] xPieces = new int[1];
@@ -120,9 +116,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
120 xPieces[0] = patchX; // patch X dimension 116 xPieces[0] = patchX; // patch X dimension
121 yPieces[0] = patchY; 117 yPieces[0] = patchY;
122 118
123 m_log.DebugFormat("{0} CreateLandPacket. patchX={1}, patchY={2}, sizeX={3}, sizeY={4}",
124 LogHeader, patchX, patchY, terrData.SizeX, terrData.SizeY);
125
126 return CreateLandPacket(terrData, xPieces, yPieces, (int)TerrainPatch.LayerType.Land); 119 return CreateLandPacket(terrData, xPieces, yPieces, (int)TerrainPatch.LayerType.Land);
127 } 120 }
128 121
@@ -130,19 +123,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
130 /// Creates a LayerData packet for compressed land data given a full 123 /// Creates a LayerData packet for compressed land data given a full
131 /// simulator heightmap and an array of indices of patches to compress 124 /// simulator heightmap and an array of indices of patches to compress
132 /// </summary> 125 /// </summary>
133 /// <param name="heightmap"> 126 /// <param name="terrData">
134 /// A 256 * 256 array of floating point values 127 /// Terrain data that can result in a meter square heightmap.
135 /// specifying the height at each meter in the simulator
136 /// </param> 128 /// </param>
137 /// <param name="x"> 129 /// <param name="x">
138 /// Array of indexes in the 16x16 grid of patches 130 /// Array of indexes in the grid of patches
139 /// for this simulator. For example if 1 and 17 are specified, patches 131 /// for this simulator.
140 /// x=1,y=0 and x=1,y=1 are sent 132 /// If creating a packet for multiple patches, there will be entries in
133 /// both the X and Y arrays for each of the patches.
134 /// For example if patches 1 and 17 are to be sent,
135 /// x[] = {1,1} and y[] = {0,1} which specifies the patches at
136 /// indexes <1,0> and <1,1> (presuming the terrain size is 16x16 patches).
141 /// </param> 137 /// </param>
142 /// <param name="y"> 138 /// <param name="y">
143 /// Array of indexes in the 16x16 grid of patches 139 /// Array of indexes in the grid of patches.
144 /// for this simulator. For example if 1 and 17 are specified, patches
145 /// x=1,y=0 and x=1,y=1 are sent
146 /// </param> 140 /// </param>
147 /// <param name="type"></param> 141 /// <param name="type"></param>
148 /// <param name="pRegionSizeX"></param> 142 /// <param name="pRegionSizeX"></param>
@@ -228,6 +222,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
228 header.PatchIDs += (patchX << 5); 222 header.PatchIDs += (patchX << 5);
229 } 223 }
230 224
225 // m_log.DebugFormat("{0} CreatePatchFromHeightmap. patchX={1}, patchY={2}, DCOffset={3}, range={4}",
226 // LogHeader, patchX, patchY, header.DCOffset, header.Range);
227
231 // NOTE: No idea what prequant and postquant should be or what they do 228 // NOTE: No idea what prequant and postquant should be or what they do
232 int wbits; 229 int wbits;
233 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits); 230 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
@@ -266,7 +263,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
266 for (int i = patchX*16; i < (patchX + 1)*16; i++) 263 for (int i = patchX*16; i < (patchX + 1)*16; i++)
267 { 264 {
268 // short val = heightmap[j*pRegionSizeX + i]; 265 // short val = heightmap[j*pRegionSizeX + i];
269 float val = terrData[j, i]; 266 float val = terrData[i, j];
270 if (val > zmax) zmax = val; 267 if (val > zmax) zmax = val;
271 if (val < zmin) zmin = val; 268 if (val < zmin) zmin = val;
272 } 269 }
@@ -838,7 +835,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
838 for (int i = patchX * Constants.TerrainPatchSize; i < iPatchLimit; i++) 835 for (int i = patchX * Constants.TerrainPatchSize; i < iPatchLimit; i++)
839 { 836 {
840 // block[k++] = (heightmap[j*pRegionSizeX + i])*premult - sub; 837 // block[k++] = (heightmap[j*pRegionSizeX + i])*premult - sub;
841 block[k++] = terrData[j, i] - sub; 838 block[k++] = terrData[i, j] * premult - sub;
842 } 839 }
843 } 840 }
844 841