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.cs224
1 files changed, 163 insertions, 61 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 60855b2..62e7d36 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
@@ -135,13 +144,18 @@ namespace OpenSim.Region.Framework.Scenes
135 144
136 protected internal void Close() 145 protected internal void Close()
137 { 146 {
138 lock (m_presenceLock) 147 m_scenePresencesLock.EnterWriteLock();
148 try
139 { 149 {
140 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 150 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
141 List<ScenePresence> newlist = new List<ScenePresence>(); 151 List<ScenePresence> newlist = new List<ScenePresence>();
142 m_scenePresenceMap = newmap; 152 m_scenePresenceMap = newmap;
143 m_scenePresenceArray = newlist; 153 m_scenePresenceArray = newlist;
144 } 154 }
155 finally
156 {
157 m_scenePresencesLock.ExitWriteLock();
158 }
145 159
146 lock (SceneObjectGroupsByFullID) 160 lock (SceneObjectGroupsByFullID)
147 SceneObjectGroupsByFullID.Clear(); 161 SceneObjectGroupsByFullID.Clear();
@@ -273,6 +287,33 @@ namespace OpenSim.Region.Framework.Scenes
273 protected internal bool AddRestoredSceneObject( 287 protected internal bool AddRestoredSceneObject(
274 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 288 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
275 { 289 {
290 if (!m_parentScene.CombineRegions)
291 {
292 // KF: Check for out-of-region, move inside and make static.
293 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
294 sceneObject.RootPart.GroupPosition.Y,
295 sceneObject.RootPart.GroupPosition.Z);
296 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 ||
297 npos.X > Constants.RegionSize ||
298 npos.Y > Constants.RegionSize))
299 {
300 if (npos.X < 0.0) npos.X = 1.0f;
301 if (npos.Y < 0.0) npos.Y = 1.0f;
302 if (npos.Z < 0.0) npos.Z = 0.0f;
303 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
304 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
305
306 foreach (SceneObjectPart part in sceneObject.Parts)
307 {
308 part.GroupPosition = npos;
309 }
310 sceneObject.RootPart.Velocity = Vector3.Zero;
311 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
312 sceneObject.RootPart.Acceleration = Vector3.Zero;
313 sceneObject.RootPart.Velocity = Vector3.Zero;
314 }
315 }
316
276 if (attachToBackup && (!alreadyPersisted)) 317 if (attachToBackup && (!alreadyPersisted))
277 { 318 {
278 sceneObject.ForceInventoryPersistence(); 319 sceneObject.ForceInventoryPersistence();
@@ -482,6 +523,30 @@ namespace OpenSim.Region.Framework.Scenes
482 m_updateList[obj.UUID] = obj; 523 m_updateList[obj.UUID] = obj;
483 } 524 }
484 525
526 public void FireAttachToBackup(SceneObjectGroup obj)
527 {
528 if (OnAttachToBackup != null)
529 {
530 OnAttachToBackup(obj);
531 }
532 }
533
534 public void FireDetachFromBackup(SceneObjectGroup obj)
535 {
536 if (OnDetachFromBackup != null)
537 {
538 OnDetachFromBackup(obj);
539 }
540 }
541
542 public void FireChangeBackup(SceneObjectGroup obj)
543 {
544 if (OnChangeBackup != null)
545 {
546 OnChangeBackup(obj);
547 }
548 }
549
485 /// <summary> 550 /// <summary>
486 /// Process all pending updates 551 /// Process all pending updates
487 /// </summary> 552 /// </summary>
@@ -617,7 +682,8 @@ namespace OpenSim.Region.Framework.Scenes
617 682
618 Entities[presence.UUID] = presence; 683 Entities[presence.UUID] = presence;
619 684
620 lock (m_presenceLock) 685 m_scenePresencesLock.EnterWriteLock();
686 try
621 { 687 {
622 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 688 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
623 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 689 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -641,6 +707,10 @@ namespace OpenSim.Region.Framework.Scenes
641 m_scenePresenceMap = newmap; 707 m_scenePresenceMap = newmap;
642 m_scenePresenceArray = newlist; 708 m_scenePresenceArray = newlist;
643 } 709 }
710 finally
711 {
712 m_scenePresencesLock.ExitWriteLock();
713 }
644 } 714 }
645 715
646 /// <summary> 716 /// <summary>
@@ -655,7 +725,8 @@ namespace OpenSim.Region.Framework.Scenes
655 agentID); 725 agentID);
656 } 726 }
657 727
658 lock (m_presenceLock) 728 m_scenePresencesLock.EnterWriteLock();
729 try
659 { 730 {
660 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 731 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
661 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 732 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -677,6 +748,10 @@ namespace OpenSim.Region.Framework.Scenes
677 m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 748 m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
678 } 749 }
679 } 750 }
751 finally
752 {
753 m_scenePresencesLock.ExitWriteLock();
754 }
680 } 755 }
681 756
682 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 757 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -800,6 +875,11 @@ namespace OpenSim.Region.Framework.Scenes
800 return m_scenePresenceArray; 875 return m_scenePresenceArray;
801 } 876 }
802 877
878 public int GetNumberOfScenePresences()
879 {
880 return m_scenePresenceArray.Count;
881 }
882
803 /// <summary> 883 /// <summary>
804 /// Request a scene presence by UUID. Fast, indexed lookup. 884 /// Request a scene presence by UUID. Fast, indexed lookup.
805 /// </summary> 885 /// </summary>
@@ -1307,8 +1387,13 @@ namespace OpenSim.Region.Framework.Scenes
1307 { 1387 {
1308 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1388 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1309 { 1389 {
1310 if (m_parentScene.AttachmentsModule != null) 1390 // Set the new attachment point data in the object
1311 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos); 1391 byte attachmentPoint = group.GetAttachmentPoint();
1392 group.UpdateGroupPosition(pos);
1393 group.RootPart.IsAttachment = false;
1394 group.AbsolutePosition = group.RootPart.AttachedPos;
1395 group.SetAttachmentPoint(attachmentPoint);
1396 group.HasGroupChanged = true;
1312 } 1397 }
1313 else 1398 else
1314 { 1399 {
@@ -1552,10 +1637,13 @@ namespace OpenSim.Region.Framework.Scenes
1552 /// <param name="childPrims"></param> 1637 /// <param name="childPrims"></param>
1553 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1638 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1554 { 1639 {
1640 SceneObjectGroup parentGroup = root.ParentGroup;
1641 if (parentGroup == null) return;
1555 Monitor.Enter(m_updateLock); 1642 Monitor.Enter(m_updateLock);
1643
1556 try 1644 try
1557 { 1645 {
1558 SceneObjectGroup parentGroup = root.ParentGroup; 1646 parentGroup.areUpdatesSuspended = true;
1559 1647
1560 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1648 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1561 if (parentGroup != null) 1649 if (parentGroup != null)
@@ -1567,11 +1655,6 @@ namespace OpenSim.Region.Framework.Scenes
1567 1655
1568 if (child != null) 1656 if (child != null)
1569 { 1657 {
1570 // Make sure no child prim is set for sale
1571 // So that, on delink, no prims are unwittingly
1572 // left for sale and sold off
1573 child.RootPart.ObjectSaleType = 0;
1574 child.RootPart.SalePrice = 10;
1575 childGroups.Add(child); 1658 childGroups.Add(child);
1576 } 1659 }
1577 } 1660 }
@@ -1594,12 +1677,13 @@ namespace OpenSim.Region.Framework.Scenes
1594 // occur on link to invoke this elsewhere (such as object selection) 1677 // occur on link to invoke this elsewhere (such as object selection)
1595 parentGroup.RootPart.CreateSelected = true; 1678 parentGroup.RootPart.CreateSelected = true;
1596 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1679 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1597 parentGroup.HasGroupChanged = true;
1598 parentGroup.ScheduleGroupForFullUpdate();
1599
1600 } 1680 }
1601 finally 1681 finally
1602 { 1682 {
1683 parentGroup.areUpdatesSuspended = false;
1684 parentGroup.HasGroupChanged = true;
1685 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1686 parentGroup.ScheduleGroupForFullUpdate();
1603 Monitor.Exit(m_updateLock); 1687 Monitor.Exit(m_updateLock);
1604 } 1688 }
1605 } 1689 }
@@ -1631,21 +1715,24 @@ namespace OpenSim.Region.Framework.Scenes
1631 1715
1632 SceneObjectGroup group = part.ParentGroup; 1716 SceneObjectGroup group = part.ParentGroup;
1633 if (!affectedGroups.Contains(group)) 1717 if (!affectedGroups.Contains(group))
1718 {
1719 group.areUpdatesSuspended = true;
1634 affectedGroups.Add(group); 1720 affectedGroups.Add(group);
1721 }
1635 } 1722 }
1636 } 1723 }
1637 } 1724 }
1638 1725
1639 foreach (SceneObjectPart child in childParts) 1726 if (childParts.Count > 0)
1640 { 1727 {
1641 // Unlink all child parts from their groups 1728 foreach (SceneObjectPart child in childParts)
1642 // 1729 {
1643 child.ParentGroup.DelinkFromGroup(child, true); 1730 // Unlink all child parts from their groups
1644 1731 //
1645 // These are not in affected groups and will not be 1732 child.ParentGroup.DelinkFromGroup(child, true);
1646 // handled further. Do the honors here. 1733 child.ParentGroup.HasGroupChanged = true;
1647 child.ParentGroup.HasGroupChanged = true; 1734 child.ParentGroup.ScheduleGroupForFullUpdate();
1648 child.ParentGroup.ScheduleGroupForFullUpdate(); 1735 }
1649 } 1736 }
1650 1737
1651 foreach (SceneObjectPart root in rootParts) 1738 foreach (SceneObjectPart root in rootParts)
@@ -1655,56 +1742,68 @@ namespace OpenSim.Region.Framework.Scenes
1655 // However, editing linked parts and unlinking may be different 1742 // However, editing linked parts and unlinking may be different
1656 // 1743 //
1657 SceneObjectGroup group = root.ParentGroup; 1744 SceneObjectGroup group = root.ParentGroup;
1745 group.areUpdatesSuspended = true;
1658 1746
1659 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1747 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1660 int numChildren = newSet.Count; 1748 int numChildren = newSet.Count;
1661 1749
1750 if (numChildren == 1)
1751 break;
1752
1662 // If there are prims left in a link set, but the root is 1753 // If there are prims left in a link set, but the root is
1663 // slated for unlink, we need to do this 1754 // slated for unlink, we need to do this
1755 // Unlink the remaining set
1664 // 1756 //
1665 if (numChildren != 1) 1757 bool sendEventsToRemainder = true;
1666 { 1758 if (numChildren > 1)
1667 // Unlink the remaining set 1759 sendEventsToRemainder = false;
1668 //
1669 bool sendEventsToRemainder = true;
1670 if (numChildren > 1)
1671 sendEventsToRemainder = false;
1672 1760
1673 foreach (SceneObjectPart p in newSet) 1761 foreach (SceneObjectPart p in newSet)
1762 {
1763 if (p != group.RootPart)
1674 { 1764 {
1675 if (p != group.RootPart) 1765 group.DelinkFromGroup(p, sendEventsToRemainder);
1676 group.DelinkFromGroup(p, sendEventsToRemainder); 1766 if (numChildren > 2)
1767 {
1768 p.ParentGroup.areUpdatesSuspended = true;
1769 }
1770 else
1771 {
1772 p.ParentGroup.HasGroupChanged = true;
1773 p.ParentGroup.ScheduleGroupForFullUpdate();
1774 }
1677 } 1775 }
1776 }
1777
1778 // If there is more than one prim remaining, we
1779 // need to re-link
1780 //
1781 if (numChildren > 2)
1782 {
1783 // Remove old root
1784 //
1785 if (newSet.Contains(root))
1786 newSet.Remove(root);
1678 1787
1679 // If there is more than one prim remaining, we 1788 // Preserve link ordering
1680 // need to re-link
1681 // 1789 //
1682 if (numChildren > 2) 1790 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1683 { 1791 {
1684 // Remove old root 1792 return a.LinkNum.CompareTo(b.LinkNum);
1685 // 1793 });
1686 if (newSet.Contains(root))
1687 newSet.Remove(root);
1688
1689 // Preserve link ordering
1690 //
1691 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1692 {
1693 return a.LinkNum.CompareTo(b.LinkNum);
1694 });
1695 1794
1696 // Determine new root 1795 // Determine new root
1697 // 1796 //
1698 SceneObjectPart newRoot = newSet[0]; 1797 SceneObjectPart newRoot = newSet[0];
1699 newSet.RemoveAt(0); 1798 newSet.RemoveAt(0);
1700 1799
1701 foreach (SceneObjectPart newChild in newSet) 1800 foreach (SceneObjectPart newChild in newSet)
1702 newChild.UpdateFlag = 0; 1801 newChild.UpdateFlag = 0;
1703 1802
1704 LinkObjects(newRoot, newSet); 1803 newRoot.ParentGroup.areUpdatesSuspended = true;
1705 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1804 LinkObjects(newRoot, newSet);
1706 affectedGroups.Add(newRoot.ParentGroup); 1805 if (!affectedGroups.Contains(newRoot.ParentGroup))
1707 } 1806 affectedGroups.Add(newRoot.ParentGroup);
1708 } 1807 }
1709 } 1808 }
1710 1809
@@ -1712,8 +1811,14 @@ namespace OpenSim.Region.Framework.Scenes
1712 // 1811 //
1713 foreach (SceneObjectGroup g in affectedGroups) 1812 foreach (SceneObjectGroup g in affectedGroups)
1714 { 1813 {
1814 // Child prims that have been unlinked and deleted will
1815 // return unless the root is deleted. This will remove them
1816 // from the database. They will be rewritten immediately,
1817 // minus the rows for the unlinked child prims.
1818 m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
1715 g.TriggerScriptChangedEvent(Changed.LINK); 1819 g.TriggerScriptChangedEvent(Changed.LINK);
1716 g.HasGroupChanged = true; // Persist 1820 g.HasGroupChanged = true; // Persist
1821 g.areUpdatesSuspended = false;
1717 g.ScheduleGroupForFullUpdate(); 1822 g.ScheduleGroupForFullUpdate();
1718 } 1823 }
1719 } 1824 }
@@ -1831,9 +1936,6 @@ namespace OpenSim.Region.Framework.Scenes
1831 child.ApplyNextOwnerPermissions(); 1936 child.ApplyNextOwnerPermissions();
1832 } 1937 }
1833 } 1938 }
1834
1835 copy.RootPart.ObjectSaleType = 0;
1836 copy.RootPart.SalePrice = 10;
1837 } 1939 }
1838 1940
1839 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 1941 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()