Properly dispose of drawing objects to reduce/stop memory leakage on generating map tiles with the MapImageModule and TexturedMapTileRenderer (the current defaults)
							parent
							
								
									a859464e91
								
							
						
					
					
						commit
						a2d5d810e0
					
				|  | @ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|     public struct DrawStruct |     public struct DrawStruct | ||||||
|     { |     { | ||||||
|         public DrawRoutine dr; |         public DrawRoutine dr; | ||||||
|         public Rectangle rect; | //        public Rectangle rect; | ||||||
|         public SolidBrush brush; |         public SolidBrush brush; | ||||||
|         public face[] trns; |         public face[] trns; | ||||||
|     } |     } | ||||||
|  | @ -119,6 +119,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|             { |             { | ||||||
|                 mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); |                 mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|             return mapbmp; |             return mapbmp; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -280,321 +281,331 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|             tc = Environment.TickCount; |             tc = Environment.TickCount; | ||||||
|             m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); |             m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); | ||||||
|             EntityBase[] objs = whichScene.GetEntities(); |             EntityBase[] objs = whichScene.GetEntities(); | ||||||
|             Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); |  | ||||||
|             //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); |  | ||||||
|             List<float> z_sortheights = new List<float>(); |             List<float> z_sortheights = new List<float>(); | ||||||
|             List<uint> z_localIDs = new List<uint>(); |             List<uint> z_localIDs = new List<uint>(); | ||||||
|  |             Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); | ||||||
| 
 | 
 | ||||||
