Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
						commit
						f8fe4dee8f
					
				|  | @ -1154,6 +1154,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         /// <summary> | ||||
|         ///  Send the region heightmap to the client | ||||
|         ///  This method is only called when not doing intellegent terrain patch sending and | ||||
|         ///  is only called when the scene presence is initially created and sends all of the | ||||
|         ///  region's patches to the client. | ||||
|         /// </summary> | ||||
|         /// <param name="map">heightmap</param> | ||||
|         public virtual void SendLayerData(float[] map) | ||||
|  | @ -1237,9 +1240,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         // Legacy form of invocation that passes around a bare data array. | ||||
|         // Just ignore what was passed and use the real terrain info that is part of the scene. | ||||
|         // As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI,  | ||||
|         //    there is a special form for specifying multiple terrain patches to send. | ||||
|         //    The form is to pass 'px' as negative the number of patches to send and to | ||||
|         //    pass the float array as pairs of patch X and Y coordinates. So, passing 'px' | ||||
|         //    as -2 and map= [3, 5, 8, 4] would mean to send two terrain heightmap patches | ||||
|         //    and the patches to send are <3,5> and <8,4>. | ||||
|         public void SendLayerData(int px, int py, float[] map) | ||||
|         { | ||||
|             SendLayerData(px, py, m_scene.Heightmap.GetTerrainData()); | ||||
|             if (px >= 0) | ||||
|             { | ||||
|                 SendLayerData(px, py, m_scene.Heightmap.GetTerrainData()); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 int numPatches = -px; | ||||
|                 int[] xPatches = new int[numPatches]; | ||||
|                 int[] yPatches = new int[numPatches]; | ||||
|                 for (int pp = 0; pp < numPatches; pp++) | ||||
|                 { | ||||
|                     xPatches[pp] = (int)map[pp * 2]; | ||||
|                     yPatches[pp] = (int)map[pp * 2 + 1]; | ||||
|                 } | ||||
| 
 | ||||
|                 // DebugSendingPatches("SendLayerData", xPatches, yPatches); | ||||
| 
 | ||||
|                 SendLayerData(xPatches, yPatches, m_scene.Heightmap.GetTerrainData()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void DebugSendingPatches(string pWho, int[] pX, int[] pY) | ||||
|         { | ||||
|             if (m_log.IsDebugEnabled) | ||||
|             { | ||||
|                 int numPatches = pX.Length; | ||||
|                 string Xs = ""; | ||||
|                 string Ys = ""; | ||||
|                 for (int pp = 0; pp < numPatches; pp++) | ||||
|                 { | ||||
|                     Xs += String.Format("{0}", (int)pX[pp]) + ","; | ||||
|                     Ys += String.Format("{0}", (int)pY[pp]) + ","; | ||||
|                 } | ||||
|                 m_log.DebugFormat("{0} {1}: numPatches={2}, X={3}, Y={4}", LogHeader, pWho, numPatches, Xs, Ys); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -1251,6 +1294,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         /// <param name="py">Patch coordinate (y) 0..15</param> | ||||
|         /// <param name="map">heightmap</param> | ||||
|         public void SendLayerData(int px, int py, TerrainData terrData) | ||||
|         { | ||||
|             int[] xPatches = new[] { px }; | ||||
|             int[] yPatches = new[] { py }; | ||||
|             SendLayerData(xPatches, yPatches, terrData); | ||||
|         } | ||||
| 
 | ||||
|         private void SendLayerData(int[] px, int[] py, TerrainData terrData) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|  | @ -1259,31 +1309,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 patchInd[0] = px + (py * Constants.TerrainPatchSize); | ||||
|                 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(terrData.GetFloatsSerialized(), patchInd); | ||||
|                  */ | ||||
|                 LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, px, py); | ||||
|                  | ||||
|                 // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience.   | ||||
|                 // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain. | ||||
|                 // We also make them unreliable because it's extremely likely that multiple packets will be sent for a terrain patch area  | ||||
|                 // invalidating previous packets for that area. | ||||
| 
 | ||||
|                 // It's possible for an editing user to flood themselves with edited packets but the majority of use cases are such that only a  | ||||
|                 // tiny percentage of users will be editing the terrain.     Other, non-editing users will see the edits much slower. | ||||
|                  | ||||
|                 // One last note on this topic, by the time users are going to be editing the terrain, it's extremely likely that the sim will  | ||||
|                 // have rezzed already and therefore this is not likely going to cause any additional issues with lost packets, objects or terrain  | ||||
|                 // patches. | ||||
| 
 | ||||
|                 // m_justEditedTerrain is volatile, so test once and duplicate two affected statements so we only have one cache miss. | ||||
|                 if (m_justEditedTerrain) | ||||
|                 // Many, many patches could have been passed to us. Since the patches will be compressed | ||||
|                 //   into variable sized blocks, we cannot pre-compute how many will fit into one | ||||
|                 //   packet. While some fancy packing algorithm is possible, 4 seems to always fit. | ||||
|                 int PatchesAssumedToFit = 4; | ||||
|                 for (int pcnt = 0; pcnt < px.Length; pcnt += PatchesAssumedToFit) | ||||
|                 { | ||||
|                     layerpack.Header.Reliable = false; | ||||
|                     OutPacket(layerpack, ThrottleOutPacketType.Unknown ); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     layerpack.Header.Reliable = true; | ||||
|                     OutPacket(layerpack, ThrottleOutPacketType.Land); | ||||
|                     int remaining = Math.Min(px.Length - pcnt, PatchesAssumedToFit); | ||||
|                     int[] xPatches = new int[remaining]; | ||||
|                     int[] yPatches = new int[remaining]; | ||||
|                     for (int ii = 0; ii < remaining; ii++) | ||||
|                     { | ||||
|                         xPatches[ii] = px[pcnt + ii]; | ||||
|                         yPatches[ii] = py[pcnt + ii]; | ||||
|                     } | ||||
|                     LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, xPatches, yPatches); | ||||
|                     // DebugSendingPatches("SendLayerDataInternal", xPatches, yPatches); | ||||
| 
 | ||||
|                     SendTheLayerPacket(layerpack); | ||||
|                 } | ||||
|                 // LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, px, py); | ||||
| 
 | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|  | @ -1291,6 +1337,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // When a user edits the terrain, so much data is sent, the data queues up fast and presents a | ||||
|         // sub optimal editing experience. To alleviate this issue, when the user edits the terrain, we | ||||
|         // start skipping the queues until they're done editing the terrain. We also make them | ||||
|         // unreliable because it's extremely likely that multiple packets will be sent for a terrain patch | ||||
|         // area invalidating previous packets for that area. | ||||
| 
 | ||||
|         // It's possible for an editing user to flood themselves with edited packets but the majority | ||||
|         // of use cases are such that only a tiny percentage of users will be editing the terrain. | ||||
|         // Other, non-editing users will see the edits much slower. | ||||
|          | ||||
|         // One last note on this topic, by the time users are going to be editing the terrain, it's | ||||
|         // extremely likely that the sim will have rezzed already and therefore this is not likely going | ||||
|         // to cause any additional issues with lost packets, objects or terrain patches. | ||||
| 
 | ||||
|         // m_justEditedTerrain is volatile, so test once and duplicate two affected statements so we | ||||
|         //    only have one cache miss. | ||||
|         private void SendTheLayerPacket(LayerDataPacket layerpack) | ||||
|         { | ||||
|             if (m_justEditedTerrain) | ||||
|             { | ||||
|                 layerpack.Header.Reliable = false; | ||||
|                 OutPacket(layerpack, ThrottleOutPacketType.Unknown ); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 layerpack.Header.Reliable = true; | ||||
|                 OutPacket(layerpack, ThrottleOutPacketType.Land); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         ///  Send the wind matrix to the client | ||||
|         /// </summary> | ||||
|  |  | |||
|  | @ -1035,12 +1035,24 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
|                             //                     LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); | ||||
|                             // Sort the patches to send by the distance from the presence | ||||
|                             toSend.Sort(); | ||||
|                             /* | ||||
|                             foreach (PatchesToSend pts in toSend) | ||||
|                             { | ||||
|                                 // TODO: one can send multiple patches in a packet. Do that. | ||||
|                                 pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); | ||||
|                                 // presence.ControllingClient.SendLayerData(xs.ToArray(), ys.ToArray(), null, TerrainPatch.LayerType.Land); | ||||
|                             } | ||||
|                             */ | ||||
| 
 | ||||
|                             int[] xPieces = new int[toSend.Count]; | ||||
|                             int[] yPieces = new int[toSend.Count]; | ||||
|                             float[] patchPieces = new float[toSend.Count * 2]; | ||||
|                             int pieceIndex = 0; | ||||
|                             foreach (PatchesToSend pts in toSend) | ||||
|                             { | ||||
|                                 patchPieces[pieceIndex++] = pts.PatchX; | ||||
|                                 patchPieces[pieceIndex++] = pts.PatchY; | ||||
|                             } | ||||
|                             pups.Presence.ControllingClient.SendLayerData(-toSend.Count, 0, patchPieces); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  |  | |||
|  | @ -119,6 +119,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             xPieces[0] = patchX;  // patch X dimension | ||||
|             yPieces[0] = patchY; | ||||
| 
 | ||||
|             return CreateLandPacket(terrData, xPieces, yPieces); | ||||
|         } | ||||
| 
 | ||||
|         public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] xPieces, int[] yPieces) | ||||
|         { | ||||
|             byte landPacketType = (byte)TerrainPatch.LayerType.Land; | ||||
|             if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) | ||||
|             { | ||||
|  | @ -148,8 +153,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         ///     Array of indexes in the grid of patches. | ||||
|         /// </param> | ||||
|         /// <param name="type"></param> | ||||
|         /// <param name="pRegionSizeX"></param> | ||||
|         /// <param name="pRegionSizeY"></param> | ||||
|         /// <returns></returns> | ||||
|         public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] x, int[] y, byte type) | ||||
|         { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Diva Canto
						Diva Canto