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 72f0402..3d6057b 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>
@@ -1309,8 +1389,13 @@ namespace OpenSim.Region.Framework.Scenes
1309 { 1389 {
1310 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1390 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1311 { 1391 {
1312 if (m_parentScene.AttachmentsModule != null) 1392 // Set the new attachment point data in the object
1313 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos); 1393 byte attachmentPoint = group.GetAttachmentPoint();
1394 group.UpdateGroupPosition(pos);
1395 group.RootPart.IsAttachment = false;
1396 group.AbsolutePosition = group.RootPart.AttachedPos;
1397 group.SetAttachmentPoint(attachmentPoint);
1398 group.HasGroupChanged = true;
1314 } 1399 }
1315 else 1400 else
1316 { 1401 {
@@ -1554,10 +1639,13 @@ namespace OpenSim.Region.Framework.Scenes
1554 /// <param name="childPrims"></param> 1639 /// <param name="childPrims"></param>
1555 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1640 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1556 { 1641 {
1642 SceneObjectGroup parentGroup = root.ParentGroup;
1643 if (parentGroup == null) return;
1557 Monitor.Enter(m_updateLock); 1644 Monitor.Enter(m_updateLock);
1645
1558 try 1646 try
1559 { 1647 {
1560 SceneObjectGroup parentGroup = root.ParentGroup; 1648 parentGroup.areUpdatesSuspended = true;
1561 1649
1562 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1650 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1563 if (parentGroup != null) 1651 if (parentGroup != null)
@@ -1569,11 +1657,6 @@ namespace OpenSim.Region.Framework.Scenes
1569 1657
1570 if (child != null) 1658 if (child != null)
1571 { 1659 {
1572 // Make sure no child prim is set for sale
1573 // So that, on delink, no prims are unwittingly
1574 // left for sale and sold off
1575 child.RootPart.ObjectSaleType = 0;
1576 child.RootPart.SalePrice = 10;
1577 childGroups.Add(child); 1660 childGroups.Add(child);
1578 } 1661 }
1579 } 1662 }
@@ -1596,12 +1679,13 @@ namespace OpenSim.Region.Framework.Scenes
1596 // occur on link to invoke this elsewhere (such as object selection) 1679 // occur on link to invoke this elsewhere (such as object selection)
1597 parentGroup.RootPart.CreateSelected = true; 1680 parentGroup.RootPart.CreateSelected = true;
1598 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1681 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1599 parentGroup.HasGroupChanged = true;
1600 parentGroup.ScheduleGroupForFullUpdate();
1601
1602 } 1682 }
1603 finally 1683 finally
1604 { 1684 {
1685 parentGroup.areUpdatesSuspended = false;
1686 parentGroup.HasGroupChanged = true;
1687 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1688 parentGroup.ScheduleGroupForFullUpdate();
1605 Monitor.Exit(m_updateLock); 1689 Monitor.Exit(m_updateLock);
1606 } 1690 }
1607 } 1691 }
@@ -1633,21 +1717,24 @@ namespace OpenSim.Region.Framework.Scenes
1633 1717
1634 SceneObjectGroup group = part.ParentGroup; 1718 SceneObjectGroup group = part.ParentGroup;
1635 if (!affectedGroups.Contains(group)) 1719 if (!affectedGroups.Contains(group))
1720 {
1721 group.areUpdatesSuspended = true;
1636 affectedGroups.Add(group); 1722 affectedGroups.Add(group);
1723 }
1637 } 1724 }
1638 } 1725 }
1639 } 1726 }
1640 1727
1641 foreach (SceneObjectPart child in childParts) 1728 if (childParts.Count > 0)
1642 { 1729 {
1643 // Unlink all child parts from their groups 1730 foreach (SceneObjectPart child in childParts)
1644 // 1731 {
1645 child.ParentGroup.DelinkFromGroup(child, true); 1732 // Unlink all child parts from their groups
1646 1733 //
1647 // These are not in affected groups and will not be 1734 child.ParentGroup.DelinkFromGroup(child, true);
1648 // handled further. Do the honors here. 1735 child.ParentGroup.HasGroupChanged = true;
1649 child.ParentGroup.HasGroupChanged = true; 1736 child.ParentGroup.ScheduleGroupForFullUpdate();
1650 child.ParentGroup.ScheduleGroupForFullUpdate(); 1737 }
1651 } 1738 }
1652 1739
1653 foreach (SceneObjectPart root in rootParts) 1740 foreach (SceneObjectPart root in rootParts)
@@ -1657,56 +1744,68 @@ namespace OpenSim.Region.Framework.Scenes
1657 // However, editing linked parts and unlinking may be different 1744 // However, editing linked parts and unlinking may be different
1658 // 1745 //
1659 SceneObjectGroup group = root.ParentGroup; 1746 SceneObjectGroup group = root.ParentGroup;
1747 group.areUpdatesSuspended = true;
1660 1748
1661 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1749 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1662 int numChildren = newSet.Count; 1750 int numChildren = newSet.Count;
1663 1751
1752 if (numChildren == 1)
1753 break;
1754
1664 // If there are prims left in a link set, but the root is 1755 // If there are prims left in a link set, but the root is
1665 // slated for unlink, we need to do this 1756 // slated for unlink, we need to do this
1757 // Unlink the remaining set
1666 // 1758 //
1667 if (numChildren != 1) 1759 bool sendEventsToRemainder = true;
1668 { 1760 if (numChildren > 1)
1669 // Unlink the remaining set 1761 sendEventsToRemainder = false;
1670 //
1671 bool sendEventsToRemainder = true;
1672 if (numChildren > 1)
1673 sendEventsToRemainder = false;
1674 1762
1675 foreach (SceneObjectPart p in newSet) 1763 foreach (SceneObjectPart p in newSet)
1764 {
1765 if (p != group.RootPart)
1676 { 1766 {
1677 if (p != group.RootPart) 1767 group.DelinkFromGroup(p, sendEventsToRemainder);
1678 group.DelinkFromGroup(p, sendEventsToRemainder); 1768 if (numChildren > 2)
1769 {
1770 p.ParentGroup.areUpdatesSuspended = true;
1771 }
1772 else
1773 {
1774 p.ParentGroup.HasGroupChanged = true;
1775 p.ParentGroup.ScheduleGroupForFullUpdate();
1776 }
1679 } 1777 }
1778 }
1779
1780 // If there is more than one prim remaining, we
1781 // need to re-link
1782 //
1783 if (numChildren > 2)
1784 {
1785 // Remove old root
1786 //
1787 if (newSet.Contains(root))
1788 newSet.Remove(root);
1680 1789
1681 // If there is more than one prim remaining, we 1790 // Preserve link ordering
1682 // need to re-link
1683 // 1791 //
1684 if (numChildren > 2) 1792 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1685 { 1793 {
1686 // Remove old root 1794 return a.LinkNum.CompareTo(b.LinkNum);
1687 // 1795 });
1688 if (newSet.Contains(root))
1689 newSet.Remove(root);
1690
1691 // Preserve link ordering
1692 //
1693 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1694 {
1695 return a.LinkNum.CompareTo(b.LinkNum);
1696 });
1697 1796
1698 // Determine new root 1797 // Determine new root
1699 // 1798 //
1700 SceneObjectPart newRoot = newSet[0]; 1799 SceneObjectPart newRoot = newSet[0];
1701 newSet.RemoveAt(0); 1800 newSet.RemoveAt(0);
1702 1801
1703 foreach (SceneObjectPart newChild in newSet) 1802 foreach (SceneObjectPart newChild in newSet)
1704 newChild.UpdateFlag = 0; 1803 newChild.UpdateFlag = 0;
1705 1804
1706 LinkObjects(newRoot, newSet); 1805 newRoot.ParentGroup.areUpdatesSuspended = true;
1707 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1806 LinkObjects(newRoot, newSet);
1708 affectedGroups.Add(newRoot.ParentGroup); 1807 if (!affectedGroups.Contains(newRoot.ParentGroup))
1709 } 1808 affectedGroups.Add(newRoot.ParentGroup);
1710 } 1809 }
1711 } 1810 }
1712 1811
@@ -1714,8 +1813,14 @@ namespace OpenSim.Region.Framework.Scenes
1714 // 1813 //
1715 foreach (SceneObjectGroup g in affectedGroups) 1814 foreach (SceneObjectGroup g in affectedGroups)
1716 { 1815 {
1816 // Child prims that have been unlinked and deleted will
1817 // return unless the root is deleted. This will remove them
1818 // from the database. They will be rewritten immediately,
1819 // minus the rows for the unlinked child prims.
1820 m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
1717 g.TriggerScriptChangedEvent(Changed.LINK); 1821 g.TriggerScriptChangedEvent(Changed.LINK);
1718 g.HasGroupChanged = true; // Persist 1822 g.HasGroupChanged = true; // Persist
1823 g.areUpdatesSuspended = false;
1719 g.ScheduleGroupForFullUpdate(); 1824 g.ScheduleGroupForFullUpdate();
1720 } 1825 }
1721 } 1826 }
@@ -1833,9 +1938,6 @@ namespace OpenSim.Region.Framework.Scenes
1833 child.ApplyNextOwnerPermissions(); 1938 child.ApplyNextOwnerPermissions();
1834 } 1939 }
1835 } 1940 }
1836
1837 copy.RootPart.ObjectSaleType = 0;
1838 copy.RootPart.SalePrice = 10;
1839 } 1941 }
1840 1942
1841 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 1943 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()