|             lock (objs) |             try  | ||||||
|             { |             { | ||||||
|                 foreach (EntityBase obj in objs) |                 //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); | ||||||
|  | 
 | ||||||
|  |                 lock (objs) | ||||||
|                 { |                 { | ||||||
|                     // Only draw the contents of SceneObjectGroup |                     foreach (EntityBase obj in objs) | ||||||
|                     if (obj is SceneObjectGroup) |  | ||||||
|                     { |                     { | ||||||
|                         SceneObjectGroup mapdot = (SceneObjectGroup)obj; |                         // Only draw the contents of SceneObjectGroup | ||||||
|                         Color mapdotspot = Color.Gray; // Default color when prim color is white |                         if (obj is SceneObjectGroup) | ||||||
|                          |  | ||||||
|                         // Loop over prim in group |  | ||||||
|                         foreach (SceneObjectPart part in mapdot.Parts) |  | ||||||
|                         { |                         { | ||||||
|                             if (part == null) |                             SceneObjectGroup mapdot = (SceneObjectGroup)obj; | ||||||
|                                 continue; |                             Color mapdotspot = Color.Gray; // Default color when prim color is white | ||||||
| 
 |                              | ||||||
|                             // Draw if the object is at least 1 meter wide in any direction |                             // Loop over prim in group | ||||||
|                             if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) |                             foreach (SceneObjectPart part in mapdot.Parts) | ||||||
|                             { |                             { | ||||||
|                                 // Try to get the RGBA of the default texture entry.. |                                 if (part == null) | ||||||
|                                 // |  | ||||||
|                                 try |  | ||||||
|                                 { |  | ||||||
|                                     // get the null checks out of the way |  | ||||||
|                                     // skip the ones that break |  | ||||||
|                                     if (part == null) |  | ||||||
|                                         continue; |  | ||||||
| 
 |  | ||||||
|                                     if (part.Shape == null) |  | ||||||
|                                         continue; |  | ||||||
| 
 |  | ||||||
|                                     if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) |  | ||||||
|                                         continue; // eliminates trees from this since we don't really have a good tree representation |  | ||||||
|                                     // if you want tree blocks on the map comment the above line and uncomment the below line |  | ||||||
|                                     //mapdotspot = Color.PaleGreen; |  | ||||||
| 
 |  | ||||||
|                                     Primitive.TextureEntry textureEntry = part.Shape.Textures; |  | ||||||
| 
 |  | ||||||
|                                     if (textureEntry == null || textureEntry.DefaultTexture == null) |  | ||||||
|                                         continue; |  | ||||||
| 
 |  | ||||||
|                                     Color4 texcolor = textureEntry.DefaultTexture.RGBA; |  | ||||||
| 
 |  | ||||||
|                                     // Not sure why some of these are null, oh well. |  | ||||||
| 
 |  | ||||||
|                                     int colorr = 255 - (int)(texcolor.R * 255f); |  | ||||||
|                                     int colorg = 255 - (int)(texcolor.G * 255f); |  | ||||||
|                                     int colorb = 255 - (int)(texcolor.B * 255f); |  | ||||||
| 
 |  | ||||||
|                                     if (!(colorr == 255 && colorg == 255 && colorb == 255)) |  | ||||||
|                                     { |  | ||||||
|                                         //Try to set the map spot color |  | ||||||
|                                         try |  | ||||||
|                                         { |  | ||||||
|                                             // If the color gets goofy somehow, skip it *shakes fist at Color4 |  | ||||||
|                                             mapdotspot = Color.FromArgb(colorr, colorg, colorb); |  | ||||||
|                                         } |  | ||||||
|                                         catch (ArgumentException) |  | ||||||
|                                         { |  | ||||||
|                                         } |  | ||||||
|                                     } |  | ||||||
|                                 } |  | ||||||
|                                 catch (IndexOutOfRangeException) |  | ||||||
|                                 { |  | ||||||
|                                     // Windows Array |  | ||||||
|                                 } |  | ||||||
|                                 catch (ArgumentOutOfRangeException) |  | ||||||
|                                 { |  | ||||||
|                                     // Mono Array |  | ||||||
|                                 } |  | ||||||
| 
 |  | ||||||
|                                 Vector3 pos = part.GetWorldPosition(); |  | ||||||
| 
 |  | ||||||
|                                 // skip prim outside of retion |  | ||||||
|                                 if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) |  | ||||||
|                                     continue; |                                     continue; | ||||||
| 
 | 
 | ||||||
|                                 // skip prim in non-finite position |                                 // Draw if the object is at least 1 meter wide in any direction | ||||||
|                                 if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || |                                 if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) | ||||||
|                                     Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) |  | ||||||
|                                     continue; |  | ||||||
| 
 |  | ||||||
|                                 // Figure out if object is under 256m above the height of the terrain |  | ||||||
|                                 bool isBelow256AboveTerrain = false; |  | ||||||
| 
 |  | ||||||
|                                 try |  | ||||||
|                                 { |                                 { | ||||||
|                                     isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); |                                     // Try to get the RGBA of the default texture entry.. | ||||||
|                                 } |                                     // | ||||||
|                                 catch (Exception) |                                     try | ||||||
|                                 { |  | ||||||
|                                 } |  | ||||||
| 
 |  | ||||||
|                                 if (isBelow256AboveTerrain) |  | ||||||
|                                 { |  | ||||||
|                                     // Translate scale by rotation so scale is represented properly when object is rotated |  | ||||||
|                                     Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); |  | ||||||
|                                     Vector3 scale = new Vector3(); |  | ||||||
|                                     Vector3 tScale = new Vector3(); |  | ||||||
|                                     Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); |  | ||||||
| 
 |  | ||||||
|                                     Quaternion llrot = part.GetWorldRotation(); |  | ||||||
|                                     Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); |  | ||||||
|                                     scale = lscale * rot; |  | ||||||
| 
 |  | ||||||
|                                     // negative scales don't work in this situation |  | ||||||
|                                     scale.X = Math.Abs(scale.X); |  | ||||||
|                                     scale.Y = Math.Abs(scale.Y); |  | ||||||
|                                     scale.Z = Math.Abs(scale.Z); |  | ||||||
| 
 |  | ||||||
|                                     // This scaling isn't very accurate and doesn't take into account the face rotation :P |  | ||||||
|                                     int mapdrawstartX = (int)(pos.X - scale.X); |  | ||||||
|                                     int mapdrawstartY = (int)(pos.Y - scale.Y); |  | ||||||
|                                     int mapdrawendX = (int)(pos.X + scale.X); |  | ||||||
|                                     int mapdrawendY = (int)(pos.Y + scale.Y); |  | ||||||
| 
 |  | ||||||
|                                     // If object is beyond the edge of the map, don't draw it to avoid errors |  | ||||||
|                                     if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) |  | ||||||
|                                                           || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 |  | ||||||
|                                                           || mapdrawendY > ((int)Constants.RegionSize - 1)) |  | ||||||
|                                         continue; |  | ||||||
| 
 |  | ||||||
| #region obb face reconstruction part duex |  | ||||||
|                                     Vector3[] vertexes = new Vector3[8]; |  | ||||||
| 
 |  | ||||||
|                                     // float[] distance = new float[6]; |  | ||||||
|                                     Vector3[] FaceA = new Vector3[6]; // vertex A for Facei |  | ||||||
|                                     Vector3[] FaceB = new Vector3[6]; // vertex B for Facei |  | ||||||
|                                     Vector3[] FaceC = new Vector3[6]; // vertex C for Facei |  | ||||||
|                                     Vector3[] FaceD = new Vector3[6]; // vertex D for Facei |  | ||||||
| 
 |  | ||||||
|                                     tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
|                                     vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
|                                     // vertexes[0].x = pos.X + vertexes[0].x; |  | ||||||
|                                     //vertexes[0].y = pos.Y + vertexes[0].y; |  | ||||||
|                                     //vertexes[0].z = pos.Z + vertexes[0].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceA[0] = vertexes[0]; |  | ||||||
|                                     FaceB[3] = vertexes[0]; |  | ||||||
|                                     FaceA[4] = vertexes[0]; |  | ||||||
| 
 |  | ||||||
|                                     tScale = lscale; |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
|                                     vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
| 
 |  | ||||||
|                                     // vertexes[1].x = pos.X + vertexes[1].x; |  | ||||||
|                                     // vertexes[1].y = pos.Y + vertexes[1].y; |  | ||||||
|                                     //vertexes[1].z = pos.Z + vertexes[1].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceB[0] = vertexes[1]; |  | ||||||
|                                     FaceA[1] = vertexes[1]; |  | ||||||
|                                     FaceC[4] = vertexes[1]; |  | ||||||
| 
 |  | ||||||
|                                     tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
| 
 |  | ||||||
|                                     vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
| 
 |  | ||||||
|                                     //vertexes[2].x = pos.X + vertexes[2].x; |  | ||||||
|                                     //vertexes[2].y = pos.Y + vertexes[2].y; |  | ||||||
|                                     //vertexes[2].z = pos.Z + vertexes[2].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceC[0] = vertexes[2]; |  | ||||||
|                                     FaceD[3] = vertexes[2]; |  | ||||||
|                                     FaceC[5] = vertexes[2]; |  | ||||||
| 
 |  | ||||||
|                                     tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
|                                     vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
| 
 |  | ||||||
|                                     //vertexes[3].x = pos.X + vertexes[3].x; |  | ||||||
|                                     // vertexes[3].y = pos.Y + vertexes[3].y; |  | ||||||
|                                     // vertexes[3].z = pos.Z + vertexes[3].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceD[0] = vertexes[3]; |  | ||||||
|                                     FaceC[1] = vertexes[3]; |  | ||||||
|                                     FaceA[5] = vertexes[3]; |  | ||||||
| 
 |  | ||||||
|                                     tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
|                                     vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
| 
 |  | ||||||
|                                     // vertexes[4].x = pos.X + vertexes[4].x; |  | ||||||
|                                     // vertexes[4].y = pos.Y + vertexes[4].y; |  | ||||||
|                                     // vertexes[4].z = pos.Z + vertexes[4].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceB[1] = vertexes[4]; |  | ||||||
|                                     FaceA[2] = vertexes[4]; |  | ||||||
|                                     FaceD[4] = vertexes[4]; |  | ||||||
| 
 |  | ||||||
|                                     tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
|                                     vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
| 
 |  | ||||||
|                                     // vertexes[5].x = pos.X + vertexes[5].x; |  | ||||||
|                                     // vertexes[5].y = pos.Y + vertexes[5].y; |  | ||||||
|                                     // vertexes[5].z = pos.Z + vertexes[5].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceD[1] = vertexes[5]; |  | ||||||
|                                     FaceC[2] = vertexes[5]; |  | ||||||
|                                     FaceB[5] = vertexes[5]; |  | ||||||
| 
 |  | ||||||
|                                     tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
|                                     vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
| 
 |  | ||||||
|                                     // vertexes[6].x = pos.X + vertexes[6].x; |  | ||||||
|                                     // vertexes[6].y = pos.Y + vertexes[6].y; |  | ||||||
|                                     // vertexes[6].z = pos.Z + vertexes[6].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceB[2] = vertexes[6]; |  | ||||||
|                                     FaceA[3] = vertexes[6]; |  | ||||||
|                                     FaceB[4] = vertexes[6]; |  | ||||||
| 
 |  | ||||||
|                                     tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); |  | ||||||
|                                     scale = ((tScale * rot)); |  | ||||||
|                                     vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |  | ||||||
| 
 |  | ||||||
