diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 131 |
1 files changed, 116 insertions, 15 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 240c688..81ef54f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -43,6 +43,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
43 | 43 | ||
44 | public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone); | 44 | public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone); |
45 | 45 | ||
46 | public delegate void AttachToBackupDelegate(SceneObjectGroup sog); | ||
47 | |||
48 | public delegate void DetachFromBackupDelegate(SceneObjectGroup sog); | ||
49 | |||
50 | public delegate void ChangedBackupDelegate(SceneObjectGroup sog); | ||
51 | |||
46 | public delegate void ObjectCreateDelegate(EntityBase obj); | 52 | public delegate void ObjectCreateDelegate(EntityBase obj); |
47 | 53 | ||
48 | public delegate void ObjectDeleteDelegate(EntityBase obj); | 54 | public delegate void ObjectDeleteDelegate(EntityBase obj); |
@@ -61,6 +67,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
61 | private PhysicsCrash handlerPhysicsCrash = null; | 67 | private PhysicsCrash handlerPhysicsCrash = null; |
62 | 68 | ||
63 | public event ObjectDuplicateDelegate OnObjectDuplicate; | 69 | public event ObjectDuplicateDelegate OnObjectDuplicate; |
70 | public event AttachToBackupDelegate OnAttachToBackup; | ||
71 | public event DetachFromBackupDelegate OnDetachFromBackup; | ||
72 | public event ChangedBackupDelegate OnChangeBackup; | ||
64 | public event ObjectCreateDelegate OnObjectCreate; | 73 | public event ObjectCreateDelegate OnObjectCreate; |
65 | public event ObjectDeleteDelegate OnObjectRemove; | 74 | public event ObjectDeleteDelegate OnObjectRemove; |
66 | 75 | ||
@@ -68,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
68 | 77 | ||
69 | #region Fields | 78 | #region Fields |
70 | 79 | ||
71 | protected object m_presenceLock = new object(); | 80 | protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); |
72 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); | 81 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); |
73 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); | 82 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); |
74 | 83 | ||
@@ -133,13 +142,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
133 | 142 | ||
134 | protected internal void Close() | 143 | protected internal void Close() |
135 | { | 144 | { |
136 | lock (m_presenceLock) | 145 | m_scenePresencesLock.EnterWriteLock(); |
146 | try | ||
137 | { | 147 | { |
138 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); | 148 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); |
139 | List<ScenePresence> newlist = new List<ScenePresence>(); | 149 | List<ScenePresence> newlist = new List<ScenePresence>(); |
140 | m_scenePresenceMap = newmap; | 150 | m_scenePresenceMap = newmap; |
141 | m_scenePresenceArray = newlist; | 151 | m_scenePresenceArray = newlist; |
142 | } | 152 | } |
153 | finally | ||
154 | { | ||
155 | m_scenePresencesLock.ExitWriteLock(); | ||
156 | } | ||
143 | 157 | ||
144 | lock (m_dictionary_lock) | 158 | lock (m_dictionary_lock) |
145 | { | 159 | { |
@@ -269,6 +283,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
269 | protected internal bool AddRestoredSceneObject( | 283 | protected internal bool AddRestoredSceneObject( |
270 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) | 284 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) |
271 | { | 285 | { |
286 | // KF: Check for out-of-region, move inside and make static. | ||
287 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | ||
288 | sceneObject.RootPart.GroupPosition.Y, | ||
289 | sceneObject.RootPart.GroupPosition.Z); | ||
290 | 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 || | ||
291 | npos.X > Constants.RegionSize || | ||
292 | npos.Y > Constants.RegionSize)) | ||
293 | { | ||
294 | if (npos.X < 0.0) npos.X = 1.0f; | ||
295 | if (npos.Y < 0.0) npos.Y = 1.0f; | ||
296 | if (npos.Z < 0.0) npos.Z = 0.0f; | ||
297 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; | ||
298 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; | ||
299 | |||
300 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
301 | { | ||
302 | part.GroupPosition = npos; | ||
303 | } | ||
304 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
305 | sceneObject.RootPart.AngularVelocity = Vector3.Zero; | ||
306 | sceneObject.RootPart.Acceleration = Vector3.Zero; | ||
307 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
308 | } | ||
309 | |||
272 | if (!alreadyPersisted) | 310 | if (!alreadyPersisted) |
273 | { | 311 | { |
274 | sceneObject.ForceInventoryPersistence(); | 312 | sceneObject.ForceInventoryPersistence(); |
@@ -359,10 +397,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
359 | m_numPrim += sceneObject.Children.Count; | 397 | m_numPrim += sceneObject.Children.Count; |
360 | 398 | ||
361 | if (attachToBackup) | 399 | if (attachToBackup) |
400 | { | ||
362 | sceneObject.AttachToBackup(); | 401 | sceneObject.AttachToBackup(); |
402 | } | ||
363 | 403 | ||
364 | if (OnObjectCreate != null) | 404 | if (OnObjectCreate != null) |
405 | { | ||
365 | OnObjectCreate(sceneObject); | 406 | OnObjectCreate(sceneObject); |
407 | } | ||
366 | 408 | ||
367 | lock (m_dictionary_lock) | 409 | lock (m_dictionary_lock) |
368 | { | 410 | { |
@@ -429,6 +471,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
429 | } | 471 | } |
430 | } | 472 | } |
431 | 473 | ||
474 | public void FireAttachToBackup(SceneObjectGroup obj) | ||
475 | { | ||
476 | if (OnAttachToBackup != null) | ||
477 | { | ||
478 | OnAttachToBackup(obj); | ||
479 | } | ||
480 | } | ||
481 | |||
482 | public void FireDetachFromBackup(SceneObjectGroup obj) | ||
483 | { | ||
484 | if (OnDetachFromBackup != null) | ||
485 | { | ||
486 | OnDetachFromBackup(obj); | ||
487 | } | ||
488 | } | ||
489 | |||
490 | public void FireChangeBackup(SceneObjectGroup obj) | ||
491 | { | ||
492 | if (OnChangeBackup != null) | ||
493 | { | ||
494 | OnChangeBackup(obj); | ||
495 | } | ||
496 | } | ||
497 | |||
432 | /// <summary> | 498 | /// <summary> |
433 | /// Process all pending updates | 499 | /// Process all pending updates |
434 | /// </summary> | 500 | /// </summary> |
@@ -565,7 +631,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
565 | 631 | ||
566 | Entities[presence.UUID] = presence; | 632 | Entities[presence.UUID] = presence; |
567 | 633 | ||
568 | lock (m_presenceLock) | 634 | m_scenePresencesLock.EnterWriteLock(); |
635 | try | ||
569 | { | 636 | { |
570 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 637 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
571 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 638 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -589,6 +656,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
589 | m_scenePresenceMap = newmap; | 656 | m_scenePresenceMap = newmap; |
590 | m_scenePresenceArray = newlist; | 657 | m_scenePresenceArray = newlist; |
591 | } | 658 | } |
659 | finally | ||
660 | { | ||
661 | m_scenePresencesLock.ExitWriteLock(); | ||
662 | } | ||
592 | } | 663 | } |
593 | 664 | ||
594 | /// <summary> | 665 | /// <summary> |
@@ -603,7 +674,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
603 | agentID); | 674 | agentID); |
604 | } | 675 | } |
605 | 676 | ||
606 | lock (m_presenceLock) | 677 | m_scenePresencesLock.EnterWriteLock(); |
678 | try | ||
607 | { | 679 | { |
608 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 680 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
609 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 681 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -625,6 +697,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
625 | m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 697 | m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); |
626 | } | 698 | } |
627 | } | 699 | } |
700 | finally | ||
701 | { | ||
702 | m_scenePresencesLock.ExitWriteLock(); | ||
703 | } | ||
628 | } | 704 | } |
629 | 705 | ||
630 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) | 706 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) |
@@ -1502,10 +1578,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1502 | /// <param name="childPrims"></param> | 1578 | /// <param name="childPrims"></param> |
1503 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) | 1579 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) |
1504 | { | 1580 | { |
1581 | SceneObjectGroup parentGroup = root.ParentGroup; | ||
1582 | if (parentGroup == null) return; | ||
1505 | Monitor.Enter(m_updateLock); | 1583 | Monitor.Enter(m_updateLock); |
1584 | |||
1506 | try | 1585 | try |
1507 | { | 1586 | { |
1508 | SceneObjectGroup parentGroup = root.ParentGroup; | 1587 | parentGroup.areUpdatesSuspended = true; |
1509 | 1588 | ||
1510 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); | 1589 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); |
1511 | if (parentGroup != null) | 1590 | if (parentGroup != null) |
@@ -1544,12 +1623,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1544 | // occur on link to invoke this elsewhere (such as object selection) | 1623 | // occur on link to invoke this elsewhere (such as object selection) |
1545 | parentGroup.RootPart.CreateSelected = true; | 1624 | parentGroup.RootPart.CreateSelected = true; |
1546 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); | 1625 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); |
1547 | parentGroup.HasGroupChanged = true; | ||
1548 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1549 | |||
1550 | } | 1626 | } |
1551 | finally | 1627 | finally |
1552 | { | 1628 | { |
1629 | parentGroup.areUpdatesSuspended = false; | ||
1630 | parentGroup.HasGroupChanged = true; | ||
1631 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1553 | Monitor.Exit(m_updateLock); | 1632 | Monitor.Exit(m_updateLock); |
1554 | } | 1633 | } |
1555 | } | 1634 | } |
@@ -1586,11 +1665,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
1586 | } | 1665 | } |
1587 | } | 1666 | } |
1588 | 1667 | ||
1589 | foreach (SceneObjectPart child in childParts) | 1668 | if (childParts.Count > 0) |
1590 | { | 1669 | { |
1591 | // Unlink all child parts from their groups | 1670 | try |
1592 | // | 1671 | { |
1593 | child.ParentGroup.DelinkFromGroup(child, true); | 1672 | childParts[0].ParentGroup.areUpdatesSuspended = true; |
1673 | foreach (SceneObjectPart child in childParts) | ||
1674 | { | ||
1675 | // Unlink all child parts from their groups | ||
1676 | // | ||
1677 | child.ParentGroup.DelinkFromGroup(child, true); | ||
1678 | } | ||
1679 | } | ||
1680 | finally | ||
1681 | { | ||
1682 | childParts[0].ParentGroup.areUpdatesSuspended = false; | ||
1683 | } | ||
1594 | } | 1684 | } |
1595 | 1685 | ||
1596 | foreach (SceneObjectPart root in rootParts) | 1686 | foreach (SceneObjectPart root in rootParts) |
@@ -1614,10 +1704,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1614 | if (numChildren > 1) | 1704 | if (numChildren > 1) |
1615 | sendEventsToRemainder = false; | 1705 | sendEventsToRemainder = false; |
1616 | 1706 | ||
1617 | foreach (SceneObjectPart p in newSet) | 1707 | if (newSet.Count > 0) |
1618 | { | 1708 | { |
1619 | if (p != group.RootPart) | 1709 | try |
1620 | group.DelinkFromGroup(p, sendEventsToRemainder); | 1710 | { |
1711 | newSet[0].ParentGroup.areUpdatesSuspended = true; | ||
1712 | foreach (SceneObjectPart p in newSet) | ||
1713 | { | ||
1714 | if (p != group.RootPart) | ||
1715 | group.DelinkFromGroup(p, sendEventsToRemainder); | ||
1716 | } | ||
1717 | } | ||
1718 | finally | ||
1719 | { | ||
1720 | newSet[0].ParentGroup.areUpdatesSuspended = false; | ||
1721 | } | ||
1621 | } | 1722 | } |
1622 | 1723 | ||
1623 | // If there is more than one prim remaining, we | 1724 | // If there is more than one prim remaining, we |