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.cs288
1 files changed, 233 insertions, 55 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index bc3400a..7b77ea0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -41,6 +41,12 @@ namespace OpenSim.Region.Framework.Scenes
41{ 41{
42 public delegate void PhysicsCrash(); 42 public delegate void PhysicsCrash();
43 43
44 public delegate void AttachToBackupDelegate(SceneObjectGroup sog);
45
46 public delegate void DetachFromBackupDelegate(SceneObjectGroup sog);
47
48 public delegate void ChangedBackupDelegate(SceneObjectGroup sog);
49
44 /// <summary> 50 /// <summary>
45 /// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components 51 /// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components
46 /// should be migrated out over time. 52 /// should be migrated out over time.
@@ -54,11 +60,15 @@ namespace OpenSim.Region.Framework.Scenes
54 protected internal event PhysicsCrash UnRecoverableError; 60 protected internal event PhysicsCrash UnRecoverableError;
55 private PhysicsCrash handlerPhysicsCrash = null; 61 private PhysicsCrash handlerPhysicsCrash = null;
56 62
63 public event AttachToBackupDelegate OnAttachToBackup;
64 public event DetachFromBackupDelegate OnDetachFromBackup;
65 public event ChangedBackupDelegate OnChangeBackup;
66
57 #endregion 67 #endregion
58 68
59 #region Fields 69 #region Fields
60 70
61 protected object m_presenceLock = new object(); 71 protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim();
62 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); 72 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
63 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); 73 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
64 74
@@ -120,13 +130,18 @@ namespace OpenSim.Region.Framework.Scenes
120 130
121 protected internal void Close() 131 protected internal void Close()
122 { 132 {
123 lock (m_presenceLock) 133 m_scenePresencesLock.EnterWriteLock();
134 try
124 { 135 {
125 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 136 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
126 List<ScenePresence> newlist = new List<ScenePresence>(); 137 List<ScenePresence> newlist = new List<ScenePresence>();
127 m_scenePresenceMap = newmap; 138 m_scenePresenceMap = newmap;
128 m_scenePresenceArray = newlist; 139 m_scenePresenceArray = newlist;
129 } 140 }
141 finally
142 {
143 m_scenePresencesLock.ExitWriteLock();
144 }
130 145
131 lock (SceneObjectGroupsByFullID) 146 lock (SceneObjectGroupsByFullID)
132 SceneObjectGroupsByFullID.Clear(); 147 SceneObjectGroupsByFullID.Clear();
@@ -247,6 +262,33 @@ namespace OpenSim.Region.Framework.Scenes
247 protected internal bool AddRestoredSceneObject( 262 protected internal bool AddRestoredSceneObject(
248 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 263 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
249 { 264 {
265 if (!m_parentScene.CombineRegions)
266 {
267 // KF: Check for out-of-region, move inside and make static.
268 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
269 sceneObject.RootPart.GroupPosition.Y,
270 sceneObject.RootPart.GroupPosition.Z);
271 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 ||
272 npos.X > Constants.RegionSize ||
273 npos.Y > Constants.RegionSize))
274 {
275 if (npos.X < 0.0) npos.X = 1.0f;
276 if (npos.Y < 0.0) npos.Y = 1.0f;
277 if (npos.Z < 0.0) npos.Z = 0.0f;
278 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
279 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
280
281 foreach (SceneObjectPart part in sceneObject.Parts)
282 {
283 part.GroupPosition = npos;
284 }
285 sceneObject.RootPart.Velocity = Vector3.Zero;
286 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
287 sceneObject.RootPart.Acceleration = Vector3.Zero;
288 sceneObject.RootPart.Velocity = Vector3.Zero;
289 }
290 }
291
250 if (attachToBackup && (!alreadyPersisted)) 292 if (attachToBackup && (!alreadyPersisted))
251 { 293 {
252 sceneObject.ForceInventoryPersistence(); 294 sceneObject.ForceInventoryPersistence();
@@ -336,6 +378,11 @@ namespace OpenSim.Region.Framework.Scenes
336 /// </returns> 378 /// </returns>
337 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 379 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
338 { 380 {
381 if (sceneObject == null)
382 {
383 m_log.ErrorFormat("[SCENEGRAPH]: Tried to add null scene object");
384 return false;
385 }
339 if (sceneObject.UUID == UUID.Zero) 386 if (sceneObject.UUID == UUID.Zero)
340 { 387 {
341 m_log.ErrorFormat( 388 m_log.ErrorFormat(
@@ -470,6 +517,30 @@ namespace OpenSim.Region.Framework.Scenes
470 m_updateList[obj.UUID] = obj; 517 m_updateList[obj.UUID] = obj;
471 } 518 }
472 519
520 public void FireAttachToBackup(SceneObjectGroup obj)
521 {
522 if (OnAttachToBackup != null)
523 {
524 OnAttachToBackup(obj);
525 }
526 }
527
528 public void FireDetachFromBackup(SceneObjectGroup obj)
529 {
530 if (OnDetachFromBackup != null)
531 {
532 OnDetachFromBackup(obj);
533 }
534 }
535
536 public void FireChangeBackup(SceneObjectGroup obj)
537 {
538 if (OnChangeBackup != null)
539 {
540 OnChangeBackup(obj);
541 }
542 }
543
473 /// <summary> 544 /// <summary>
474 /// Process all pending updates 545 /// Process all pending updates
475 /// </summary> 546 /// </summary>
@@ -587,7 +658,8 @@ namespace OpenSim.Region.Framework.Scenes
587 658
588 Entities[presence.UUID] = presence; 659 Entities[presence.UUID] = presence;
589 660
590 lock (m_presenceLock) 661 m_scenePresencesLock.EnterWriteLock();
662 try
591 { 663 {
592 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 664 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
593 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 665 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -611,6 +683,10 @@ namespace OpenSim.Region.Framework.Scenes
611 m_scenePresenceMap = newmap; 683 m_scenePresenceMap = newmap;
612 m_scenePresenceArray = newlist; 684 m_scenePresenceArray = newlist;
613 } 685 }
686 finally
687 {
688 m_scenePresencesLock.ExitWriteLock();
689 }
614 } 690 }
615 691
616 /// <summary> 692 /// <summary>
@@ -625,7 +701,8 @@ namespace OpenSim.Region.Framework.Scenes
625 agentID); 701 agentID);
626 } 702 }
627 703
628 lock (m_presenceLock) 704 m_scenePresencesLock.EnterWriteLock();
705 try
629 { 706 {
630 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 707 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
631 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 708 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -647,6 +724,10 @@ namespace OpenSim.Region.Framework.Scenes
647 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 724 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
648 } 725 }
649 } 726 }
727 finally
728 {
729 m_scenePresencesLock.ExitWriteLock();
730 }
650 } 731 }
651 732
652 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 733 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1208,6 +1289,25 @@ namespace OpenSim.Region.Framework.Scenes
1208 1289
1209 #region Client Event handlers 1290 #region Client Event handlers
1210 1291
1292 protected internal void ClientChangeObject(uint localID, object odata, IClientAPI remoteClient)
1293 {
1294 SceneObjectPart part = GetSceneObjectPart(localID);
1295 ObjectChangeData data = (ObjectChangeData)odata;
1296
1297 if (part != null)
1298 {
1299 SceneObjectGroup grp = part.ParentGroup;
1300 if (grp != null)
1301 {
1302 if (m_parentScene.Permissions.CanEditObject(grp.UUID, remoteClient.AgentId))
1303 {
1304 part.StoreUndoState(data.change); // lets test only saving what we changed
1305 grp.doChangeObject(part, (ObjectChangeData)data);
1306 }
1307 }
1308 }
1309 }
1310
1211 /// <summary> 1311 /// <summary>
1212 /// Update the scale of an individual prim. 1312 /// Update the scale of an individual prim.
1213 /// </summary> 1313 /// </summary>
@@ -1222,7 +1322,17 @@ namespace OpenSim.Region.Framework.Scenes
1222 { 1322 {
1223 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)) 1323 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId))
1224 { 1324 {
1325 bool physbuild = false;
1326 if (part.ParentGroup.RootPart.PhysActor != null)
1327 {
1328 part.ParentGroup.RootPart.PhysActor.Building = true;
1329 physbuild = true;
1330 }
1331
1225 part.Resize(scale); 1332 part.Resize(scale);
1333
1334 if (physbuild)
1335 part.ParentGroup.RootPart.PhysActor.Building = false;
1226 } 1336 }
1227 } 1337 }
1228 } 1338 }
@@ -1234,7 +1344,17 @@ namespace OpenSim.Region.Framework.Scenes
1234 { 1344 {
1235 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1345 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1236 { 1346 {
1347 bool physbuild = false;
1348 if (group.RootPart.PhysActor != null)
1349 {
1350 group.RootPart.PhysActor.Building = true;
1351 physbuild = true;
1352 }
1353
1237 group.GroupResize(scale); 1354 group.GroupResize(scale);
1355
1356 if (physbuild)
1357 group.RootPart.PhysActor.Building = false;
1238 } 1358 }
1239 } 1359 }
1240 } 1360 }
@@ -1362,8 +1482,13 @@ namespace OpenSim.Region.Framework.Scenes
1362 { 1482 {
1363 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1483 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1364 { 1484 {
1365 if (m_parentScene.AttachmentsModule != null) 1485 // Set the new attachment point data in the object
1366 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos); 1486 byte attachmentPoint = group.GetAttachmentPoint();
1487 group.UpdateGroupPosition(pos);
1488 group.IsAttachment = false;
1489 group.AbsolutePosition = group.RootPart.AttachedPos;
1490 group.AttachmentPoint = attachmentPoint;
1491 group.HasGroupChanged = true;
1367 } 1492 }
1368 else 1493 else
1369 { 1494 {
@@ -1411,7 +1536,7 @@ namespace OpenSim.Region.Framework.Scenes
1411 /// <param name="SetPhantom"></param> 1536 /// <param name="SetPhantom"></param>
1412 /// <param name="remoteClient"></param> 1537 /// <param name="remoteClient"></param>
1413 protected internal void UpdatePrimFlags( 1538 protected internal void UpdatePrimFlags(
1414 uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, IClientAPI remoteClient) 1539 uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, ExtraPhysicsData PhysData, IClientAPI remoteClient)
1415 { 1540 {
1416 SceneObjectGroup group = GetGroupByPrim(localID); 1541 SceneObjectGroup group = GetGroupByPrim(localID);
1417 if (group != null) 1542 if (group != null)
@@ -1419,7 +1544,14 @@ namespace OpenSim.Region.Framework.Scenes
1419 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1544 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1420 { 1545 {
1421 // VolumeDetect can't be set via UI and will always be off when a change is made there 1546 // VolumeDetect can't be set via UI and will always be off when a change is made there
1422 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false); 1547 if (PhysData.PhysShapeType == PhysShapeType.invalid)
1548 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false);
1549 else
1550 {
1551 SceneObjectPart part = GetSceneObjectPart(localID);
1552 if (part != null)
1553 part.UpdateExtraPhysics(PhysData);
1554 }
1423 } 1555 }
1424 } 1556 }
1425 } 1557 }
@@ -1627,6 +1759,12 @@ namespace OpenSim.Region.Framework.Scenes
1627 /// <param name="childPrims"></param> 1759 /// <param name="childPrims"></param>
1628 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1760 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1629 { 1761 {
1762 if (root.KeyframeMotion != null)
1763 {
1764 root.KeyframeMotion.Stop();
1765 root.KeyframeMotion = null;
1766 }
1767
1630 SceneObjectGroup parentGroup = root.ParentGroup; 1768 SceneObjectGroup parentGroup = root.ParentGroup;
1631 if (parentGroup == null) return; 1769 if (parentGroup == null) return;
1632 1770
@@ -1635,8 +1773,11 @@ namespace OpenSim.Region.Framework.Scenes
1635 return; 1773 return;
1636 1774
1637 Monitor.Enter(m_updateLock); 1775 Monitor.Enter(m_updateLock);
1776
1638 try 1777 try
1639 { 1778 {
1779 parentGroup.areUpdatesSuspended = true;
1780
1640 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1781 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1641 1782
1642 // We do this in reverse to get the link order of the prims correct 1783 // We do this in reverse to get the link order of the prims correct
@@ -1651,9 +1792,13 @@ namespace OpenSim.Region.Framework.Scenes
1651 // Make sure no child prim is set for sale 1792 // Make sure no child prim is set for sale
1652 // So that, on delink, no prims are unwittingly 1793 // So that, on delink, no prims are unwittingly
1653 // left for sale and sold off 1794 // left for sale and sold off
1654 child.RootPart.ObjectSaleType = 0; 1795
1655 child.RootPart.SalePrice = 10; 1796 if (child != null)
1656 childGroups.Add(child); 1797 {
1798 child.RootPart.ObjectSaleType = 0;
1799 child.RootPart.SalePrice = 10;
1800 childGroups.Add(child);
1801 }
1657 } 1802 }
1658 1803
1659 foreach (SceneObjectGroup child in childGroups) 1804 foreach (SceneObjectGroup child in childGroups)
@@ -1680,6 +1825,16 @@ namespace OpenSim.Region.Framework.Scenes
1680 } 1825 }
1681 finally 1826 finally
1682 { 1827 {
1828 lock (SceneObjectGroupsByLocalPartID)
1829 {
1830 foreach (SceneObjectPart part in parentGroup.Parts)
1831 SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup;
1832 }
1833
1834 parentGroup.areUpdatesSuspended = false;
1835 parentGroup.HasGroupChanged = true;
1836 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1837 parentGroup.ScheduleGroupForFullUpdate();
1683 Monitor.Exit(m_updateLock); 1838 Monitor.Exit(m_updateLock);
1684 } 1839 }
1685 } 1840 }
@@ -1702,6 +1857,11 @@ namespace OpenSim.Region.Framework.Scenes
1702 { 1857 {
1703 if (part != null) 1858 if (part != null)
1704 { 1859 {
1860 if (part.KeyframeMotion != null)
1861 {
1862 part.KeyframeMotion.Stop();
1863 part.KeyframeMotion = null;
1864 }
1705 if (part.ParentGroup.PrimCount != 1) // Skip single 1865 if (part.ParentGroup.PrimCount != 1) // Skip single
1706 { 1866 {
1707 if (part.LinkNum < 2) // Root 1867 if (part.LinkNum < 2) // Root
@@ -1716,21 +1876,24 @@ namespace OpenSim.Region.Framework.Scenes
1716 1876
1717 SceneObjectGroup group = part.ParentGroup; 1877 SceneObjectGroup group = part.ParentGroup;
1718 if (!affectedGroups.Contains(group)) 1878 if (!affectedGroups.Contains(group))
1879 {
1880 group.areUpdatesSuspended = true;
1719 affectedGroups.Add(group); 1881 affectedGroups.Add(group);
1882 }
1720 } 1883 }
1721 } 1884 }
1722 } 1885 }
1723 1886
1724 foreach (SceneObjectPart child in childParts) 1887 if (childParts.Count > 0)
1725 { 1888 {
1726 // Unlink all child parts from their groups 1889 foreach (SceneObjectPart child in childParts)
1727 // 1890 {
1728 child.ParentGroup.DelinkFromGroup(child, true); 1891 // Unlink all child parts from their groups
1729 1892 //
1730 // These are not in affected groups and will not be 1893 child.ParentGroup.DelinkFromGroup(child, true);
1731 // handled further. Do the honors here. 1894 child.ParentGroup.HasGroupChanged = true;
1732 child.ParentGroup.HasGroupChanged = true; 1895 child.ParentGroup.ScheduleGroupForFullUpdate();
1733 child.ParentGroup.ScheduleGroupForFullUpdate(); 1896 }
1734 } 1897 }
1735 1898
1736 foreach (SceneObjectPart root in rootParts) 1899 foreach (SceneObjectPart root in rootParts)
@@ -1740,56 +1903,68 @@ namespace OpenSim.Region.Framework.Scenes
1740 // However, editing linked parts and unlinking may be different 1903 // However, editing linked parts and unlinking may be different
1741 // 1904 //
1742 SceneObjectGroup group = root.ParentGroup; 1905 SceneObjectGroup group = root.ParentGroup;
1906 group.areUpdatesSuspended = true;
1743 1907
1744 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1908 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1745 int numChildren = newSet.Count; 1909 int numChildren = newSet.Count;
1746 1910
1911 if (numChildren == 1)
1912 break;
1913
1747 // If there are prims left in a link set, but the root is 1914 // If there are prims left in a link set, but the root is
1748 // slated for unlink, we need to do this 1915 // slated for unlink, we need to do this
1916 // Unlink the remaining set
1749 // 1917 //
1750 if (numChildren != 1) 1918 bool sendEventsToRemainder = true;
1751 { 1919 if (numChildren > 1)
1752 // Unlink the remaining set 1920 sendEventsToRemainder = false;
1753 //
1754 bool sendEventsToRemainder = true;
1755 if (numChildren > 1)
1756 sendEventsToRemainder = false;
1757 1921
1758 foreach (SceneObjectPart p in newSet) 1922 foreach (SceneObjectPart p in newSet)
1923 {
1924 if (p != group.RootPart)
1759 { 1925 {
1760 if (p != group.RootPart) 1926 group.DelinkFromGroup(p, sendEventsToRemainder);
1761 group.DelinkFromGroup(p, sendEventsToRemainder); 1927 if (numChildren > 2)
1928 {
1929 p.ParentGroup.areUpdatesSuspended = true;
1930 }
1931 else
1932 {
1933 p.ParentGroup.HasGroupChanged = true;
1934 p.ParentGroup.ScheduleGroupForFullUpdate();
1935 }
1762 } 1936 }
1937 }
1938
1939 // If there is more than one prim remaining, we
1940 // need to re-link
1941 //
1942 if (numChildren > 2)
1943 {
1944 // Remove old root
1945 //
1946 if (newSet.Contains(root))
1947 newSet.Remove(root);
1763 1948
1764 // If there is more than one prim remaining, we 1949 // Preserve link ordering
1765 // need to re-link
1766 // 1950 //
1767 if (numChildren > 2) 1951 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1768 { 1952 {
1769 // Remove old root 1953 return a.LinkNum.CompareTo(b.LinkNum);
1770 // 1954 });
1771 if (newSet.Contains(root))
1772 newSet.Remove(root);
1773
1774 // Preserve link ordering
1775 //
1776 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1777 {
1778 return a.LinkNum.CompareTo(b.LinkNum);
1779 });
1780 1955
1781 // Determine new root 1956 // Determine new root
1782 // 1957 //
1783 SceneObjectPart newRoot = newSet[0]; 1958 SceneObjectPart newRoot = newSet[0];
1784 newSet.RemoveAt(0); 1959 newSet.RemoveAt(0);
1785 1960
1786 foreach (SceneObjectPart newChild in newSet) 1961 foreach (SceneObjectPart newChild in newSet)
1787 newChild.ClearUpdateSchedule(); 1962 newChild.ClearUpdateSchedule();
1788 1963
1789 LinkObjects(newRoot, newSet); 1964 newRoot.ParentGroup.areUpdatesSuspended = true;
1790 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1965 LinkObjects(newRoot, newSet);
1791 affectedGroups.Add(newRoot.ParentGroup); 1966 if (!affectedGroups.Contains(newRoot.ParentGroup))
1792 } 1967 affectedGroups.Add(newRoot.ParentGroup);
1793 } 1968 }
1794 } 1969 }
1795 1970
@@ -1797,8 +1972,14 @@ namespace OpenSim.Region.Framework.Scenes
1797 // 1972 //
1798 foreach (SceneObjectGroup g in affectedGroups) 1973 foreach (SceneObjectGroup g in affectedGroups)
1799 { 1974 {
1975 // Child prims that have been unlinked and deleted will
1976 // return unless the root is deleted. This will remove them
1977 // from the database. They will be rewritten immediately,
1978 // minus the rows for the unlinked child prims.
1979 m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
1800 g.TriggerScriptChangedEvent(Changed.LINK); 1980 g.TriggerScriptChangedEvent(Changed.LINK);
1801 g.HasGroupChanged = true; // Persist 1981 g.HasGroupChanged = true; // Persist
1982 g.areUpdatesSuspended = false;
1802 g.ScheduleGroupForFullUpdate(); 1983 g.ScheduleGroupForFullUpdate();
1803 } 1984 }
1804 } 1985 }
@@ -1900,9 +2081,6 @@ namespace OpenSim.Region.Framework.Scenes
1900 child.ApplyNextOwnerPermissions(); 2081 child.ApplyNextOwnerPermissions();
1901 } 2082 }
1902 } 2083 }
1903
1904 copy.RootPart.ObjectSaleType = 0;
1905 copy.RootPart.SalePrice = 10;
1906 } 2084 }
1907 2085
1908 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 2086 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()