|                                     // vertexes[7].x = pos.X + vertexes[7].x; |  | ||||||
|                                     // vertexes[7].y = pos.Y + vertexes[7].y; |  | ||||||
|                                     // vertexes[7].z = pos.Z + vertexes[7].z; |  | ||||||
| 
 |  | ||||||
|                                     FaceD[2] = vertexes[7]; |  | ||||||
|                                     FaceC[3] = vertexes[7]; |  | ||||||
|                                     FaceD[5] = vertexes[7]; |  | ||||||
| #endregion |  | ||||||
| 
 |  | ||||||
|                                     //int wy = 0; |  | ||||||
| 
 |  | ||||||
|                                     //bool breakYN = false; // If we run into an error drawing, break out of the |  | ||||||
|                                     // loop so we don't lag to death on error handling |  | ||||||
|                                     DrawStruct ds = new DrawStruct(); |  | ||||||
|                                     ds.brush = new SolidBrush(mapdotspot); |  | ||||||
|                                     //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); |  | ||||||
| 
 |  | ||||||
|                                     ds.trns = new face[FaceA.Length]; |  | ||||||
| 
 |  | ||||||
|                                     for (int i = 0; i < FaceA.Length; i++) |  | ||||||
|                                     { |                                     { | ||||||
|                                         Point[] working = new Point[5]; |                                         // get the null checks out of the way | ||||||
|                                         working[0] = project(FaceA[i], axPos); |                                         // skip the ones that break | ||||||
|                                         working[1] = project(FaceB[i], axPos); |                                         if (part == null) | ||||||
|                                         working[2] = project(FaceD[i], axPos); |                                             continue; | ||||||
|                                         working[3] = project(FaceC[i], axPos); |  | ||||||
|                                         working[4] = project(FaceA[i], axPos); |  | ||||||
| 
 | 
 | ||||||
|                                         face workingface = new face(); |                                         if (part.Shape == null) | ||||||
|                                         workingface.pts = working; |                                             continue; | ||||||
| 
 | 
 | ||||||
|                                         ds.trns[i] = workingface; |                                         if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) | ||||||
|  |                                             continue; // eliminates trees from this since we don't really have a good tree representation | ||||||
|  |                                         // if you want tree blocks on the map comment the above line and uncomment the below line | ||||||
|  |                                         //mapdotspot = Color.PaleGreen; | ||||||
|  | 
 | ||||||
|  |                                         Primitive.TextureEntry textureEntry = part.Shape.Textures; | ||||||
|  | 
 | ||||||
|  |                                         if (textureEntry == null || textureEntry.DefaultTexture == null) | ||||||
|  |                                             continue; | ||||||
|  | 
 | ||||||
|  |                                         Color4 texcolor = textureEntry.DefaultTexture.RGBA; | ||||||
|  | 
 | ||||||
|  |                                         // Not sure why some of these are null, oh well. | ||||||
|  | 
 | ||||||
|  |                                         int colorr = 255 - (int)(texcolor.R * 255f); | ||||||
|  |                                         int colorg = 255 - (int)(texcolor.G * 255f); | ||||||
|  |                                         int colorb = 255 - (int)(texcolor.B * 255f); | ||||||
|  | 
 | ||||||
|  |                                         if (!(colorr == 255 && colorg == 255 && colorb == 255)) | ||||||
|  |                                         { | ||||||
|  |                                             //Try to set the map spot color | ||||||
|  |                                             try | ||||||
|  |                                             { | ||||||
|  |                                                 // If the color gets goofy somehow, skip it *shakes fist at Color4 | ||||||
|  |                                                 mapdotspot = Color.FromArgb(colorr, colorg, colorb); | ||||||
|  |                                             } | ||||||
|  |                                             catch (ArgumentException) | ||||||
|  |                                             { | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                     catch (IndexOutOfRangeException) | ||||||
|  |                                     { | ||||||
|  |                                         // Windows Array | ||||||
|  |                                     } | ||||||
|  |                                     catch (ArgumentOutOfRangeException) | ||||||
|  |                                     { | ||||||
|  |                                         // Mono Array | ||||||
|                                     } |                                     } | ||||||
| 
 | 
 | ||||||
|                                     z_sort.Add(part.LocalId, ds); |                                     Vector3 pos = part.GetWorldPosition(); | ||||||
|                                     z_localIDs.Add(part.LocalId); |  | ||||||
|                                     z_sortheights.Add(pos.Z); |  | ||||||
| 
 | 
 | ||||||
|                                     //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) |                                     // skip prim outside of retion | ||||||
|                                     //{ |                                     if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) | ||||||
|                                         //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) |                                         continue; | ||||||
|  | 
 | ||||||
|  |                                     // skip prim in non-finite position | ||||||
|  |                                     if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || | ||||||
|  |                                         Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) | ||||||
|  |                                         continue; | ||||||
|  | 
 | ||||||
|  |                                     // Figure out if object is under 256m above the height of the terrain | ||||||
|  |                                     bool isBelow256AboveTerrain = false; | ||||||
|  | 
 | ||||||
|  |                                     try | ||||||
|  |                                     { | ||||||
|  |                                         isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); | ||||||
|  |                                     } | ||||||
|  |                                     catch (Exception) | ||||||
|  |                                     { | ||||||
|  |                                     } | ||||||
|  | 
 | ||||||
