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 a02f614..5fbc658 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 | { |
@@ -228,6 +233,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
228 | protected internal bool AddRestoredSceneObject( | 233 | protected internal bool AddRestoredSceneObject( |
229 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) | 234 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) |
230 | { | 235 | { |
236 | // KF: Check for out-of-region, move inside and make static. | ||
237 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | ||
238 | sceneObject.RootPart.GroupPosition.Y, | ||
239 | sceneObject.RootPart.GroupPosition.Z); | ||
240 | 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 || | ||
241 | npos.X > Constants.RegionSize || | ||
242 | npos.Y > Constants.RegionSize)) | ||
243 | { | ||
244 | if (npos.X < 0.0) npos.X = 1.0f; | ||
245 | if (npos.Y < 0.0) npos.Y = 1.0f; | ||
246 | if (npos.Z < 0.0) npos.Z = 0.0f; | ||
247 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; | ||
248 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; | ||
249 | |||
250 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
251 | { | ||
252 | part.GroupPosition = npos; | ||
253 | } | ||
254 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
255 | sceneObject.RootPart.AngularVelocity = Vector3.Zero; | ||
256 | sceneObject.RootPart.Acceleration = Vector3.Zero; | ||
257 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
258 | } | ||
259 | |||
231 | if (!alreadyPersisted) | 260 | if (!alreadyPersisted) |
232 | { | 261 | { |
233 | sceneObject.ForceInventoryPersistence(); | 262 | sceneObject.ForceInventoryPersistence(); |
@@ -524,7 +553,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
524 | 553 | ||
525 | Entities[presence.UUID] = presence; | 554 | Entities[presence.UUID] = presence; |
526 | 555 | ||
527 | lock (m_presenceLock) | 556 | m_scenePresencesLock.EnterWriteLock(); |
557 | try | ||
528 | { | 558 | { |
529 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 559 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
530 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 560 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -548,6 +578,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
548 | m_scenePresenceMap = newmap; | 578 | m_scenePresenceMap = newmap; |
549 | m_scenePresenceArray = newlist; | 579 | m_scenePresenceArray = newlist; |
550 | } | 580 | } |
581 | finally | ||
582 | { | ||
583 | m_scenePresencesLock.ExitWriteLock(); | ||
584 | } | ||
551 | } | 585 | } |
552 | 586 | ||
553 | /// <summary> | 587 | /// <summary> |
@@ -562,7 +596,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
562 | agentID); | 596 | agentID); |
563 | } | 597 | } |
564 | 598 | ||
565 | lock (m_presenceLock) | 599 | m_scenePresencesLock.EnterWriteLock(); |
600 | try | ||
566 | { | 601 | { |
567 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 602 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
568 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 603 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -583,6 +618,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
583 | m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 618 | m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); |
584 | } | 619 | } |
585 | } | 620 | } |
621 | finally | ||
622 | { | ||
623 | m_scenePresencesLock.ExitWriteLock(); | ||
624 | } | ||
586 | } | 625 | } |
587 | 626 | ||
588 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) | 627 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) |
@@ -1460,10 +1499,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1460 | /// <param name="childPrims"></param> | 1499 | /// <param name="childPrims"></param> |
1461 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) | 1500 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) |
1462 | { | 1501 | { |
1502 | SceneObjectGroup parentGroup = root.ParentGroup; | ||
1503 | if (parentGroup == null) return; | ||
1463 | Monitor.Enter(m_updateLock); | 1504 | Monitor.Enter(m_updateLock); |
1505 | |||
1464 | try | 1506 | try |
1465 | { | 1507 | { |
1466 | SceneObjectGroup parentGroup = root.ParentGroup; | 1508 | parentGroup.areUpdatesSuspended = true; |
1467 | 1509 | ||
1468 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); | 1510 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); |
1469 | if (parentGroup != null) | 1511 | if (parentGroup != null) |
@@ -1502,12 +1544,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1502 | // occur on link to invoke this elsewhere (such as object selection) | 1544 | // occur on link to invoke this elsewhere (such as object selection) |
1503 | parentGroup.RootPart.CreateSelected = true; | 1545 | parentGroup.RootPart.CreateSelected = true; |
1504 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); | 1546 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); |
1505 | parentGroup.HasGroupChanged = true; | ||
1506 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1507 | |||
1508 | } | 1547 | } |
1509 | finally | 1548 | finally |
1510 | { | 1549 | { |
1550 | parentGroup.areUpdatesSuspended = false; | ||
1551 | parentGroup.HasGroupChanged = true; | ||
1552 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1511 | Monitor.Exit(m_updateLock); | 1553 | Monitor.Exit(m_updateLock); |
1512 | } | 1554 | } |
1513 | } | 1555 | } |
@@ -1544,11 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
1544 | } | 1586 | } |
1545 | } | 1587 | } |
1546 | 1588 | ||
1547 | foreach (SceneObjectPart child in childParts) | 1589 | if (childParts.Count > 0) |
1548 | { | 1590 | { |
1549 | // Unlink all child parts from their groups | 1591 | try |
1550 | // | 1592 | { |
1551 | child.ParentGroup.DelinkFromGroup(child, true); | 1593 | childParts[0].ParentGroup.areUpdatesSuspended = true; |
1594 | foreach (SceneObjectPart child in childParts) | ||
1595 | { | ||
1596 | // Unlink all child parts from their groups | ||
1597 | // | ||
1598 | child.ParentGroup.DelinkFromGroup(child, true); | ||
1599 | } | ||
1600 | } | ||
1601 | finally | ||
1602 | { | ||
1603 | childParts[0].ParentGroup.areUpdatesSuspended = false; | ||
1604 | } | ||
1552 | } | 1605 | } |
1553 | 1606 | ||
1554 | foreach (SceneObjectPart root in rootParts) | 1607 | foreach (SceneObjectPart root in rootParts) |
@@ -1572,10 +1625,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1572 | if (numChildren > 1) | 1625 | if (numChildren > 1) |
1573 | sendEventsToRemainder = false; | 1626 | sendEventsToRemainder = false; |
1574 | 1627 | ||
1575 | foreach (SceneObjectPart p in newSet) | 1628 | if (newSet.Count > 0) |
1576 | { | 1629 | { |
1577 | if (p != group.RootPart) | 1630 | try |
1578 | group.DelinkFromGroup(p, sendEventsToRemainder); | 1631 | { |
1632 | newSet[0].ParentGroup.areUpdatesSuspended = true; | ||
1633 | foreach (SceneObjectPart p in newSet) | ||
1634 | { | ||
1635 | if (p != group.RootPart) | ||
1636 | group.DelinkFromGroup(p, sendEventsToRemainder); | ||
1637 | } | ||
1638 | } | ||
1639 | finally | ||
1640 | { | ||
1641 | newSet[0].ParentGroup.areUpdatesSuspended = false; | ||
1642 | } | ||
1579 | } | 1643 | } |
1580 | 1644 | ||
1581 | // If there is more than one prim remaining, we | 1645 | // If there is more than one prim remaining, we |