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.cs235
1 files changed, 152 insertions, 83 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 85ff32e..9c3486e 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.Children.Values)
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>
@@ -584,7 +630,8 @@ namespace OpenSim.Region.Framework.Scenes
584 630
585 Entities[presence.UUID] = presence; 631 Entities[presence.UUID] = presence;
586 632
587 lock (m_presenceLock) 633 m_scenePresencesLock.EnterWriteLock();
634 try
588 { 635 {
589 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 636 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
590 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 637 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -608,6 +655,10 @@ namespace OpenSim.Region.Framework.Scenes
608 m_scenePresenceMap = newmap; 655 m_scenePresenceMap = newmap;
609 m_scenePresenceArray = newlist; 656 m_scenePresenceArray = newlist;
610 } 657 }
658 finally
659 {
660 m_scenePresencesLock.ExitWriteLock();
661 }
611 } 662 }
612 663
613 /// <summary> 664 /// <summary>
@@ -622,7 +673,8 @@ namespace OpenSim.Region.Framework.Scenes
622 agentID); 673 agentID);
623 } 674 }
624 675
625 lock (m_presenceLock) 676 m_scenePresencesLock.EnterWriteLock();
677 try
626 { 678 {
627 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 679 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
628 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 680 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -644,6 +696,10 @@ namespace OpenSim.Region.Framework.Scenes
644 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 696 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
645 } 697 }
646 } 698 }
699 finally
700 {
701 m_scenePresencesLock.ExitWriteLock();
702 }
647 } 703 }
648 704
649 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 705 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1063,9 +1119,11 @@ namespace OpenSim.Region.Framework.Scenes
1063 /// <param name="action"></param> 1119 /// <param name="action"></param>
1064 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1120 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1065 { 1121 {
1066 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1122 EntityBase[] objlist = Entities.GetAllByType<SceneObjectGroup>();
1067 foreach (SceneObjectGroup obj in objlist) 1123 foreach (EntityBase ent in objlist)
1068 { 1124 {
1125 SceneObjectGroup obj = (SceneObjectGroup)ent;
1126
1069 try 1127 try
1070 { 1128 {
1071 action(obj); 1129 action(obj);
@@ -1522,10 +1580,13 @@ namespace OpenSim.Region.Framework.Scenes
1522 /// <param name="childPrims"></param> 1580 /// <param name="childPrims"></param>
1523 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1581 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1524 { 1582 {
1583 SceneObjectGroup parentGroup = root.ParentGroup;
1584 if (parentGroup == null) return;
1525 Monitor.Enter(m_updateLock); 1585 Monitor.Enter(m_updateLock);
1586
1526 try 1587 try
1527 { 1588 {
1528 SceneObjectGroup parentGroup = root.ParentGroup; 1589 parentGroup.areUpdatesSuspended = true;
1529 1590
1530 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1591 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1531 if (parentGroup != null) 1592 if (parentGroup != null)
@@ -1537,11 +1598,6 @@ namespace OpenSim.Region.Framework.Scenes
1537 1598
1538 if (child != null) 1599 if (child != null)
1539 { 1600 {
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); 1601 childGroups.Add(child);
1546 } 1602 }
1547 } 1603 }
@@ -1564,12 +1620,12 @@ namespace OpenSim.Region.Framework.Scenes
1564 // occur on link to invoke this elsewhere (such as object selection) 1620 // occur on link to invoke this elsewhere (such as object selection)
1565 parentGroup.RootPart.CreateSelected = true; 1621 parentGroup.RootPart.CreateSelected = true;
1566 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1622 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1567 parentGroup.HasGroupChanged = true;
1568 parentGroup.ScheduleGroupForFullUpdate();
1569
1570 } 1623 }
1571 finally 1624 finally
1572 { 1625 {
1626 parentGroup.areUpdatesSuspended = false;
1627 parentGroup.HasGroupChanged = true;
1628 parentGroup.ScheduleGroupForFullUpdate();
1573 Monitor.Exit(m_updateLock); 1629 Monitor.Exit(m_updateLock);
1574 } 1630 }
1575 } 1631 }
@@ -1601,21 +1657,24 @@ namespace OpenSim.Region.Framework.Scenes
1601 1657
1602 SceneObjectGroup group = part.ParentGroup; 1658 SceneObjectGroup group = part.ParentGroup;
1603 if (!affectedGroups.Contains(group)) 1659 if (!affectedGroups.Contains(group))
1660 {
1661 group.areUpdatesSuspended = true;
1604 affectedGroups.Add(group); 1662 affectedGroups.Add(group);
1663 }
1605 } 1664 }
1606 } 1665 }
1607 } 1666 }
1608 1667
1609 foreach (SceneObjectPart child in childParts) 1668 if (childParts.Count > 0)
1610 { 1669 {
1611 // Unlink all child parts from their groups 1670 foreach (SceneObjectPart child in childParts)
1612 // 1671 {
1613 child.ParentGroup.DelinkFromGroup(child, true); 1672 // Unlink all child parts from their groups
1614 1673 //
1615 // These are not in affected groups and will not be 1674 child.ParentGroup.DelinkFromGroup(child, true);
1616 // handled further. Do the honors here. 1675 child.ParentGroup.HasGroupChanged = true;
1617 child.ParentGroup.HasGroupChanged = true; 1676 child.ParentGroup.ScheduleGroupForFullUpdate();
1618 child.ParentGroup.ScheduleGroupForFullUpdate(); 1677 }
1619 } 1678 }
1620 1679
1621 foreach (SceneObjectPart root in rootParts) 1680 foreach (SceneObjectPart root in rootParts)
@@ -1625,9 +1684,10 @@ namespace OpenSim.Region.Framework.Scenes
1625 // However, editing linked parts and unlinking may be different 1684 // However, editing linked parts and unlinking may be different
1626 // 1685 //
1627 SceneObjectGroup group = root.ParentGroup; 1686 SceneObjectGroup group = root.ParentGroup;
1687 group.areUpdatesSuspended = true;
1628 1688
1629 List<SceneObjectPart> newSet = null; 1689 List<SceneObjectPart> newSet = null;
1630 int numChildren = -1; 1690 int numChildren;
1631 1691
1632 lock (group.Children) 1692 lock (group.Children)
1633 { 1693 {
@@ -1635,52 +1695,63 @@ namespace OpenSim.Region.Framework.Scenes
1635 numChildren = group.PrimCount; 1695 numChildren = group.PrimCount;
1636 } 1696 }
1637 1697
1698 if (numChildren == 1)
1699 break;
1700
1638 // If there are prims left in a link set, but the root is 1701 // If there are prims left in a link set, but the root is
1639 // slated for unlink, we need to do this 1702 // slated for unlink, we need to do this
1703 // Unlink the remaining set
1640 // 1704 //
1641 if (numChildren != 1) 1705 bool sendEventsToRemainder = true;
1642 { 1706 if (numChildren > 1)
1643 // Unlink the remaining set 1707 sendEventsToRemainder = false;
1644 //
1645 bool sendEventsToRemainder = true;
1646 if (numChildren > 1)
1647 sendEventsToRemainder = false;
1648 1708
1649 foreach (SceneObjectPart p in newSet) 1709 foreach (SceneObjectPart p in newSet)
1710 {
1711 if (p != group.RootPart)
1650 { 1712 {
1651 if (p != group.RootPart) 1713 group.DelinkFromGroup(p, sendEventsToRemainder);
1652 group.DelinkFromGroup(p, sendEventsToRemainder); 1714 if (numChildren > 2)
1715 {
1716 p.ParentGroup.areUpdatesSuspended = true;
1717 }
1718 else
1719 {
1720 p.ParentGroup.HasGroupChanged = true;
1721 p.ParentGroup.ScheduleGroupForFullUpdate();
1722 }
1653 } 1723 }
1724 }
1725
1726 // If there is more than one prim remaining, we
1727 // need to re-link
1728 //
1729 if (numChildren > 2)
1730 {
1731 // Remove old root
1732 //
1733 if (newSet.Contains(root))
1734 newSet.Remove(root);
1654 1735
1655 // If there is more than one prim remaining, we 1736 // Preserve link ordering
1656 // need to re-link
1657 // 1737 //
1658 if (numChildren > 2) 1738 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1659 { 1739 {
1660 // Remove old root 1740 return a.LinkNum.CompareTo(b.LinkNum);
1661 // 1741 });
1662 if (newSet.Contains(root))
1663 newSet.Remove(root);
1664
1665 // Preserve link ordering
1666 //
1667 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1668 {
1669 return a.LinkNum.CompareTo(b.LinkNum);
1670 });
1671 1742
1672 // Determine new root 1743 // Determine new root
1673 // 1744 //
1674 SceneObjectPart newRoot = newSet[0]; 1745 SceneObjectPart newRoot = newSet[0];
1675 newSet.RemoveAt(0); 1746 newSet.RemoveAt(0);
1676 1747
1677 foreach (SceneObjectPart newChild in newSet) 1748 foreach (SceneObjectPart newChild in newSet)
1678 newChild.UpdateFlag = 0; 1749 newChild.UpdateFlag = 0;
1679 1750
1680 LinkObjects(newRoot, newSet); 1751 newRoot.ParentGroup.areUpdatesSuspended = true;
1681 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1752 LinkObjects(newRoot, newSet);
1682 affectedGroups.Add(newRoot.ParentGroup); 1753 if (!affectedGroups.Contains(newRoot.ParentGroup))
1683 } 1754 affectedGroups.Add(newRoot.ParentGroup);
1684 } 1755 }
1685 } 1756 }
1686 1757
@@ -1690,6 +1761,7 @@ namespace OpenSim.Region.Framework.Scenes
1690 { 1761 {
1691 g.TriggerScriptChangedEvent(Changed.LINK); 1762 g.TriggerScriptChangedEvent(Changed.LINK);
1692 g.HasGroupChanged = true; // Persist 1763 g.HasGroupChanged = true; // Persist
1764 g.areUpdatesSuspended = false;
1693 g.ScheduleGroupForFullUpdate(); 1765 g.ScheduleGroupForFullUpdate();
1694 } 1766 }
1695 } 1767 }
@@ -1808,9 +1880,6 @@ namespace OpenSim.Region.Framework.Scenes
1808 child.ApplyNextOwnerPermissions(); 1880 child.ApplyNextOwnerPermissions();
1809 } 1881 }
1810 } 1882 }
1811
1812 copy.RootPart.ObjectSaleType = 0;
1813 copy.RootPart.SalePrice = 10;
1814 } 1883 }
1815 1884
1816 Entities.Add(copy); 1885 Entities.Add(copy);