aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs16
-rwxr-xr-xOpenSim/Region/Framework/Scenes/SceneGraph.cs797
2 files changed, 434 insertions, 379 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 252ae21..aac791d 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2796,12 +2796,6 @@ namespace OpenSim.Region.Framework.Scenes
2796 return false; 2796 return false;
2797 } 2797 }
2798 2798
2799
2800 public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp)
2801 {
2802 m_sceneGraph.updateScenePartGroup(part, grp);
2803 }
2804
2805/* not in use, outdate by async method 2799/* not in use, outdate by async method
2806 /// <summary> 2800 /// <summary>
2807 /// Move the given scene object into a new region depending on which region its absolute position has moved 2801 /// Move the given scene object into a new region depending on which region its absolute position has moved
@@ -5065,16 +5059,6 @@ Label_GroupsDone:
5065 5059
5066 #region SceneGraph wrapper methods 5060 #region SceneGraph wrapper methods
5067 5061
5068 /// <summary>
5069 ///
5070 /// </summary>
5071 /// <param name="localID"></param>
5072 /// <returns></returns>
5073 public UUID ConvertLocalIDToFullID(uint localID)
5074 {
5075 return m_sceneGraph.ConvertLocalIDToFullID(localID);
5076 }
5077
5078 public void SwapRootAgentCount(bool rootChildChildRootTF) 5062 public void SwapRootAgentCount(bool rootChildChildRootTF)
5079 { 5063 {
5080 m_sceneGraph.SwapRootChildAgent(rootChildChildRootTF); 5064 m_sceneGraph.SwapRootChildAgent(rootChildChildRootTF);
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index e37841f..17efcc5 100755
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -41,7 +41,6 @@ using OpenSim.Region.Framework.Interfaces;
41namespace OpenSim.Region.Framework.Scenes 41namespace OpenSim.Region.Framework.Scenes
42{ 42{
43 public delegate void PhysicsCrash(); 43 public delegate void PhysicsCrash();
44
45 public delegate void AttachToBackupDelegate(SceneObjectGroup sog); 44 public delegate void AttachToBackupDelegate(SceneObjectGroup sog);
46 public delegate void DetachFromBackupDelegate(SceneObjectGroup sog); 45 public delegate void DetachFromBackupDelegate(SceneObjectGroup sog);
47 public delegate void ChangedBackupDelegate(SceneObjectGroup sog); 46 public delegate void ChangedBackupDelegate(SceneObjectGroup sog);
@@ -58,7 +57,6 @@ namespace OpenSim.Region.Framework.Scenes
58 57
59 protected internal event PhysicsCrash UnRecoverableError; 58 protected internal event PhysicsCrash UnRecoverableError;
60 private PhysicsCrash handlerPhysicsCrash = null; 59 private PhysicsCrash handlerPhysicsCrash = null;
61
62 public event AttachToBackupDelegate OnAttachToBackup; 60 public event AttachToBackupDelegate OnAttachToBackup;
63 public event DetachFromBackupDelegate OnDetachFromBackup; 61 public event DetachFromBackupDelegate OnDetachFromBackup;
64 public event ChangedBackupDelegate OnChangeBackup; 62 public event ChangedBackupDelegate OnChangeBackup;
@@ -67,44 +65,29 @@ namespace OpenSim.Region.Framework.Scenes
67 65
68 #region Fields 66 #region Fields
69 67
70 protected System.Threading.ReaderWriterLockSlim m_scenePresencesLock;
71
72 protected ConcurrentDictionary<UUID, ScenePresence> m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>();
73 protected ConcurrentDictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>();
74 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
75 private int m_spArrayLastVersion;
76 private int m_spArrayVersion;
77 68
78 protected internal EntityManager Entities = new EntityManager(); 69 protected internal EntityManager Entities = new EntityManager();
79 70
80 protected Scene m_parentScene; 71 private Dictionary<UUID, SceneObjectPart> m_scenePartsByID = new Dictionary<UUID, SceneObjectPart>(1024);
81 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); 72 private Dictionary<uint, SceneObjectPart> m_scenePartsByLocalID = new Dictionary<uint, SceneObjectPart>(1024);
82 protected int m_numRootAgents = 0; 73 private SceneObjectPart[] m_scenePartsArray;
83 protected int m_numTotalPrim = 0; 74 private Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
84 protected int m_numPrim = 0; 75 private Dictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new Dictionary<uint, ScenePresence>();
85 protected int m_numMesh = 0; 76 private Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
86 protected int m_numChildAgents = 0; 77 private List<ScenePresence> m_scenePresenceList;
87 protected int m_physicalPrim = 0;
88 78
89 protected int m_activeScripts = 0; 79 private Scene m_parentScene;
90 protected int m_scriptLPS = 0; 80 private PhysicsScene _PhyScene;
91 81
92 protected internal PhysicsScene _PhyScene; 82 private int m_numRootAgents = 0;
93 83 private int m_numTotalPrim = 0;
94 /// <summary> 84 private int m_numPrim = 0;
95 /// Index the SceneObjectGroup for each part by the root part's UUID. 85 private int m_numMesh = 0;
96 /// </summary> 86 private int m_numChildAgents = 0;
97 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); 87 private int m_physicalPrim = 0;
98 88
99 /// <summary> 89 private int m_activeScripts = 0;
100 /// Index the SceneObjectGroup for each part by that part's UUID. 90 private int m_scriptLPS = 0;
101 /// </summary>
102 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullPartID = new Dictionary<UUID, SceneObjectGroup>();
103
104 /// <summary>
105 /// Index the SceneObjectGroup for each part by that part's local ID.
106 /// </summary>
107 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>();
108 91
109 /// <summary> 92 /// <summary>
110 /// Lock to prevent object group update, linking, delinking and duplication operations from running concurrently. 93 /// Lock to prevent object group update, linking, delinking and duplication operations from running concurrently.
@@ -114,15 +97,24 @@ namespace OpenSim.Region.Framework.Scenes
114 /// conditions can occur. 97 /// conditions can occur.
115 /// </remarks> 98 /// </remarks>
116 private Object m_updateLock = new Object(); 99 private Object m_updateLock = new Object();
100 private System.Threading.ReaderWriterLockSlim m_scenePresencesLock;
101 private System.Threading.ReaderWriterLockSlim m_scenePartsLock;
117 102
118 #endregion 103 #endregion
119 104
120 protected internal SceneGraph(Scene parent) 105 protected internal SceneGraph(Scene parent)
121 { 106 {
122 m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim(); 107 m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim();
108 m_scenePartsLock = new System.Threading.ReaderWriterLockSlim();
123 m_parentScene = parent; 109 m_parentScene = parent;
124 m_spArrayLastVersion = 0; 110 m_scenePresenceList = null;
125 m_spArrayVersion = 0; 111 m_scenePartsArray = null;
112 }
113
114 ~SceneGraph()
115 {
116 m_scenePartsLock.Dispose();
117 m_scenePresencesLock.Dispose();
126 } 118 }
127 119
128 public PhysicsScene PhysicsScene 120 public PhysicsScene PhysicsScene
@@ -158,32 +150,40 @@ namespace OpenSim.Region.Framework.Scenes
158 { 150 {
159 m_scenePresencesLock.EnterWriteLock(); 151 m_scenePresencesLock.EnterWriteLock();
160 entered = true; 152 entered = true;
161 m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>();
162 m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>();
163 m_scenePresenceArray = new List<ScenePresence>();
164 m_spArrayLastVersion = 0;
165 m_spArrayVersion = 0;
166 if (_PhyScene != null)
167 _PhyScene.OnPhysicsCrash -= physicsBasedCrash;
168 _PhyScene = null;
169 } 153 }
154 m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
155 m_scenePresenceLocalIDMap = new Dictionary<uint, ScenePresence>();
156 m_scenePresenceList = null;
170 } 157 }
171 finally 158 finally
172 { 159 {
173 if(entered) 160 if (entered)
174 m_scenePresencesLock.ExitWriteLock(); 161 m_scenePresencesLock.ExitWriteLock();
175 } 162 }
176 163
177 lock (SceneObjectGroupsByFullID) 164 entered = false;
178 SceneObjectGroupsByFullID.Clear(); 165 try
179 lock (SceneObjectGroupsByFullPartID) 166 {
180 SceneObjectGroupsByFullPartID.Clear(); 167 try { }
181 lock (SceneObjectGroupsByLocalPartID) 168 finally
182 SceneObjectGroupsByLocalPartID.Clear(); 169 {
170 m_scenePartsLock.EnterWriteLock();
171 entered = true;
172 }
183 173
184 Entities.Clear(); 174 Entities.Clear();
185 m_scenePresencesLock.Dispose(); 175 m_scenePartsArray = null;
186 m_scenePresencesLock = null; 176 m_scenePartsByID = new Dictionary<UUID, SceneObjectPart>();
177 m_scenePartsByLocalID = new Dictionary<uint, SceneObjectPart>();
178 if (_PhyScene != null)
179 _PhyScene.OnPhysicsCrash -= physicsBasedCrash;
180 _PhyScene = null;
181 }
182 finally
183 {
184 if (entered)
185 m_scenePartsLock.ExitWriteLock();
186 }
187 } 187 }
188 188
189 #region Update Methods 189 #region Update Methods
@@ -251,9 +251,14 @@ namespace OpenSim.Region.Framework.Scenes
251 scaleY = 1.0f / scaleY; 251 scaleY = 1.0f / scaleY;
252 252
253 List<ScenePresence> presences = GetScenePresences(); 253 List<ScenePresence> presences = GetScenePresences();
254 for (int i = 0; i < Math.Min(presences.Count, maxLocations); ++i) 254 int len = presences.Count;
255 if(len > maxLocations)
256 len = (int)maxLocations;
257
258 ScenePresence sp;
259 for (int i = 0; i < len; ++i)
255 { 260 {
256 ScenePresence sp = presences[i]; 261 sp = presences[i];
257 262
258 // If this presence is a child agent, we don't want its coarse locations 263 // If this presence is a child agent, we don't want its coarse locations
259 if (sp.IsChildAgent) 264 if (sp.IsChildAgent)
@@ -295,16 +300,10 @@ namespace OpenSim.Region.Framework.Scenes
295 { 300 {
296 // temporary checks to remove after varsize suport 301 // temporary checks to remove after varsize suport
297 float regionSizeX = m_parentScene.RegionInfo.RegionSizeX; 302 float regionSizeX = m_parentScene.RegionInfo.RegionSizeX;
298 if (regionSizeX == 0)
299 regionSizeX = Constants.RegionSize;
300 float regionSizeY = m_parentScene.RegionInfo.RegionSizeY; 303 float regionSizeY = m_parentScene.RegionInfo.RegionSizeY;
301 if (regionSizeY == 0)
302 regionSizeY = Constants.RegionSize;
303 304
304 // KF: Check for out-of-region, move inside and make static. 305 // KF: Check for out-of-region, move inside and make static.
305 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, 306 Vector3 npos = sceneObject.RootPart.GroupPosition;
306 sceneObject.RootPart.GroupPosition.Y,
307 sceneObject.RootPart.GroupPosition.Z);
308 bool clampZ = m_parentScene.ClampNegativeZ; 307 bool clampZ = m_parentScene.ClampNegativeZ;
309 308
310 if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || (npos.Z < 0.0 && clampZ) || 309 if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || (npos.Z < 0.0 && clampZ) ||
@@ -454,13 +453,16 @@ namespace OpenSim.Region.Framework.Scenes
454// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); 453// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
455 454
456 SceneObjectPart[] parts = sceneObject.Parts; 455 SceneObjectPart[] parts = sceneObject.Parts;
456 int partsLength = parts.Length;
457 SceneObjectPart part;
457 458
458 // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives 459 // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives
459 // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count 460 // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count
460 if (m_parentScene.m_clampPrimSize) 461 if (m_parentScene.m_clampPrimSize)
461 { 462 {
462 foreach (SceneObjectPart part in parts) 463 for (int i = 0; i< partsLength; ++i)
463 { 464 {
465 part = parts[i];
464 Vector3 scale = part.Shape.Scale; 466 Vector3 scale = part.Shape.Scale;
465 467
466 scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); 468 scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
@@ -470,34 +472,38 @@ namespace OpenSim.Region.Framework.Scenes
470 part.Shape.Scale = scale; 472 part.Shape.Scale = scale;
471 } 473 }
472 } 474 }
473 m_numTotalPrim += parts.Length;
474
475 // Go through all parts (geometric primitives and meshes) of this Scene Object
476 foreach (SceneObjectPart part in parts)
477 {
478 // Keep track of the total number of meshes or geometric primitives now in the scene;
479 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
480 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
481 if (part.GetPrimType() == PrimType.SCULPT)
482 m_numMesh++;
483 else
484 m_numPrim++;
485 }
486 475
487 sceneObject.AttachToScene(m_parentScene); 476 sceneObject.AttachToScene(m_parentScene);
488 477
489 Entities.Add(sceneObject); 478 bool entered = false;
479 try
480 {
481 try { }
482 finally
483 {
484 m_scenePartsLock.EnterWriteLock();
485 entered = true;
486 }
490 487
491 lock (SceneObjectGroupsByFullID) 488 m_numTotalPrim += partsLength;
492 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
493 489
494 foreach (SceneObjectPart part in parts) 490 Entities.Add(sceneObject);
491 m_scenePartsArray = null;
492 for (int i = 0; i < partsLength; ++i)
493 {
494 part = parts[i];
495 m_scenePartsByID[part.UUID] = part;
496 m_scenePartsByLocalID[part.LocalId] = part;
497 if (part.GetPrimType() == PrimType.SCULPT)
498 ++m_numMesh;
499 else
500 ++m_numPrim;
501 }
502 }
503 finally
495 { 504 {
496 lock (SceneObjectGroupsByFullPartID) 505 if(entered)
497 SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; 506 m_scenePartsLock.ExitWriteLock();
498
499 lock (SceneObjectGroupsByLocalPartID)
500 SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
501 } 507 }
502 508
503 if (sendClientUpdates) 509 if (sendClientUpdates)
@@ -509,16 +515,6 @@ namespace OpenSim.Region.Framework.Scenes
509 return true; 515 return true;
510 } 516 }
511 517
512 public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp)
513 {
514 // no tests, caller has responsability...
515 lock (SceneObjectGroupsByFullPartID)
516 SceneObjectGroupsByFullPartID[part.UUID] = grp;
517
518 lock (SceneObjectGroupsByLocalPartID)
519 SceneObjectGroupsByLocalPartID[part.LocalId] = grp;
520 }
521
522 /// <summary> 518 /// <summary>
523 /// Delete an object from the scene 519 /// Delete an object from the scene
524 /// </summary> 520 /// </summary>
@@ -534,9 +530,9 @@ namespace OpenSim.Region.Framework.Scenes
534 return false; 530 return false;
535 531
536 SceneObjectGroup grp = (SceneObjectGroup)entity; 532 SceneObjectGroup grp = (SceneObjectGroup)entity;
537 533 SceneObjectPart[] parts = grp.Parts;
538 if (entity == null) 534 int partsLength = parts.Length;
539 return false; 535 SceneObjectPart part;
540 536
541 if (!resultOfObjectLinked) 537 if (!resultOfObjectLinked)
542 { 538 {
@@ -546,9 +542,11 @@ namespace OpenSim.Region.Framework.Scenes
546 542
547 bool isPh = (grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics; 543 bool isPh = (grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics;
548 int nphysparts = 0; 544 int nphysparts = 0;
545
549 // Go through all parts (primitives and meshes) of this Scene Object 546 // Go through all parts (primitives and meshes) of this Scene Object
550 foreach (SceneObjectPart part in grp.Parts) 547 for (int i= 0; i < partsLength; ++i)
551 { 548 {
549 part = parts[i];
552 // Keep track of the total number of meshes or geometric primitives left in the scene; 550 // Keep track of the total number of meshes or geometric primitives left in the scene;
553 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to 551 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
554 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives 552 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
@@ -565,21 +563,31 @@ namespace OpenSim.Region.Framework.Scenes
565 RemovePhysicalPrim(nphysparts); 563 RemovePhysicalPrim(nphysparts);
566 } 564 }
567 565
568 bool ret = Entities.Remove(uuid); 566 bool ret = false;
569 567 bool entered = false;
570 lock (SceneObjectGroupsByFullID) 568 try
571 SceneObjectGroupsByFullID.Remove(grp.UUID);
572
573 SceneObjectPart[] parts = grp.Parts;
574 for (int i = 0; i < parts.Length; i++)
575 { 569 {
576 lock (SceneObjectGroupsByFullPartID) 570 try { }
577 SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); 571 finally
572 {
573 m_scenePartsLock.EnterWriteLock();
574 entered = true;
575 }
578 576
579 lock (SceneObjectGroupsByLocalPartID) 577 for (int i = 0; i < parts.Length; ++i)
580 SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); 578 {
579 part = parts[i];
580 m_scenePartsByID.Remove(part.UUID);
581 m_scenePartsByLocalID.Remove(part.LocalId);
582 }
583 m_scenePartsArray = null;
584 ret = Entities.Remove(uuid);
585 }
586 finally
587 {
588 if(entered)
589 m_scenePartsLock.ExitWriteLock();
581 } 590 }
582
583 return ret; 591 return ret;
584 } 592 }
585 593
@@ -591,7 +599,7 @@ namespace OpenSim.Region.Framework.Scenes
591 /// </param> 599 /// </param>
592 protected internal void AddToUpdateList(SceneObjectGroup obj) 600 protected internal void AddToUpdateList(SceneObjectGroup obj)
593 { 601 {
594 lock (m_updateList) 602 lock(m_updateLock)
595 m_updateList[obj.UUID] = obj; 603 m_updateList[obj.UUID] = obj;
596 } 604 }
597 605
@@ -628,20 +636,17 @@ namespace OpenSim.Region.Framework.Scenes
628 return; 636 return;
629 try 637 try
630 { 638 {
631 List<SceneObjectGroup> updates; 639 Dictionary<UUID, SceneObjectGroup> updates;
632
633 // Some updates add more updates to the updateList.
634 // Get the current list of updates and clear the list before iterating 640 // Get the current list of updates and clear the list before iterating
635 lock (m_updateList) 641 lock (m_updateLock)
636 { 642 {
637 updates = new List<SceneObjectGroup>(m_updateList.Values); 643 updates = m_updateList;
638 m_updateList = new Dictionary<UUID, SceneObjectGroup>(); 644 m_updateList = new Dictionary<UUID, SceneObjectGroup>();
639 } 645 }
640 646
641 // Go through all updates 647 // Go through all updates
642 for (int i = 0; i < updates.Count; i++) 648 foreach (SceneObjectGroup sog in updates.Values)
643 { 649 {
644 SceneObjectGroup sog = updates[i];
645 if (sog.IsDeleted) 650 if (sog.IsDeleted)
646 continue; 651 continue;
647 652
@@ -656,6 +661,7 @@ namespace OpenSim.Region.Framework.Scenes
656 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); 661 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
657 } 662 }
658 } 663 }
664 updates = null;
659 } 665 }
660 finally 666 finally
661 { 667 {
@@ -705,14 +711,11 @@ namespace OpenSim.Region.Framework.Scenes
705 } 711 }
706 712
707 protected internal ScenePresence CreateAndAddChildScenePresence( 713 protected internal ScenePresence CreateAndAddChildScenePresence(
708 IClientAPI client, AvatarAppearance appearance, PresenceType type) 714 IClientAPI client, AvatarAppearance appearance, PresenceType type)
709 { 715 {
710 // ScenePresence always defaults to child agent
711 ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type); 716 ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type);
712 717
713 Entities[presence.UUID] = presence;
714 bool entered = false; 718 bool entered = false;
715
716 try 719 try
717 { 720 {
718 try{ } 721 try{ }
@@ -720,31 +723,31 @@ namespace OpenSim.Region.Framework.Scenes
720 { 723 {
721 m_scenePresencesLock.EnterWriteLock(); 724 m_scenePresencesLock.EnterWriteLock();
722 entered = true; 725 entered = true;
726 }
723 727
724 m_numChildAgents++; 728 UUID id = presence.UUID;
725 729 Entities[id] = presence;
726 if (!m_scenePresenceMap.ContainsKey(presence.UUID)) 730 // ScenePresence always defaults to child agent
727 { 731 ++m_numChildAgents;
728 m_scenePresenceMap[presence.UUID] = presence;
729 m_scenePresenceLocalIDMap[presence.LocalId] = presence;
730 }
731 else
732 {
733 // Remember the old presence reference from the dictionary
734 ScenePresence oldref = m_scenePresenceMap[presence.UUID];
735 uint oldLocalID = oldref.LocalId;
736 // Replace the presence reference in the dictionary with the new value
737 m_scenePresenceMap[presence.UUID] = presence;
738 if(presence.LocalId != oldLocalID)
739 {
740 m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref);
741 m_scenePresenceLocalIDMap[presence.LocalId] = presence;
742 }
743 // Find the index in the list where the old ref was stored and update the reference
744 }
745 732
746 ++m_spArrayVersion; 733 uint localid = presence.LocalId;
734 ScenePresence oldref;
735 if (m_scenePresenceMap.TryGetValue(id, out oldref))
736 {
737 // Remember the old presence reference from the dictionary
738 uint oldLocalID = oldref.LocalId;
739 // Replace the presence reference in the dictionary with the new value
740 m_scenePresenceMap[id] = presence;
741 if (localid != oldLocalID)
742 m_scenePresenceLocalIDMap.Remove(oldLocalID);
743 m_scenePresenceLocalIDMap[localid] = presence;
744 }
745 else
746 {
747 m_scenePresenceMap[id] = presence;
748 m_scenePresenceLocalIDMap[localid] = presence;
747 } 749 }
750 m_scenePresenceList = null;
748 } 751 }
749 finally 752 finally
750 { 753 {
@@ -775,18 +778,19 @@ namespace OpenSim.Region.Framework.Scenes
775 { 778 {
776 m_scenePresencesLock.EnterWriteLock(); 779 m_scenePresencesLock.EnterWriteLock();
777 entered = true; 780 entered = true;
778 // Remove the presence reference from the dictionary 781 }
779 ScenePresence oldref; 782 // Remove the presence reference from the dictionary
780 if(m_scenePresenceMap.TryRemove(agentID, out oldref)) 783 ScenePresence oldref;
781 { 784 if(m_scenePresenceMap.TryGetValue(agentID, out oldref))
782 // Find the index in the list where the old ref was stored and remove the reference 785 {
783 m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref); 786 m_scenePresenceMap.Remove(agentID);
784 ++m_spArrayVersion; 787 // Find the index in the list where the old ref was stored and remove the reference
785 } 788 m_scenePresenceLocalIDMap.Remove(oldref.LocalId);
786 else 789 m_scenePresenceList = null;
787 { 790 }
788 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 791 else
789 } 792 {
793 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
790 } 794 }
791 } 795 }
792 finally 796 finally
@@ -900,14 +904,29 @@ namespace OpenSim.Region.Framework.Scenes
900 /// prevents CapabilitiesModule from accessing it</remarks> 904 /// prevents CapabilitiesModule from accessing it</remarks>
901 public IClientAPI GetControllingClient(UUID agentId) 905 public IClientAPI GetControllingClient(UUID agentId)
902 { 906 {
903 ScenePresence presence = GetScenePresence(agentId); 907 bool entered = false;
904 908 try
905 if (presence != null) 909 {
910 try { }
911 finally
912 {
913 m_scenePresencesLock.EnterReadLock();
914 entered = true;
915 }
916 ScenePresence presence;
917 if (m_scenePresenceMap.TryGetValue(agentId, out presence))
918 return presence.ControllingClient;
919 return null;
920 }
921 catch
906 { 922 {
907 return presence.ControllingClient; 923 return null;
924 }
925 finally
926 {
927 if (entered)
928 m_scenePresencesLock.ExitReadLock();
908 } 929 }
909
910 return null;
911 } 930 }
912 931
913 /// <summary> 932 /// <summary>
@@ -920,7 +939,6 @@ namespace OpenSim.Region.Framework.Scenes
920 protected internal List<ScenePresence> GetScenePresences() 939 protected internal List<ScenePresence> GetScenePresences()
921 { 940 {
922 bool entered = false; 941 bool entered = false;
923 List<ScenePresence> ret = new List<ScenePresence>();
924 try 942 try
925 { 943 {
926 try{ } 944 try{ }
@@ -928,20 +946,22 @@ namespace OpenSim.Region.Framework.Scenes
928 { 946 {
929 m_scenePresencesLock.EnterWriteLock(); 947 m_scenePresencesLock.EnterWriteLock();
930 entered = true; 948 entered = true;
931 if(m_spArrayLastVersion != m_spArrayVersion)
932 {
933 m_scenePresenceArray = new List<ScenePresence>(m_scenePresenceMap.Values);
934 m_spArrayLastVersion = m_spArrayVersion;
935 }
936 ret = m_scenePresenceArray;
937 } 949 }
950
951 if(m_scenePresenceList == null)
952 m_scenePresenceList = new List<ScenePresence>(m_scenePresenceMap.Values);
953
954 return m_scenePresenceList;
955 }
956 catch
957 {
958 return new List<ScenePresence>();
938 } 959 }
939 finally 960 finally
940 { 961 {
941 if(entered) 962 if(entered)
942 m_scenePresencesLock.ExitWriteLock(); 963 m_scenePresencesLock.ExitWriteLock();
943 } 964 }
944 return ret;
945 } 965 }
946 966
947 /// <summary> 967 /// <summary>
@@ -951,9 +971,28 @@ namespace OpenSim.Region.Framework.Scenes
951 /// <returns>null if the presence was not found</returns> 971 /// <returns>null if the presence was not found</returns>
952 protected internal ScenePresence GetScenePresence(UUID agentID) 972 protected internal ScenePresence GetScenePresence(UUID agentID)
953 { 973 {
954 ScenePresence presence; 974 bool entered = false;
955 m_scenePresenceMap.TryGetValue(agentID, out presence); 975 try
956 return presence; 976 {
977 try { }
978 finally
979 {
980 m_scenePresencesLock.EnterReadLock();
981 entered = true;
982 }
983 ScenePresence presence;
984 m_scenePresenceMap.TryGetValue(agentID, out presence);
985 return presence;
986 }
987 catch
988 {
989 return null;
990 }
991 finally
992 {
993 if (entered)
994 m_scenePresencesLock.ExitReadLock();
995 }
957 } 996 }
958 997
959 /// <summary> 998 /// <summary>
@@ -981,21 +1020,50 @@ namespace OpenSim.Region.Framework.Scenes
981 /// <returns>null if the presence was not found</returns> 1020 /// <returns>null if the presence was not found</returns>
982 protected internal ScenePresence GetScenePresence(uint localID) 1021 protected internal ScenePresence GetScenePresence(uint localID)
983 { 1022 {
984 ScenePresence sp = null; 1023 bool entered = false;
985 if(m_scenePresenceLocalIDMap.TryGetValue(localID, out sp)) 1024 try
986 return sp; 1025 {
987/* 1026 try { }
988 List<ScenePresence> presences = GetScenePresences(); 1027 finally
989 foreach (ScenePresence presence in presences) 1028 {
990 if (presence.LocalId == localID) 1029 m_scenePresencesLock.EnterReadLock();
991 return presence; 1030 entered = true;
992*/ 1031 }
1032 ScenePresence sp;
1033 if (m_scenePresenceLocalIDMap.TryGetValue(localID, out sp))
1034 return sp;
1035 }
1036 finally
1037 {
1038 if (entered)
1039 m_scenePresencesLock.ExitReadLock();
1040 }
993 return null; 1041 return null;
994 } 1042 }
995 1043
996 protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) 1044 protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar)
997 { 1045 {
998 return m_scenePresenceMap.TryGetValue(agentID, out avatar); 1046 bool entered = false;
1047 try
1048 {
1049 try { }
1050 finally
1051 {
1052 m_scenePresencesLock.EnterReadLock();
1053 entered = true;
1054 }
1055 return m_scenePresenceMap.TryGetValue(agentID, out avatar);
1056 }
1057 catch
1058 {
1059 avatar = null;
1060 return false;
1061 }
1062 finally
1063 {
1064 if (entered)
1065 m_scenePresencesLock.ExitReadLock();
1066 }
999 } 1067 }
1000 1068
1001 protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) 1069 protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
@@ -1020,56 +1088,25 @@ namespace OpenSim.Region.Framework.Scenes
1020 /// <returns>null if no scene object group containing that prim is found</returns> 1088 /// <returns>null if no scene object group containing that prim is found</returns>
1021 public SceneObjectGroup GetGroupByPrim(uint localID) 1089 public SceneObjectGroup GetGroupByPrim(uint localID)
1022 { 1090 {
1023 EntityBase entity; 1091 bool entered = false;
1024 if (Entities.TryGetValue(localID, out entity)) 1092 try
1025 return entity as SceneObjectGroup;
1026
1027// m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID);
1028
1029 SceneObjectGroup sog;
1030 lock (SceneObjectGroupsByLocalPartID)
1031 SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
1032
1033 if (sog != null)
1034 { 1093 {
1035 if (sog.ContainsPart(localID)) 1094 try { }
1036 { 1095 finally
1037// m_log.DebugFormat(
1038// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.",
1039// sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
1040
1041 return sog;
1042 }
1043 else
1044 { 1096 {
1045 lock (SceneObjectGroupsByLocalPartID) 1097 m_scenePartsLock.EnterReadLock();
1046 { 1098 entered = true;
1047 m_log.WarnFormat(
1048 "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.",
1049 sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
1050 m_log.WarnFormat("stack: {0}", Environment.StackTrace);
1051 SceneObjectGroupsByLocalPartID.Remove(localID);
1052 }
1053 } 1099 }
1100 SceneObjectPart sop;
1101 if(m_scenePartsByLocalID.TryGetValue(localID, out sop))
1102 return sop.ParentGroup;
1103 return null;
1054 } 1104 }
1055 1105 finally
1056 EntityBase[] entityList = GetEntities();
1057 foreach (EntityBase ent in entityList)
1058 { 1106 {
1059 //m_log.DebugFormat("Looking at entity {0}", ent.UUID); 1107 if(entered)
1060 if (ent is SceneObjectGroup) 1108 m_scenePartsLock.ExitReadLock();
1061 {
1062 sog = (SceneObjectGroup)ent;
1063 if (sog.ContainsPart(localID))
1064 {
1065 lock (SceneObjectGroupsByLocalPartID)
1066 SceneObjectGroupsByLocalPartID[localID] = sog;
1067 return sog;
1068 }
1069 }
1070 } 1109 }
1071
1072 return null;
1073 } 1110 }
1074 1111
1075 /// <summary> 1112 /// <summary>
@@ -1079,35 +1116,25 @@ namespace OpenSim.Region.Framework.Scenes
1079 /// <returns>null if no scene object group containing that prim is found</returns> 1116 /// <returns>null if no scene object group containing that prim is found</returns>
1080 public SceneObjectGroup GetGroupByPrim(UUID fullID) 1117 public SceneObjectGroup GetGroupByPrim(UUID fullID)
1081 { 1118 {
1082 SceneObjectGroup sog; 1119 bool entered = false;
1083 lock (SceneObjectGroupsByFullPartID) 1120 try
1084 SceneObjectGroupsByFullPartID.TryGetValue(fullID, out sog);
1085
1086 if (sog != null)
1087 {
1088 if (sog.ContainsPart(fullID))
1089 return sog;
1090
1091 lock (SceneObjectGroupsByFullPartID)
1092 SceneObjectGroupsByFullPartID.Remove(fullID);
1093 }
1094
1095 EntityBase[] entityList = GetEntities();
1096 foreach (EntityBase ent in entityList)
1097 { 1121 {
1098 if (ent is SceneObjectGroup) 1122 try { }
1123 finally
1099 { 1124 {
1100 sog = (SceneObjectGroup)ent; 1125 m_scenePartsLock.EnterReadLock();
1101 if (sog.ContainsPart(fullID)) 1126 entered = true;
1102 {
1103 lock (SceneObjectGroupsByFullPartID)
1104 SceneObjectGroupsByFullPartID[fullID] = sog;
1105 return sog;
1106 }
1107 } 1127 }
1128 SceneObjectPart sop;
1129 if (m_scenePartsByID.TryGetValue(fullID, out sop))
1130 return sop.ParentGroup;
1131 return null;
1132 }
1133 finally
1134 {
1135 if (entered)
1136 m_scenePartsLock.ExitReadLock();
1108 } 1137 }
1109
1110 return null;
1111 } 1138 }
1112 1139
1113 protected internal EntityIntersection GetClosestIntersectingPrim(Ray hray, bool frontFacesOnly, bool faceCenters) 1140 protected internal EntityIntersection GetClosestIntersectingPrim(Ray hray, bool frontFacesOnly, bool faceCenters)
@@ -1140,8 +1167,15 @@ namespace OpenSim.Region.Framework.Scenes
1140 /// </returns> 1167 /// </returns>
1141 protected internal List<SceneObjectGroup> GetSceneObjectGroups() 1168 protected internal List<SceneObjectGroup> GetSceneObjectGroups()
1142 { 1169 {
1143 lock (SceneObjectGroupsByFullID) 1170 EntityBase[] entities = Entities.GetEntities();
1144 return new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1171 List<SceneObjectGroup> ret = new List<SceneObjectGroup>(256);
1172 int len = entities.Length;
1173 for (int i = 0; i < len; ++i)
1174 {
1175 if(entities[i] is SceneObjectGroup)
1176 ret.Add((SceneObjectGroup)entities[i]);
1177 }
1178 return ret;
1145 } 1179 }
1146 1180
1147 /// <summary> 1181 /// <summary>
@@ -1151,36 +1185,21 @@ namespace OpenSim.Region.Framework.Scenes
1151 /// <returns>null if no such group was found</returns> 1185 /// <returns>null if no such group was found</returns>
1152 protected internal SceneObjectGroup GetSceneObjectGroup(UUID fullID) 1186 protected internal SceneObjectGroup GetSceneObjectGroup(UUID fullID)
1153 { 1187 {
1154 lock (SceneObjectGroupsByFullID) 1188 EntityBase entity;
1155 { 1189 if (Entities.TryGetValue(fullID, out entity) && (entity is SceneObjectGroup))
1156 if (SceneObjectGroupsByFullID.ContainsKey(fullID)) 1190 return (SceneObjectGroup)entity;
1157 return SceneObjectGroupsByFullID[fullID];
1158 }
1159
1160 return null; 1191 return null;
1161 } 1192 }
1162 1193
1163 /// <summary> 1194 /// <summary>
1164 /// Get a group in the scene 1195 /// Get a group in the scene
1165 /// </summary>
1166 /// <remarks>
1167 /// This will only return a group if the local ID matches the root part, not other parts.
1168 /// </remarks>
1169 /// <param name="localID">Local id of the root part of the group</param> 1196 /// <param name="localID">Local id of the root part of the group</param>
1170 /// <returns>null if no such group was found</returns> 1197 /// <returns>null if no such group was found</returns>
1171 protected internal SceneObjectGroup GetSceneObjectGroup(uint localID) 1198 protected internal SceneObjectGroup GetSceneObjectGroup(uint localID)
1172 { 1199 {
1173 lock (SceneObjectGroupsByLocalPartID) 1200 EntityBase entity;
1174 { 1201 if (Entities.TryGetValue(localID, out entity) && (entity is SceneObjectGroup))
1175 if (SceneObjectGroupsByLocalPartID.ContainsKey(localID)) 1202 return (SceneObjectGroup)entity;
1176 {
1177 SceneObjectGroup so = SceneObjectGroupsByLocalPartID[localID];
1178
1179 if (so.LocalId == localID)
1180 return so;
1181 }
1182 }
1183
1184 return null; 1203 return null;
1185 } 1204 }
1186 1205
@@ -1192,25 +1211,16 @@ namespace OpenSim.Region.Framework.Scenes
1192 /// <returns>null if the part was not found</returns> 1211 /// <returns>null if the part was not found</returns>
1193 protected internal SceneObjectGroup GetSceneObjectGroup(string name) 1212 protected internal SceneObjectGroup GetSceneObjectGroup(string name)
1194 { 1213 {
1195 SceneObjectGroup so = null; 1214 EntityBase entity = null;
1196 1215 EntityBase[] entities = Entities.GetEntities();
1197 Entities.Find( 1216 int len = entities.Length;
1198 delegate(EntityBase entity) 1217 for (int i = 0; i < len; ++i)
1199 { 1218 {
1200 if (entity is SceneObjectGroup) 1219 entity = entities[i];
1201 { 1220 if (entity is SceneObjectGroup && entity.Name == name)
1202 if (entity.Name == name) 1221 return (SceneObjectGroup)entity;
1203 { 1222 }
1204 so = (SceneObjectGroup)entity; 1223 return null;
1205 return true;
1206 }
1207 }
1208
1209 return false;
1210 }
1211 );
1212
1213 return so;
1214 } 1224 }
1215 1225
1216 /// <summary> 1226 /// <summary>
@@ -1220,57 +1230,108 @@ namespace OpenSim.Region.Framework.Scenes
1220 /// <returns>null if the part was not found</returns> 1230 /// <returns>null if the part was not found</returns>
1221 protected internal SceneObjectPart GetSceneObjectPart(uint localID) 1231 protected internal SceneObjectPart GetSceneObjectPart(uint localID)
1222 { 1232 {
1223 SceneObjectGroup group = GetGroupByPrim(localID); 1233 bool entered = false;
1224 if (group == null || group.IsDeleted) 1234 try
1235 {
1236 try { }
1237 finally
1238 {
1239 m_scenePartsLock.EnterReadLock();
1240 entered = true;
1241 }
1242 SceneObjectPart sop;
1243 if (m_scenePartsByLocalID.TryGetValue(localID, out sop))
1244 {
1245 if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
1246 return null;
1247 return sop;
1248 }
1225 return null; 1249 return null;
1226 return group.GetPart(localID); 1250 }
1251 finally
1252 {
1253 if (entered)
1254 m_scenePartsLock.ExitReadLock();
1255 }
1227 } 1256 }
1228
1229 /// <summary> 1257 /// <summary>
1230 /// Get a prim by name from the scene (will return the first 1258 /// Get a part contained in this scene.
1231 /// found, if there are more than one prim with the same name)
1232 /// </summary> 1259 /// </summary>
1233 /// <param name="name"></param> 1260 /// <param name="fullID"></param>
1234 /// <returns>null if the part was not found</returns> 1261 /// <returns>null if the part was not found</returns>
1235 protected internal SceneObjectPart GetSceneObjectPart(string name) 1262 protected internal SceneObjectPart GetSceneObjectPart(UUID fullID)
1236 { 1263 {
1237 SceneObjectPart sop = null; 1264 bool entered = false;
1238 1265 try
1239 Entities.Find( 1266 {
1240 delegate(EntityBase entity) 1267 try { }
1268 finally
1241 { 1269 {
1242 if (entity is SceneObjectGroup) 1270 m_scenePartsLock.EnterReadLock();
1243 { 1271 entered = true;
1244 foreach (SceneObjectPart p in ((SceneObjectGroup)entity).Parts)
1245 {
1246 if (p.Name == name)
1247 {
1248 sop = p;
1249 return true;
1250 }
1251 }
1252 }
1253
1254 return false;
1255 } 1272 }
1256 ); 1273 SceneObjectPart sop;
1257 1274 if (m_scenePartsByID.TryGetValue(fullID, out sop))
1258 return sop; 1275 {
1276 if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
1277 return null;
1278 return sop;
1279 }
1280 return null;
1281 }
1282 finally
1283 {
1284 if (entered)
1285 m_scenePartsLock.ExitReadLock();
1286 }
1259 } 1287 }
1260 1288
1261 /// <summary> 1289 /// <summary>
1262 /// Get a part contained in this scene. 1290 /// Get a prim by name from the scene (will return the first
1291 /// found, if there are more than one prim with the same name)
1263 /// </summary> 1292 /// </summary>
1264 /// <param name="fullID"></param> 1293 /// <param name="name"></param>
1265 /// <returns>null if the part was not found</returns> 1294 /// <returns>null if the part was not found</returns>
1266 protected internal SceneObjectPart GetSceneObjectPart(UUID fullID) 1295 protected internal SceneObjectPart GetSceneObjectPart(string name)
1267 { 1296 {
1268 SceneObjectGroup group = GetGroupByPrim(fullID); 1297 SceneObjectPart[] parts = GetPartsArray();
1269 if (group == null) 1298 int len = parts.Length;
1270 return null; 1299 SceneObjectPart sop;
1271 return group.GetPart(fullID); 1300 for (int i = 0; i < len; ++i)
1301 {
1302 sop = parts[i];
1303 if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
1304 continue;
1305 if (sop.Name == name)
1306 return sop;
1307 }
1308 return null;
1272 } 1309 }
1273 1310
1311 protected internal SceneObjectPart[] GetPartsArray()
1312 {
1313 bool entered = false;
1314 try
1315 {
1316 try { }
1317 finally
1318 {
1319 m_scenePartsLock.EnterWriteLock();
1320 entered = true;
1321 }
1322 if(m_scenePartsArray == null)
1323 {
1324 m_scenePartsArray = new SceneObjectPart[m_scenePartsByID.Count];
1325 m_scenePartsByID.Values.CopyTo(m_scenePartsArray, 0);
1326 }
1327 return m_scenePartsArray;
1328 }
1329 finally
1330 {
1331 if(entered)
1332 m_scenePartsLock.ExitWriteLock();
1333 }
1334 }
1274 /// <summary> 1335 /// <summary>
1275 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over 1336 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over
1276 /// it 1337 /// it
@@ -1294,32 +1355,30 @@ namespace OpenSim.Region.Framework.Scenes
1294 } 1355 }
1295 } 1356 }
1296 1357
1297 protected internal UUID ConvertLocalIDToFullID(uint localID)
1298 {
1299 SceneObjectGroup group = GetGroupByPrim(localID);
1300 if (group != null)
1301 return group.GetPartsFullID(localID);
1302 else
1303 return UUID.Zero;
1304 }
1305
1306 /// <summary> 1358 /// <summary>
1307 /// Performs action once on all scene object groups. 1359 /// Performs action once on all scene object groups.
1308 /// </summary> 1360 /// </summary>
1309 /// <param name="action"></param> 1361 /// <param name="action"></param>
1310 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1362 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1311 { 1363 {
1312 foreach (SceneObjectGroup obj in GetSceneObjectGroups()) 1364 EntityBase[] entities = Entities.GetEntities();
1365 int len = entities.Length;
1366 EntityBase entity;
1367 for (int i = 0; i < len; ++i)
1313 { 1368 {
1314 try 1369 entity = entities[i];
1315 { 1370 if (entity is SceneObjectGroup)
1316 action(obj);
1317 }
1318 catch (Exception e)
1319 { 1371 {
1320 // Catch it and move on. This includes situations where objlist has inconsistent info 1372 try
1321 m_log.WarnFormat( 1373 {
1322 "[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace); 1374 action((SceneObjectGroup)entity);
1375 }
1376 catch (Exception e)
1377 {
1378 // Catch it and move on. This includes situations where objlist has inconsistent info
1379 m_log.WarnFormat(
1380 "[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace);
1381 }
1323 } 1382 }
1324 } 1383 }
1325 } 1384 }
@@ -1664,7 +1723,7 @@ namespace OpenSim.Region.Framework.Scenes
1664 } 1723 }
1665 else 1724 else
1666 { 1725 {
1667 SceneObjectPart part = GetSceneObjectPart(localID); 1726 SceneObjectPart part = group.GetPart(localID);
1668 if (part != null) 1727 if (part != null)
1669 { 1728 {
1670 part.UpdateExtraPhysics(PhysData); 1729 part.UpdateExtraPhysics(PhysData);
@@ -2113,24 +2172,36 @@ namespace OpenSim.Region.Framework.Scenes
2113 } 2172 }
2114 2173
2115 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 2174 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()
2116 Entities.Add(copy); 2175 bool entered = false;
2176 try
2177 {
2178 try { }
2179 finally
2180 {
2181 m_scenePartsLock.EnterWriteLock();
2182 entered = true;
2183 }
2117 2184
2118 lock (SceneObjectGroupsByFullID) 2185 Entities.Add(copy);
2119 SceneObjectGroupsByFullID[copy.UUID] = copy; 2186 m_scenePartsArray = null;
2187 foreach (SceneObjectPart part in parts)
2188 {
2189 if (part.GetPrimType() == PrimType.SCULPT)
2190 m_numMesh++;
2191 else
2192 m_numPrim++;
2120 2193
2121 foreach (SceneObjectPart part in parts) 2194 m_scenePartsByID[part.UUID] = part;
2195 m_scenePartsByLocalID[part.LocalId] = part;
2196 }
2197 }
2198 finally
2122 { 2199 {
2123 if (part.GetPrimType() == PrimType.SCULPT) 2200 if(entered)
2124 m_numMesh++; 2201 m_scenePartsLock.ExitWriteLock();
2125 else
2126 m_numPrim++;
2127
2128 lock (SceneObjectGroupsByFullPartID)
2129 SceneObjectGroupsByFullPartID[part.UUID] = copy;
2130 lock (SceneObjectGroupsByLocalPartID)
2131 SceneObjectGroupsByLocalPartID[part.LocalId] = copy;
2132 } 2202 }
2133 2203
2204
2134 // PROBABLE END OF FIXME 2205 // PROBABLE END OF FIXME
2135 2206
2136 copy.IsSelected = createSelected; 2207 copy.IsSelected = createSelected;