diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 94 |
1 files changed, 79 insertions, 15 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 673674d..80f9114 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -68,7 +68,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
68 | 68 | ||
69 | #region Fields | 69 | #region Fields |
70 | 70 | ||
71 | protected object m_presenceLock = new object(); | 71 | protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); |
72 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); | 72 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); |
73 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); | 73 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); |
74 | 74 | ||
@@ -133,13 +133,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
133 | 133 | ||
134 | protected internal void Close() | 134 | protected internal void Close() |
135 | { | 135 | { |
136 | lock (m_presenceLock) | 136 | m_scenePresencesLock.EnterWriteLock(); |
137 | try | ||
137 | { | 138 | { |
138 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); | 139 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); |
139 | List<ScenePresence> newlist = new List<ScenePresence>(); | 140 | List<ScenePresence> newlist = new List<ScenePresence>(); |
140 | m_scenePresenceMap = newmap; | 141 | m_scenePresenceMap = newmap; |
141 | m_scenePresenceArray = newlist; | 142 | m_scenePresenceArray = newlist; |
142 | } | 143 | } |
144 | finally | ||
145 | { | ||
146 | m_scenePresencesLock.ExitWriteLock(); | ||
147 | } | ||
143 | 148 | ||
144 | lock (m_dictionary_lock) | 149 | lock (m_dictionary_lock) |
145 | { | 150 | { |
@@ -269,6 +274,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
269 | protected internal bool AddRestoredSceneObject( | 274 | protected internal bool AddRestoredSceneObject( |
270 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) | 275 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) |
271 | { | 276 | { |
277 | // KF: Check for out-of-region, move inside and make static. | ||
278 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | ||
279 | sceneObject.RootPart.GroupPosition.Y, | ||
280 | sceneObject.RootPart.GroupPosition.Z); | ||
281 | 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 || | ||
282 | npos.X > Constants.RegionSize || | ||
283 | npos.Y > Constants.RegionSize)) | ||
284 | { | ||
285 | if (npos.X < 0.0) npos.X = 1.0f; | ||
286 | if (npos.Y < 0.0) npos.Y = 1.0f; | ||
287 | if (npos.Z < 0.0) npos.Z = 0.0f; | ||
288 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; | ||
289 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; | ||
290 | |||
291 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
292 | { | ||
293 | part.GroupPosition = npos; | ||
294 | } | ||
295 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
296 | sceneObject.RootPart.AngularVelocity = Vector3.Zero; | ||
297 | sceneObject.RootPart.Acceleration = Vector3.Zero; | ||
298 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
299 | } | ||
300 | |||
272 | if (!alreadyPersisted) | 301 | if (!alreadyPersisted) |
273 | { | 302 | { |
274 | sceneObject.ForceInventoryPersistence(); | 303 | sceneObject.ForceInventoryPersistence(); |
@@ -565,7 +594,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
565 | 594 | ||
566 | Entities[presence.UUID] = presence; | 595 | Entities[presence.UUID] = presence; |
567 | 596 | ||
568 | lock (m_presenceLock) | 597 | m_scenePresencesLock.EnterWriteLock(); |
598 | try | ||
569 | { | 599 | { |
570 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 600 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
571 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 601 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -589,6 +619,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
589 | m_scenePresenceMap = newmap; | 619 | m_scenePresenceMap = newmap; |
590 | m_scenePresenceArray = newlist; | 620 | m_scenePresenceArray = newlist; |
591 | } | 621 | } |
622 | finally | ||
623 | { | ||
624 | m_scenePresencesLock.ExitWriteLock(); | ||
625 | } | ||
592 | } | 626 | } |
593 | 627 | ||
594 | /// <summary> | 628 | /// <summary> |
@@ -603,7 +637,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
603 | agentID); | 637 | agentID); |
604 | } | 638 | } |
605 | 639 | ||
606 | lock (m_presenceLock) | 640 | m_scenePresencesLock.EnterWriteLock(); |
641 | try | ||
607 | { | 642 | { |
608 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 643 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
609 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 644 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -624,6 +659,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
624 | m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 659 | m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); |
625 | } | 660 | } |
626 | } | 661 | } |
662 | finally | ||
663 | { | ||
664 | m_scenePresencesLock.ExitWriteLock(); | ||
665 | } | ||
627 | } | 666 | } |
628 | 667 | ||
629 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) | 668 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) |
@@ -1501,10 +1540,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1501 | /// <param name="childPrims"></param> | 1540 | /// <param name="childPrims"></param> |
1502 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) | 1541 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) |
1503 | { | 1542 | { |
1543 | SceneObjectGroup parentGroup = root.ParentGroup; | ||
1544 | if (parentGroup == null) return; | ||
1504 | Monitor.Enter(m_updateLock); | 1545 | Monitor.Enter(m_updateLock); |
1546 | |||
1505 | try | 1547 | try |
1506 | { | 1548 | { |
1507 | SceneObjectGroup parentGroup = root.ParentGroup; | 1549 | parentGroup.areUpdatesSuspended = true; |
1508 | 1550 | ||
1509 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); | 1551 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); |
1510 | if (parentGroup != null) | 1552 | if (parentGroup != null) |
@@ -1543,12 +1585,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1543 | // occur on link to invoke this elsewhere (such as object selection) | 1585 | // occur on link to invoke this elsewhere (such as object selection) |
1544 | parentGroup.RootPart.CreateSelected = true; | 1586 | parentGroup.RootPart.CreateSelected = true; |
1545 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); | 1587 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); |
1546 | parentGroup.HasGroupChanged = true; | ||
1547 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1548 | |||
1549 | } | 1588 | } |
1550 | finally | 1589 | finally |
1551 | { | 1590 | { |
1591 | parentGroup.areUpdatesSuspended = false; | ||
1592 | parentGroup.HasGroupChanged = true; | ||
1593 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1552 | Monitor.Exit(m_updateLock); | 1594 | Monitor.Exit(m_updateLock); |
1553 | } | 1595 | } |
1554 | } | 1596 | } |
@@ -1585,11 +1627,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
1585 | } | 1627 | } |
1586 | } | 1628 | } |
1587 | 1629 | ||
1588 | foreach (SceneObjectPart child in childParts) | 1630 | if (childParts.Count > 0) |
1589 | { | 1631 | { |
1590 | // Unlink all child parts from their groups | 1632 | try |
1591 | // | 1633 | { |
1592 | child.ParentGroup.DelinkFromGroup(child, true); | 1634 | childParts[0].ParentGroup.areUpdatesSuspended = true; |
1635 | foreach (SceneObjectPart child in childParts) | ||
1636 | { | ||
1637 | // Unlink all child parts from their groups | ||
1638 | // | ||
1639 | child.ParentGroup.DelinkFromGroup(child, true); | ||
1640 | } | ||
1641 | } | ||
1642 | finally | ||
1643 | { | ||
1644 | childParts[0].ParentGroup.areUpdatesSuspended = false; | ||
1645 | } | ||
1593 | } | 1646 | } |
1594 | 1647 | ||
1595 | foreach (SceneObjectPart root in rootParts) | 1648 | foreach (SceneObjectPart root in rootParts) |
@@ -1613,10 +1666,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1613 | if (numChildren > 1) | 1666 | if (numChildren > 1) |
1614 | sendEventsToRemainder = false; | 1667 | sendEventsToRemainder = false; |
1615 | 1668 | ||
1616 | foreach (SceneObjectPart p in newSet) | 1669 | if (newSet.Count > 0) |
1617 | { | 1670 | { |
1618 | if (p != group.RootPart) | 1671 | try |
1619 | group.DelinkFromGroup(p, sendEventsToRemainder); | 1672 | { |
1673 | newSet[0].ParentGroup.areUpdatesSuspended = true; | ||
1674 | foreach (SceneObjectPart p in newSet) | ||
1675 | { | ||
1676 | if (p != group.RootPart) | ||
1677 | group.DelinkFromGroup(p, sendEventsToRemainder); | ||
1678 | } | ||
1679 | } | ||
1680 | finally | ||
1681 | { | ||
1682 | newSet[0].ParentGroup.areUpdatesSuspended = false; | ||
1683 | } | ||
1620 | } | 1684 | } |
1621 | 1685 | ||
1622 | // If there is more than one prim remaining, we | 1686 | // If there is more than one prim remaining, we |