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, 165 insertions, 59 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 1af18e7..a6178e7 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
@@ -130,13 +139,18 @@ namespace OpenSim.Region.Framework.Scenes
130 139
131 protected internal void Close() 140 protected internal void Close()
132 { 141 {
133 lock (m_presenceLock) 142 m_scenePresencesLock.EnterWriteLock();
143 try
134 { 144 {
135 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 145 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
136 List<ScenePresence> newlist = new List<ScenePresence>(); 146 List<ScenePresence> newlist = new List<ScenePresence>();
137 m_scenePresenceMap = newmap; 147 m_scenePresenceMap = newmap;
138 m_scenePresenceArray = newlist; 148 m_scenePresenceArray = newlist;
139 } 149 }
150 finally
151 {
152 m_scenePresencesLock.ExitWriteLock();
153 }
140 154
141 lock (SceneObjectGroupsByFullID) 155 lock (SceneObjectGroupsByFullID)
142 SceneObjectGroupsByFullID.Clear(); 156 SceneObjectGroupsByFullID.Clear();
@@ -275,6 +289,33 @@ namespace OpenSim.Region.Framework.Scenes
275 protected internal bool AddRestoredSceneObject( 289 protected internal bool AddRestoredSceneObject(
276 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 290 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
277 { 291 {
292 if (!m_parentScene.CombineRegions)
293 {
294 // KF: Check for out-of-region, move inside and make static.
295 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
296 sceneObject.RootPart.GroupPosition.Y,
297 sceneObject.RootPart.GroupPosition.Z);
298 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 ||
299 npos.X > Constants.RegionSize ||
300 npos.Y > Constants.RegionSize))
301 {
302 if (npos.X < 0.0) npos.X = 1.0f;
303 if (npos.Y < 0.0) npos.Y = 1.0f;
304 if (npos.Z < 0.0) npos.Z = 0.0f;
305 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
306 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
307
308 foreach (SceneObjectPart part in sceneObject.Parts)
309 {
310 part.GroupPosition = npos;
311 }
312 sceneObject.RootPart.Velocity = Vector3.Zero;
313 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
314 sceneObject.RootPart.Acceleration = Vector3.Zero;
315 sceneObject.RootPart.Velocity = Vector3.Zero;
316 }
317 }
318
278 if (attachToBackup && (!alreadyPersisted)) 319 if (attachToBackup && (!alreadyPersisted))
279 { 320 {
280 sceneObject.ForceInventoryPersistence(); 321 sceneObject.ForceInventoryPersistence();
@@ -492,6 +533,30 @@ namespace OpenSim.Region.Framework.Scenes
492 m_updateList[obj.UUID] = obj; 533 m_updateList[obj.UUID] = obj;
493 } 534 }
494 535
536 public void FireAttachToBackup(SceneObjectGroup obj)
537 {
538 if (OnAttachToBackup != null)
539 {
540 OnAttachToBackup(obj);
541 }
542 }
543
544 public void FireDetachFromBackup(SceneObjectGroup obj)
545 {
546 if (OnDetachFromBackup != null)
547 {
548 OnDetachFromBackup(obj);
549 }
550 }
551
552 public void FireChangeBackup(SceneObjectGroup obj)
553 {
554 if (OnChangeBackup != null)
555 {
556 OnChangeBackup(obj);
557 }
558 }
559
495 /// <summary> 560 /// <summary>
496 /// Process all pending updates 561 /// Process all pending updates
497 /// </summary> 562 /// </summary>
@@ -623,7 +688,8 @@ namespace OpenSim.Region.Framework.Scenes
623 688
624 Entities[presence.UUID] = presence; 689 Entities[presence.UUID] = presence;
625 690
626 lock (m_presenceLock) 691 m_scenePresencesLock.EnterWriteLock();
692 try
627 { 693 {
628 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 694 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
629 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 695 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -647,6 +713,10 @@ namespace OpenSim.Region.Framework.Scenes
647 m_scenePresenceMap = newmap; 713 m_scenePresenceMap = newmap;
648 m_scenePresenceArray = newlist; 714 m_scenePresenceArray = newlist;
649 } 715 }
716 finally
717 {
718 m_scenePresencesLock.ExitWriteLock();
719 }
650 } 720 }
651 721
652 /// <summary> 722 /// <summary>
@@ -661,7 +731,8 @@ namespace OpenSim.Region.Framework.Scenes
661 agentID); 731 agentID);
662 } 732 }
663 733
664 lock (m_presenceLock) 734 m_scenePresencesLock.EnterWriteLock();
735 try
665 { 736 {
666 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 737 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
667 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 738 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -683,6 +754,10 @@ namespace OpenSim.Region.Framework.Scenes
683 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 754 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
684 } 755 }
685 } 756 }
757 finally
758 {
759 m_scenePresencesLock.ExitWriteLock();
760 }
686 } 761 }
687 762
688 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 763 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1396,8 +1471,13 @@ namespace OpenSim.Region.Framework.Scenes
1396 { 1471 {
1397 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1472 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1398 { 1473 {
1399 if (m_parentScene.AttachmentsModule != null) 1474 // Set the new attachment point data in the object
1400 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos); 1475 byte attachmentPoint = group.GetAttachmentPoint();
1476 group.UpdateGroupPosition(pos);
1477 group.IsAttachment = false;
1478 group.AbsolutePosition = group.RootPart.AttachedPos;
1479 group.AttachmentPoint = attachmentPoint;
1480 group.HasGroupChanged = true;
1401 } 1481 }
1402 else 1482 else
1403 { 1483 {
@@ -1661,10 +1741,13 @@ namespace OpenSim.Region.Framework.Scenes
1661 /// <param name="childPrims"></param> 1741 /// <param name="childPrims"></param>
1662 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1742 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1663 { 1743 {
1744 SceneObjectGroup parentGroup = root.ParentGroup;
1745 if (parentGroup == null) return;
1664 Monitor.Enter(m_updateLock); 1746 Monitor.Enter(m_updateLock);
1747
1665 try 1748 try
1666 { 1749 {
1667 SceneObjectGroup parentGroup = root.ParentGroup; 1750 parentGroup.areUpdatesSuspended = true;
1668 1751
1669 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1752 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1670 1753
@@ -1676,9 +1759,13 @@ namespace OpenSim.Region.Framework.Scenes
1676 // Make sure no child prim is set for sale 1759 // Make sure no child prim is set for sale
1677 // So that, on delink, no prims are unwittingly 1760 // So that, on delink, no prims are unwittingly
1678 // left for sale and sold off 1761 // left for sale and sold off
1679 child.RootPart.ObjectSaleType = 0; 1762
1680 child.RootPart.SalePrice = 10; 1763 if (child != null)
1681 childGroups.Add(child); 1764 {
1765 child.RootPart.ObjectSaleType = 0;
1766 child.RootPart.SalePrice = 10;
1767 childGroups.Add(child);
1768 }
1682 } 1769 }
1683 1770
1684 foreach (SceneObjectGroup child in childGroups) 1771 foreach (SceneObjectGroup child in childGroups)
@@ -1694,12 +1781,13 @@ namespace OpenSim.Region.Framework.Scenes
1694 // occur on link to invoke this elsewhere (such as object selection) 1781 // occur on link to invoke this elsewhere (such as object selection)
1695 parentGroup.RootPart.CreateSelected = true; 1782 parentGroup.RootPart.CreateSelected = true;
1696 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1783 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1697 parentGroup.HasGroupChanged = true;
1698 parentGroup.ScheduleGroupForFullUpdate();
1699
1700 } 1784 }
1701 finally 1785 finally
1702 { 1786 {
1787 parentGroup.areUpdatesSuspended = false;
1788 parentGroup.HasGroupChanged = true;
1789 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1790 parentGroup.ScheduleGroupForFullUpdate();
1703 Monitor.Exit(m_updateLock); 1791 Monitor.Exit(m_updateLock);
1704 } 1792 }
1705 } 1793 }
@@ -1731,21 +1819,24 @@ namespace OpenSim.Region.Framework.Scenes
1731 1819
1732 SceneObjectGroup group = part.ParentGroup; 1820 SceneObjectGroup group = part.ParentGroup;
1733 if (!affectedGroups.Contains(group)) 1821 if (!affectedGroups.Contains(group))
1822 {
1823 group.areUpdatesSuspended = true;
1734 affectedGroups.Add(group); 1824 affectedGroups.Add(group);
1825 }
1735 } 1826 }
1736 } 1827 }
1737 } 1828 }
1738 1829
1739 foreach (SceneObjectPart child in childParts) 1830 if (childParts.Count > 0)
1740 { 1831 {
1741 // Unlink all child parts from their groups 1832 foreach (SceneObjectPart child in childParts)
1742 // 1833 {
1743 child.ParentGroup.DelinkFromGroup(child, true); 1834 // Unlink all child parts from their groups
1744 1835 //
1745 // These are not in affected groups and will not be 1836 child.ParentGroup.DelinkFromGroup(child, true);
1746 // handled further. Do the honors here. 1837 child.ParentGroup.HasGroupChanged = true;
1747 child.ParentGroup.HasGroupChanged = true; 1838 child.ParentGroup.ScheduleGroupForFullUpdate();
1748 child.ParentGroup.ScheduleGroupForFullUpdate(); 1839 }
1749 } 1840 }
1750 1841
1751 foreach (SceneObjectPart root in rootParts) 1842 foreach (SceneObjectPart root in rootParts)
@@ -1755,56 +1846,68 @@ namespace OpenSim.Region.Framework.Scenes
1755 // However, editing linked parts and unlinking may be different 1846 // However, editing linked parts and unlinking may be different
1756 // 1847 //
1757 SceneObjectGroup group = root.ParentGroup; 1848 SceneObjectGroup group = root.ParentGroup;
1849 group.areUpdatesSuspended = true;
1758 1850
1759 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1851 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1760 int numChildren = newSet.Count; 1852 int numChildren = newSet.Count;
1761 1853
1854 if (numChildren == 1)
1855 break;
1856
1762 // If there are prims left in a link set, but the root is 1857 // If there are prims left in a link set, but the root is
1763 // slated for unlink, we need to do this 1858 // slated for unlink, we need to do this
1859 // Unlink the remaining set
1764 // 1860 //
1765 if (numChildren != 1) 1861 bool sendEventsToRemainder = true;
1766 { 1862 if (numChildren > 1)
1767 // Unlink the remaining set 1863 sendEventsToRemainder = false;
1768 //
1769 bool sendEventsToRemainder = true;
1770 if (numChildren > 1)
1771 sendEventsToRemainder = false;
1772 1864
1773 foreach (SceneObjectPart p in newSet) 1865 foreach (SceneObjectPart p in newSet)
1866 {
1867 if (p != group.RootPart)
1774 { 1868 {
1775 if (p != group.RootPart) 1869 group.DelinkFromGroup(p, sendEventsToRemainder);
1776 group.DelinkFromGroup(p, sendEventsToRemainder); 1870 if (numChildren > 2)
1871 {
1872 p.ParentGroup.areUpdatesSuspended = true;
1873 }
1874 else
1875 {
1876 p.ParentGroup.HasGroupChanged = true;
1877 p.ParentGroup.ScheduleGroupForFullUpdate();
1878 }
1777 } 1879 }
1880 }
1778 1881
1779 // If there is more than one prim remaining, we 1882 // If there is more than one prim remaining, we
1780 // need to re-link 1883 // need to re-link
1884 //
1885 if (numChildren > 2)
1886 {
1887 // Remove old root
1888 //
1889 if (newSet.Contains(root))
1890 newSet.Remove(root);
1891
1892 // Preserve link ordering
1781 // 1893 //
1782 if (numChildren > 2) 1894 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1783 { 1895 {
1784 // Remove old root 1896 return a.LinkNum.CompareTo(b.LinkNum);
1785 // 1897 });
1786 if (newSet.Contains(root))
1787 newSet.Remove(root);
1788
1789 // Preserve link ordering
1790 //
1791 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1792 {
1793 return a.LinkNum.CompareTo(b.LinkNum);
1794 });
1795 1898
1796 // Determine new root 1899 // Determine new root
1797 // 1900 //
1798 SceneObjectPart newRoot = newSet[0]; 1901 SceneObjectPart newRoot = newSet[0];
1799 newSet.RemoveAt(0); 1902 newSet.RemoveAt(0);
1800 1903
1801 foreach (SceneObjectPart newChild in newSet) 1904 foreach (SceneObjectPart newChild in newSet)
1802 newChild.UpdateFlag = 0; 1905 newChild.UpdateFlag = 0;
1803 1906
1804 LinkObjects(newRoot, newSet); 1907 newRoot.ParentGroup.areUpdatesSuspended = true;
1805 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1908 LinkObjects(newRoot, newSet);
1806 affectedGroups.Add(newRoot.ParentGroup); 1909 if (!affectedGroups.Contains(newRoot.ParentGroup))
1807 } 1910 affectedGroups.Add(newRoot.ParentGroup);
1808 } 1911 }
1809 } 1912 }
1810 1913
@@ -1812,8 +1915,14 @@ namespace OpenSim.Region.Framework.Scenes
1812 // 1915 //
1813 foreach (SceneObjectGroup g in affectedGroups) 1916 foreach (SceneObjectGroup g in affectedGroups)
1814 { 1917 {
1918 // Child prims that have been unlinked and deleted will
1919 // return unless the root is deleted. This will remove them
1920 // from the database. They will be rewritten immediately,
1921 // minus the rows for the unlinked child prims.
1922 m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
1815 g.TriggerScriptChangedEvent(Changed.LINK); 1923 g.TriggerScriptChangedEvent(Changed.LINK);
1816 g.HasGroupChanged = true; // Persist 1924 g.HasGroupChanged = true; // Persist
1925 g.areUpdatesSuspended = false;
1817 g.ScheduleGroupForFullUpdate(); 1926 g.ScheduleGroupForFullUpdate();
1818 } 1927 }
1819 } 1928 }
@@ -1931,9 +2040,6 @@ namespace OpenSim.Region.Framework.Scenes
1931 child.ApplyNextOwnerPermissions(); 2040 child.ApplyNextOwnerPermissions();
1932 } 2041 }
1933 } 2042 }
1934
1935 copy.RootPart.ObjectSaleType = 0;
1936 copy.RootPart.SalePrice = 10;
1937 } 2043 }
1938 2044
1939 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 2045 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()