aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment
diff options
context:
space:
mode:
authorTeravus Ovares2008-08-17 18:59:58 +0000
committerTeravus Ovares2008-08-17 18:59:58 +0000
commit0683a07081802105cbc40ca9d75c26e135342f3e (patch)
tree93a4fd544dab170d8b91c1c3c36bdaf936908ee3 /OpenSim/Region/Environment
parentAdd the IInventoryModule interface and a sample method call (diff)
downloadopensim-SC-0683a07081802105cbc40ca9d75c26e135342f3e.zip
opensim-SC-0683a07081802105cbc40ca9d75c26e135342f3e.tar.gz
opensim-SC-0683a07081802105cbc40ca9d75c26e135342f3e.tar.bz2
opensim-SC-0683a07081802105cbc40ca9d75c26e135342f3e.tar.xz
* Turned on the MapImageModule as opposed to the code in Scene for generating the map image. Copied the code in Scene into the MapImageModule, made a few tweaks to get it to work with the module's interface.
* Refactored a few things in Scene to make maptile saving easier to understand. * Added comments to describe the 'clever code' assetcache update without the gridasset being updated so as to lessen possible confusion in patches in the future. * If the MapImageModule isn't loaded, default to the code in Scene still.
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r--OpenSim/Region/Environment/Modules/World/WorldMap/MapImageModule.cs412
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs166
2 files changed, 478 insertions, 100 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/Environment/Modules/World/WorldMap/MapImageModule.cs
index 68c8046..a331d37 100644
--- a/OpenSim/Region/Environment/Modules/World/WorldMap/MapImageModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/WorldMap/MapImageModule.cs
@@ -26,29 +26,58 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Drawing; 30using System.Drawing;
31using System.Reflection;
32using Axiom.Math;
30using Nini.Config; 33using Nini.Config;
34using log4net;
31using OpenJPEGNet; 35using OpenJPEGNet;
32using OpenSim.Region.Environment.Interfaces; 36using OpenSim.Region.Environment.Interfaces;
33using OpenSim.Region.Environment.Scenes; 37using OpenSim.Region.Environment.Scenes;
38using libsecondlife;
34 39
35namespace OpenSim.Region.Environment.Modules.World.WorldMap 40namespace OpenSim.Region.Environment.Modules.World.WorldMap
36{ 41{
37 internal class MapImageModule : IMapImageGenerator, IRegionModule 42 public class MapImageModule : IMapImageGenerator, IRegionModule
38 { 43 {
44 private static readonly ILog m_log =
45 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
39 private Scene m_scene; 47 private Scene m_scene;
48 private IConfigSource m_config;
40 49
41 #region IMapImageGenerator Members 50 #region IMapImageGenerator Members
42 51
43 public byte[] WriteJpeg2000Image(string gradientmap) 52 public byte[] WriteJpeg2000Image(string gradientmap)
44 { 53 {
45 byte[] imageData = null; 54 byte[] imageData = null;
55 Bitmap mapbmp = new Bitmap(256, 256);
56
57 //Bitmap bmp = TerrainToBitmap(gradientmap);
58 mapbmp = TerrainToBitmap2(m_scene,mapbmp);
59
60 bool drawPrimVolume = true;
61
62 try
63 {
64 IConfig startupConfig = m_config.Configs["Startup"];
65 drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", true);
66 }
67 catch (Exception)
68 {
69 m_log.Warn("Failed to load StartupConfig");
70 }
71
72 if (drawPrimVolume)
73 {
74 DrawObjectVolume(m_scene, mapbmp);
75 }
46 76
47 Bitmap bmp = TerrainToBitmap(gradientmap);
48 77
49 try 78 try
50 { 79 {
51 imageData = OpenJPEG.EncodeFromImage(bmp, true); 80 imageData = OpenJPEG.EncodeFromImage(mapbmp, true);
52 } 81 }
53 catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke 82 catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
54 { 83 {
@@ -65,6 +94,7 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap
65 public void Initialise(Scene scene, IConfigSource source) 94 public void Initialise(Scene scene, IConfigSource source)
66 { 95 {
67 m_scene = scene; 96 m_scene = scene;
97 m_config = source;
68 m_scene.RegisterModuleInterface<IMapImageGenerator>(this); 98 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
69 } 99 }
70 100
@@ -128,6 +158,381 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap
128 } 158 }
129 } 159 }
130 160
161 private Bitmap TerrainToBitmap2(Scene whichScene, Bitmap mapbmp)
162 {
163 int tc = System.Environment.TickCount;
164 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain");
165
166 double[,] hm = whichScene.Heightmap.GetDoubles();
167 bool ShadowDebugContinue = true;
168 //Color prim = Color.FromArgb(120, 120, 120);
169 //LLVector3 RayEnd = new LLVector3(0, 0, 0);
170 //LLVector3 RayStart = new LLVector3(0, 0, 0);
171 //LLVector3 direction = new LLVector3(0, 0, -1);
172 //Vector3 AXOrigin = new Vector3();
173 //Vector3 AXdirection = new Vector3();
174 //Ray testRay = new Ray();
175 //EntityIntersection rt = new EntityIntersection();
176 bool terraincorruptedwarningsaid = false;
177
178 float low = 255;
179 float high = 0;
180 for (int x = 0; x < 256; x++)
181 {
182 for (int y = 0; y < 256; y++)
183 {
184 float hmval = (float)hm[x, y];
185 if (hmval < low)
186 low = hmval;
187 if (hmval > high)
188 high = hmval;
189 }
190 }
191
192 float mid = (high + low) * 0.5f;
193
194 // temporary initializer
195 float hfvalue = (float)whichScene.RegionInfo.RegionSettings.WaterHeight;
196 float hfvaluecompare = hfvalue;
197 float hfdiff = hfvalue;
198 int hfdiffi = 0;
199
200
201 for (int x = 0; x < 256; x++)
202 {
203 //int tc = System.Environment.TickCount;
204 for (int y = 0; y < 256; y++)
205 {
206 //RayEnd = new LLVector3(x, y, 0);
207 //RayStart = new LLVector3(x, y, 255);
208
209 //direction = LLVector3.Norm(RayEnd - RayStart);
210 //AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
211 //AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
212
213 //testRay = new Ray(AXOrigin, AXdirection);
214 //rt = m_innerScene.GetClosestIntersectingPrim(testRay);
215
216 //if (rt.HitTF)
217 //{
218 //mapbmp.SetPixel(x, y, prim);
219 //}
220 //else
221 //{
222 //float tmpval = (float)hm[x, y];
223 float heightvalue = (float)hm[x, y];
224
225
226 if (heightvalue > (float)whichScene.RegionInfo.RegionSettings.WaterHeight)
227 {
228
229 // scale height value
230 heightvalue = low + mid * (heightvalue - low) / mid;
231
232 if (heightvalue > 255)
233 heightvalue = 255;
234
235 if (heightvalue < 0)
236 heightvalue = 0;
237
238 if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
239 heightvalue = 0;
240 try
241 {
242 Color green = Color.FromArgb((int)heightvalue, 100, (int)heightvalue);
243
244 // Y flip the cordinates
245 mapbmp.SetPixel(x, (256 - y) - 1, green);
246
247 //X
248 // .
249 //
250 // Shade the terrain for shadows
251 if ((x - 1 > 0) && (y - 1 > 0))
252 {
253 hfvalue = (float)hm[x, y];
254 hfvaluecompare = (float)hm[x - 1, y - 1];
255
256 if (Single.IsInfinity(hfvalue) || Single.IsNaN(hfvalue))
257 hfvalue = 0;
258
259 if (Single.IsInfinity(hfvaluecompare) || Single.IsNaN(hfvaluecompare))
260 hfvaluecompare = 0;
261
262 hfdiff = hfvaluecompare - hfvalue;
263
264 if (hfdiff > 0.3f)
265 {
266
267 }
268 else if (hfdiff < -0.3f)
269 {
270 // We have to desaturate and blacken the land at the same time
271 // we use floats, colors use bytes, so shrink are space down to
272 // 0-255
273
274
275 try
276 {
277 hfdiffi = Math.Abs((int)((hfdiff * 4) + (hfdiff * 0.5))) + 1;
278 if (hfdiff % 1 != 0)
279 {
280 hfdiffi = hfdiffi + Math.Abs((int)(((hfdiff % 1) * 0.5f) * 10f) - 1);
281 }
282 }
283 catch (System.OverflowException)
284 {
285 m_log.Debug("[MAPTILE]: Shadow failed at value: " + hfdiff.ToString());
286 ShadowDebugContinue = false;
287 }
288
289 if (ShadowDebugContinue)
290 {
291 if ((256 - y) - 1 > 0)
292 {
293 Color Shade = mapbmp.GetPixel(x - 1, (256 - y) - 1);
294
295 int r = Shade.R;
296
297 int g = Shade.G;
298 int b = Shade.B;
299 Shade = Color.FromArgb((r - hfdiffi > 0) ? r - hfdiffi : 0, (g - hfdiffi > 0) ? g - hfdiffi : 0, (b - hfdiffi > 0) ? b - hfdiffi : 0);
300 //Console.WriteLine("d:" + hfdiff.ToString() + ", i:" + hfdiffi + ", pos: " + x + "," + y + " - R:" + Shade.R.ToString() + ", G:" + Shade.G.ToString() + ", B:" + Shade.G.ToString());
301 mapbmp.SetPixel(x - 1, (256 - y) - 1, Shade);
302 }
303 }
304
305
306 }
307
308 }
309
310
311
312
313 }
314 catch (System.ArgumentException)
315 {
316 if (!terraincorruptedwarningsaid)
317 {
318 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", whichScene.RegionInfo.RegionName);
319 terraincorruptedwarningsaid = true;
320 }
321 Color black = Color.Black;
322 mapbmp.SetPixel(x, (256 - y) - 1, black);
323 }
324 }
325 else
326 {
327 // Y flip the cordinates
328 heightvalue = (float)whichScene.RegionInfo.RegionSettings.WaterHeight - heightvalue;
329 if (heightvalue > 19)
330 heightvalue = 19;
331 if (heightvalue < 0)
332 heightvalue = 0;
333
334 heightvalue = 100 - (heightvalue * 100) / 19;
335
336 if (heightvalue > 255)
337 heightvalue = 255;
338
339 if (heightvalue < 0)
340 heightvalue = 0;
341
342 if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
343 heightvalue = 0;
344
345 try
346 {
347 Color water = Color.FromArgb((int)heightvalue, (int)heightvalue, 255);
348 mapbmp.SetPixel(x, (256 - y) - 1, water);
349 }
350 catch (System.ArgumentException)
351 {
352 if (!terraincorruptedwarningsaid)
353 {
354 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", whichScene.RegionInfo.RegionName);
355 terraincorruptedwarningsaid = true;
356 }
357 Color black = Color.Black;
358 mapbmp.SetPixel(x, (256 - y) - 1, black);
359 }
360 }
361 }
362 //}
363
364 //tc = System.Environment.TickCount - tc;
365 //m_log.Info("[MAPTILE]: Completed One row in " + tc + " ms");
366 }
367 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (System.Environment.TickCount - tc) + " ms");
368
369 return mapbmp;
370 }
371
372
373 private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp)
374 {
375 int tc = 0;
376 double[,] hm = whichScene.Heightmap.GetDoubles();
377 tc = System.Environment.TickCount;
378 m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile");
379 List<EntityBase> objs = whichScene.GetEntities();
380
381 lock (objs)
382 {
383 foreach (EntityBase obj in objs)
384 {
385 // Only draw the contents of SceneObjectGroup
386 if (obj is SceneObjectGroup)
387 {
388 SceneObjectGroup mapdot = (SceneObjectGroup)obj;
389 Color mapdotspot = Color.Gray; // Default color when prim color is white
390 // Loop over prim in group
391 foreach (SceneObjectPart part in mapdot.Children.Values)
392 {
393 if (part == null)
394 continue;
395
396
397 // Draw if the object is at least 1 meter wide in any direction
398 if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
399 {
400 // Try to get the RGBA of the default texture entry..
401 //
402 try
403 {
404 if (part == null)
405 continue;
406
407 if (part.Shape == null)
408 continue;
409
410 if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree)
411 continue; // eliminates trees from this since we don't really have a good tree representation
412 // if you want tree blocks on the map comment the above line and uncomment the below line
413 //mapdotspot = Color.PaleGreen;
414
415 if (part.Shape.Textures == null)
416 continue;
417
418 if (part.Shape.Textures.DefaultTexture == null)
419 continue;
420
421 LLColor texcolor = part.Shape.Textures.DefaultTexture.RGBA;
422
423 // Not sure why some of these are null, oh well.
424
425 int colorr = 255 - (int)(texcolor.R * 255f);
426 int colorg = 255 - (int)(texcolor.G * 255f);
427 int colorb = 255 - (int)(texcolor.B * 255f);
428
429 if (!(colorr == 255 && colorg == 255 && colorb == 255))
430 {
431 //Try to set the map spot color
432 try
433 {
434 // If the color gets goofy somehow, skip it *shakes fist at LLColor
435 mapdotspot = Color.FromArgb(colorr, colorg, colorb);
436 }
437 catch (ArgumentException)
438 {
439 }
440 }
441 }
442 catch (IndexOutOfRangeException)
443 {
444 // Windows Array
445 }
446 catch (ArgumentOutOfRangeException)
447 {
448 // Mono Array
449 }
450
451 LLVector3 pos = part.GetWorldPosition();
452
453 // skip prim outside of retion
454 if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
455 continue;
456
457 // skip prim in non-finite position
458 if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || Single.IsInfinity(pos.X)
459 || Single.IsInfinity(pos.Y))
460 continue;
461
462 // Figure out if object is under 256m above the height of the terrain
463 bool isBelow256AboveTerrain = false;
464
465 try
466 {
467 isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
468 }
469 catch (Exception)
470 {
471 }
472
473 if (isBelow256AboveTerrain)
474 {
475 // Translate scale by rotation so scale is represented properly when object is rotated
476 Vector3 scale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z);
477 LLQuaternion llrot = part.GetWorldRotation();
478 Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z);
479 scale = rot * scale;
480
481 // negative scales don't work in this situation
482 scale.x = Math.Abs(scale.x);
483 scale.y = Math.Abs(scale.y);
484 scale.z = Math.Abs(scale.z);
485
486 // This scaling isn't very accurate and doesn't take into account the face rotation :P
487 int mapdrawstartX = (int)(pos.X - scale.x);
488 int mapdrawstartY = (int)(pos.Y - scale.y);
489 int mapdrawendX = (int)(pos.X + scale.x);
490 int mapdrawendY = (int)(pos.Y + scale.y);
491
492 // If object is beyond the edge of the map, don't draw it to avoid errors
493 if (mapdrawstartX < 0 || mapdrawstartX > 255 || mapdrawendX < 0 || mapdrawendX > 255
494 || mapdrawstartY < 0 || mapdrawstartY > 255 || mapdrawendY < 0
495 || mapdrawendY > 255)
496 continue;
497
498 int wy = 0;
499
500 bool breakYN = false; // If we run into an error drawing, break out of the
501 // loop so we don't lag to death on error handling
502 for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
503 {
504 for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
505 {
506 //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
507 try
508 {
509 // Remember, flip the y!
510 mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
511 }
512 catch (ArgumentException)
513 {
514 breakYN = true;
515 }
516
517 if (breakYN)
518 break;
519 }
520
521 if (breakYN)
522 break;
523 }
524 } // Object is within 256m Z of terrain
525 } // object is at least a meter wide
526 } // loop over group children
527 } // entitybase is sceneobject group
528 } // foreach loop over entities
529 } // lock entities objs
530
531 m_log.Info("[MAPTILE]: Generating Maptile Step 2: Done in " + (System.Environment.TickCount - tc) + " ms");
532 return mapbmp;
533 }
534
535 # region Depreciated Maptile Generation. Adam may update this
131 private Bitmap TerrainToBitmap(string gradientmap) 536 private Bitmap TerrainToBitmap(string gradientmap)
132 { 537 {
133 Bitmap gradientmapLd = new Bitmap(gradientmap); 538 Bitmap gradientmapLd = new Bitmap(gradientmap);
@@ -163,5 +568,6 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap
163 return bmp; 568 return bmp;
164 } 569 }
165 } 570 }
571 #endregion
166 } 572 }
167} \ No newline at end of file 573} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index e060f3d..e8a8a78 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -1023,6 +1023,8 @@ namespace OpenSim.Region.Environment.Scenes
1023 1023
1024 if (terrain == null) 1024 if (terrain == null)
1025 { 1025 {
1026 #region Fallback default maptile generation
1027
1026 int tc = System.Environment.TickCount; 1028 int tc = System.Environment.TickCount;
1027 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain"); 1029 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain");
1028 Bitmap mapbmp = new Bitmap(256, 256); 1030 Bitmap mapbmp = new Bitmap(256, 256);
@@ -1053,13 +1055,13 @@ namespace OpenSim.Region.Environment.Scenes
1053 } 1055 }
1054 1056
1055 float mid = (high + low) * 0.5f; 1057 float mid = (high + low) * 0.5f;
1056 1058
1057 // temporary initializer 1059 // temporary initializer
1058 float hfvalue = (float)m_regInfo.RegionSettings.WaterHeight; 1060 float hfvalue = (float)m_regInfo.RegionSettings.WaterHeight;
1059 float hfvaluecompare = hfvalue; 1061 float hfvaluecompare = hfvalue;
1060 float hfdiff = hfvalue; 1062 float hfdiff = hfvalue;
1061 int hfdiffi = 0; 1063 int hfdiffi = 0;
1062 1064
1063 1065
1064 for (int x = 0; x < 256; x++) 1066 for (int x = 0; x < 256; x++)
1065 { 1067 {
@@ -1088,7 +1090,7 @@ namespace OpenSim.Region.Environment.Scenes
1088 1090
1089 if (heightvalue > (float)m_regInfo.RegionSettings.WaterHeight) 1091 if (heightvalue > (float)m_regInfo.RegionSettings.WaterHeight)
1090 { 1092 {
1091 1093
1092 // scale height value 1094 // scale height value
1093 heightvalue = low + mid * (heightvalue - low) / mid; 1095 heightvalue = low + mid * (heightvalue - low) / mid;
1094 1096
@@ -1115,7 +1117,7 @@ namespace OpenSim.Region.Environment.Scenes
1115 { 1117 {
1116 hfvalue = (float)hm[x, y]; 1118 hfvalue = (float)hm[x, y];
1117 hfvaluecompare = (float)hm[x - 1, y - 1]; 1119 hfvaluecompare = (float)hm[x - 1, y - 1];
1118 1120
1119 if (Single.IsInfinity(hfvalue) || Single.IsNaN(hfvalue)) 1121 if (Single.IsInfinity(hfvalue) || Single.IsNaN(hfvalue))
1120 hfvalue = 0; 1122 hfvalue = 0;
1121 1123
@@ -1133,7 +1135,7 @@ namespace OpenSim.Region.Environment.Scenes
1133 // We have to desaturate and blacken the land at the same time 1135 // We have to desaturate and blacken the land at the same time
1134 // we use floats, colors use bytes, so shrink are space down to 1136 // we use floats, colors use bytes, so shrink are space down to
1135 // 0-255 1137 // 0-255
1136 1138
1137 1139
1138 try 1140 try
1139 { 1141 {
@@ -1148,7 +1150,7 @@ namespace OpenSim.Region.Environment.Scenes
1148 m_log.Debug("[MAPTILE]: Shadow failed at value: " + hfdiff.ToString()); 1150 m_log.Debug("[MAPTILE]: Shadow failed at value: " + hfdiff.ToString());
1149 ShadowDebugContinue = false; 1151 ShadowDebugContinue = false;
1150 } 1152 }
1151 1153
1152 if (ShadowDebugContinue) 1154 if (ShadowDebugContinue)
1153 { 1155 {
1154 if ((256 - y) - 1 > 0) 1156 if ((256 - y) - 1 > 0)
@@ -1164,13 +1166,13 @@ namespace OpenSim.Region.Environment.Scenes
1164 mapbmp.SetPixel(x - 1, (256 - y) - 1, Shade); 1166 mapbmp.SetPixel(x - 1, (256 - y) - 1, Shade);
1165 } 1167 }
1166 } 1168 }
1167 1169
1168 1170
1169 } 1171 }
1170 1172
1171 } 1173 }
1172 1174
1173 1175
1174 1176
1175 1177
1176 } 1178 }
@@ -1178,7 +1180,7 @@ namespace OpenSim.Region.Environment.Scenes
1178 { 1180 {
1179 if (!terraincorruptedwarningsaid) 1181 if (!terraincorruptedwarningsaid)
1180 { 1182 {
1181 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",RegionInfo.RegionName); 1183 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", RegionInfo.RegionName);
1182 terraincorruptedwarningsaid = true; 1184 terraincorruptedwarningsaid = true;
1183 } 1185 }
1184 Color black = Color.Black; 1186 Color black = Color.Black;
@@ -1262,7 +1264,7 @@ namespace OpenSim.Region.Environment.Scenes
1262 if (part == null) 1264 if (part == null)
1263 continue; 1265 continue;
1264 1266
1265 1267
1266 // Draw if the object is at least 1 meter wide in any direction 1268 // Draw if the object is at least 1 meter wide in any direction
1267 if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) 1269 if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
1268 { 1270 {
@@ -1278,8 +1280,8 @@ namespace OpenSim.Region.Environment.Scenes
1278 1280
1279 if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree) 1281 if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree)
1280 continue; // eliminates trees from this since we don't really have a good tree representation 1282 continue; // eliminates trees from this since we don't really have a good tree representation
1281 // if you want tree blocks on the map comment the above line and uncomment the below line 1283 // if you want tree blocks on the map comment the above line and uncomment the below line
1282 //mapdotspot = Color.PaleGreen; 1284 //mapdotspot = Color.PaleGreen;
1283 1285
1284 if (part.Shape.Textures == null) 1286 if (part.Shape.Textures == null)
1285 continue; 1287 continue;
@@ -1410,106 +1412,76 @@ namespace OpenSim.Region.Environment.Scenes
1410 return; 1412 return;
1411 } 1413 }
1412 1414
1413 LLUUID lastMapRegionUUID = m_regInfo.lastMapUUID; 1415 LazySaveGeneratedMaptile(data,temporary);
1414 1416
1415 int lastMapRefresh = 0; 1417 #endregion
1416 int twoDays = 172800; 1418 }
1417 int RefreshSeconds = twoDays; 1419 else
1418 1420 {
1419 try 1421 // Use the module to generate the maptile.
1420 { 1422 byte[] data = terrain.WriteJpeg2000Image("defaultstripe.png");
1421 lastMapRefresh = Convert.ToInt32(m_regInfo.lastMapRefresh); 1423 if (data != null)
1422 }
1423 catch (ArgumentException)
1424 {
1425 }
1426 catch (FormatException)
1427 {
1428 }
1429 catch (OverflowException)
1430 { 1424 {
1425 LazySaveGeneratedMaptile(data,temporary);
1431 } 1426 }
1427 }
1428 }
1429 public void LazySaveGeneratedMaptile(byte[] data, bool temporary)
1430 {
1431 // Overwrites the local Asset cache with new maptile data
1432 // Assets are single write, this causes the asset server to ignore this update,
1433 // but the local asset cache does not
1432 1434
1433 LLUUID TerrainImageLLUUID = LLUUID.Random(); 1435 // this is on purpose! The net result of this is the region always has the most up to date
1436 // map tile while protecting the (grid) asset database from bloat caused by a new asset each
1437 // time a mapimage is generated!
1438
1439 LLUUID lastMapRegionUUID = m_regInfo.lastMapUUID;
1434 1440
1435 if (lastMapRegionUUID == LLUUID.Zero || (lastMapRefresh + RefreshSeconds) < Util.UnixTimeSinceEpoch()) 1441 int lastMapRefresh = 0;
1436 { 1442 int twoDays = 172800;
1437 m_regInfo.SaveLastMapUUID(TerrainImageLLUUID); 1443 int RefreshSeconds = twoDays;
1438 1444
1439 m_log.Warn("[MAPTILE]: STORING MAPTILE IMAGE"); 1445 try
1440 //Extra protection.. probably not needed. 1446 {
1441 } 1447 lastMapRefresh = Convert.ToInt32(m_regInfo.lastMapRefresh);
1442 else 1448 }
1443 { 1449 catch (ArgumentException)
1444 TerrainImageLLUUID = lastMapRegionUUID; 1450 {
1445 m_log.Warn("[MAPTILE]: REUSING OLD MAPTILE IMAGE ID"); 1451 }
1446 } 1452 catch (FormatException)
1453 {
1454 }
1455 catch (OverflowException)
1456 {
1457 }
1447 1458
1448 m_regInfo.RegionSettings.TerrainImageID = TerrainImageLLUUID; 1459 LLUUID TerrainImageLLUUID = LLUUID.Random();
1449 1460
1450 AssetBase asset = new AssetBase(); 1461 if (lastMapRegionUUID == LLUUID.Zero || (lastMapRefresh + RefreshSeconds) < Util.UnixTimeSinceEpoch())
1451 asset.FullID = m_regInfo.RegionSettings.TerrainImageID; 1462 {
1452 asset.Data = data; 1463 m_regInfo.SaveLastMapUUID(TerrainImageLLUUID);
1453 asset.Name = "terrainImage_" + m_regInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString();
1454 asset.Description = RegionInfo.RegionName;
1455 1464
1456 asset.Type = 0; 1465 m_log.Warn("[MAPTILE]: STORING MAPTILE IMAGE");
1457 asset.Temporary = temporary;
1458 AssetCache.AddAsset(asset);
1459 } 1466 }
1460 else 1467 else
1461 { 1468 {
1462 byte[] data = terrain.WriteJpeg2000Image("defaultstripe.png"); 1469 TerrainImageLLUUID = lastMapRegionUUID;
1463 if (data != null) 1470 m_log.Warn("[MAPTILE]: REUSING OLD MAPTILE IMAGE ID");
1464 { 1471 }
1465 LLUUID lastMapRegionUUID = m_regInfo.lastMapUUID;
1466
1467 int lastMapRefresh = 0;
1468 int twoDays = 172800;
1469 int RefreshSeconds = twoDays;
1470
1471 try
1472 {
1473 lastMapRefresh = Convert.ToInt32(m_regInfo.lastMapRefresh);
1474 }
1475 catch (ArgumentException)
1476 {
1477 }
1478 catch (FormatException)
1479 {
1480 }
1481 catch (OverflowException)
1482 {
1483 }
1484
1485 LLUUID TerrainImageLLUUID = LLUUID.Random();
1486
1487 if (lastMapRegionUUID == LLUUID.Zero || (lastMapRefresh + RefreshSeconds) < Util.UnixTimeSinceEpoch())
1488 {
1489 m_regInfo.SaveLastMapUUID(TerrainImageLLUUID);
1490 1472
1491 //m_log.Warn(terrainImageID); 1473 m_regInfo.RegionSettings.TerrainImageID = TerrainImageLLUUID;
1492 //Extra protection.. probably not needed.
1493 }
1494 else
1495 {
1496 TerrainImageLLUUID = lastMapRegionUUID;
1497 }
1498 1474
1499 m_regInfo.RegionSettings.TerrainImageID = TerrainImageLLUUID; 1475 AssetBase asset = new AssetBase();
1476 asset.FullID = m_regInfo.RegionSettings.TerrainImageID;
1477 asset.Data = data;
1478 asset.Name = "terrainImage_" + m_regInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString();
1479 asset.Description = RegionInfo.RegionName;
1500 1480
1501 AssetBase asset = new AssetBase(); 1481 asset.Type = 0;
1502 asset.FullID = m_regInfo.RegionSettings.TerrainImageID; 1482 asset.Temporary = temporary;
1503 asset.Data = data; 1483 AssetCache.AddAsset(asset);
1504 asset.Name = "terrainImage_" + m_regInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString();
1505 asset.Description = RegionInfo.RegionName;
1506 asset.Type = 0;
1507 asset.Temporary = temporary;
1508 AssetCache.AddAsset(asset);
1509 }
1510 }
1511 } 1484 }
1512
1513 #endregion 1485 #endregion
1514 1486
1515 #region Load Land 1487 #region Load Land