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 a79dc98..1163ebf 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();
@@ -453,6 +475,30 @@ namespace OpenSim.Region.Framework.Scenes
453 m_updateList[obj.UUID] = obj; 475 m_updateList[obj.UUID] = obj;
454 } 476 }
455 477
478 public void FireAttachToBackup(SceneObjectGroup obj)
479 {
480 if (OnAttachToBackup != null)
481 {
482 OnAttachToBackup(obj);
483 }
484 }
485
486 public void FireDetachFromBackup(SceneObjectGroup obj)
487 {
488 if (OnDetachFromBackup != null)
489 {
490 OnDetachFromBackup(obj);
491 }
492 }
493
494 public void FireChangeBackup(SceneObjectGroup obj)
495 {
496 if (OnChangeBackup != null)
497 {
498 OnChangeBackup(obj);
499 }
500 }
501
456 /// <summary> 502 /// <summary>
457 /// Process all pending updates 503 /// Process all pending updates
458 /// </summary> 504 /// </summary>
@@ -587,7 +633,8 @@ namespace OpenSim.Region.Framework.Scenes
587 633
588 Entities[presence.UUID] = presence; 634 Entities[presence.UUID] = presence;
589 635
590 lock (m_presenceLock) 636 m_scenePresencesLock.EnterWriteLock();
637 try
591 { 638 {
592 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 639 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
593 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 640 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -611,6 +658,10 @@ namespace OpenSim.Region.Framework.Scenes
611 m_scenePresenceMap = newmap; 658 m_scenePresenceMap = newmap;
612 m_scenePresenceArray = newlist; 659 m_scenePresenceArray = newlist;
613 } 660 }
661 finally
662 {
663 m_scenePresencesLock.ExitWriteLock();
664 }
614 } 665 }
615 666
616 /// <summary> 667 /// <summary>
@@ -625,7 +676,8 @@ namespace OpenSim.Region.Framework.Scenes
625 agentID); 676 agentID);
626 } 677 }
627 678
628 lock (m_presenceLock) 679 m_scenePresencesLock.EnterWriteLock();
680 try
629 { 681 {
630 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 682 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
631 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 683 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -647,6 +699,10 @@ namespace OpenSim.Region.Framework.Scenes
647 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 699 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
648 } 700 }
649 } 701 }
702 finally
703 {
704 m_scenePresencesLock.ExitWriteLock();
705 }
650 } 706 }
651 707
652 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 708 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -770,6 +826,11 @@ namespace OpenSim.Region.Framework.Scenes
770 return m_scenePresenceArray; 826 return m_scenePresenceArray;
771 } 827 }
772 828
829 public int GetNumberOfScenePresences()
830 {
831 return m_scenePresenceArray.Count;
832 }
833
773 /// <summary> 834 /// <summary>
774 /// Request a scene presence by UUID. Fast, indexed lookup. 835 /// Request a scene presence by UUID. Fast, indexed lookup.
775 /// </summary> 836 /// </summary>
@@ -1063,9 +1124,11 @@ namespace OpenSim.Region.Framework.Scenes
1063 /// <param name="action"></param> 1124 /// <param name="action"></param>
1064 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1125 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1065 { 1126 {
1066 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1127 EntityBase[] objlist = Entities.GetAllByType<SceneObjectGroup>();
1067 foreach (SceneObjectGroup obj in objlist) 1128 foreach (EntityBase ent in objlist)
1068 { 1129 {
1130 SceneObjectGroup obj = (SceneObjectGroup)ent;
1131
1069 try 1132 try
1070 { 1133 {
1071 action(obj); 1134 action(obj);
@@ -1522,10 +1585,13 @@ namespace OpenSim.Region.Framework.Scenes
1522 /// <param name="childPrims"></param> 1585 /// <param name="childPrims"></param>
1523 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1586 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1524 { 1587 {
1588 SceneObjectGroup parentGroup = root.ParentGroup;
1589 if (parentGroup == null) return;
1525 Monitor.Enter(m_updateLock); 1590 Monitor.Enter(m_updateLock);
1591
1526 try 1592 try
1527 { 1593 {
1528 SceneObjectGroup parentGroup = root.ParentGroup; 1594 parentGroup.areUpdatesSuspended = true;
1529 1595
1530 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1596 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1531 if (parentGroup != null) 1597 if (parentGroup != null)
@@ -1537,11 +1603,6 @@ namespace OpenSim.Region.Framework.Scenes
1537 1603
1538 if (child != null) 1604 if (child != null)
1539 { 1605 {
1540 // Make sure no child prim is set for sale
1541 // So that, on delink, no prims are unwittingly
1542 // left for sale and sold off
1543 child.RootPart.ObjectSaleType = 0;
1544 child.RootPart.SalePrice = 10;
1545 childGroups.Add(child); 1606 childGroups.Add(child);
1546 } 1607 }
1547 } 1608 }
@@ -1564,12 +1625,12 @@ namespace OpenSim.Region.Framework.Scenes
1564 // occur on link to invoke this elsewhere (such as object selection) 1625 // occur on link to invoke this elsewhere (such as object selection)
1565 parentGroup.RootPart.CreateSelected = true; 1626 parentGroup.RootPart.CreateSelected = true;
1566 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1627 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1567 parentGroup.HasGroupChanged = true;
1568 parentGroup.ScheduleGroupForFullUpdate();
1569
1570 } 1628 }
1571 finally 1629 finally
1572 { 1630 {
1631 parentGroup.areUpdatesSuspended = false;
1632 parentGroup.HasGroupChanged = true;
1633 parentGroup.ScheduleGroupForFullUpdate();
1573 Monitor.Exit(m_updateLock); 1634 Monitor.Exit(m_updateLock);
1574 } 1635 }
1575 } 1636 }
@@ -1601,21 +1662,24 @@ namespace OpenSim.Region.Framework.Scenes
1601 1662
1602 SceneObjectGroup group = part.ParentGroup; 1663 SceneObjectGroup group = part.ParentGroup;
1603 if (!affectedGroups.Contains(group)) 1664 if (!affectedGroups.Contains(group))
1665 {
1666 group.areUpdatesSuspended = true;
1604 affectedGroups.Add(group); 1667 affectedGroups.Add(group);
1668 }
1605 } 1669 }
1606 } 1670 }
1607 } 1671 }
1608 1672
1609 foreach (SceneObjectPart child in childParts) 1673 if (childParts.Count > 0)
1610 { 1674 {
1611 // Unlink all child parts from their groups 1675 foreach (SceneObjectPart child in childParts)
1612 // 1676 {
1613 child.ParentGroup.DelinkFromGroup(child, true); 1677 // Unlink all child parts from their groups
1614 1678 //
1615 // These are not in affected groups and will not be 1679 child.ParentGroup.DelinkFromGroup(child, true);
1616 // handled further. Do the honors here. 1680 child.ParentGroup.HasGroupChanged = true;
1617 child.ParentGroup.HasGroupChanged = true; 1681 child.ParentGroup.ScheduleGroupForFullUpdate();
1618 child.ParentGroup.ScheduleGroupForFullUpdate(); 1682 }
1619 } 1683 }
1620 1684
1621 foreach (SceneObjectPart root in rootParts) 1685 foreach (SceneObjectPart root in rootParts)
@@ -1625,56 +1689,68 @@ namespace OpenSim.Region.Framework.Scenes
1625 // However, editing linked parts and unlinking may be different 1689 // However, editing linked parts and unlinking may be different
1626 // 1690 //
1627 SceneObjectGroup group = root.ParentGroup; 1691 SceneObjectGroup group = root.ParentGroup;
1692 group.areUpdatesSuspended = true;
1628 1693
1629 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1694 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1630 int numChildren = newSet.Count; 1695 int numChildren = newSet.Count;
1631 1696
1697 if (numChildren == 1)
1698 break;
1699
1632 // If there are prims left in a link set, but the root is 1700 // If there are prims left in a link set, but the root is
1633 // slated for unlink, we need to do this 1701 // slated for unlink, we need to do this
1702 // Unlink the remaining set
1634 // 1703 //
1635 if (numChildren != 1) 1704 bool sendEventsToRemainder = true;
1636 { 1705 if (numChildren > 1)
1637 // Unlink the remaining set 1706 sendEventsToRemainder = false;
1638 //
1639 bool sendEventsToRemainder = true;
1640 if (numChildren > 1)
1641 sendEventsToRemainder = false;
1642 1707
1643 foreach (SceneObjectPart p in newSet) 1708 foreach (SceneObjectPart p in newSet)
1709 {
1710 if (p != group.RootPart)
1644 { 1711 {
1645 if (p != group.RootPart) 1712 group.DelinkFromGroup(p, sendEventsToRemainder);
1646 group.DelinkFromGroup(p, sendEventsToRemainder); 1713 if (numChildren > 2)
1714 {
1715 p.ParentGroup.areUpdatesSuspended = true;
1716 }
1717 else
1718 {
1719 p.ParentGroup.HasGroupChanged = true;
1720 p.ParentGroup.ScheduleGroupForFullUpdate();
1721 }
1647 } 1722 }
1723 }
1724
1725 // If there is more than one prim remaining, we
1726 // need to re-link
1727 //
1728 if (numChildren > 2)
1729 {
1730 // Remove old root
1731 //
1732 if (newSet.Contains(root))
1733 newSet.Remove(root);
1648 1734
1649 // If there is more than one prim remaining, we 1735 // Preserve link ordering
1650 // need to re-link
1651 // 1736 //
1652 if (numChildren > 2) 1737 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1653 { 1738 {
1654 // Remove old root 1739 return a.LinkNum.CompareTo(b.LinkNum);
1655 // 1740 });
1656 if (newSet.Contains(root))
1657 newSet.Remove(root);
1658
1659 // Preserve link ordering
1660 //
1661 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1662 {
1663 return a.LinkNum.CompareTo(b.LinkNum);
1664 });
1665 1741
1666 // Determine new root 1742 // Determine new root
1667 // 1743 //
1668 SceneObjectPart newRoot = newSet[0]; 1744 SceneObjectPart newRoot = newSet[0];
1669 newSet.RemoveAt(0); 1745 newSet.RemoveAt(0);
1670 1746
1671 foreach (SceneObjectPart newChild in newSet) 1747 foreach (SceneObjectPart newChild in newSet)
1672 newChild.UpdateFlag = 0; 1748 newChild.UpdateFlag = 0;
1673 1749
1674 LinkObjects(newRoot, newSet); 1750 newRoot.ParentGroup.areUpdatesSuspended = true;
1675 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1751 LinkObjects(newRoot, newSet);
1676 affectedGroups.Add(newRoot.ParentGroup); 1752 if (!affectedGroups.Contains(newRoot.ParentGroup))
1677 } 1753 affectedGroups.Add(newRoot.ParentGroup);
1678 } 1754 }
1679 } 1755 }
1680 1756
@@ -1684,6 +1760,7 @@ namespace OpenSim.Region.Framework.Scenes
1684 { 1760 {
1685 g.TriggerScriptChangedEvent(Changed.LINK); 1761 g.TriggerScriptChangedEvent(Changed.LINK);
1686 g.HasGroupChanged = true; // Persist 1762 g.HasGroupChanged = true; // Persist
1763 g.areUpdatesSuspended = false;
1687 g.ScheduleGroupForFullUpdate(); 1764 g.ScheduleGroupForFullUpdate();
1688 } 1765 }
1689 } 1766 }
@@ -1798,9 +1875,6 @@ namespace OpenSim.Region.Framework.Scenes
1798 child.ApplyNextOwnerPermissions(); 1875 child.ApplyNextOwnerPermissions();
1799 } 1876 }
1800 } 1877 }
1801
1802 copy.RootPart.ObjectSaleType = 0;
1803 copy.RootPart.SalePrice = 10;
1804 } 1878 }
1805 1879
1806 Entities.Add(copy); 1880 Entities.Add(copy);