|  |                                     if (isBelow256AboveTerrain) | ||||||
|  |                                     { | ||||||
|  |                                         // Translate scale by rotation so scale is represented properly when object is rotated | ||||||
|  |                                         Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); | ||||||
|  |                                         Vector3 scale = new Vector3(); | ||||||
|  |                                         Vector3 tScale = new Vector3(); | ||||||
|  |                                         Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | ||||||
|  | 
 | ||||||
|  |                                         Quaternion llrot = part.GetWorldRotation(); | ||||||
|  |                                         Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | ||||||
|  |                                         scale = lscale * rot; | ||||||
|  | 
 | ||||||
|  |                                         // negative scales don't work in this situation | ||||||
|  |                                         scale.X = Math.Abs(scale.X); | ||||||
|  |                                         scale.Y = Math.Abs(scale.Y); | ||||||
|  |                                         scale.Z = Math.Abs(scale.Z); | ||||||
|  | 
 | ||||||
|  |                                         // This scaling isn't very accurate and doesn't take into account the face rotation :P | ||||||
|  |                                         int mapdrawstartX = (int)(pos.X - scale.X); | ||||||
|  |                                         int mapdrawstartY = (int)(pos.Y - scale.Y); | ||||||
|  |                                         int mapdrawendX = (int)(pos.X + scale.X); | ||||||
|  |                                         int mapdrawendY = (int)(pos.Y + scale.Y); | ||||||
|  | 
 | ||||||
|  |                                         // If object is beyond the edge of the map, don't draw it to avoid errors | ||||||
|  |                                         if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | ||||||
|  |                                                               || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | ||||||
|  |                                                               || mapdrawendY > ((int)Constants.RegionSize - 1)) | ||||||
|  |                                             continue; | ||||||
|  | 
 | ||||||
|  |     #region obb face reconstruction part duex | ||||||
|  |                                         Vector3[] vertexes = new Vector3[8]; | ||||||
|  | 
 | ||||||
