diff options
author | Justin Clark-Casey (justincc) | 2014-01-24 19:16:59 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2014-01-24 19:16:59 +0000 |
commit | 87e725cd2474efcdfec3d85794ef2b877c8b78d6 (patch) | |
tree | ffd2f4e5fffecb84e76f07d3fd87d9f29b5fcada | |
parent | Change version to 0.7.6.1-rc1 instead (diff) | |
parent | Properly dispose of drawing objects to reduce/stop memory leakage on generati... (diff) | |
download | opensim-SC_OLD-87e725cd2474efcdfec3d85794ef2b877c8b78d6.zip opensim-SC_OLD-87e725cd2474efcdfec3d85794ef2b877c8b78d6.tar.gz opensim-SC_OLD-87e725cd2474efcdfec3d85794ef2b877c8b78d6.tar.bz2 opensim-SC_OLD-87e725cd2474efcdfec3d85794ef2b877c8b78d6.tar.xz |
Merge branch '0.7.6-extended' into 0.7.6-post-fixes
13 files changed, 616 insertions, 417 deletions
diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index db8c53e..a895c40 100644 --- a/OpenSim/Framework/RegionSettings.cs +++ b/OpenSim/Framework/RegionSettings.cs | |||
@@ -482,21 +482,14 @@ namespace OpenSim.Framework | |||
482 | set { m_LoadedCreationID = value; } | 482 | set { m_LoadedCreationID = value; } |
483 | } | 483 | } |
484 | 484 | ||
485 | // Connected Telehub object | 485 | /// <summary> |
486 | private UUID m_TelehubObject = UUID.Zero; | 486 | /// Connected Telehub object |
487 | public UUID TelehubObject | 487 | /// </summary> |
488 | { | 488 | public UUID TelehubObject { get; set; } |
489 | get | ||
490 | { | ||
491 | return m_TelehubObject; | ||
492 | } | ||
493 | set | ||
494 | { | ||
495 | m_TelehubObject = value; | ||
496 | } | ||
497 | } | ||
498 | 489 | ||
499 | // Our Connected Telehub's SpawnPoints | 490 | /// <summary> |
491 | /// Our connected Telehub's SpawnPoints | ||
492 | /// </summary> | ||
500 | public List<SpawnPoint> l_SpawnPoints = new List<SpawnPoint>(); | 493 | public List<SpawnPoint> l_SpawnPoints = new List<SpawnPoint>(); |
501 | 494 | ||
502 | // Add a SpawnPoint | 495 | // Add a SpawnPoint |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index 173b603..1659493 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs | |||
@@ -60,7 +60,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
60 | 60 | ||
61 | public void Initialise() | 61 | public void Initialise() |
62 | { | 62 | { |
63 | m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName); | 63 | // m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName); |
64 | 64 | ||
65 | m_module.Scene.AddCommand("Regions", m_module, "set terrain texture", | 65 | m_module.Scene.AddCommand("Regions", m_module, "set terrain texture", |
66 | "set terrain texture <number> <uuid> [<x>] [<y>]", | 66 | "set terrain texture <number> <uuid> [<x>] [<y>]", |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 42db1cf..cf74350 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -702,7 +702,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
702 | } | 702 | } |
703 | } | 703 | } |
704 | 704 | ||
705 | public void handleOnEstateManageTelehub(IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) | 705 | public void HandleOnEstateManageTelehub(IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) |
706 | { | 706 | { |
707 | SceneObjectPart part; | 707 | SceneObjectPart part; |
708 | 708 | ||
@@ -742,7 +742,9 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
742 | default: | 742 | default: |
743 | break; | 743 | break; |
744 | } | 744 | } |
745 | SendTelehubInfo(client); | 745 | |
746 | if (client != null) | ||
747 | SendTelehubInfo(client); | ||
746 | } | 748 | } |
747 | 749 | ||
748 | private void SendSimulatorBlueBoxMessage( | 750 | private void SendSimulatorBlueBoxMessage( |
@@ -1207,7 +1209,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
1207 | client.OnEstateRestartSimRequest += handleEstateRestartSimRequest; | 1209 | client.OnEstateRestartSimRequest += handleEstateRestartSimRequest; |
1208 | client.OnEstateChangeCovenantRequest += handleChangeEstateCovenantRequest; | 1210 | client.OnEstateChangeCovenantRequest += handleChangeEstateCovenantRequest; |
1209 | client.OnEstateChangeInfo += handleEstateChangeInfo; | 1211 | client.OnEstateChangeInfo += handleEstateChangeInfo; |
1210 | client.OnEstateManageTelehub += handleOnEstateManageTelehub; | 1212 | client.OnEstateManageTelehub += HandleOnEstateManageTelehub; |
1211 | client.OnUpdateEstateAccessDeltaRequest += handleEstateAccessDeltaRequest; | 1213 | client.OnUpdateEstateAccessDeltaRequest += handleEstateAccessDeltaRequest; |
1212 | client.OnSimulatorBlueBoxMessageRequest += SendSimulatorBlueBoxMessage; | 1214 | client.OnSimulatorBlueBoxMessageRequest += SendSimulatorBlueBoxMessage; |
1213 | client.OnEstateBlueBoxMessageRequest += SendEstateBlueBoxMessage; | 1215 | client.OnEstateBlueBoxMessageRequest += SendEstateBlueBoxMessage; |
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index 40638f8..bc52a43 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs | |||
@@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
55 | public struct DrawStruct | 55 | public struct DrawStruct |
56 | { | 56 | { |
57 | public DrawRoutine dr; | 57 | public DrawRoutine dr; |
58 | public Rectangle rect; | 58 | // public Rectangle rect; |
59 | public SolidBrush brush; | 59 | public SolidBrush brush; |
60 | public face[] trns; | 60 | public face[] trns; |
61 | } | 61 | } |
@@ -119,6 +119,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
119 | { | 119 | { |
120 | mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); | 120 | mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); |
121 | } | 121 | } |
122 | |||
122 | return mapbmp; | 123 | return mapbmp; |
123 | } | 124 | } |
124 | 125 | ||
@@ -127,7 +128,10 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
127 | try | 128 | try |
128 | { | 129 | { |
129 | using (Bitmap mapbmp = CreateMapTile()) | 130 | using (Bitmap mapbmp = CreateMapTile()) |
130 | return OpenJPEG.EncodeFromImage(mapbmp, true); | 131 | { |
132 | if (mapbmp != null) | ||
133 | return OpenJPEG.EncodeFromImage(mapbmp, true); | ||
134 | } | ||
131 | } | 135 | } |
132 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke | 136 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke |
133 | { | 137 | { |
@@ -277,321 +281,331 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
277 | tc = Environment.TickCount; | 281 | tc = Environment.TickCount; |
278 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); | 282 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); |
279 | EntityBase[] objs = whichScene.GetEntities(); | 283 | EntityBase[] objs = whichScene.GetEntities(); |
280 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); | ||
281 | //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); | ||
282 | List<float> z_sortheights = new List<float>(); | 284 | List<float> z_sortheights = new List<float>(); |
283 | List<uint> z_localIDs = new List<uint>(); | 285 | List<uint> z_localIDs = new List<uint>(); |
286 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); | ||
284 | 287 | ||
285 | lock (objs) | 288 | try |
286 | { | 289 | { |
287 | foreach (EntityBase obj in objs) | 290 | //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); |
291 | |||
292 | lock (objs) | ||
288 | { | 293 | { |
289 | // Only draw the contents of SceneObjectGroup | 294 | foreach (EntityBase obj in objs) |
290 | if (obj is SceneObjectGroup) | ||
291 | { | 295 | { |
292 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; | 296 | // Only draw the contents of SceneObjectGroup |
293 | Color mapdotspot = Color.Gray; // Default color when prim color is white | 297 | if (obj is SceneObjectGroup) |
294 | |||
295 | // Loop over prim in group | ||
296 | foreach (SceneObjectPart part in mapdot.Parts) | ||
297 | { | 298 | { |
298 | if (part == null) | 299 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; |
299 | continue; | 300 | Color mapdotspot = Color.Gray; // Default color when prim color is white |
300 | 301 | ||
301 | // Draw if the object is at least 1 meter wide in any direction | 302 | // Loop over prim in group |
302 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) | 303 | foreach (SceneObjectPart part in mapdot.Parts) |
303 | { | 304 | { |
304 | // Try to get the RGBA of the default texture entry.. | 305 | if (part == null) |
305 | // | 306 | continue; |
306 | try | 307 | |
308 | // Draw if the object is at least 1 meter wide in any direction | ||
309 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) | ||
307 | { | 310 | { |
308 | // get the null checks out of the way | 311 | // Try to get the RGBA of the default texture entry.. |
309 | // skip the ones that break | 312 | // |
310 | if (part == null) | 313 | try |
311 | continue; | 314 | { |
315 | // get the null checks out of the way | ||
316 | // skip the ones that break | ||
317 | if (part == null) | ||
318 | continue; | ||
312 | 319 | ||
313 | if (part.Shape == null) | 320 | if (part.Shape == null) |
314 | continue; | 321 | continue; |
315 | 322 | ||
316 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) | 323 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) |
317 | continue; // eliminates trees from this since we don't really have a good tree representation | 324 | continue; // eliminates trees from this since we don't really have a good tree representation |
318 | // if you want tree blocks on the map comment the above line and uncomment the below line | 325 | // if you want tree blocks on the map comment the above line and uncomment the below line |
319 | //mapdotspot = Color.PaleGreen; | 326 | //mapdotspot = Color.PaleGreen; |
320 | 327 | ||
321 | Primitive.TextureEntry textureEntry = part.Shape.Textures; | 328 | Primitive.TextureEntry textureEntry = part.Shape.Textures; |
322 | 329 | ||
323 | if (textureEntry == null || textureEntry.DefaultTexture == null) | 330 | if (textureEntry == null || textureEntry.DefaultTexture == null) |
324 | continue; | 331 | continue; |
325 | 332 | ||
326 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; | 333 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; |
327 | 334 | ||
328 | // Not sure why some of these are null, oh well. | 335 | // Not sure why some of these are null, oh well. |
329 | 336 | ||
330 | int colorr = 255 - (int)(texcolor.R * 255f); | 337 | int colorr = 255 - (int)(texcolor.R * 255f); |
331 | int colorg = 255 - (int)(texcolor.G * 255f); | 338 | int colorg = 255 - (int)(texcolor.G * 255f); |
332 | int colorb = 255 - (int)(texcolor.B * 255f); | 339 | int colorb = 255 - (int)(texcolor.B * 255f); |
333 | 340 | ||
334 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) | 341 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) |
335 | { | ||
336 | //Try to set the map spot color | ||
337 | try | ||
338 | { | ||
339 | // If the color gets goofy somehow, skip it *shakes fist at Color4 | ||
340 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); | ||
341 | } | ||
342 | catch (ArgumentException) | ||
343 | { | 342 | { |
343 | //Try to set the map spot color | ||
344 | try | ||
345 | { | ||
346 | // If the color gets goofy somehow, skip it *shakes fist at Color4 | ||
347 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); | ||
348 | } | ||
349 | catch (ArgumentException) | ||
350 | { | ||
351 | } | ||
344 | } | 352 | } |
345 | } | 353 | } |
346 | } | 354 | catch (IndexOutOfRangeException) |
347 | catch (IndexOutOfRangeException) | 355 | { |
348 | { | 356 | // Windows Array |
349 | // Windows Array | 357 | } |
350 | } | 358 | catch (ArgumentOutOfRangeException) |
351 | catch (ArgumentOutOfRangeException) | 359 | { |
352 | { | 360 | // Mono Array |
353 | // Mono Array | 361 | } |
354 | } | ||
355 | |||
356 | Vector3 pos = part.GetWorldPosition(); | ||
357 | |||
358 | // skip prim outside of retion | ||
359 | if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) | ||
360 | continue; | ||
361 | |||
362 | // skip prim in non-finite position | ||
363 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || | ||
364 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) | ||
365 | continue; | ||
366 | |||
367 | // Figure out if object is under 256m above the height of the terrain | ||
368 | bool isBelow256AboveTerrain = false; | ||
369 | 362 | ||
370 | try | 363 | Vector3 pos = part.GetWorldPosition(); |
371 | { | ||
372 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); | ||
373 | } | ||
374 | catch (Exception) | ||
375 | { | ||
376 | } | ||
377 | 364 | ||
378 | if (isBelow256AboveTerrain) | 365 | // skip prim outside of retion |
379 | { | 366 | if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) |
380 | // Translate scale by rotation so scale is represented properly when object is rotated | ||
381 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); | ||
382 | Vector3 scale = new Vector3(); | ||
383 | Vector3 tScale = new Vector3(); | ||
384 | Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | ||
385 | |||
386 | Quaternion llrot = part.GetWorldRotation(); | ||
387 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | ||
388 | scale = lscale * rot; | ||
389 | |||
390 | // negative scales don't work in this situation | ||
391 | scale.X = Math.Abs(scale.X); | ||
392 | scale.Y = Math.Abs(scale.Y); | ||
393 | scale.Z = Math.Abs(scale.Z); | ||
394 | |||
395 | // This scaling isn't very accurate and doesn't take into account the face rotation :P | ||
396 | int mapdrawstartX = (int)(pos.X - scale.X); | ||
397 | int mapdrawstartY = (int)(pos.Y - scale.Y); | ||
398 | int mapdrawendX = (int)(pos.X + scale.X); | ||
399 | int mapdrawendY = (int)(pos.Y + scale.Y); | ||
400 | |||
401 | // If object is beyond the edge of the map, don't draw it to avoid errors | ||
402 | if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | ||
403 | || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | ||
404 | || mapdrawendY > ((int)Constants.RegionSize - 1)) | ||
405 | continue; | 367 | continue; |
406 | 368 | ||
407 | #region obb face reconstruction part duex | 369 | // skip prim in non-finite position |
408 | Vector3[] vertexes = new Vector3[8]; | 370 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || |
409 | 371 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) | |
410 | // float[] distance = new float[6]; | 372 | continue; |
411 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei | ||
412 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei | ||
413 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei | ||
414 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei | ||
415 | |||
416 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); | ||
417 | scale = ((tScale * rot)); | ||
418 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
419 | // vertexes[0].x = pos.X + vertexes[0].x; | ||
420 | //vertexes[0].y = pos.Y + vertexes[0].y; | ||
421 | //vertexes[0].z = pos.Z + vertexes[0].z; | ||
422 | |||
423 | FaceA[0] = vertexes[0]; | ||
424 | FaceB[3] = vertexes[0]; | ||
425 | FaceA[4] = vertexes[0]; | ||
426 | |||
427 | tScale = lscale; | ||
428 | scale = ((tScale * rot)); | ||
429 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
430 | |||
431 | // vertexes[1].x = pos.X + vertexes[1].x; | ||
432 | // vertexes[1].y = pos.Y + vertexes[1].y; | ||
433 | //vertexes[1].z = pos.Z + vertexes[1].z; | ||
434 | |||
435 | FaceB[0] = vertexes[1]; | ||
436 | FaceA[1] = vertexes[1]; | ||
437 | FaceC[4] = vertexes[1]; | ||
438 | |||
439 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); | ||
440 | scale = ((tScale * rot)); | ||
441 | |||
442 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
443 | |||
444 | //vertexes[2].x = pos.X + vertexes[2].x; | ||
445 | //vertexes[2].y = pos.Y + vertexes[2].y; | ||
446 | //vertexes[2].z = pos.Z + vertexes[2].z; | ||
447 | |||
448 | FaceC[0] = vertexes[2]; | ||
449 | FaceD[3] = vertexes[2]; | ||
450 | FaceC[5] = vertexes[2]; | ||
451 | |||
452 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); | ||
453 | scale = ((tScale * rot)); | ||
454 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
455 | |||
456 | //vertexes[3].x = pos.X + vertexes[3].x; | ||
457 | // vertexes[3].y = pos.Y + vertexes[3].y; | ||
458 | // vertexes[3].z = pos.Z + vertexes[3].z; | ||
459 | |||
460 | FaceD[0] = vertexes[3]; | ||
461 | FaceC[1] = vertexes[3]; | ||
462 | FaceA[5] = vertexes[3]; | ||
463 | |||
464 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); | ||
465 | scale = ((tScale * rot)); | ||
466 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
467 | |||
468 | // vertexes[4].x = pos.X + vertexes[4].x; | ||
469 | // vertexes[4].y = pos.Y + vertexes[4].y; | ||
470 | // vertexes[4].z = pos.Z + vertexes[4].z; | ||
471 | |||
472 | FaceB[1] = vertexes[4]; | ||
473 | FaceA[2] = vertexes[4]; | ||
474 | FaceD[4] = vertexes[4]; | ||
475 | |||
476 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); | ||
477 | scale = ((tScale * rot)); | ||
478 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
479 | |||
480 | // vertexes[5].x = pos.X + vertexes[5].x; | ||
481 | // vertexes[5].y = pos.Y + vertexes[5].y; | ||
482 | // vertexes[5].z = pos.Z + vertexes[5].z; | ||
483 | |||
484 | FaceD[1] = vertexes[5]; | ||
485 | FaceC[2] = vertexes[5]; | ||
486 | FaceB[5] = vertexes[5]; | ||
487 | 373 | ||
488 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); | 374 | // Figure out if object is under 256m above the height of the terrain |
489 | scale = ((tScale * rot)); | 375 | bool isBelow256AboveTerrain = false; |
490 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
491 | 376 | ||
492 | // vertexes[6].x = pos.X + vertexes[6].x; | 377 | try |
493 | // vertexes[6].y = pos.Y + vertexes[6].y; | 378 | { |
494 | // vertexes[6].z = pos.Z + vertexes[6].z; | 379 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); |
380 | } | ||
381 | catch (Exception) | ||
382 | { | ||
383 | } | ||
495 | 384 | ||
496 | FaceB[2] = vertexes[6]; | 385 | if (isBelow256AboveTerrain) |
497 | FaceA[3] = vertexes[6]; | 386 | { |
498 | FaceB[4] = vertexes[6]; | 387 | // Translate scale by rotation so scale is represented properly when object is rotated |
388 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); | ||
389 | Vector3 scale = new Vector3(); | ||
390 | Vector3 tScale = new Vector3(); | ||
391 | Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | ||
392 | |||
393 | Quaternion llrot = part.GetWorldRotation(); | ||
394 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | ||
395 | scale = lscale * rot; | ||
396 | |||
397 | // negative scales don't work in this situation | ||
398 | scale.X = Math.Abs(scale.X); | ||
399 | scale.Y = Math.Abs(scale.Y); | ||
400 | scale.Z = Math.Abs(scale.Z); | ||
401 | |||
402 | // This scaling isn't very accurate and doesn't take into account the face rotation :P | ||
403 | int mapdrawstartX = (int)(pos.X - scale.X); | ||
404 | int mapdrawstartY = (int)(pos.Y - scale.Y); | ||
405 | int mapdrawendX = (int)(pos.X + scale.X); | ||
406 | int mapdrawendY = (int)(pos.Y + scale.Y); | ||
407 | |||
408 | // If object is beyond the edge of the map, don't draw it to avoid errors | ||
409 | if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | ||
410 | || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | ||
411 | || mapdrawendY > ((int)Constants.RegionSize - 1)) | ||
412 | continue; | ||
413 | |||
414 | #region obb face reconstruction part duex | ||
415 | Vector3[] vertexes = new Vector3[8]; | ||
416 | |||
417 | // float[] distance = new float[6]; | ||
418 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei | ||
419 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei | ||
420 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei | ||
421 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei | ||
422 | |||
423 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); | ||
424 | scale = ((tScale * rot)); | ||
425 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
426 | // vertexes[0].x = pos.X + vertexes[0].x; | ||
427 | //vertexes[0].y = pos.Y + vertexes[0].y; | ||
428 | //vertexes[0].z = pos.Z + vertexes[0].z; | ||
429 | |||
430 | FaceA[0] = vertexes[0]; | ||
431 | FaceB[3] = vertexes[0]; | ||
432 | FaceA[4] = vertexes[0]; | ||
433 | |||
434 | tScale = lscale; | ||
435 | scale = ((tScale * rot)); | ||
436 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
437 | |||
438 | // vertexes[1].x = pos.X + vertexes[1].x; | ||
439 | // vertexes[1].y = pos.Y + vertexes[1].y; | ||
440 | //vertexes[1].z = pos.Z + vertexes[1].z; | ||
441 | |||
442 | FaceB[0] = vertexes[1]; | ||
443 | FaceA[1] = vertexes[1]; | ||
444 | FaceC[4] = vertexes[1]; | ||
445 | |||
446 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); | ||
447 | scale = ((tScale * rot)); | ||
448 | |||
449 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
450 | |||
451 | //vertexes[2].x = pos.X + vertexes[2].x; | ||
452 | //vertexes[2].y = pos.Y + vertexes[2].y; | ||
453 | //vertexes[2].z = pos.Z + vertexes[2].z; | ||
454 | |||
455 | FaceC[0] = vertexes[2]; | ||
456 | FaceD[3] = vertexes[2]; | ||
457 | FaceC[5] = vertexes[2]; | ||
458 | |||
459 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); | ||
460 | scale = ((tScale * rot)); | ||
461 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
462 | |||
463 | //vertexes[3].x = pos.X + vertexes[3].x; | ||
464 | // vertexes[3].y = pos.Y + vertexes[3].y; | ||
465 | // vertexes[3].z = pos.Z + vertexes[3].z; | ||
466 | |||
467 | FaceD[0] = vertexes[3]; | ||
468 | FaceC[1] = vertexes[3]; | ||
469 | FaceA[5] = vertexes[3]; | ||
470 | |||
471 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); | ||
472 | scale = ((tScale * rot)); | ||
473 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
474 | |||
475 | // vertexes[4].x = pos.X + vertexes[4].x; | ||
476 | // vertexes[4].y = pos.Y + vertexes[4].y; | ||
477 | // vertexes[4].z = pos.Z + vertexes[4].z; | ||
478 | |||
479 | FaceB[1] = vertexes[4]; | ||
480 | FaceA[2] = vertexes[4]; | ||
481 | FaceD[4] = vertexes[4]; | ||
482 | |||
483 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); | ||
484 | scale = ((tScale * rot)); | ||
485 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
486 | |||
487 | // vertexes[5].x = pos.X + vertexes[5].x; | ||
488 | // vertexes[5].y = pos.Y + vertexes[5].y; | ||
489 | // vertexes[5].z = pos.Z + vertexes[5].z; | ||
490 | |||
491 | FaceD[1] = vertexes[5]; | ||
492 | FaceC[2] = vertexes[5]; | ||
493 | FaceB[5] = vertexes[5]; | ||
494 | |||
495 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); | ||
496 | scale = ((tScale * rot)); | ||
497 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
498 | |||
499 | // vertexes[6].x = pos.X + vertexes[6].x; | ||
500 | // vertexes[6].y = pos.Y + vertexes[6].y; | ||
501 | // vertexes[6].z = pos.Z + vertexes[6].z; | ||
502 | |||
503 | FaceB[2] = vertexes[6]; | ||
504 | FaceA[3] = vertexes[6]; | ||
505 | FaceB[4] = vertexes[6]; | ||
499 | 506 | ||
500 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); | 507 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); |
501 | scale = ((tScale * rot)); | 508 | scale = ((tScale * rot)); |
502 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | 509 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
503 | 510 | ||
504 | // vertexes[7].x = pos.X + vertexes[7].x; | 511 | // vertexes[7].x = pos.X + vertexes[7].x; |
505 | // vertexes[7].y = pos.Y + vertexes[7].y; | 512 | // vertexes[7].y = pos.Y + vertexes[7].y; |
506 | // vertexes[7].z = pos.Z + vertexes[7].z; | 513 | // vertexes[7].z = pos.Z + vertexes[7].z; |
507 | 514 | ||
508 | FaceD[2] = vertexes[7]; | 515 | FaceD[2] = vertexes[7]; |
509 | FaceC[3] = vertexes[7]; | 516 | FaceC[3] = vertexes[7]; |
510 | FaceD[5] = vertexes[7]; | 517 | FaceD[5] = vertexes[7]; |
511 | #endregion | 518 | #endregion |
512 | 519 | ||
513 | //int wy = 0; | 520 | //int wy = 0; |
514 | 521 | ||
515 | //bool breakYN = false; // If we run into an error drawing, break out of the | 522 | //bool breakYN = false; // If we run into an error drawing, break out of the |
516 | // loop so we don't lag to death on error handling | 523 | // loop so we don't lag to death on error handling |
517 | DrawStruct ds = new DrawStruct(); | 524 | DrawStruct ds = new DrawStruct(); |
518 | ds.brush = new SolidBrush(mapdotspot); | 525 | ds.brush = new SolidBrush(mapdotspot); |
519 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); | 526 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); |
520 | 527 | ||
521 | ds.trns = new face[FaceA.Length]; | 528 | ds.trns = new face[FaceA.Length]; |
522 | 529 | ||
523 | for (int i = 0; i < FaceA.Length; i++) | 530 | for (int i = 0; i < FaceA.Length; i++) |
524 | { | 531 | { |
525 | Point[] working = new Point[5]; | 532 | Point[] working = new Point[5]; |
526 | working[0] = project(FaceA[i], axPos); | 533 | working[0] = project(FaceA[i], axPos); |
527 | working[1] = project(FaceB[i], axPos); | 534 | working[1] = project(FaceB[i], axPos); |
528 | working[2] = project(FaceD[i], axPos); | 535 | working[2] = project(FaceD[i], axPos); |
529 | working[3] = project(FaceC[i], axPos); | 536 | working[3] = project(FaceC[i], axPos); |
530 | working[4] = project(FaceA[i], axPos); | 537 | working[4] = project(FaceA[i], axPos); |
531 | 538 | ||
532 | face workingface = new face(); | 539 | face workingface = new face(); |
533 | workingface.pts = working; | 540 | workingface.pts = working; |
534 | 541 | ||
535 | ds.trns[i] = workingface; | 542 | ds.trns[i] = workingface; |
536 | } | 543 | } |
537 | 544 | ||
538 | z_sort.Add(part.LocalId, ds); | 545 | z_sort.Add(part.LocalId, ds); |
539 | z_localIDs.Add(part.LocalId); | 546 | z_localIDs.Add(part.LocalId); |
540 | z_sortheights.Add(pos.Z); | 547 | z_sortheights.Add(pos.Z); |
541 | 548 | ||
542 | //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) | 549 | //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) |
543 | //{ | ||
544 | //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) | ||
545 | //{ | 550 | //{ |
546 | //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); | 551 | //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) |
547 | //try | ||
548 | //{ | ||
549 | // Remember, flip the y! | ||
550 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); | ||
551 | //} | ||
552 | //catch (ArgumentException) | ||
553 | //{ | 552 | //{ |
554 | // breakYN = true; | 553 | //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); |
554 | //try | ||
555 | //{ | ||
556 | // Remember, flip the y! | ||
557 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); | ||
558 | //} | ||
559 | //catch (ArgumentException) | ||
560 | //{ | ||
561 | // breakYN = true; | ||
562 | //} | ||
563 | |||
564 | //if (breakYN) | ||
565 | // break; | ||
555 | //} | 566 | //} |
556 | 567 | ||
557 | //if (breakYN) | 568 | //if (breakYN) |
558 | // break; | 569 | // break; |
559 | //} | 570 | //} |
571 | } // Object is within 256m Z of terrain | ||
572 | } // object is at least a meter wide | ||
573 | } // loop over group children | ||
574 | } // entitybase is sceneobject group | ||
575 | } // foreach loop over entities | ||
560 | 576 | ||
561 | //if (breakYN) | 577 | float[] sortedZHeights = z_sortheights.ToArray(); |
562 | // break; | 578 | uint[] sortedlocalIds = z_localIDs.ToArray(); |
563 | //} | ||
564 | } // Object is within 256m Z of terrain | ||
565 | } // object is at least a meter wide | ||
566 | } // loop over group children | ||
567 | } // entitybase is sceneobject group | ||
568 | } // foreach loop over entities | ||
569 | |||
570 | float[] sortedZHeights = z_sortheights.ToArray(); | ||
571 | uint[] sortedlocalIds = z_localIDs.ToArray(); | ||
572 | |||
573 | // Sort prim by Z position | ||
574 | Array.Sort(sortedZHeights, sortedlocalIds); | ||
575 | 579 | ||
576 | Graphics g = Graphics.FromImage(mapbmp); | 580 | // Sort prim by Z position |
581 | Array.Sort(sortedZHeights, sortedlocalIds); | ||
577 | 582 | ||
578 | for (int s = 0; s < sortedZHeights.Length; s++) | 583 | using (Graphics g = Graphics.FromImage(mapbmp)) |
579 | { | ||
580 | if (z_sort.ContainsKey(sortedlocalIds[s])) | ||
581 | { | 584 | { |
582 | DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; | 585 | for (int s = 0; s < sortedZHeights.Length; s++) |
583 | for (int r = 0; r < rectDrawStruct.trns.Length; r++) | ||
584 | { | 586 | { |
585 | g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); | 587 | if (z_sort.ContainsKey(sortedlocalIds[s])) |
588 | { | ||
589 | DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; | ||
590 | for (int r = 0; r < rectDrawStruct.trns.Length; r++) | ||
591 | { | ||
592 | g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); | ||
593 | } | ||
594 | //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); | ||
595 | } | ||
586 | } | 596 | } |
587 | //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); | ||
588 | } | 597 | } |
589 | } | 598 | } // lock entities objs |
590 | 599 | ||
591 | g.Dispose(); | 600 | } |
592 | } // lock entities objs | 601 | finally |
602 | { | ||
603 | foreach (DrawStruct ds in z_sort.Values) | ||
604 | ds.brush.Dispose(); | ||
605 | } | ||
593 | 606 | ||
594 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); | 607 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); |
608 | |||
595 | return mapbmp; | 609 | return mapbmp; |
596 | } | 610 | } |
597 | 611 | ||
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs index 992bff3..cb06fd4 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs | |||
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
54 | public void TerrainToBitmap(Bitmap mapbmp) | 54 | public void TerrainToBitmap(Bitmap mapbmp) |
55 | { | 55 | { |
56 | int tc = Environment.TickCount; | 56 | int tc = Environment.TickCount; |
57 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); | 57 | m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Terrain"); |
58 | 58 | ||
59 | double[,] hm = m_scene.Heightmap.GetDoubles(); | 59 | double[,] hm = m_scene.Heightmap.GetDoubles(); |
60 | bool ShadowDebugContinue = true; | 60 | bool ShadowDebugContinue = true; |
@@ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
199 | { | 199 | { |
200 | if (!terraincorruptedwarningsaid) | 200 | if (!terraincorruptedwarningsaid) |
201 | { | 201 | { |
202 | 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); | 202 | 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); |
203 | terraincorruptedwarningsaid = true; | 203 | terraincorruptedwarningsaid = true; |
204 | } | 204 | } |
205 | color = Color.Black; | 205 | color = Color.Black; |
@@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
229 | { | 229 | { |
230 | if (!terraincorruptedwarningsaid) | 230 | if (!terraincorruptedwarningsaid) |
231 | { | 231 | { |
232 | 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); | 232 | 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); |
233 | terraincorruptedwarningsaid = true; | 233 | terraincorruptedwarningsaid = true; |
234 | } | 234 | } |
235 | Color black = Color.Black; | 235 | Color black = Color.Black; |
@@ -238,7 +238,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
238 | } | 238 | } |
239 | } | 239 | } |
240 | } | 240 | } |
241 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 241 | |
242 | m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | ||
242 | } | 243 | } |
243 | } | 244 | } |
244 | } | 245 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs index d13c2ef..e895178 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs | |||
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
173 | private Bitmap fetchTexture(UUID id) | 173 | private Bitmap fetchTexture(UUID id) |
174 | { | 174 | { |
175 | AssetBase asset = m_scene.AssetService.Get(id.ToString()); | 175 | AssetBase asset = m_scene.AssetService.Get(id.ToString()); |
176 | m_log.DebugFormat("[TexturedMapTileRenderer]: Fetched texture {0}, found: {1}", id, asset != null); | 176 | m_log.DebugFormat("[TEXTURED MAP TILE RENDERER]: Fetched texture {0}, found: {1}", id, asset != null); |
177 | if (asset == null) return null; | 177 | if (asset == null) return null; |
178 | 178 | ||
179 | ManagedImage managedImage; | 179 | ManagedImage managedImage; |
@@ -188,17 +188,17 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
188 | } | 188 | } |
189 | catch (DllNotFoundException) | 189 | catch (DllNotFoundException) |
190 | { | 190 | { |
191 | m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); | 191 | m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); |
192 | 192 | ||
193 | } | 193 | } |
194 | catch (IndexOutOfRangeException) | 194 | catch (IndexOutOfRangeException) |
195 | { | 195 | { |
196 | m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); | 196 | m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); |
197 | 197 | ||
198 | } | 198 | } |
199 | catch (Exception) | 199 | catch (Exception) |
200 | { | 200 | { |
201 | m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); | 201 | m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); |
202 | 202 | ||
203 | } | 203 | } |
204 | return null; | 204 | return null; |
@@ -233,10 +233,14 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
233 | if (textureID == UUID.Zero) return defaultColor; // not set | 233 | if (textureID == UUID.Zero) return defaultColor; // not set |
234 | if (m_mapping.ContainsKey(textureID)) return m_mapping[textureID]; // one of the predefined textures | 234 | if (m_mapping.ContainsKey(textureID)) return m_mapping[textureID]; // one of the predefined textures |
235 | 235 | ||
236 | Bitmap bmp = fetchTexture(textureID); | 236 | Color color; |
237 | Color color = bmp == null ? defaultColor : computeAverageColor(bmp); | 237 | |
238 | // store it for future reference | 238 | using (Bitmap bmp = fetchTexture(textureID)) |
239 | m_mapping[textureID] = color; | 239 | { |
240 | color = bmp == null ? defaultColor : computeAverageColor(bmp); | ||
241 | // store it for future reference | ||
242 | m_mapping[textureID] = color; | ||
243 | } | ||
240 | 244 | ||
241 | return color; | 245 | return color; |
242 | } | 246 | } |
@@ -278,7 +282,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
278 | public void TerrainToBitmap(Bitmap mapbmp) | 282 | public void TerrainToBitmap(Bitmap mapbmp) |
279 | { | 283 | { |
280 | int tc = Environment.TickCount; | 284 | int tc = Environment.TickCount; |
281 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); | 285 | m_log.Debug("[TEXTURED MAP TILE RENDERER]: Generating Maptile Step 1: Terrain"); |
282 | 286 | ||
283 | // These textures should be in the AssetCache anyway, as every client conneting to this | 287 | // These textures should be in the AssetCache anyway, as every client conneting to this |
284 | // region needs them. Except on start, when the map is recreated (before anyone connected), | 288 | // region needs them. Except on start, when the map is recreated (before anyone connected), |
@@ -412,7 +416,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
412 | } | 416 | } |
413 | } | 417 | } |
414 | } | 418 | } |
415 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 419 | |
420 | m_log.Debug("[TEXTURED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | ||
416 | } | 421 | } |
417 | } | 422 | } |
418 | } | 423 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index a26a5f0..ddaf9fb 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -114,6 +114,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
114 | "export-map [<path>]", | 114 | "export-map [<path>]", |
115 | "Save an image of the world map", HandleExportWorldMapConsoleCommand); | 115 | "Save an image of the world map", HandleExportWorldMapConsoleCommand); |
116 | 116 | ||
117 | m_scene.AddCommand( | ||
118 | "Regions", this, "generate map", | ||
119 | "generate map", | ||
120 | "Generates and stores a new maptile.", HandleGenerateMapConsoleCommand); | ||
121 | |||
117 | AddHandlers(); | 122 | AddHandlers(); |
118 | } | 123 | } |
119 | } | 124 | } |
@@ -1255,6 +1260,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1255 | m_scene.RegionInfo.RegionName, exportPath); | 1260 | m_scene.RegionInfo.RegionName, exportPath); |
1256 | } | 1261 | } |
1257 | 1262 | ||
1263 | public void HandleGenerateMapConsoleCommand(string module, string[] cmdparams) | ||
1264 | { | ||
1265 | Scene consoleScene = m_scene.ConsoleScene(); | ||
1266 | |||
1267 | if (consoleScene != null && consoleScene != m_scene) | ||
1268 | return; | ||
1269 | |||
1270 | GenerateMaptile(); | ||
1271 | } | ||
1272 | |||
1258 | public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint) | 1273 | public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint) |
1259 | { | 1274 | { |
1260 | uint xstart = 0; | 1275 | uint xstart = 0; |
@@ -1486,62 +1501,69 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1486 | 1501 | ||
1487 | private Byte[] GenerateOverlay() | 1502 | private Byte[] GenerateOverlay() |
1488 | { | 1503 | { |
1489 | Bitmap overlay = new Bitmap(256, 256); | 1504 | using (Bitmap overlay = new Bitmap(256, 256)) |
1490 | |||
1491 | bool[,] saleBitmap = new bool[64, 64]; | ||
1492 | for (int x = 0 ; x < 64 ; x++) | ||
1493 | { | 1505 | { |
1494 | for (int y = 0 ; y < 64 ; y++) | 1506 | bool[,] saleBitmap = new bool[64, 64]; |
1495 | saleBitmap[x, y] = false; | 1507 | for (int x = 0 ; x < 64 ; x++) |
1496 | } | 1508 | { |
1497 | 1509 | for (int y = 0 ; y < 64 ; y++) | |
1498 | bool landForSale = false; | 1510 | saleBitmap[x, y] = false; |
1511 | } | ||
1499 | 1512 | ||
1500 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); | 1513 | bool landForSale = false; |
1501 | 1514 | ||
1502 | Color background = Color.FromArgb(0, 0, 0, 0); | 1515 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); |
1503 | SolidBrush transparent = new SolidBrush(background); | ||
1504 | Graphics g = Graphics.FromImage(overlay); | ||
1505 | g.FillRectangle(transparent, 0, 0, 256, 256); | ||
1506 | 1516 | ||
1507 | SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); | 1517 | Color background = Color.FromArgb(0, 0, 0, 0); |
1508 | 1518 | ||
1509 | foreach (ILandObject land in parcels) | 1519 | using (Graphics g = Graphics.FromImage(overlay)) |
1510 | { | ||
1511 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); | ||
1512 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||
1513 | { | 1520 | { |
1514 | landForSale = true; | 1521 | using (SolidBrush transparent = new SolidBrush(background)) |
1522 | g.FillRectangle(transparent, 0, 0, 256, 256); | ||
1515 | 1523 | ||
1516 | saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); | ||
1517 | } | ||
1518 | } | ||
1519 | 1524 | ||
1520 | if (!landForSale) | 1525 | foreach (ILandObject land in parcels) |
1521 | { | 1526 | { |
1522 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); | 1527 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); |
1523 | return null; | 1528 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) |
1524 | } | 1529 | { |
1530 | landForSale = true; | ||
1531 | |||
1532 | saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); | ||
1533 | } | ||
1534 | } | ||
1535 | |||
1536 | if (!landForSale) | ||
1537 | { | ||
1538 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); | ||
1539 | return null; | ||
1540 | } | ||
1525 | 1541 | ||
1526 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); | 1542 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); |
1527 | 1543 | ||
1528 | for (int x = 0 ; x < 64 ; x++) | 1544 | using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9))) |
1529 | { | 1545 | { |
1530 | for (int y = 0 ; y < 64 ; y++) | 1546 | for (int x = 0 ; x < 64 ; x++) |
1547 | { | ||
1548 | for (int y = 0 ; y < 64 ; y++) | ||
1549 | { | ||
1550 | if (saleBitmap[x, y]) | ||
1551 | g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | ||
1552 | } | ||
1553 | } | ||
1554 | } | ||
1555 | } | ||
1556 | |||
1557 | try | ||
1531 | { | 1558 | { |
1532 | if (saleBitmap[x, y]) | 1559 | return OpenJPEG.EncodeFromImage(overlay, true); |
1533 | g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | 1560 | } |
1561 | catch (Exception e) | ||
1562 | { | ||
1563 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1534 | } | 1564 | } |
1535 | } | 1565 | } |
1536 | 1566 | ||
1537 | try | ||
1538 | { | ||
1539 | return OpenJPEG.EncodeFromImage(overlay, true); | ||
1540 | } | ||
1541 | catch (Exception e) | ||
1542 | { | ||
1543 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1544 | } | ||
1545 | return null; | 1567 | return null; |
1546 | } | 1568 | } |
1547 | } | 1569 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7772f94..420c0b5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -3946,32 +3946,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
3946 | } | 3946 | } |
3947 | } | 3947 | } |
3948 | 3948 | ||
3949 | // m_log.DebugFormat( | ||
3950 | // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", | ||
3951 | // RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); | ||
3952 | |||
3949 | // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags | 3953 | // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags |
3950 | if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && | 3954 | if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && |
3951 | RegionInfo.EstateSettings.AllowDirectTeleport == false && | 3955 | RegionInfo.EstateSettings.AllowDirectTeleport == false && |
3952 | !viahome && !godlike) | 3956 | !viahome && !godlike) |
3953 | { | 3957 | { |
3954 | SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); | 3958 | SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); |
3955 | // Can have multiple SpawnPoints | 3959 | |
3956 | List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); | 3960 | if (telehub != null) |
3957 | if (spawnpoints.Count > 1) | ||
3958 | { | 3961 | { |
3959 | // We have multiple SpawnPoints, Route the agent to a random or sequential one | 3962 | // Can have multiple SpawnPoints |
3960 | if (SpawnPointRouting == "random") | 3963 | List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); |
3961 | acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( | 3964 | if (spawnpoints.Count > 1) |
3962 | telehub.AbsolutePosition, | 3965 | { |
3963 | telehub.GroupRotation | 3966 | // We have multiple SpawnPoints, Route the agent to a random or sequential one |
3964 | ); | 3967 | if (SpawnPointRouting == "random") |
3968 | acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( | ||
3969 | telehub.AbsolutePosition, | ||
3970 | telehub.GroupRotation | ||
3971 | ); | ||
3972 | else | ||
3973 | acd.startpos = spawnpoints[SpawnPoint()].GetLocation( | ||
3974 | telehub.AbsolutePosition, | ||
3975 | telehub.GroupRotation | ||
3976 | ); | ||
3977 | } | ||
3978 | else if (spawnpoints.Count == 1) | ||
3979 | { | ||
3980 | // We have a single SpawnPoint and will route the agent to it | ||
3981 | acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | ||
3982 | } | ||
3965 | else | 3983 | else |
3966 | acd.startpos = spawnpoints[SpawnPoint()].GetLocation( | 3984 | { |
3967 | telehub.AbsolutePosition, | 3985 | m_log.DebugFormat( |
3968 | telehub.GroupRotation | 3986 | "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.", |
3969 | ); | 3987 | RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); |
3988 | } | ||
3970 | } | 3989 | } |
3971 | else | 3990 | else |
3972 | { | 3991 | { |
3973 | // We have a single SpawnPoint and will route the agent to it | 3992 | m_log.DebugFormat( |
3974 | acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | 3993 | "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.", |
3994 | RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); | ||
3975 | } | 3995 | } |
3976 | 3996 | ||
3977 | return true; | 3997 | return true; |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7243db1..c2554d8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -108,6 +108,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | /// <summary> | ||
112 | /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and | ||
113 | /// the viewer fires these in quick succession. | ||
114 | /// </summary> | ||
115 | /// <remarks> | ||
116 | /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement | ||
117 | /// regulation done there. | ||
118 | /// </remarks> | ||
119 | private object m_completeMovementLock = new object(); | ||
120 | |||
111 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 121 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
112 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 122 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
113 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 123 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
@@ -904,6 +914,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
904 | /// <summary> | 914 | /// <summary> |
905 | /// Turns a child agent into a root agent. | 915 | /// Turns a child agent into a root agent. |
906 | /// </summary> | 916 | /// </summary> |
917 | /// <remarks> | ||
907 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the | 918 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the |
908 | /// avatar is actual in the sim. They can perform all actions. | 919 | /// avatar is actual in the sim. They can perform all actions. |
909 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, | 920 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, |
@@ -911,8 +922,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
911 | /// | 922 | /// |
912 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here | 923 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here |
913 | /// delays that crossing. | 924 | /// delays that crossing. |
914 | /// </summary> | 925 | /// </remarks> |
915 | private void MakeRootAgent(Vector3 pos, bool isFlying) | 926 | private bool MakeRootAgent(Vector3 pos, bool isFlying) |
916 | { | 927 | { |
917 | // m_log.InfoFormat( | 928 | // m_log.InfoFormat( |
918 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", | 929 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", |
@@ -920,7 +931,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
920 | 931 | ||
921 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | 932 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); |
922 | 933 | ||
923 | IsChildAgent = false; | 934 | lock (m_completeMovementLock) |
935 | { | ||
936 | if (!IsChildAgent) | ||
937 | return false; | ||
938 | |||
939 | IsChildAgent = false; | ||
940 | } | ||
924 | 941 | ||
925 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag | 942 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag |
926 | // set and prevent the close of the connection on a subsequent re-teleport. | 943 | // set and prevent the close of the connection on a subsequent re-teleport. |
@@ -1069,6 +1086,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1069 | 1086 | ||
1070 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1087 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1071 | 1088 | ||
1089 | return true; | ||
1072 | } | 1090 | } |
1073 | 1091 | ||
1074 | public int GetStateSource() | 1092 | public int GetStateSource() |
@@ -1442,7 +1460,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1442 | } | 1460 | } |
1443 | 1461 | ||
1444 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1462 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1445 | MakeRootAgent(AbsolutePosition, flying); | 1463 | if (!MakeRootAgent(AbsolutePosition, flying)) |
1464 | { | ||
1465 | m_log.DebugFormat( | ||
1466 | "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", | ||
1467 | Name, Scene.Name); | ||
1468 | |||
1469 | return; | ||
1470 | } | ||
1446 | 1471 | ||
1447 | // Tell the client that we're totally ready | 1472 | // Tell the client that we're totally ready |
1448 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | 1473 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index d1aeaee..1ff1329 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs | |||
@@ -111,6 +111,45 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
111 | Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1)); | 111 | Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1)); |
112 | } | 112 | } |
113 | 113 | ||
114 | /// <summary> | ||
115 | /// Test that duplicate complete movement calls are ignored. | ||
116 | /// </summary> | ||
117 | /// <remarks> | ||
118 | /// If duplicate calls are not ignored then there is a risk of race conditions or other unexpected effects. | ||
119 | /// </remarks> | ||
120 | [Test] | ||
121 | public void TestDupeCompleteMovementCalls() | ||
122 | { | ||
123 | TestHelpers.InMethod(); | ||
124 | // TestHelpers.EnableLogging(); | ||
125 | |||
126 | UUID spUuid = TestHelpers.ParseTail(0x1); | ||
127 | |||
128 | TestScene scene = new SceneHelpers().SetupScene(); | ||
129 | |||
130 | int makeRootAgentEvents = 0; | ||
131 | scene.EventManager.OnMakeRootAgent += spi => makeRootAgentEvents++; | ||
132 | |||
133 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, spUuid); | ||
134 | |||
135 | Assert.That(makeRootAgentEvents, Is.EqualTo(1)); | ||
136 | |||
137 | // Normally these would be invoked by a CompleteMovement message coming in to the UDP stack. But for | ||
138 | // convenience, here we will invoke it manually. | ||
139 | sp.CompleteMovement(sp.ControllingClient, true); | ||
140 | |||
141 | Assert.That(makeRootAgentEvents, Is.EqualTo(1)); | ||
142 | |||
143 | // Check rest of exepcted parameters. | ||
144 | Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null); | ||
145 | Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); | ||
146 | |||
147 | Assert.That(sp.IsChildAgent, Is.False); | ||
148 | Assert.That(sp.UUID, Is.EqualTo(spUuid)); | ||
149 | |||
150 | Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1)); | ||
151 | } | ||
152 | |||
114 | [Test] | 153 | [Test] |
115 | public void TestCreateDuplicateRootScenePresence() | 154 | public void TestCreateDuplicateRootScenePresence() |
116 | { | 155 | { |
@@ -249,58 +288,5 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
249 | // Assert.That(childPresence, Is.Not.Null); | 288 | // Assert.That(childPresence, Is.Not.Null); |
250 | // Assert.That(childPresence.IsChildAgent, Is.True); | 289 | // Assert.That(childPresence.IsChildAgent, Is.True); |
251 | } | 290 | } |
252 | |||
253 | // /// <summary> | ||
254 | // /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene. | ||
255 | // /// </summary> | ||
256 | // [Test] | ||
257 | // public void T010_TestAddRootAgent() | ||
258 | // { | ||
259 | // TestHelpers.InMethod(); | ||
260 | // | ||
261 | // string firstName = "testfirstname"; | ||
262 | // | ||
263 | // AgentCircuitData agent = new AgentCircuitData(); | ||
264 | // agent.AgentID = agent1; | ||
265 | // agent.firstname = firstName; | ||
266 | // agent.lastname = "testlastname"; | ||
267 | // agent.SessionID = UUID.Random(); | ||
268 | // agent.SecureSessionID = UUID.Random(); | ||
269 | // agent.circuitcode = 123; | ||
270 | // agent.BaseFolder = UUID.Zero; | ||
271 | // agent.InventoryFolder = UUID.Zero; | ||
272 | // agent.startpos = Vector3.Zero; | ||
273 | // agent.CapsPath = GetRandomCapsObjectPath(); | ||
274 | // agent.ChildrenCapSeeds = new Dictionary<ulong, string>(); | ||
275 | // agent.child = true; | ||
276 | // | ||
277 | // scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID); | ||
278 | // | ||
279 | // string reason; | ||
280 | // scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason); | ||
281 | // testclient = new TestClient(agent, scene); | ||
282 | // scene.AddNewAgent(testclient); | ||
283 | // | ||
284 | // ScenePresence presence = scene.GetScenePresence(agent1); | ||
285 | // | ||
286 | // Assert.That(presence, Is.Not.Null, "presence is null"); | ||
287 | // Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same"); | ||
288 | // acd1 = agent; | ||
289 | // } | ||
290 | // | ||
291 | // /// <summary> | ||
292 | // /// Test removing an uncrossed root agent from a scene. | ||
293 | // /// </summary> | ||
294 | // [Test] | ||
295 | // public void T011_TestRemoveRootAgent() | ||
296 | // { | ||
297 | // TestHelpers.InMethod(); | ||
298 | // | ||
299 | // scene.RemoveClient(agent1); | ||
300 | // | ||
301 | // ScenePresence presence = scene.GetScenePresence(agent1); | ||
302 | // | ||
303 | // Assert.That(presence, Is.Null, "presence is not null"); | ||
304 | // } | ||
305 | } | 291 | } |
306 | } \ No newline at end of file | 292 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs new file mode 100644 index 0000000..9a97acc --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | * Redistribution and use in source and binary forms, with or without | ||
3 | * modification, are permitted provided that the following conditions are met: | ||
4 | * * Redistributions of source code must retain the above copyright | ||
5 | * notice, this list of conditions and the following disclaimer. | ||
6 | * * Redistributions in binary form must reproduce the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer in the | ||
8 | * documentation and/or other materials provided with the distribution. | ||
9 | * * Neither the name of the OpenSimulator Project nor the | ||
10 | * names of its contributors may be used to endorse or promote products | ||
11 | * derived from this software without specific prior written permission. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
16 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
17 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
18 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
19 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
20 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
22 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | using System; | ||
26 | using Nini.Config; | ||
27 | using NUnit.Framework; | ||
28 | using OpenMetaverse; | ||
29 | using OpenSim.Framework; | ||
30 | using OpenSim.Region.CoreModules.World.Estate; | ||
31 | using OpenSim.Region.Framework.Scenes; | ||
32 | using OpenSim.Region.Framework.Interfaces; | ||
33 | using OpenSim.Services.Interfaces; | ||
34 | using OpenSim.Tests.Common; | ||
35 | using OpenSim.Tests.Common.Mock; | ||
36 | |||
37 | namespace OpenSim.Region.Framework.Scenes.Tests | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// Scene telehub tests | ||
41 | /// </summary> | ||
42 | /// <remarks> | ||
43 | /// TODO: Tests which run through normal functionality. Currently, the only test is one that checks behaviour | ||
44 | /// in the case of an error condition | ||
45 | /// </remarks> | ||
46 | [TestFixture] | ||
47 | public class SceneTelehubTests : OpenSimTestCase | ||
48 | { | ||
49 | /// <summary> | ||
50 | /// Test for desired behaviour when a telehub has no spawn points | ||
51 | /// </summary> | ||
52 | [Test] | ||
53 | public void TestNoTelehubSpawnPoints() | ||
54 | { | ||
55 | TestHelpers.InMethod(); | ||
56 | // TestHelpers.EnableLogging(); | ||
57 | |||
58 | EstateManagementModule emm = new EstateManagementModule(); | ||
59 | |||
60 | SceneHelpers sh = new SceneHelpers(); | ||
61 | Scene scene = sh.SetupScene(); | ||
62 | SceneHelpers.SetupSceneModules(scene, emm); | ||
63 | |||
64 | UUID telehubSceneObjectOwner = TestHelpers.ParseTail(0x1); | ||
65 | |||
66 | SceneObjectGroup telehubSo = SceneHelpers.AddSceneObject(scene, "telehubObject", telehubSceneObjectOwner); | ||
67 | |||
68 | emm.HandleOnEstateManageTelehub(null, UUID.Zero, UUID.Zero, "connect", telehubSo.LocalId); | ||
69 | scene.RegionInfo.EstateSettings.AllowDirectTeleport = false; | ||
70 | |||
71 | // Must still be possible to successfully log in | ||
72 | UUID loggingInUserId = TestHelpers.ParseTail(0x2); | ||
73 | |||
74 | UserAccount ua | ||
75 | = UserAccountHelpers.CreateUserWithInventory(scene, "Test", "User", loggingInUserId, "password"); | ||
76 | |||
77 | SceneHelpers.AddScenePresence(scene, ua); | ||
78 | |||
79 | Assert.That(scene.GetScenePresence(loggingInUserId), Is.Not.Null); | ||
80 | } | ||
81 | |||
82 | /// <summary> | ||
83 | /// Test for desired behaviour when the scene object nominated as a telehub object does not exist. | ||
84 | /// </summary> | ||
85 | [Test] | ||
86 | public void TestNoTelehubSceneObject() | ||
87 | { | ||
88 | TestHelpers.InMethod(); | ||
89 | // TestHelpers.EnableLogging(); | ||
90 | |||
91 | EstateManagementModule emm = new EstateManagementModule(); | ||
92 | |||
93 | SceneHelpers sh = new SceneHelpers(); | ||
94 | Scene scene = sh.SetupScene(); | ||
95 | SceneHelpers.SetupSceneModules(scene, emm); | ||
96 | |||
97 | UUID telehubSceneObjectOwner = TestHelpers.ParseTail(0x1); | ||
98 | |||
99 | SceneObjectGroup telehubSo = SceneHelpers.AddSceneObject(scene, "telehubObject", telehubSceneObjectOwner); | ||
100 | SceneObjectGroup spawnPointSo = SceneHelpers.AddSceneObject(scene, "spawnpointObject", telehubSceneObjectOwner); | ||
101 | |||
102 | emm.HandleOnEstateManageTelehub(null, UUID.Zero, UUID.Zero, "connect", telehubSo.LocalId); | ||
103 | emm.HandleOnEstateManageTelehub(null, UUID.Zero, UUID.Zero, "spawnpoint add", spawnPointSo.LocalId); | ||
104 | scene.RegionInfo.EstateSettings.AllowDirectTeleport = false; | ||
105 | |||
106 | scene.DeleteSceneObject(telehubSo, false); | ||
107 | |||
108 | // Must still be possible to successfully log in | ||
109 | UUID loggingInUserId = TestHelpers.ParseTail(0x2); | ||
110 | |||
111 | UserAccount ua | ||
112 | = UserAccountHelpers.CreateUserWithInventory(scene, "Test", "User", loggingInUserId, "password"); | ||
113 | |||
114 | SceneHelpers.AddScenePresence(scene, ua); | ||
115 | |||
116 | Assert.That(scene.GetScenePresence(loggingInUserId), Is.Not.Null); | ||
117 | } | ||
118 | } | ||
119 | } \ No newline at end of file | ||
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 9370102..a4247e3 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs | |||
@@ -788,11 +788,6 @@ namespace OpenSim.Tests.Common.Mock | |||
788 | { | 788 | { |
789 | OnRegionHandShakeReply(this); | 789 | OnRegionHandShakeReply(this); |
790 | } | 790 | } |
791 | |||
792 | if (OnCompleteMovementToRegion != null) | ||
793 | { | ||
794 | OnCompleteMovementToRegion(this, true); | ||
795 | } | ||
796 | } | 791 | } |
797 | 792 | ||
798 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) | 793 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) |
diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index a684d72..6bf23f8 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs | |||
@@ -117,8 +117,6 @@ namespace OpenSim.Tests.Common | |||
117 | /// Parse a UUID stem into a full UUID. | 117 | /// Parse a UUID stem into a full UUID. |
118 | /// </summary> | 118 | /// </summary> |
119 | /// <remarks> | 119 | /// <remarks> |
120 | /// Yes, this is completely inconsistent with ParseTail but this is probably a better way to do it, | ||
121 | /// UUIDs are conceptually not hexadecmial numbers. | ||
122 | /// The fragment will come at the start of the UUID. The rest will be 0s | 120 | /// The fragment will come at the start of the UUID. The rest will be 0s |
123 | /// </remarks> | 121 | /// </remarks> |
124 | /// <returns></returns> | 122 | /// <returns></returns> |
@@ -143,5 +141,24 @@ namespace OpenSim.Tests.Common | |||
143 | { | 141 | { |
144 | return new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", tail)); | 142 | return new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", tail)); |
145 | } | 143 | } |
144 | |||
145 | /// <summary> | ||
146 | /// Parse a UUID tail section into a full UUID. | ||
147 | /// </summary> | ||
148 | /// <remarks> | ||
149 | /// The fragment will come at the end of the UUID. The rest will be 0s | ||
150 | /// </remarks> | ||
151 | /// <returns></returns> | ||
152 | /// <param name='frag'> | ||
153 | /// A UUID fragment that will be parsed into a full UUID. Therefore, it can only contain | ||
154 | /// cahracters which are valid in a UUID, except for "-" which is currently only allowed if a full UUID is | ||
155 | /// given as the 'fragment'. | ||
156 | /// </param> | ||
157 | public static UUID ParseTail(string stem) | ||
158 | { | ||
159 | string rawUuid = stem.PadLeft(32, '0'); | ||
160 | |||
161 | return UUID.Parse(rawUuid); | ||
162 | } | ||
146 | } | 163 | } |
147 | } | 164 | } |