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.cs238
1 files changed, 156 insertions, 82 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 24d7334..b016065 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
@@ -124,13 +133,18 @@ namespace OpenSim.Region.Framework.Scenes
124 133
125 protected internal void Close() 134 protected internal void Close()
126 { 135 {
127 lock (m_presenceLock) 136 m_scenePresencesLock.EnterWriteLock();
137 try
128 { 138 {
129 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 139 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
130 List<ScenePresence> newlist = new List<ScenePresence>(); 140 List<ScenePresence> newlist = new List<ScenePresence>();
131 m_scenePresenceMap = newmap; 141 m_scenePresenceMap = newmap;
132 m_scenePresenceArray = newlist; 142 m_scenePresenceArray = newlist;
133 } 143 }
144 finally
145 {
146 m_scenePresencesLock.ExitWriteLock();
147 }
134 148
135 lock (SceneObjectGroupsByFullID) 149 lock (SceneObjectGroupsByFullID)
136 SceneObjectGroupsByFullID.Clear(); 150 SceneObjectGroupsByFullID.Clear();
@@ -209,27 +223,8 @@ namespace OpenSim.Region.Framework.Scenes
209 if (sp.IsChildAgent) 223 if (sp.IsChildAgent)
210 return; 224 return;
211 225
212 if (sp.ParentID != 0) 226 coarseLocations.Add(sp.AbsolutePosition);
213 { 227 avatarUUIDs.Add(sp.UUID);
214 // sitting avatar
215 SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID);
216 if (sop != null)
217 {
218 coarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition);
219 avatarUUIDs.Add(sp.UUID);
220 }
221 else
222 {
223 // we can't find the parent.. ! arg!
224 coarseLocations.Add(sp.AbsolutePosition);
225 avatarUUIDs.Add(sp.UUID);
226 }
227 }
228 else
229 {
230 coarseLocations.Add(sp.AbsolutePosition);
231 avatarUUIDs.Add(sp.UUID);
232 }
233 } 228 }
234 } 229 }
235 230
@@ -259,6 +254,33 @@ namespace OpenSim.Region.Framework.Scenes
259 protected internal bool AddRestoredSceneObject( 254 protected internal bool AddRestoredSceneObject(
260 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 255 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
261 { 256 {
257 if (!m_parentScene.CombineRegions)
258 {
259 // KF: Check for out-of-region, move inside and make static.
260 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
261 sceneObject.RootPart.GroupPosition.Y,
262 sceneObject.RootPart.GroupPosition.Z);
263 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 ||
264 npos.X > Constants.RegionSize ||
265 npos.Y > Constants.RegionSize))
266 {
267 if (npos.X < 0.0) npos.X = 1.0f;
268 if (npos.Y < 0.0) npos.Y = 1.0f;
269 if (npos.Z < 0.0) npos.Z = 0.0f;
270 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
271 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
272
273 foreach (SceneObjectPart part in sceneObject.Parts)
274 {
275 part.GroupPosition = npos;
276 }
277 sceneObject.RootPart.Velocity = Vector3.Zero;
278 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
279 sceneObject.RootPart.Acceleration = Vector3.Zero;
280 sceneObject.RootPart.Velocity = Vector3.Zero;
281 }
282 }
283
262 if (!alreadyPersisted) 284 if (!alreadyPersisted)
263 { 285 {
264 sceneObject.ForceInventoryPersistence(); 286 sceneObject.ForceInventoryPersistence();
@@ -456,6 +478,30 @@ namespace OpenSim.Region.Framework.Scenes
456 m_updateList[obj.UUID] = obj; 478 m_updateList[obj.UUID] = obj;
457 } 479 }
458 480
481 public void FireAttachToBackup(SceneObjectGroup obj)
482 {
483 if (OnAttachToBackup != null)
484 {
485 OnAttachToBackup(obj);
486 }
487 }
488
489 public void FireDetachFromBackup(SceneObjectGroup obj)
490 {
491 if (OnDetachFromBackup != null)
492 {
493 OnDetachFromBackup(obj);
494 }
495 }
496
497 public void FireChangeBackup(SceneObjectGroup obj)
498 {
499 if (OnChangeBackup != null)
500 {
501 OnChangeBackup(obj);
502 }
503 }
504
459 /// <summary> 505 /// <summary>
460 /// Process all pending updates 506 /// Process all pending updates
461 /// </summary> 507 /// </summary>
@@ -590,7 +636,8 @@ namespace OpenSim.Region.Framework.Scenes
590 636
591 Entities[presence.UUID] = presence; 637 Entities[presence.UUID] = presence;
592 638
593 lock (m_presenceLock) 639 m_scenePresencesLock.EnterWriteLock();
640 try
594 { 641 {
595 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 642 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
596 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 643 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -614,6 +661,10 @@ namespace OpenSim.Region.Framework.Scenes
614 m_scenePresenceMap = newmap; 661 m_scenePresenceMap = newmap;
615 m_scenePresenceArray = newlist; 662 m_scenePresenceArray = newlist;
616 } 663 }
664 finally
665 {
666 m_scenePresencesLock.ExitWriteLock();
667 }
617 } 668 }
618 669
619 /// <summary> 670 /// <summary>
@@ -628,7 +679,8 @@ namespace OpenSim.Region.Framework.Scenes
628 agentID); 679 agentID);
629 } 680 }
630 681
631 lock (m_presenceLock) 682 m_scenePresencesLock.EnterWriteLock();
683 try
632 { 684 {
633 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 685 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
634 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 686 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -650,6 +702,10 @@ namespace OpenSim.Region.Framework.Scenes
650 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 702 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
651 } 703 }
652 } 704 }
705 finally
706 {
707 m_scenePresencesLock.ExitWriteLock();
708 }
653 } 709 }
654 710
655 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 711 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -773,6 +829,11 @@ namespace OpenSim.Region.Framework.Scenes
773 return m_scenePresenceArray; 829 return m_scenePresenceArray;
774 } 830 }
775 831
832 public int GetNumberOfScenePresences()
833 {
834 return m_scenePresenceArray.Count;
835 }
836
776 /// <summary> 837 /// <summary>
777 /// Request a scene presence by UUID. Fast, indexed lookup. 838 /// Request a scene presence by UUID. Fast, indexed lookup.
778 /// </summary> 839 /// </summary>
@@ -1066,9 +1127,11 @@ namespace OpenSim.Region.Framework.Scenes
1066 /// <param name="action"></param> 1127 /// <param name="action"></param>
1067 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1128 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1068 { 1129 {
1069 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1130 EntityBase[] objlist = Entities.GetAllByType<SceneObjectGroup>();
1070 foreach (SceneObjectGroup obj in objlist) 1131 foreach (EntityBase ent in objlist)
1071 { 1132 {
1133 SceneObjectGroup obj = (SceneObjectGroup)ent;
1134
1072 try 1135 try
1073 { 1136 {
1074 action(obj); 1137 action(obj);
@@ -1524,10 +1587,13 @@ namespace OpenSim.Region.Framework.Scenes
1524 /// <param name="childPrims"></param> 1587 /// <param name="childPrims"></param>
1525 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1588 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1526 { 1589 {
1590 SceneObjectGroup parentGroup = root.ParentGroup;
1591 if (parentGroup == null) return;
1527 Monitor.Enter(m_updateLock); 1592 Monitor.Enter(m_updateLock);
1593
1528 try 1594 try
1529 { 1595 {
1530 SceneObjectGroup parentGroup = root.ParentGroup; 1596 parentGroup.areUpdatesSuspended = true;
1531 1597
1532 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1598 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1533 if (parentGroup != null) 1599 if (parentGroup != null)
@@ -1539,11 +1605,6 @@ namespace OpenSim.Region.Framework.Scenes
1539 1605
1540 if (child != null) 1606 if (child != null)
1541 { 1607 {
1542 // Make sure no child prim is set for sale
1543 // So that, on delink, no prims are unwittingly
1544 // left for sale and sold off
1545 child.RootPart.ObjectSaleType = 0;
1546 child.RootPart.SalePrice = 10;
1547 childGroups.Add(child); 1608 childGroups.Add(child);
1548 } 1609 }
1549 } 1610 }
@@ -1566,12 +1627,12 @@ namespace OpenSim.Region.Framework.Scenes
1566 // occur on link to invoke this elsewhere (such as object selection) 1627 // occur on link to invoke this elsewhere (such as object selection)
1567 parentGroup.RootPart.CreateSelected = true; 1628 parentGroup.RootPart.CreateSelected = true;
1568 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1629 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1569 parentGroup.HasGroupChanged = true;
1570 parentGroup.ScheduleGroupForFullUpdate();
1571
1572 } 1630 }
1573 finally 1631 finally
1574 { 1632 {
1633 parentGroup.areUpdatesSuspended = false;
1634 parentGroup.HasGroupChanged = true;
1635 parentGroup.ScheduleGroupForFullUpdate();
1575 Monitor.Exit(m_updateLock); 1636 Monitor.Exit(m_updateLock);
1576 } 1637 }
1577 } 1638 }
@@ -1603,21 +1664,24 @@ namespace OpenSim.Region.Framework.Scenes
1603 1664
1604 SceneObjectGroup group = part.ParentGroup; 1665 SceneObjectGroup group = part.ParentGroup;
1605 if (!affectedGroups.Contains(group)) 1666 if (!affectedGroups.Contains(group))
1667 {
1668 group.areUpdatesSuspended = true;
1606 affectedGroups.Add(group); 1669 affectedGroups.Add(group);
1670 }
1607 } 1671 }
1608 } 1672 }
1609 } 1673 }
1610 1674
1611 foreach (SceneObjectPart child in childParts) 1675 if (childParts.Count > 0)
1612 { 1676 {
1613 // Unlink all child parts from their groups 1677 foreach (SceneObjectPart child in childParts)
1614 // 1678 {
1615 child.ParentGroup.DelinkFromGroup(child, true); 1679 // Unlink all child parts from their groups
1616 1680 //
1617 // These are not in affected groups and will not be 1681 child.ParentGroup.DelinkFromGroup(child, true);
1618 // handled further. Do the honors here. 1682 child.ParentGroup.HasGroupChanged = true;
1619 child.ParentGroup.HasGroupChanged = true; 1683 child.ParentGroup.ScheduleGroupForFullUpdate();
1620 child.ParentGroup.ScheduleGroupForFullUpdate(); 1684 }
1621 } 1685 }
1622 1686
1623 foreach (SceneObjectPart root in rootParts) 1687 foreach (SceneObjectPart root in rootParts)
@@ -1627,56 +1691,68 @@ namespace OpenSim.Region.Framework.Scenes
1627 // However, editing linked parts and unlinking may be different 1691 // However, editing linked parts and unlinking may be different
1628 // 1692 //
1629 SceneObjectGroup group = root.ParentGroup; 1693 SceneObjectGroup group = root.ParentGroup;
1694 group.areUpdatesSuspended = true;
1630 1695
1631 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1696 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1632 int numChildren = newSet.Count; 1697 int numChildren = newSet.Count;
1633 1698
1699 if (numChildren == 1)
1700 break;
1701
1634 // If there are prims left in a link set, but the root is 1702 // If there are prims left in a link set, but the root is
1635 // slated for unlink, we need to do this 1703 // slated for unlink, we need to do this
1704 // Unlink the remaining set
1636 // 1705 //
1637 if (numChildren != 1) 1706 bool sendEventsToRemainder = true;
1638 { 1707 if (numChildren > 1)
1639 // Unlink the remaining set 1708 sendEventsToRemainder = false;
1640 //
1641 bool sendEventsToRemainder = true;
1642 if (numChildren > 1)
1643 sendEventsToRemainder = false;
1644 1709
1645 foreach (SceneObjectPart p in newSet) 1710 foreach (SceneObjectPart p in newSet)
1711 {
1712 if (p != group.RootPart)
1646 { 1713 {
1647 if (p != group.RootPart) 1714 group.DelinkFromGroup(p, sendEventsToRemainder);
1648 group.DelinkFromGroup(p, sendEventsToRemainder); 1715 if (numChildren > 2)
1716 {
1717 p.ParentGroup.areUpdatesSuspended = true;
1718 }
1719 else
1720 {
1721 p.ParentGroup.HasGroupChanged = true;
1722 p.ParentGroup.ScheduleGroupForFullUpdate();
1723 }
1649 } 1724 }
1725 }
1726
1727 // If there is more than one prim remaining, we
1728 // need to re-link
1729 //
1730 if (numChildren > 2)
1731 {
1732 // Remove old root
1733 //
1734 if (newSet.Contains(root))
1735 newSet.Remove(root);
1650 1736
1651 // If there is more than one prim remaining, we 1737 // Preserve link ordering
1652 // need to re-link
1653 // 1738 //
1654 if (numChildren > 2) 1739 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1655 { 1740 {
1656 // Remove old root 1741 return a.LinkNum.CompareTo(b.LinkNum);
1657 // 1742 });
1658 if (newSet.Contains(root))
1659 newSet.Remove(root);
1660
1661 // Preserve link ordering
1662 //
1663 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1664 {
1665 return a.LinkNum.CompareTo(b.LinkNum);
1666 });
1667 1743
1668 // Determine new root 1744 // Determine new root
1669 // 1745 //
1670 SceneObjectPart newRoot = newSet[0]; 1746 SceneObjectPart newRoot = newSet[0];
1671 newSet.RemoveAt(0); 1747 newSet.RemoveAt(0);
1672 1748
1673 foreach (SceneObjectPart newChild in newSet) 1749 foreach (SceneObjectPart newChild in newSet)
1674 newChild.UpdateFlag = 0; 1750 newChild.UpdateFlag = 0;
1675 1751
1676 LinkObjects(newRoot, newSet); 1752 newRoot.ParentGroup.areUpdatesSuspended = true;
1677 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1753 LinkObjects(newRoot, newSet);
1678 affectedGroups.Add(newRoot.ParentGroup); 1754 if (!affectedGroups.Contains(newRoot.ParentGroup))
1679 } 1755 affectedGroups.Add(newRoot.ParentGroup);
1680 } 1756 }
1681 } 1757 }
1682 1758
@@ -1686,6 +1762,7 @@ namespace OpenSim.Region.Framework.Scenes
1686 { 1762 {
1687 g.TriggerScriptChangedEvent(Changed.LINK); 1763 g.TriggerScriptChangedEvent(Changed.LINK);
1688 g.HasGroupChanged = true; // Persist 1764 g.HasGroupChanged = true; // Persist
1765 g.areUpdatesSuspended = false;
1689 g.ScheduleGroupForFullUpdate(); 1766 g.ScheduleGroupForFullUpdate();
1690 } 1767 }
1691 } 1768 }
@@ -1800,9 +1877,6 @@ namespace OpenSim.Region.Framework.Scenes
1800 child.ApplyNextOwnerPermissions(); 1877 child.ApplyNextOwnerPermissions();
1801 } 1878 }
1802 } 1879 }
1803
1804 copy.RootPart.ObjectSaleType = 0;
1805 copy.RootPart.SalePrice = 10;
1806 } 1880 }
1807 1881
1808 Entities.Add(copy); 1882 Entities.Add(copy);