aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs307
1 files changed, 148 insertions, 159 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index a39f27a..6246400 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -81,10 +81,7 @@ namespace OpenSim.Region.Framework.Scenes
81 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); 81 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
82 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); 82 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
83 83
84 // SceneObjects is not currently populated or used.
85 //public Dictionary<UUID, SceneObjectGroup> SceneObjects;
86 protected internal EntityManager Entities = new EntityManager(); 84 protected internal EntityManager Entities = new EntityManager();
87// protected internal Dictionary<UUID, EntityBase> Entities = new Dictionary<UUID, EntityBase>();
88 protected internal Dictionary<UUID, ScenePresence> RestorePresences = new Dictionary<UUID, ScenePresence>(); 85 protected internal Dictionary<UUID, ScenePresence> RestorePresences = new Dictionary<UUID, ScenePresence>();
89 86
90 protected RegionInfo m_regInfo; 87 protected RegionInfo m_regInfo;
@@ -323,7 +320,7 @@ namespace OpenSim.Region.Framework.Scenes
323 /// <param name="pos">Position of the object</param> 320 /// <param name="pos">Position of the object</param>
324 /// <param name="rot">Rotation of the object</param> 321 /// <param name="rot">Rotation of the object</param>
325 /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param> 322 /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param>
326 /// <returns></returns> 323 /// <returns></returns>
327 public bool AddNewSceneObject( 324 public bool AddNewSceneObject(
328 SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) 325 SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel)
329 { 326 {
@@ -347,7 +344,7 @@ namespace OpenSim.Region.Framework.Scenes
347 } 344 }
348 345
349 return true; 346 return true;
350 } 347 }
351 348
352 /// <summary> 349 /// <summary>
353 /// Add an object to the scene. This will both update the scene, and send information about the 350 /// Add an object to the scene. This will both update the scene, and send information about the
@@ -370,68 +367,57 @@ namespace OpenSim.Region.Framework.Scenes
370 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) 367 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
371 return false; 368 return false;
372 369
373 lock (sceneObject) 370 if (Entities.ContainsKey(sceneObject.UUID))
374 { 371 return false;
375 if (Entities.ContainsKey(sceneObject.UUID)) 372
376 { 373 List<SceneObjectPart> children;
377// m_log.WarnFormat( 374 lock (sceneObject.Children)
378// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request", 375 children = new List<SceneObjectPart>(sceneObject.Children.Values);
379// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); 376
380 return false; 377 // Clamp child prim sizes and add child prims to the m_numPrim count
381 } 378 if (m_parentScene.m_clampPrimSize)
382 379 {
383// m_log.DebugFormat( 380 foreach (SceneObjectPart part in children)
384// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
385// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
386
387 lock (sceneObject.Children)
388 { 381 {
389 if (m_parentScene.m_clampPrimSize) 382 Vector3 scale = part.Shape.Scale;
390 { 383
391 foreach (SceneObjectPart part in sceneObject.Children.Values) 384 if (scale.X > m_parentScene.m_maxNonphys)
392 { 385 scale.X = m_parentScene.m_maxNonphys;
393 Vector3 scale = part.Shape.Scale; 386 if (scale.Y > m_parentScene.m_maxNonphys)
394 387 scale.Y = m_parentScene.m_maxNonphys;
395 if (scale.X > m_parentScene.m_maxNonphys) 388 if (scale.Z > m_parentScene.m_maxNonphys)
396 scale.X = m_parentScene.m_maxNonphys; 389 scale.Z = m_parentScene.m_maxNonphys;
397 if (scale.Y > m_parentScene.m_maxNonphys) 390
398 scale.Y = m_parentScene.m_maxNonphys; 391 part.Shape.Scale = scale;
399 if (scale.Z > m_parentScene.m_maxNonphys)
400 scale.Z = m_parentScene.m_maxNonphys;
401
402 part.Shape.Scale = scale;
403 }
404 }
405
406 m_numPrim += sceneObject.Children.Count;
407 } 392 }
408 393 }
409 sceneObject.AttachToScene(m_parentScene); 394 m_numPrim += children.Count;
410 395
411 if (sendClientUpdates) 396 sceneObject.AttachToScene(m_parentScene);
412 sceneObject.ScheduleGroupForFullUpdate();
413
414 Entities.Add(sceneObject);
415 397
416 if (attachToBackup) 398 if (sendClientUpdates)
417 sceneObject.AttachToBackup(); 399 sceneObject.ScheduleGroupForFullUpdate();
418 400
419 if (OnObjectCreate != null) 401 Entities.Add(sceneObject);
420 OnObjectCreate(sceneObject); 402
421 403 if (attachToBackup)
422 lock (SceneObjectGroupsByFullID) 404 sceneObject.AttachToBackup();
423 { 405
424 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; 406 if (OnObjectCreate != null)
425 foreach (SceneObjectPart part in sceneObject.Children.Values) 407 OnObjectCreate(sceneObject);
426 SceneObjectGroupsByFullID[part.UUID] = sceneObject; 408
427 } 409 lock (SceneObjectGroupsByFullID)
428 410 {
429 lock (SceneObjectGroupsByLocalID) 411 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
430 { 412 foreach (SceneObjectPart part in children)
431 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; 413 SceneObjectGroupsByFullID[part.UUID] = sceneObject;
432 foreach (SceneObjectPart part in sceneObject.Children.Values) 414 }
433 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; 415
434 } 416 lock (SceneObjectGroupsByLocalID)
417 {
418 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
419 foreach (SceneObjectPart part in children)
420 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
435 } 421 }
436 422
437 return true; 423 return true;
@@ -443,42 +429,38 @@ namespace OpenSim.Region.Framework.Scenes
443 /// <returns>true if the object was deleted, false if there was no object to delete</returns> 429 /// <returns>true if the object was deleted, false if there was no object to delete</returns>
444 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) 430 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
445 { 431 {
446 if (Entities.ContainsKey(uuid)) 432 EntityBase entity;
447 { 433 if (!Entities.TryGetValue(uuid, out entity) && entity is SceneObjectGroup)
448 SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; 434 return false;
449 435
450 if (!resultOfObjectLinked) 436 SceneObjectGroup grp = (SceneObjectGroup)entity;
451 {
452 m_numPrim -= grp.PrimCount;
453 437
454 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 438 if (!resultOfObjectLinked)
455 RemovePhysicalPrim(grp.PrimCount); 439 {
456 } 440 m_numPrim -= grp.PrimCount;
457 441
458 if (OnObjectRemove != null) 442 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
459 OnObjectRemove(Entities[uuid]); 443 RemovePhysicalPrim(grp.PrimCount);
444 }
460 445
461 lock (SceneObjectGroupsByFullID) 446 if (OnObjectRemove != null)
462 { 447 OnObjectRemove(Entities[uuid]);
463 foreach (SceneObjectPart part in grp.Children.Values)
464 SceneObjectGroupsByFullID.Remove(part.UUID);
465 SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
466 }
467 lock (SceneObjectGroupsByLocalID)
468 {
469 foreach (SceneObjectPart part in grp.Children.Values)
470 SceneObjectGroupsByLocalID.Remove(part.LocalId);
471 SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
472 }
473 448
474 Entities.Remove(uuid); 449 lock (SceneObjectGroupsByFullID)
475 //SceneObjectGroup part; 450 {
476 //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 451 foreach (SceneObjectPart part in grp.Children.Values)
452 SceneObjectGroupsByFullID.Remove(part.UUID);
453 SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
454 }
477 455
478 return true; 456 lock (SceneObjectGroupsByLocalID)
457 {
458 foreach (SceneObjectPart part in grp.Children.Values)
459 SceneObjectGroupsByLocalID.Remove(part.LocalId);
460 SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
479 } 461 }
480 462
481 return false; 463 return Entities.Remove(uuid);
482 } 464 }
483 465
484 /// <summary> 466 /// <summary>
@@ -490,9 +472,7 @@ namespace OpenSim.Region.Framework.Scenes
490 protected internal void AddToUpdateList(SceneObjectGroup obj) 472 protected internal void AddToUpdateList(SceneObjectGroup obj)
491 { 473 {
492 lock (m_updateList) 474 lock (m_updateList)
493 {
494 m_updateList[obj.UUID] = obj; 475 m_updateList[obj.UUID] = obj;
495 }
496 } 476 }
497 477
498 public void FireAttachToBackup(SceneObjectGroup obj) 478 public void FireAttachToBackup(SceneObjectGroup obj)
@@ -526,34 +506,39 @@ namespace OpenSim.Region.Framework.Scenes
526 { 506 {
527 if (!Monitor.TryEnter(m_updateLock)) 507 if (!Monitor.TryEnter(m_updateLock))
528 return; 508 return;
529 509 try
530 List<SceneObjectGroup> updates;
531
532 // Some updates add more updates to the updateList.
533 // Get the current list of updates and clear the list before iterating
534 lock (m_updateList)
535 {
536 updates = new List<SceneObjectGroup>(m_updateList.Values);
537 m_updateList.Clear();
538 }
539
540 // Go through all updates
541 for (int i = 0; i < updates.Count; i++)
542 { 510 {
543 SceneObjectGroup sog = updates[i]; 511 List<SceneObjectGroup> updates;
544 512
545 // Don't abort the whole update if one entity happens to give us an exception. 513 // Some updates add more updates to the updateList.
546 try 514 // Get the current list of updates and clear the list before iterating
515 lock (m_updateList)
547 { 516 {
548 sog.Update(); 517 updates = new List<SceneObjectGroup>(m_updateList.Values);
518 m_updateList.Clear();
549 } 519 }
550 catch (Exception e) 520
521 // Go through all updates
522 for (int i = 0; i < updates.Count; i++)
551 { 523 {
552 m_log.ErrorFormat( 524 SceneObjectGroup sog = updates[i];
553 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); 525
526 // Don't abort the whole update if one entity happens to give us an exception.
527 try
528 {
529 sog.Update();
530 }
531 catch (Exception e)
532 {
533 m_log.ErrorFormat(
534 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
535 }
554 } 536 }
555 } 537 }
556 Monitor.Exit(m_updateLock); 538 finally
539 {
540 Monitor.Exit(m_updateLock);
541 }
557 } 542 }
558 543
559 protected internal void AddPhysicalPrim(int number) 544 protected internal void AddPhysicalPrim(int number)
@@ -920,38 +905,38 @@ namespace OpenSim.Region.Framework.Scenes
920 /// <returns>null if no scene object group containing that prim is found</returns> 905 /// <returns>null if no scene object group containing that prim is found</returns>
921 public SceneObjectGroup GetGroupByPrim(uint localID) 906 public SceneObjectGroup GetGroupByPrim(uint localID)
922 { 907 {
923 if (Entities.ContainsKey(localID)) 908 EntityBase entity;
924 return Entities[localID] as SceneObjectGroup; 909 if (Entities.TryGetValue(localID, out entity))
910 return entity as SceneObjectGroup;
925 911
926 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); 912 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
927 SceneObjectGroup sog; 913 SceneObjectGroup sog;
928 lock (SceneObjectGroupsByLocalID) 914 lock (SceneObjectGroupsByLocalID)
915 SceneObjectGroupsByLocalID.TryGetValue(localID, out sog);
916
917 if (sog != null)
929 { 918 {
930 if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) 919 if (sog.HasChildPrim(localID))
931 { 920 return sog;
932 if (sog.HasChildPrim(localID)) 921 SceneObjectGroupsByLocalID.Remove(localID);
933 return sog;
934 SceneObjectGroupsByLocalID.Remove(localID);
935 }
936 } 922 }
937 923
938 List<EntityBase> EntityList = GetEntities(); 924 EntityBase[] entityList = GetEntities();
939 foreach (EntityBase ent in EntityList) 925 foreach (EntityBase ent in entityList)
940 { 926 {
941 //m_log.DebugFormat("Looking at entity {0}", ent.UUID); 927 //m_log.DebugFormat("Looking at entity {0}", ent.UUID);
942 if (ent is SceneObjectGroup) 928 if (ent is SceneObjectGroup)
943 { 929 {
944 if (((SceneObjectGroup)ent).HasChildPrim(localID)) 930 sog = (SceneObjectGroup)ent;
931 if (sog.HasChildPrim(localID))
945 { 932 {
946 sog = (SceneObjectGroup)ent;
947 lock (SceneObjectGroupsByLocalID) 933 lock (SceneObjectGroupsByLocalID)
948 {
949 SceneObjectGroupsByLocalID[localID] = sog; 934 SceneObjectGroupsByLocalID[localID] = sog;
950 }
951 return sog; 935 return sog;
952 } 936 }
953 } 937 }
954 } 938 }
939
955 return null; 940 return null;
956 } 941 }
957 942
@@ -964,36 +949,35 @@ namespace OpenSim.Region.Framework.Scenes
964 { 949 {
965 SceneObjectGroup sog; 950 SceneObjectGroup sog;
966 lock (SceneObjectGroupsByFullID) 951 lock (SceneObjectGroupsByFullID)
952 SceneObjectGroupsByFullID.TryGetValue(fullID, out sog);
953
954 if (sog != null)
967 { 955 {
968 if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) 956 lock (sog.Children)
969 { 957 {
970 lock (sog.Children) 958 if (sog.Children.ContainsKey(fullID))
971 { 959 return sog;
972 if (sog.Children.ContainsKey(fullID))
973 return sog;
974 }
975
976 SceneObjectGroupsByFullID.Remove(fullID);
977 } 960 }
978 }
979 961
980 List<EntityBase> EntityList = GetEntities(); 962 lock (SceneObjectGroupsByFullID)
963 SceneObjectGroupsByFullID.Remove(fullID);
964 }
981 965
982 foreach (EntityBase ent in EntityList) 966 EntityBase[] entityList = GetEntities();
967 foreach (EntityBase ent in entityList)
983 { 968 {
984 if (ent is SceneObjectGroup) 969 if (ent is SceneObjectGroup)
985 { 970 {
986 if (((SceneObjectGroup)ent).HasChildPrim(fullID)) 971 sog = (SceneObjectGroup)ent;
972 if (sog.HasChildPrim(fullID))
987 { 973 {
988 sog = (SceneObjectGroup)ent;
989 lock (SceneObjectGroupsByFullID) 974 lock (SceneObjectGroupsByFullID)
990 {
991 SceneObjectGroupsByFullID[fullID] = sog; 975 SceneObjectGroupsByFullID[fullID] = sog;
992 }
993 return sog; 976 return sog;
994 } 977 }
995 } 978 }
996 } 979 }
980
997 return null; 981 return null;
998 } 982 }
999 983
@@ -1002,7 +986,7 @@ namespace OpenSim.Region.Framework.Scenes
1002 // Primitive Ray Tracing 986 // Primitive Ray Tracing
1003 float closestDistance = 280f; 987 float closestDistance = 280f;
1004 EntityIntersection result = new EntityIntersection(); 988 EntityIntersection result = new EntityIntersection();
1005 List<EntityBase> EntityList = GetEntities(); 989 EntityBase[] EntityList = GetEntities();
1006 foreach (EntityBase ent in EntityList) 990 foreach (EntityBase ent in EntityList)
1007 { 991 {
1008 if (ent is SceneObjectGroup) 992 if (ent is SceneObjectGroup)
@@ -1040,23 +1024,28 @@ namespace OpenSim.Region.Framework.Scenes
1040 /// <returns>null if the part was not found</returns> 1024 /// <returns>null if the part was not found</returns>
1041 protected internal SceneObjectPart GetSceneObjectPart(string name) 1025 protected internal SceneObjectPart GetSceneObjectPart(string name)
1042 { 1026 {
1043 List<EntityBase> EntityList = GetEntities(); 1027 SceneObjectPart sop = null;
1044 1028
1045 // FIXME: use a dictionary here 1029 Entities.Find(
1046 foreach (EntityBase ent in EntityList) 1030 delegate(EntityBase entity)
1047 {
1048 if (ent is SceneObjectGroup)
1049 { 1031 {
1050 foreach (SceneObjectPart p in ((SceneObjectGroup) ent).GetParts()) 1032 if (entity is SceneObjectGroup)
1051 { 1033 {
1052 if (p.Name == name) 1034 foreach (SceneObjectPart p in ((SceneObjectGroup)entity).GetParts())
1053 { 1035 {
1054 return p; 1036 if (p.Name == name)
1037 {
1038 sop = p;
1039 return true;
1040 }
1055 } 1041 }
1056 } 1042 }
1043
1044 return false;
1057 } 1045 }
1058 } 1046 );
1059 return null; 1047
1048 return sop;
1060 } 1049 }
1061 1050
1062 /// <summary> 1051 /// <summary>
@@ -1077,7 +1066,7 @@ namespace OpenSim.Region.Framework.Scenes
1077 /// it 1066 /// it
1078 /// </summary> 1067 /// </summary>
1079 /// <returns></returns> 1068 /// <returns></returns>
1080 protected internal List<EntityBase> GetEntities() 1069 protected internal EntityBase[] GetEntities()
1081 { 1070 {
1082 return Entities.GetEntities(); 1071 return Entities.GetEntities();
1083 } 1072 }
@@ -1086,7 +1075,7 @@ namespace OpenSim.Region.Framework.Scenes
1086 { 1075 {
1087 Dictionary<uint, float> topScripts = new Dictionary<uint, float>(); 1076 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1088 1077
1089 List<EntityBase> EntityList = GetEntities(); 1078 EntityBase[] EntityList = GetEntities();
1090 int limit = 0; 1079 int limit = 0;
1091 foreach (EntityBase ent in EntityList) 1080 foreach (EntityBase ent in EntityList)
1092 { 1081 {
@@ -1140,7 +1129,7 @@ namespace OpenSim.Region.Framework.Scenes
1140 /// <param name="action"></param> 1129 /// <param name="action"></param>
1141 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1130 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1142 { 1131 {
1143 List<EntityBase> objlist = Entities.GetAllByType<SceneObjectGroup>(); 1132 EntityBase[] objlist = Entities.GetAllByType<SceneObjectGroup>();
1144 foreach (EntityBase ent in objlist) 1133 foreach (EntityBase ent in objlist)
1145 { 1134 {
1146 SceneObjectGroup obj = (SceneObjectGroup)ent; 1135 SceneObjectGroup obj = (SceneObjectGroup)ent;
@@ -1353,7 +1342,7 @@ namespace OpenSim.Region.Framework.Scenes
1353 SceneObjectGroup group = GetGroupByPrim(localID); 1342 SceneObjectGroup group = GetGroupByPrim(localID);
1354 1343
1355 if (group != null) 1344 if (group != null)
1356 { 1345 {
1357 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1346 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1358 { 1347 {
1359 if (m_parentScene.AttachmentsModule != null) 1348 if (m_parentScene.AttachmentsModule != null)
@@ -1798,8 +1787,8 @@ namespace OpenSim.Region.Framework.Scenes
1798 UUID objid = UUID.Zero; 1787 UUID objid = UUID.Zero;
1799 SceneObjectPart obj = null; 1788 SceneObjectPart obj = null;
1800 1789
1801 List<EntityBase> EntityList = GetEntities(); 1790 EntityBase[] entityList = GetEntities();
1802 foreach (EntityBase ent in EntityList) 1791 foreach (EntityBase ent in entityList)
1803 { 1792 {
1804 if (ent is SceneObjectGroup) 1793 if (ent is SceneObjectGroup)
1805 { 1794 {