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.cs233
1 files changed, 151 insertions, 82 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 28b80bb..5ef14bf 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>
@@ -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)
@@ -1060,9 +1116,11 @@ namespace OpenSim.Region.Framework.Scenes
1060 /// <param name="action"></param> 1116 /// <param name="action"></param>
1061 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1117 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1062 { 1118 {
1063 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1119 EntityBase[] objlist = Entities.GetAllByType<SceneObjectGroup>();
1064 foreach (SceneObjectGroup obj in objlist) 1120 foreach (EntityBase ent in objlist)
1065 { 1121 {
1122 SceneObjectGroup obj = (SceneObjectGroup)ent;
1123
1066 try 1124 try
1067 { 1125 {
1068 action(obj); 1126 action(obj);
@@ -1519,10 +1577,13 @@ namespace OpenSim.Region.Framework.Scenes
1519 /// <param name="childPrims"></param> 1577 /// <param name="childPrims"></param>
1520 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1578 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1521 { 1579 {
1580 SceneObjectGroup parentGroup = root.ParentGroup;
1581 if (parentGroup == null) return;
1522 Monitor.Enter(m_updateLock); 1582 Monitor.Enter(m_updateLock);
1583
1523 try 1584 try
1524 { 1585 {
1525 SceneObjectGroup parentGroup = root.ParentGroup; 1586 parentGroup.areUpdatesSuspended = true;
1526 1587
1527 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1588 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1528 if (parentGroup != null) 1589 if (parentGroup != null)
@@ -1534,11 +1595,6 @@ namespace OpenSim.Region.Framework.Scenes
1534 1595
1535 if (child != null) 1596 if (child != null)
1536 { 1597 {
1537 // Make sure no child prim is set for sale
1538 // So that, on delink, no prims are unwittingly
1539 // left for sale and sold off
1540 child.RootPart.ObjectSaleType = 0;
1541 child.RootPart.SalePrice = 10;
1542 childGroups.Add(child); 1598 childGroups.Add(child);
1543 } 1599 }
1544 } 1600 }
@@ -1561,12 +1617,12 @@ namespace OpenSim.Region.Framework.Scenes
1561 // occur on link to invoke this elsewhere (such as object selection) 1617 // occur on link to invoke this elsewhere (such as object selection)
1562 parentGroup.RootPart.CreateSelected = true; 1618 parentGroup.RootPart.CreateSelected = true;
1563 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1619 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1564 parentGroup.HasGroupChanged = true;
1565 parentGroup.ScheduleGroupForFullUpdate();
1566
1567 } 1620 }
1568 finally 1621 finally
1569 { 1622 {
1623 parentGroup.areUpdatesSuspended = false;
1624 parentGroup.HasGroupChanged = true;
1625 parentGroup.ScheduleGroupForFullUpdate();
1570 Monitor.Exit(m_updateLock); 1626 Monitor.Exit(m_updateLock);
1571 } 1627 }
1572 } 1628 }
@@ -1598,21 +1654,24 @@ namespace OpenSim.Region.Framework.Scenes
1598 1654
1599 SceneObjectGroup group = part.ParentGroup; 1655 SceneObjectGroup group = part.ParentGroup;
1600 if (!affectedGroups.Contains(group)) 1656 if (!affectedGroups.Contains(group))
1657 {
1658 group.areUpdatesSuspended = true;
1601 affectedGroups.Add(group); 1659 affectedGroups.Add(group);
1660 }
1602 } 1661 }
1603 } 1662 }
1604 } 1663 }
1605 1664
1606 foreach (SceneObjectPart child in childParts) 1665 if (childParts.Count > 0)
1607 { 1666 {
1608 // Unlink all child parts from their groups 1667 foreach (SceneObjectPart child in childParts)
1609 // 1668 {
1610 child.ParentGroup.DelinkFromGroup(child, true); 1669 // Unlink all child parts from their groups
1611 1670 //
1612 // These are not in affected groups and will not be 1671 child.ParentGroup.DelinkFromGroup(child, true);
1613 // handled further. Do the honors here. 1672 child.ParentGroup.HasGroupChanged = true;
1614 child.ParentGroup.HasGroupChanged = true; 1673 child.ParentGroup.ScheduleGroupForFullUpdate();
1615 child.ParentGroup.ScheduleGroupForFullUpdate(); 1674 }
1616 } 1675 }
1617 1676
1618 foreach (SceneObjectPart root in rootParts) 1677 foreach (SceneObjectPart root in rootParts)
@@ -1622,56 +1681,68 @@ namespace OpenSim.Region.Framework.Scenes
1622 // However, editing linked parts and unlinking may be different 1681 // However, editing linked parts and unlinking may be different
1623 // 1682 //
1624 SceneObjectGroup group = root.ParentGroup; 1683 SceneObjectGroup group = root.ParentGroup;
1684 group.areUpdatesSuspended = true;
1625 1685
1626 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1686 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1627 int numChildren = newSet.Count; 1687 int numChildren = newSet.Count;
1628 1688
1689 if (numChildren == 1)
1690 break;
1691
1629 // If there are prims left in a link set, but the root is 1692 // If there are prims left in a link set, but the root is
1630 // slated for unlink, we need to do this 1693 // slated for unlink, we need to do this
1694 // Unlink the remaining set
1631 // 1695 //
1632 if (numChildren != 1) 1696 bool sendEventsToRemainder = true;
1633 { 1697 if (numChildren > 1)
1634 // Unlink the remaining set 1698 sendEventsToRemainder = false;
1635 //
1636 bool sendEventsToRemainder = true;
1637 if (numChildren > 1)
1638 sendEventsToRemainder = false;
1639 1699
1640 foreach (SceneObjectPart p in newSet) 1700 foreach (SceneObjectPart p in newSet)
1701 {
1702 if (p != group.RootPart)
1641 { 1703 {
1642 if (p != group.RootPart) 1704 group.DelinkFromGroup(p, sendEventsToRemainder);
1643 group.DelinkFromGroup(p, sendEventsToRemainder); 1705 if (numChildren > 2)
1706 {
1707 p.ParentGroup.areUpdatesSuspended = true;
1708 }
1709 else
1710 {
1711 p.ParentGroup.HasGroupChanged = true;
1712 p.ParentGroup.ScheduleGroupForFullUpdate();
1713 }
1644 } 1714 }
1715 }
1716
1717 // If there is more than one prim remaining, we
1718 // need to re-link
1719 //
1720 if (numChildren > 2)
1721 {
1722 // Remove old root
1723 //
1724 if (newSet.Contains(root))
1725 newSet.Remove(root);
1645 1726
1646 // If there is more than one prim remaining, we 1727 // Preserve link ordering
1647 // need to re-link
1648 // 1728 //
1649 if (numChildren > 2) 1729 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1650 { 1730 {
1651 // Remove old root 1731 return a.LinkNum.CompareTo(b.LinkNum);
1652 // 1732 });
1653 if (newSet.Contains(root))
1654 newSet.Remove(root);
1655
1656 // Preserve link ordering
1657 //
1658 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1659 {
1660 return a.LinkNum.CompareTo(b.LinkNum);
1661 });
1662 1733
1663 // Determine new root 1734 // Determine new root
1664 // 1735 //
1665 SceneObjectPart newRoot = newSet[0]; 1736 SceneObjectPart newRoot = newSet[0];
1666 newSet.RemoveAt(0); 1737 newSet.RemoveAt(0);
1667 1738
1668 foreach (SceneObjectPart newChild in newSet) 1739 foreach (SceneObjectPart newChild in newSet)
1669 newChild.UpdateFlag = 0; 1740 newChild.UpdateFlag = 0;
1670 1741
1671 LinkObjects(newRoot, newSet); 1742 newRoot.ParentGroup.areUpdatesSuspended = true;
1672 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1743 LinkObjects(newRoot, newSet);
1673 affectedGroups.Add(newRoot.ParentGroup); 1744 if (!affectedGroups.Contains(newRoot.ParentGroup))
1674 } 1745 affectedGroups.Add(newRoot.ParentGroup);
1675 } 1746 }
1676 } 1747 }
1677 1748
@@ -1681,6 +1752,7 @@ namespace OpenSim.Region.Framework.Scenes
1681 { 1752 {
1682 g.TriggerScriptChangedEvent(Changed.LINK); 1753 g.TriggerScriptChangedEvent(Changed.LINK);
1683 g.HasGroupChanged = true; // Persist 1754 g.HasGroupChanged = true; // Persist
1755 g.areUpdatesSuspended = false;
1684 g.ScheduleGroupForFullUpdate(); 1756 g.ScheduleGroupForFullUpdate();
1685 } 1757 }
1686 } 1758 }
@@ -1795,9 +1867,6 @@ namespace OpenSim.Region.Framework.Scenes
1795 child.ApplyNextOwnerPermissions(); 1867 child.ApplyNextOwnerPermissions();
1796 } 1868 }
1797 } 1869 }
1798
1799 copy.RootPart.ObjectSaleType = 0;
1800 copy.RootPart.SalePrice = 10;
1801 } 1870 }
1802 1871
1803 Entities.Add(copy); 1872 Entities.Add(copy);