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.cs219
1 files changed, 158 insertions, 61 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index fc31b65..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)
@@ -1314,8 +1389,13 @@ namespace OpenSim.Region.Framework.Scenes
1314 { 1389 {
1315 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))
1316 { 1391 {
1317 if (m_parentScene.AttachmentsModule != null) 1392 // Set the new attachment point data in the object
1318 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;
1319 } 1399 }
1320 else 1400 else
1321 { 1401 {
@@ -1559,10 +1639,13 @@ namespace OpenSim.Region.Framework.Scenes
1559 /// <param name="childPrims"></param> 1639 /// <param name="childPrims"></param>
1560 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1640 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1561 { 1641 {
1642 SceneObjectGroup parentGroup = root.ParentGroup;
1643 if (parentGroup == null) return;
1562 Monitor.Enter(m_updateLock); 1644 Monitor.Enter(m_updateLock);
1645
1563 try 1646 try
1564 { 1647 {
1565 SceneObjectGroup parentGroup = root.ParentGroup; 1648 parentGroup.areUpdatesSuspended = true;
1566 1649
1567 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1650 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1568 if (parentGroup != null) 1651 if (parentGroup != null)
@@ -1574,11 +1657,6 @@ namespace OpenSim.Region.Framework.Scenes
1574 1657
1575 if (child != null) 1658 if (child != null)
1576 { 1659 {
1577 // Make sure no child prim is set for sale
1578 // So that, on delink, no prims are unwittingly
1579 // left for sale and sold off
1580 child.RootPart.ObjectSaleType = 0;
1581 child.RootPart.SalePrice = 10;
1582 childGroups.Add(child); 1660 childGroups.Add(child);
1583 } 1661 }
1584 } 1662 }
@@ -1601,12 +1679,13 @@ namespace OpenSim.Region.Framework.Scenes
1601 // occur on link to invoke this elsewhere (such as object selection) 1679 // occur on link to invoke this elsewhere (such as object selection)
1602 parentGroup.RootPart.CreateSelected = true; 1680 parentGroup.RootPart.CreateSelected = true;
1603 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1681 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1604 parentGroup.HasGroupChanged = true;
1605 parentGroup.ScheduleGroupForFullUpdate();
1606
1607 } 1682 }
1608 finally 1683 finally
1609 { 1684 {
1685 parentGroup.areUpdatesSuspended = false;
1686 parentGroup.HasGroupChanged = true;
1687 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1688 parentGroup.ScheduleGroupForFullUpdate();
1610 Monitor.Exit(m_updateLock); 1689 Monitor.Exit(m_updateLock);
1611 } 1690 }
1612 } 1691 }
@@ -1638,21 +1717,24 @@ namespace OpenSim.Region.Framework.Scenes
1638 1717
1639 SceneObjectGroup group = part.ParentGroup; 1718 SceneObjectGroup group = part.ParentGroup;
1640 if (!affectedGroups.Contains(group)) 1719 if (!affectedGroups.Contains(group))
1720 {
1721 group.areUpdatesSuspended = true;
1641 affectedGroups.Add(group); 1722 affectedGroups.Add(group);
1723 }
1642 } 1724 }
1643 } 1725 }
1644 } 1726 }
1645 1727
1646 foreach (SceneObjectPart child in childParts) 1728 if (childParts.Count > 0)
1647 { 1729 {
1648 // Unlink all child parts from their groups 1730 foreach (SceneObjectPart child in childParts)
1649 // 1731 {
1650 child.ParentGroup.DelinkFromGroup(child, true); 1732 // Unlink all child parts from their groups
1651 1733 //
1652 // These are not in affected groups and will not be 1734 child.ParentGroup.DelinkFromGroup(child, true);
1653 // handled further. Do the honors here. 1735 child.ParentGroup.HasGroupChanged = true;
1654 child.ParentGroup.HasGroupChanged = true; 1736 child.ParentGroup.ScheduleGroupForFullUpdate();
1655 child.ParentGroup.ScheduleGroupForFullUpdate(); 1737 }
1656 } 1738 }
1657 1739
1658 foreach (SceneObjectPart root in rootParts) 1740 foreach (SceneObjectPart root in rootParts)
@@ -1662,56 +1744,68 @@ namespace OpenSim.Region.Framework.Scenes
1662 // However, editing linked parts and unlinking may be different 1744 // However, editing linked parts and unlinking may be different
1663 // 1745 //
1664 SceneObjectGroup group = root.ParentGroup; 1746 SceneObjectGroup group = root.ParentGroup;
1747 group.areUpdatesSuspended = true;
1665 1748
1666 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1749 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1667 int numChildren = newSet.Count; 1750 int numChildren = newSet.Count;
1668 1751
1752 if (numChildren == 1)
1753 break;
1754
1669 // 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
1670 // slated for unlink, we need to do this 1756 // slated for unlink, we need to do this
1757 // Unlink the remaining set
1671 // 1758 //
1672 if (numChildren != 1) 1759 bool sendEventsToRemainder = true;
1673 { 1760 if (numChildren > 1)
1674 // Unlink the remaining set 1761 sendEventsToRemainder = false;
1675 //
1676 bool sendEventsToRemainder = true;
1677 if (numChildren > 1)
1678 sendEventsToRemainder = false;
1679 1762
1680 foreach (SceneObjectPart p in newSet) 1763 foreach (SceneObjectPart p in newSet)
1764 {
1765 if (p != group.RootPart)
1681 { 1766 {
1682 if (p != group.RootPart) 1767 group.DelinkFromGroup(p, sendEventsToRemainder);
1683 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 }
1684 } 1777 }
1778 }
1685 1779
1686 // If there is more than one prim remaining, we 1780 // If there is more than one prim remaining, we
1687 // need to re-link 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);
1789
1790 // Preserve link ordering
1688 // 1791 //
1689 if (numChildren > 2) 1792 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1690 { 1793 {
1691 // Remove old root 1794 return a.LinkNum.CompareTo(b.LinkNum);
1692 // 1795 });
1693 if (newSet.Contains(root))
1694 newSet.Remove(root);
1695
1696 // Preserve link ordering
1697 //
1698 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1699 {
1700 return a.LinkNum.CompareTo(b.LinkNum);
1701 });
1702 1796
1703 // Determine new root 1797 // Determine new root
1704 // 1798 //
1705 SceneObjectPart newRoot = newSet[0]; 1799 SceneObjectPart newRoot = newSet[0];
1706 newSet.RemoveAt(0); 1800 newSet.RemoveAt(0);
1707 1801
1708 foreach (SceneObjectPart newChild in newSet) 1802 foreach (SceneObjectPart newChild in newSet)
1709 newChild.UpdateFlag = 0; 1803 newChild.UpdateFlag = 0;
1710 1804
1711 LinkObjects(newRoot, newSet); 1805 newRoot.ParentGroup.areUpdatesSuspended = true;
1712 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1806 LinkObjects(newRoot, newSet);
1713 affectedGroups.Add(newRoot.ParentGroup); 1807 if (!affectedGroups.Contains(newRoot.ParentGroup))
1714 } 1808 affectedGroups.Add(newRoot.ParentGroup);
1715 } 1809 }
1716 } 1810 }
1717 1811
@@ -1719,8 +1813,14 @@ namespace OpenSim.Region.Framework.Scenes
1719 // 1813 //
1720 foreach (SceneObjectGroup g in affectedGroups) 1814 foreach (SceneObjectGroup g in affectedGroups)
1721 { 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);
1722 g.TriggerScriptChangedEvent(Changed.LINK); 1821 g.TriggerScriptChangedEvent(Changed.LINK);
1723 g.HasGroupChanged = true; // Persist 1822 g.HasGroupChanged = true; // Persist
1823 g.areUpdatesSuspended = false;
1724 g.ScheduleGroupForFullUpdate(); 1824 g.ScheduleGroupForFullUpdate();
1725 } 1825 }
1726 } 1826 }
@@ -1838,9 +1938,6 @@ namespace OpenSim.Region.Framework.Scenes
1838 child.ApplyNextOwnerPermissions(); 1938 child.ApplyNextOwnerPermissions();
1839 } 1939 }
1840 } 1940 }
1841
1842 copy.RootPart.ObjectSaleType = 0;
1843 copy.RootPart.SalePrice = 10;
1844 } 1941 }
1845 1942
1846 // 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()