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 f81c551..d4e3717 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);
@@ -1521,10 +1584,13 @@ namespace OpenSim.Region.Framework.Scenes
1521 /// <param name="childPrims"></param> 1584 /// <param name="childPrims"></param>
1522 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1585 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1523 { 1586 {
1587 SceneObjectGroup parentGroup = root.ParentGroup;
1588 if (parentGroup == null) return;
1524 Monitor.Enter(m_updateLock); 1589 Monitor.Enter(m_updateLock);
1590
1525 try 1591 try
1526 { 1592 {
1527 SceneObjectGroup parentGroup = root.ParentGroup; 1593 parentGroup.areUpdatesSuspended = true;
1528 1594
1529 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1595 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1530 if (parentGroup != null) 1596 if (parentGroup != null)
@@ -1536,11 +1602,6 @@ namespace OpenSim.Region.Framework.Scenes
1536 1602
1537 if (child != null) 1603 if (child != null)
1538 { 1604 {
1539 // Make sure no child prim is set for sale
1540 // So that, on delink, no prims are unwittingly
1541 // left for sale and sold off
1542 child.RootPart.ObjectSaleType = 0;
1543 child.RootPart.SalePrice = 10;
1544 childGroups.Add(child); 1605 childGroups.Add(child);
1545 } 1606 }
1546 } 1607 }
@@ -1563,12 +1624,12 @@ namespace OpenSim.Region.Framework.Scenes
1563 // occur on link to invoke this elsewhere (such as object selection) 1624 // occur on link to invoke this elsewhere (such as object selection)
1564 parentGroup.RootPart.CreateSelected = true; 1625 parentGroup.RootPart.CreateSelected = true;
1565 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1626 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1566 parentGroup.HasGroupChanged = true;
1567 parentGroup.ScheduleGroupForFullUpdate();
1568
1569 } 1627 }
1570 finally 1628 finally
1571 { 1629 {
1630 parentGroup.areUpdatesSuspended = false;
1631 parentGroup.HasGroupChanged = true;
1632 parentGroup.ScheduleGroupForFullUpdate();
1572 Monitor.Exit(m_updateLock); 1633 Monitor.Exit(m_updateLock);
1573 } 1634 }
1574 } 1635 }
@@ -1600,21 +1661,24 @@ namespace OpenSim.Region.Framework.Scenes
1600 1661
1601 SceneObjectGroup group = part.ParentGroup; 1662 SceneObjectGroup group = part.ParentGroup;
1602 if (!affectedGroups.Contains(group)) 1663 if (!affectedGroups.Contains(group))
1664 {
1665 group.areUpdatesSuspended = true;
1603 affectedGroups.Add(group); 1666 affectedGroups.Add(group);
1667 }
1604 } 1668 }
1605 } 1669 }
1606 } 1670 }
1607 1671
1608 foreach (SceneObjectPart child in childParts) 1672 if (childParts.Count > 0)
1609 { 1673 {
1610 // Unlink all child parts from their groups 1674 foreach (SceneObjectPart child in childParts)
1611 // 1675 {
1612 child.ParentGroup.DelinkFromGroup(child, true); 1676 // Unlink all child parts from their groups
1613 1677 //
1614 // These are not in affected groups and will not be 1678 child.ParentGroup.DelinkFromGroup(child, true);
1615 // handled further. Do the honors here. 1679 child.ParentGroup.HasGroupChanged = true;
1616 child.ParentGroup.HasGroupChanged = true; 1680 child.ParentGroup.ScheduleGroupForFullUpdate();
1617 child.ParentGroup.ScheduleGroupForFullUpdate(); 1681 }
1618 } 1682 }
1619 1683
1620 foreach (SceneObjectPart root in rootParts) 1684 foreach (SceneObjectPart root in rootParts)
@@ -1624,56 +1688,68 @@ namespace OpenSim.Region.Framework.Scenes
1624 // However, editing linked parts and unlinking may be different 1688 // However, editing linked parts and unlinking may be different
1625 // 1689 //
1626 SceneObjectGroup group = root.ParentGroup; 1690 SceneObjectGroup group = root.ParentGroup;
1691 group.areUpdatesSuspended = true;
1627 1692
1628 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1693 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1629 int numChildren = newSet.Count; 1694 int numChildren = newSet.Count;
1630 1695
1696 if (numChildren == 1)
1697 break;
1698
1631 // If there are prims left in a link set, but the root is 1699 // If there are prims left in a link set, but the root is
1632 // slated for unlink, we need to do this 1700 // slated for unlink, we need to do this
1701 // Unlink the remaining set
1633 // 1702 //
1634 if (numChildren != 1) 1703 bool sendEventsToRemainder = true;
1635 { 1704 if (numChildren > 1)
1636 // Unlink the remaining set 1705 sendEventsToRemainder = false;
1637 //
1638 bool sendEventsToRemainder = true;
1639 if (numChildren > 1)
1640 sendEventsToRemainder = false;
1641 1706
1642 foreach (SceneObjectPart p in newSet) 1707 foreach (SceneObjectPart p in newSet)
1708 {
1709 if (p != group.RootPart)
1643 { 1710 {
1644 if (p != group.RootPart) 1711 group.DelinkFromGroup(p, sendEventsToRemainder);
1645 group.DelinkFromGroup(p, sendEventsToRemainder); 1712 if (numChildren > 2)
1713 {
1714 p.ParentGroup.areUpdatesSuspended = true;
1715 }
1716 else
1717 {
1718 p.ParentGroup.HasGroupChanged = true;
1719 p.ParentGroup.ScheduleGroupForFullUpdate();
1720 }
1646 } 1721 }
1722 }
1723
1724 // If there is more than one prim remaining, we
1725 // need to re-link
1726 //
1727 if (numChildren > 2)
1728 {
1729 // Remove old root
1730 //
1731 if (newSet.Contains(root))
1732 newSet.Remove(root);
1647 1733
1648 // If there is more than one prim remaining, we 1734 // Preserve link ordering
1649 // need to re-link
1650 // 1735 //
1651 if (numChildren > 2) 1736 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1652 { 1737 {
1653 // Remove old root 1738 return a.LinkNum.CompareTo(b.LinkNum);
1654 // 1739 });
1655 if (newSet.Contains(root))
1656 newSet.Remove(root);
1657
1658 // Preserve link ordering
1659 //
1660 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1661 {
1662 return a.LinkNum.CompareTo(b.LinkNum);
1663 });
1664 1740
1665 // Determine new root 1741 // Determine new root
1666 // 1742 //
1667 SceneObjectPart newRoot = newSet[0]; 1743 SceneObjectPart newRoot = newSet[0];
1668 newSet.RemoveAt(0); 1744 newSet.RemoveAt(0);
1669 1745
1670 foreach (SceneObjectPart newChild in newSet) 1746 foreach (SceneObjectPart newChild in newSet)
1671 newChild.UpdateFlag = 0; 1747 newChild.UpdateFlag = 0;
1672 1748
1673 LinkObjects(newRoot, newSet); 1749 newRoot.ParentGroup.areUpdatesSuspended = true;
1674 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1750 LinkObjects(newRoot, newSet);
1675 affectedGroups.Add(newRoot.ParentGroup); 1751 if (!affectedGroups.Contains(newRoot.ParentGroup))
1676 } 1752 affectedGroups.Add(newRoot.ParentGroup);
1677 } 1753 }
1678 } 1754 }
1679 1755
@@ -1683,6 +1759,7 @@ namespace OpenSim.Region.Framework.Scenes
1683 { 1759 {
1684 g.TriggerScriptChangedEvent(Changed.LINK); 1760 g.TriggerScriptChangedEvent(Changed.LINK);
1685 g.HasGroupChanged = true; // Persist 1761 g.HasGroupChanged = true; // Persist
1762 g.areUpdatesSuspended = false;
1686 g.ScheduleGroupForFullUpdate(); 1763 g.ScheduleGroupForFullUpdate();
1687 } 1764 }
1688 } 1765 }
@@ -1797,9 +1874,6 @@ namespace OpenSim.Region.Framework.Scenes
1797 child.ApplyNextOwnerPermissions(); 1874 child.ApplyNextOwnerPermissions();
1798 } 1875 }
1799 } 1876 }
1800
1801 copy.RootPart.ObjectSaleType = 0;
1802 copy.RootPart.SalePrice = 10;
1803 } 1877 }
1804 1878
1805 Entities.Add(copy); 1879 Entities.Add(copy);