|  |                                         // float[] distance = new float[6]; | ||||||
|  |                                         Vector3[] FaceA = new Vector3[6]; // vertex A for Facei | ||||||
|  |                                         Vector3[] FaceB = new Vector3[6]; // vertex B for Facei | ||||||
|  |                                         Vector3[] FaceC = new Vector3[6]; // vertex C for Facei | ||||||
|  |                                         Vector3[] FaceD = new Vector3[6]; // vertex D for Facei | ||||||
|  | 
 | ||||||
|  |                                         tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  |                                         vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  |                                         // vertexes[0].x = pos.X + vertexes[0].x; | ||||||
|  |                                         //vertexes[0].y = pos.Y + vertexes[0].y; | ||||||
|  |                                         //vertexes[0].z = pos.Z + vertexes[0].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceA[0] = vertexes[0]; | ||||||
|  |                                         FaceB[3] = vertexes[0]; | ||||||
|  |                                         FaceA[4] = vertexes[0]; | ||||||
|  | 
 | ||||||
|  |                                         tScale = lscale; | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  |                                         vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  | 
 | ||||||
|  |                                         // vertexes[1].x = pos.X + vertexes[1].x; | ||||||
|  |                                         // vertexes[1].y = pos.Y + vertexes[1].y; | ||||||
|  |                                         //vertexes[1].z = pos.Z + vertexes[1].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceB[0] = vertexes[1]; | ||||||
|  |                                         FaceA[1] = vertexes[1]; | ||||||
|  |                                         FaceC[4] = vertexes[1]; | ||||||
|  | 
 | ||||||
|  |                                         tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  | 
 | ||||||
|  |                                         vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  | 
 | ||||||
|  |                                         //vertexes[2].x = pos.X + vertexes[2].x; | ||||||
|  |                                         //vertexes[2].y = pos.Y + vertexes[2].y; | ||||||
|  |                                         //vertexes[2].z = pos.Z + vertexes[2].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceC[0] = vertexes[2]; | ||||||
|  |                                         FaceD[3] = vertexes[2]; | ||||||
|  |                                         FaceC[5] = vertexes[2]; | ||||||
|  | 
 | ||||||
|  |                                         tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  |                                         vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  | 
 | ||||||
|  |                                         //vertexes[3].x = pos.X + vertexes[3].x; | ||||||
|  |                                         // vertexes[3].y = pos.Y + vertexes[3].y; | ||||||
|  |                                         // vertexes[3].z = pos.Z + vertexes[3].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceD[0] = vertexes[3]; | ||||||
|  |                                         FaceC[1] = vertexes[3]; | ||||||
|  |                                         FaceA[5] = vertexes[3]; | ||||||
|  | 
 | ||||||
|  |                                         tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  |                                         vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  | 
 | ||||||
|  |                                         // vertexes[4].x = pos.X + vertexes[4].x; | ||||||
|  |                                         // vertexes[4].y = pos.Y + vertexes[4].y; | ||||||
|  |                                         // vertexes[4].z = pos.Z + vertexes[4].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceB[1] = vertexes[4]; | ||||||
|  |                                         FaceA[2] = vertexes[4]; | ||||||
|  |                                         FaceD[4] = vertexes[4]; | ||||||
|  | 
 | ||||||
|  |                                         tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  |                                         vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  | 
 | ||||||
|  |                                         // vertexes[5].x = pos.X + vertexes[5].x; | ||||||
|  |                                         // vertexes[5].y = pos.Y + vertexes[5].y; | ||||||
|  |                                         // vertexes[5].z = pos.Z + vertexes[5].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceD[1] = vertexes[5]; | ||||||
|  |                                         FaceC[2] = vertexes[5]; | ||||||
|  |                                         FaceB[5] = vertexes[5]; | ||||||
|  | 
 | ||||||
|  |                                         tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  |                                         vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  | 
 | ||||||
|  |                                         // vertexes[6].x = pos.X + vertexes[6].x; | ||||||
|  |                                         // vertexes[6].y = pos.Y + vertexes[6].y; | ||||||
|  |                                         // vertexes[6].z = pos.Z + vertexes[6].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceB[2] = vertexes[6]; | ||||||
|  |                                         FaceA[3] = vertexes[6]; | ||||||
|  |                                         FaceB[4] = vertexes[6]; | ||||||
|  | 
 | ||||||
|  |                                         tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); | ||||||
|  |                                         scale = ((tScale * rot)); | ||||||
|  |                                         vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||||||
|  | 
 | ||||||
|  |                                         // vertexes[7].x = pos.X + vertexes[7].x; | ||||||
|  |                                         // vertexes[7].y = pos.Y + vertexes[7].y; | ||||||
|  |                                         // vertexes[7].z = pos.Z + vertexes[7].z; | ||||||
|  | 
 | ||||||
|  |                                         FaceD[2] = vertexes[7]; | ||||||
|  |                                         FaceC[3] = vertexes[7]; | ||||||
|  |                                         FaceD[5] = vertexes[7]; | ||||||
|  |     #endregion | ||||||
|  | 
 | ||||||
|  |                                         //int wy = 0; | ||||||
|  | 
 | ||||||
|  |                                         //bool breakYN = false; // If we run into an error drawing, break out of the | ||||||
|  |                                         // loop so we don't lag to death on error handling | ||||||
|  |                                         DrawStruct ds = new DrawStruct(); | ||||||
|  |                                         ds.brush = new SolidBrush(mapdotspot); | ||||||
|  |                                         //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); | ||||||
|  | 
 | ||||||
|  |                                         ds.trns = new face[FaceA.Length]; | ||||||
|  | 
 | ||||||
|  |                                         for (int i = 0; i < FaceA.Length; i++) | ||||||
|  |                                         { | ||||||
|  |                                             Point[] working = new Point[5]; | ||||||
|  |                                             working[0] = project(FaceA[i], axPos); | ||||||
|  |                                             working[1] = project(FaceB[i], axPos); | ||||||
|  |                                             working[2] = project(FaceD[i], axPos); | ||||||
|  |                                             working[3] = project(FaceC[i], axPos); | ||||||
|  |                                             working[4] = project(FaceA[i], axPos); | ||||||
|  | 
 | ||||||
|  |                                             face workingface = new face(); | ||||||
|  |                                             workingface.pts = working; | ||||||
|  | 
 | ||||||
|  |                                             ds.trns[i] = workingface; | ||||||
|  |                                         } | ||||||
|  | 
 | ||||||
|  |                                         z_sort.Add(part.LocalId, ds); | ||||||
|  |                                         z_localIDs.Add(part.LocalId); | ||||||
|  |                                         z_sortheights.Add(pos.Z); | ||||||
|  | 
 | ||||||
|  |                                         //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) | ||||||
|                                         //{ |                                         //{ | ||||||
|                                             //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); |                                             //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) | ||||||
|                                             //try |  | ||||||
|                                             //{ |                                             //{ | ||||||
|                                                 // Remember, flip the y! |                                                 //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); | ||||||
|                                             //    mapbmp.SetPixel(wx, (255 - wy), mapdotspot); |                                                 //try | ||||||
|                                             //} |                                                 //{ | ||||||
|                                             //catch (ArgumentException) |                                                     // Remember, flip the y! | ||||||
|                                             //{ |                                                 //    mapbmp.SetPixel(wx, (255 - wy), mapdotspot); | ||||||
|                                             //    breakYN = true; |                                                 //} | ||||||
|  |                                                 //catch (ArgumentException) | ||||||
|  |                                                 //{ | ||||||
|  |                                                 //    breakYN = true; | ||||||
|  |                                                 //} | ||||||
|  | 
 | ||||||
|  |                                                 //if (breakYN) | ||||||
|  |                                                 //    break; | ||||||
|                                             //} |                                             //} | ||||||
| 
 | 
 | ||||||
|                                             //if (breakYN) |                                             //if (breakYN) | ||||||
|                                             //    break; |                                             //    break; | ||||||
|                                         //} |                                         //} | ||||||
|  |                                     } // Object is within 256m Z of terrain | ||||||
|  |                                 } // object is at least a meter wide | ||||||
|  |                             } // loop over group children | ||||||
|  |                         } // entitybase is sceneobject group | ||||||
|  |                     } // foreach loop over entities | ||||||
| 
 | 
 | ||||||
|                                         //if (breakYN) |                     float[] sortedZHeights = z_sortheights.ToArray(); | ||||||
|                                         //    break; |                     uint[] sortedlocalIds = z_localIDs.ToArray(); | ||||||
|                                     //} |  | ||||||
|                                 } // Object is within 256m Z of terrain |  | ||||||
|                             } // object is at least a meter wide |  | ||||||
|                         } // loop over group children |  | ||||||
|                     } // entitybase is sceneobject group |  | ||||||
|                 } // foreach loop over entities |  | ||||||
| 
 | 
 | ||||||
|                 float[] sortedZHeights = z_sortheights.ToArray(); |                     // Sort prim by Z position | ||||||
|                 uint[] sortedlocalIds = z_localIDs.ToArray(); |                     Array.Sort(sortedZHeights, sortedlocalIds); | ||||||
| 
 | 
 | ||||||
|                 // Sort prim by Z position |                     using (Graphics g = Graphics.FromImage(mapbmp)) | ||||||
|                 Array.Sort(sortedZHeights, sortedlocalIds); |  | ||||||
| 
 |  | ||||||
|                 Graphics g = Graphics.FromImage(mapbmp); |  | ||||||
| 
 |  | ||||||
|                 for (int s = 0; s < sortedZHeights.Length; s++) |  | ||||||
|                 { |  | ||||||
|                     if (z_sort.ContainsKey(sortedlocalIds[s])) |  | ||||||
|                     { |                     { | ||||||
|                         DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; |                         for (int s = 0; s < sortedZHeights.Length; s++) | ||||||
|                         for (int r = 0; r < rectDrawStruct.trns.Length; r++) |  | ||||||
|                         { |                         { | ||||||
|                             g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); |                             if (z_sort.ContainsKey(sortedlocalIds[s])) | ||||||
|  |                             { | ||||||
|  |                                 DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; | ||||||
|  |                                 for (int r = 0; r < rectDrawStruct.trns.Length; r++) | ||||||
|  |                                 { | ||||||
|  |                                     g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); | ||||||
|  |                                 } | ||||||
|  |                                 //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|                         //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } // lock entities objs | ||||||
| 
 | 
 | ||||||
|                 g.Dispose(); |             } | ||||||
|             } // lock entities objs |             finally | ||||||
|  |             { | ||||||
|  |                 foreach (DrawStruct ds in z_sort.Values) | ||||||
|  |                     ds.brush.Dispose(); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); |             m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); | ||||||
|  | 
 | ||||||
|             return mapbmp; |             return mapbmp; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|         public void TerrainToBitmap(Bitmap mapbmp) |         public void TerrainToBitmap(Bitmap mapbmp) | ||||||
|         { |         { | ||||||
|             int tc = Environment.TickCount; |             int tc = Environment.TickCount; | ||||||
|             m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); |             m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Terrain"); | ||||||
| 
 | 
 | ||||||
|             double[,] hm = m_scene.Heightmap.GetDoubles(); |             double[,] hm = m_scene.Heightmap.GetDoubles(); | ||||||
|             bool ShadowDebugContinue = true; |             bool ShadowDebugContinue = true; | ||||||
|  | @ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|                         { |                         { | ||||||
|                             if (!terraincorruptedwarningsaid) |                             if (!terraincorruptedwarningsaid) | ||||||
|                             { |                             { | ||||||
|                                 m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); |                                 m_log.WarnFormat("[SHADED MAP TILE RENDERER]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); | ||||||
|                                 terraincorruptedwarningsaid = true; |                                 terraincorruptedwarningsaid = true; | ||||||
|                             } |                             } | ||||||
|                             color = Color.Black; |                             color = Color.Black; | ||||||
|  | @ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|                         { |                         { | ||||||
|                             if (!terraincorruptedwarningsaid) |                             if (!terraincorruptedwarningsaid) | ||||||
|                             { |                             { | ||||||
|                                 m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); |                                 m_log.WarnFormat("[SHADED MAP TILE RENDERER]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); | ||||||
|                                 terraincorruptedwarningsaid = true; |                                 terraincorruptedwarningsaid = true; | ||||||
|                             } |                             } | ||||||
|                             Color black = Color.Black; |                             Color black = Color.Black; | ||||||
|  | @ -238,7 +238,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 
 | ||||||
|  |             m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|         private Bitmap fetchTexture(UUID id) |         private Bitmap fetchTexture(UUID id) | ||||||
|         { |         { | ||||||
|             AssetBase asset = m_scene.AssetService.Get(id.ToString()); |             AssetBase asset = m_scene.AssetService.Get(id.ToString()); | ||||||
|             m_log.DebugFormat("[TexturedMapTileRenderer]: Fetched texture {0}, found: {1}", id, asset != null); |             m_log.DebugFormat("[TEXTURED MAP TILE RENDERER]: Fetched texture {0}, found: {1}", id, asset != null); | ||||||
|             if (asset == null) return null; |             if (asset == null) return null; | ||||||
| 
 | 
 | ||||||
|             ManagedImage managedImage; |             ManagedImage managedImage; | ||||||
|  | @ -188,17 +188,17 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|             } |             } | ||||||
|             catch (DllNotFoundException) |             catch (DllNotFoundException) | ||||||
|             { |             { | ||||||
|                 m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg is not installed correctly on this system.   Asset Data is empty for {0}", id); |                 m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg is not installed correctly on this system.   Asset Data is empty for {0}", id); | ||||||
|                  |                  | ||||||
|             } |             } | ||||||
|             catch (IndexOutOfRangeException) |             catch (IndexOutOfRangeException) | ||||||
|             { |             { | ||||||
|                 m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this.   Asset Data is empty for {0}", id); |                 m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg was unable to encode this.   Asset Data is empty for {0}", id); | ||||||
|                  |                  | ||||||
|             } |             } | ||||||
|             catch (Exception) |             catch (Exception) | ||||||
|             { |             { | ||||||
|                 m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this.   Asset Data is empty for {0}", id); |                 m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg was unable to encode this.   Asset Data is empty for {0}", id); | ||||||
|                  |                  | ||||||
|             } |             } | ||||||
|             return null; |             return null; | ||||||
|  | @ -233,10 +233,14 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|             if (textureID == UUID.Zero) return defaultColor; // not set |             if (textureID == UUID.Zero) return defaultColor; // not set | ||||||
|             if (m_mapping.ContainsKey(textureID)) return m_mapping[textureID]; // one of the predefined textures |             if (m_mapping.ContainsKey(textureID)) return m_mapping[textureID]; // one of the predefined textures | ||||||
| 
 | 
 | ||||||
|             Bitmap bmp = fetchTexture(textureID); |             Color color; | ||||||
|             Color color = bmp == null ? defaultColor : computeAverageColor(bmp); | 
 | ||||||
|             // store it for future reference |             using (Bitmap bmp = fetchTexture(textureID)) | ||||||
|             m_mapping[textureID] = color; |             { | ||||||
|  |                 color = bmp == null ? defaultColor : computeAverageColor(bmp); | ||||||
|  |                 // store it for future reference | ||||||
|  |                 m_mapping[textureID] = color; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             return color; |             return color; | ||||||
|         } |         } | ||||||
|  | @ -278,7 +282,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|         public void TerrainToBitmap(Bitmap mapbmp) |         public void TerrainToBitmap(Bitmap mapbmp) | ||||||
|         { |         { | ||||||
|             int tc = Environment.TickCount; |             int tc = Environment.TickCount; | ||||||
|             m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); |             m_log.Debug("[TEXTURED MAP TILE RENDERER]: Generating Maptile Step 1: Terrain"); | ||||||
| 
 | 
 | ||||||
|             // These textures should be in the AssetCache anyway, as every client conneting to this |             // These textures should be in the AssetCache anyway, as every client conneting to this | ||||||
|             // region needs them. Except on start, when the map is recreated (before anyone connected), |             // region needs them. Except on start, when the map is recreated (before anyone connected), | ||||||
|  | @ -412,7 +416,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 
 | ||||||
|  |             m_log.Debug("[TEXTURED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -1520,62 +1520,69 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | ||||||
| 
 | 
 | ||||||
|         private Byte[] GenerateOverlay() |         private Byte[] GenerateOverlay() | ||||||
|         { |         { | ||||||
|             Bitmap overlay = new Bitmap(256, 256); |             using (Bitmap overlay = new Bitmap(256, 256)) | ||||||
| 
 |  | ||||||
|             bool[,] saleBitmap = new bool[64, 64]; |  | ||||||
|             for (int x = 0 ; x < 64 ; x++) |  | ||||||
|             { |             { | ||||||
|                 for (int y = 0 ; y < 64 ; y++) |                 bool[,] saleBitmap = new bool[64, 64]; | ||||||
|                     saleBitmap[x, y] = false; |                 for (int x = 0 ; x < 64 ; x++) | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             bool landForSale = false; |  | ||||||
| 
 |  | ||||||
|             List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); |  | ||||||
| 
 |  | ||||||
|             Color background = Color.FromArgb(0, 0, 0, 0); |  | ||||||
|             SolidBrush transparent = new SolidBrush(background); |  | ||||||
|             Graphics g = Graphics.FromImage(overlay); |  | ||||||
|             g.FillRectangle(transparent, 0, 0, 256, 256); |  | ||||||
| 
 |  | ||||||
|             SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); |  | ||||||
| 
 |  | ||||||
|             foreach (ILandObject land in parcels) |  | ||||||
|             { |  | ||||||
|                 // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); |  | ||||||
|                 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) |  | ||||||
|                 { |                 { | ||||||
|                     landForSale = true; |                     for (int y = 0 ; y < 64 ; y++) | ||||||
|  |                         saleBitmap[x, y] = false; | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|                     saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); |                 bool landForSale = false; | ||||||
|  | 
 | ||||||
|  |                 List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); | ||||||
|  | 
 | ||||||
|  |                 Color background = Color.FromArgb(0, 0, 0, 0); | ||||||
|  | 
 | ||||||
|  |                 using (Graphics g = Graphics.FromImage(overlay)) | ||||||
|  |                 { | ||||||
|  |                     using (SolidBrush transparent = new SolidBrush(background)) | ||||||
|  |                         g.FillRectangle(transparent, 0, 0, 256, 256); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                     foreach (ILandObject land in parcels) | ||||||
|  |                     { | ||||||
|  |                         // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); | ||||||
|  |                         if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||||||
|  |                         { | ||||||
|  |                             landForSale = true; | ||||||
|  | 
 | ||||||
|  |                             saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (!landForSale) | ||||||
|  |                     { | ||||||
|  |                         m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); | ||||||
|  |                         return null; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); | ||||||
|  | 
 | ||||||
|  |                     using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9))) | ||||||
|  |                     { | ||||||
|  |                         for (int x = 0 ; x < 64 ; x++) | ||||||
|  |                         { | ||||||
|  |                             for (int y = 0 ; y < 64 ; y++) | ||||||
|  |                             { | ||||||
|  |                                 if (saleBitmap[x, y]) | ||||||
|  |                                     g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     return OpenJPEG.EncodeFromImage(overlay, true); | ||||||
|  |                 } | ||||||
|  |                 catch (Exception e) | ||||||
|  |                 { | ||||||
|  |                     m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (!landForSale) |  | ||||||
|             { |  | ||||||
|                 m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); |  | ||||||
|                 return null; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); |  | ||||||
| 
 |  | ||||||
|             for (int x = 0 ; x < 64 ; x++) |  | ||||||
|             { |  | ||||||
|                 for (int y = 0 ; y < 64 ; y++) |  | ||||||
|                 { |  | ||||||
|                     if (saleBitmap[x, y]) |  | ||||||
|                         g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 return OpenJPEG.EncodeFromImage(overlay, true); |  | ||||||
|             } |  | ||||||
|             catch (Exception e) |  | ||||||
|             { |  | ||||||
|                 m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); |  | ||||||
|             } |  | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Justin Clark-Casey (justincc)
						Justin Clark-Casey (justincc)