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.cs293
1 files changed, 238 insertions, 55 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 0098add..cd4bd42 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();
@@ -337,6 +379,11 @@ namespace OpenSim.Region.Framework.Scenes
337 /// </returns> 379 /// </returns>
338 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 380 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
339 { 381 {
382 if (sceneObject == null)
383 {
384 m_log.ErrorFormat("[SCENEGRAPH]: Tried to add null scene object");
385 return false;
386 }
340 if (sceneObject.UUID == UUID.Zero) 387 if (sceneObject.UUID == UUID.Zero)
341 { 388 {
342 m_log.ErrorFormat( 389 m_log.ErrorFormat(
@@ -471,6 +518,30 @@ namespace OpenSim.Region.Framework.Scenes
471 m_updateList[obj.UUID] = obj; 518 m_updateList[obj.UUID] = obj;
472 } 519 }
473 520
521 public void FireAttachToBackup(SceneObjectGroup obj)
522 {
523 if (OnAttachToBackup != null)
524 {
525 OnAttachToBackup(obj);
526 }
527 }
528
529 public void FireDetachFromBackup(SceneObjectGroup obj)
530 {
531 if (OnDetachFromBackup != null)
532 {
533 OnDetachFromBackup(obj);
534 }
535 }
536
537 public void FireChangeBackup(SceneObjectGroup obj)
538 {
539 if (OnChangeBackup != null)
540 {
541 OnChangeBackup(obj);
542 }
543 }
544
474 /// <summary> 545 /// <summary>
475 /// Process all pending updates 546 /// Process all pending updates
476 /// </summary> 547 /// </summary>
@@ -588,7 +659,8 @@ namespace OpenSim.Region.Framework.Scenes
588 659
589 Entities[presence.UUID] = presence; 660 Entities[presence.UUID] = presence;
590 661
591 lock (m_presenceLock) 662 m_scenePresencesLock.EnterWriteLock();
663 try
592 { 664 {
593 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 665 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
594 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 666 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -612,6 +684,10 @@ namespace OpenSim.Region.Framework.Scenes
612 m_scenePresenceMap = newmap; 684 m_scenePresenceMap = newmap;
613 m_scenePresenceArray = newlist; 685 m_scenePresenceArray = newlist;
614 } 686 }
687 finally
688 {
689 m_scenePresencesLock.ExitWriteLock();
690 }
615 } 691 }
616 692
617 /// <summary> 693 /// <summary>
@@ -626,7 +702,8 @@ namespace OpenSim.Region.Framework.Scenes
626 agentID); 702 agentID);
627 } 703 }
628 704
629 lock (m_presenceLock) 705 m_scenePresencesLock.EnterWriteLock();
706 try
630 { 707 {
631 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 708 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
632 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 709 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -648,6 +725,10 @@ namespace OpenSim.Region.Framework.Scenes
648 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 725 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
649 } 726 }
650 } 727 }
728 finally
729 {
730 m_scenePresencesLock.ExitWriteLock();
731 }
651 } 732 }
652 733
653 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 734 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1180,6 +1261,25 @@ namespace OpenSim.Region.Framework.Scenes
1180 1261
1181 #region Client Event handlers 1262 #region Client Event handlers
1182 1263
1264 protected internal void ClientChangeObject(uint localID, object odata, IClientAPI remoteClient)
1265 {
1266 SceneObjectPart part = GetSceneObjectPart(localID);
1267 ObjectChangeData data = (ObjectChangeData)odata;
1268
1269 if (part != null)
1270 {
1271 SceneObjectGroup grp = part.ParentGroup;
1272 if (grp != null)
1273 {
1274 if (m_parentScene.Permissions.CanEditObject(grp.UUID, remoteClient.AgentId))
1275 {
1276 part.StoreUndoState(data.change); // lets test only saving what we changed
1277 grp.doChangeObject(part, (ObjectChangeData)data);
1278 }
1279 }
1280 }
1281 }
1282
1183 /// <summary> 1283 /// <summary>
1184 /// Update the scale of an individual prim. 1284 /// Update the scale of an individual prim.
1185 /// </summary> 1285 /// </summary>
@@ -1194,7 +1294,17 @@ namespace OpenSim.Region.Framework.Scenes
1194 { 1294 {
1195 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)) 1295 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId))
1196 { 1296 {
1297 bool physbuild = false;
1298 if (part.ParentGroup.RootPart.PhysActor != null)
1299 {
1300 part.ParentGroup.RootPart.PhysActor.Building = true;
1301 physbuild = true;
1302 }
1303
1197 part.Resize(scale); 1304 part.Resize(scale);
1305
1306 if (physbuild)
1307 part.ParentGroup.RootPart.PhysActor.Building = false;
1198 } 1308 }
1199 } 1309 }
1200 } 1310 }
@@ -1206,7 +1316,17 @@ namespace OpenSim.Region.Framework.Scenes
1206 { 1316 {
1207 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1317 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1208 { 1318 {
1319 bool physbuild = false;
1320 if (group.RootPart.PhysActor != null)
1321 {
1322 group.RootPart.PhysActor.Building = true;
1323 physbuild = true;
1324 }
1325
1209 group.GroupResize(scale); 1326 group.GroupResize(scale);
1327
1328 if (physbuild)
1329 group.RootPart.PhysActor.Building = false;
1210 } 1330 }
1211 } 1331 }
1212 } 1332 }
@@ -1334,8 +1454,13 @@ namespace OpenSim.Region.Framework.Scenes
1334 { 1454 {
1335 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1455 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1336 { 1456 {
1337 if (m_parentScene.AttachmentsModule != null) 1457 // Set the new attachment point data in the object
1338 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos); 1458 byte attachmentPoint = group.GetAttachmentPoint();
1459 group.UpdateGroupPosition(pos);
1460 group.IsAttachment = false;
1461 group.AbsolutePosition = group.RootPart.AttachedPos;
1462 group.AttachmentPoint = attachmentPoint;
1463 group.HasGroupChanged = true;
1339 } 1464 }
1340 else 1465 else
1341 { 1466 {
@@ -1383,7 +1508,7 @@ namespace OpenSim.Region.Framework.Scenes
1383 /// <param name="SetPhantom"></param> 1508 /// <param name="SetPhantom"></param>
1384 /// <param name="remoteClient"></param> 1509 /// <param name="remoteClient"></param>
1385 protected internal void UpdatePrimFlags( 1510 protected internal void UpdatePrimFlags(
1386 uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, IClientAPI remoteClient) 1511 uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, ExtraPhysicsData PhysData, IClientAPI remoteClient)
1387 { 1512 {
1388 SceneObjectGroup group = GetGroupByPrim(localID); 1513 SceneObjectGroup group = GetGroupByPrim(localID);
1389 if (group != null) 1514 if (group != null)
@@ -1391,7 +1516,18 @@ namespace OpenSim.Region.Framework.Scenes
1391 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1516 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1392 { 1517 {
1393 // VolumeDetect can't be set via UI and will always be off when a change is made there 1518 // VolumeDetect can't be set via UI and will always be off when a change is made there
1394 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false); 1519 if (PhysData.PhysShapeType == PhysShapeType.invalid)
1520 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false);
1521 else
1522 {
1523 SceneObjectPart part = GetSceneObjectPart(localID);
1524 if (part != null)
1525 {
1526 part.UpdateExtraPhysics(PhysData);
1527 if (part.UpdatePhysRequired)
1528 remoteClient.SendPartPhysicsProprieties(part);
1529 }
1530 }
1395 } 1531 }
1396 } 1532 }
1397 } 1533 }
@@ -1535,6 +1671,7 @@ namespace OpenSim.Region.Framework.Scenes
1535 { 1671 {
1536 part.Material = Convert.ToByte(material); 1672 part.Material = Convert.ToByte(material);
1537 group.HasGroupChanged = true; 1673 group.HasGroupChanged = true;
1674 remoteClient.SendPartPhysicsProprieties(part);
1538 } 1675 }
1539 } 1676 }
1540 } 1677 }
@@ -1599,6 +1736,12 @@ namespace OpenSim.Region.Framework.Scenes
1599 /// <param name="childPrims"></param> 1736 /// <param name="childPrims"></param>
1600 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1737 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1601 { 1738 {
1739 if (root.KeyframeMotion != null)
1740 {
1741 root.KeyframeMotion.Stop();
1742 root.KeyframeMotion = null;
1743 }
1744
1602 SceneObjectGroup parentGroup = root.ParentGroup; 1745 SceneObjectGroup parentGroup = root.ParentGroup;
1603 if (parentGroup == null) return; 1746 if (parentGroup == null) return;
1604 1747
@@ -1607,8 +1750,11 @@ namespace OpenSim.Region.Framework.Scenes
1607 return; 1750 return;
1608 1751
1609 Monitor.Enter(m_updateLock); 1752 Monitor.Enter(m_updateLock);
1753
1610 try 1754 try
1611 { 1755 {
1756 parentGroup.areUpdatesSuspended = true;
1757
1612 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1758 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1613 1759
1614 // We do this in reverse to get the link order of the prims correct 1760 // We do this in reverse to get the link order of the prims correct
@@ -1623,9 +1769,13 @@ namespace OpenSim.Region.Framework.Scenes
1623 // Make sure no child prim is set for sale 1769 // Make sure no child prim is set for sale
1624 // So that, on delink, no prims are unwittingly 1770 // So that, on delink, no prims are unwittingly
1625 // left for sale and sold off 1771 // left for sale and sold off
1626 child.RootPart.ObjectSaleType = 0; 1772
1627 child.RootPart.SalePrice = 10; 1773 if (child != null)
1628 childGroups.Add(child); 1774 {
1775 child.RootPart.ObjectSaleType = 0;
1776 child.RootPart.SalePrice = 10;
1777 childGroups.Add(child);
1778 }
1629 } 1779 }
1630 1780
1631 foreach (SceneObjectGroup child in childGroups) 1781 foreach (SceneObjectGroup child in childGroups)
@@ -1652,6 +1802,16 @@ namespace OpenSim.Region.Framework.Scenes
1652 } 1802 }
1653 finally 1803 finally
1654 { 1804 {
1805 lock (SceneObjectGroupsByLocalPartID)
1806 {
1807 foreach (SceneObjectPart part in parentGroup.Parts)
1808 SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup;
1809 }
1810
1811 parentGroup.areUpdatesSuspended = false;
1812 parentGroup.HasGroupChanged = true;
1813 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1814 parentGroup.ScheduleGroupForFullUpdate();
1655 Monitor.Exit(m_updateLock); 1815 Monitor.Exit(m_updateLock);
1656 } 1816 }
1657 } 1817 }
@@ -1674,6 +1834,11 @@ namespace OpenSim.Region.Framework.Scenes
1674 { 1834 {
1675 if (part != null) 1835 if (part != null)
1676 { 1836 {
1837 if (part.KeyframeMotion != null)
1838 {
1839 part.KeyframeMotion.Stop();
1840 part.KeyframeMotion = null;
1841 }
1677 if (part.ParentGroup.PrimCount != 1) // Skip single 1842 if (part.ParentGroup.PrimCount != 1) // Skip single
1678 { 1843 {
1679 if (part.LinkNum < 2) // Root 1844 if (part.LinkNum < 2) // Root
@@ -1688,21 +1853,24 @@ namespace OpenSim.Region.Framework.Scenes
1688 1853
1689 SceneObjectGroup group = part.ParentGroup; 1854 SceneObjectGroup group = part.ParentGroup;
1690 if (!affectedGroups.Contains(group)) 1855 if (!affectedGroups.Contains(group))
1856 {
1857 group.areUpdatesSuspended = true;
1691 affectedGroups.Add(group); 1858 affectedGroups.Add(group);
1859 }
1692 } 1860 }
1693 } 1861 }
1694 } 1862 }
1695 1863
1696 foreach (SceneObjectPart child in childParts) 1864 if (childParts.Count > 0)
1697 { 1865 {
1698 // Unlink all child parts from their groups 1866 foreach (SceneObjectPart child in childParts)
1699 // 1867 {
1700 child.ParentGroup.DelinkFromGroup(child, true); 1868 // Unlink all child parts from their groups
1701 1869 //
1702 // These are not in affected groups and will not be 1870 child.ParentGroup.DelinkFromGroup(child, true);
1703 // handled further. Do the honors here. 1871 child.ParentGroup.HasGroupChanged = true;
1704 child.ParentGroup.HasGroupChanged = true; 1872 child.ParentGroup.ScheduleGroupForFullUpdate();
1705 child.ParentGroup.ScheduleGroupForFullUpdate(); 1873 }
1706 } 1874 }
1707 1875
1708 foreach (SceneObjectPart root in rootParts) 1876 foreach (SceneObjectPart root in rootParts)
@@ -1712,56 +1880,68 @@ namespace OpenSim.Region.Framework.Scenes
1712 // However, editing linked parts and unlinking may be different 1880 // However, editing linked parts and unlinking may be different
1713 // 1881 //
1714 SceneObjectGroup group = root.ParentGroup; 1882 SceneObjectGroup group = root.ParentGroup;
1883 group.areUpdatesSuspended = true;
1715 1884
1716 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1885 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1717 int numChildren = newSet.Count; 1886 int numChildren = newSet.Count;
1718 1887
1888 if (numChildren == 1)
1889 break;
1890
1719 // If there are prims left in a link set, but the root is 1891 // If there are prims left in a link set, but the root is
1720 // slated for unlink, we need to do this 1892 // slated for unlink, we need to do this
1893 // Unlink the remaining set
1721 // 1894 //
1722 if (numChildren != 1) 1895 bool sendEventsToRemainder = true;
1723 { 1896 if (numChildren > 1)
1724 // Unlink the remaining set 1897 sendEventsToRemainder = false;
1725 //
1726 bool sendEventsToRemainder = true;
1727 if (numChildren > 1)
1728 sendEventsToRemainder = false;
1729 1898
1730 foreach (SceneObjectPart p in newSet) 1899 foreach (SceneObjectPart p in newSet)
1900 {
1901 if (p != group.RootPart)
1731 { 1902 {
1732 if (p != group.RootPart) 1903 group.DelinkFromGroup(p, sendEventsToRemainder);
1733 group.DelinkFromGroup(p, sendEventsToRemainder); 1904 if (numChildren > 2)
1905 {
1906 p.ParentGroup.areUpdatesSuspended = true;
1907 }
1908 else
1909 {
1910 p.ParentGroup.HasGroupChanged = true;
1911 p.ParentGroup.ScheduleGroupForFullUpdate();
1912 }
1734 } 1913 }
1914 }
1915
1916 // If there is more than one prim remaining, we
1917 // need to re-link
1918 //
1919 if (numChildren > 2)
1920 {
1921 // Remove old root
1922 //
1923 if (newSet.Contains(root))
1924 newSet.Remove(root);
1735 1925
1736 // If there is more than one prim remaining, we 1926 // Preserve link ordering
1737 // need to re-link
1738 // 1927 //
1739 if (numChildren > 2) 1928 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1740 { 1929 {
1741 // Remove old root 1930 return a.LinkNum.CompareTo(b.LinkNum);
1742 // 1931 });
1743 if (newSet.Contains(root))
1744 newSet.Remove(root);
1745
1746 // Preserve link ordering
1747 //
1748 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1749 {
1750 return a.LinkNum.CompareTo(b.LinkNum);
1751 });
1752 1932
1753 // Determine new root 1933 // Determine new root
1754 // 1934 //
1755 SceneObjectPart newRoot = newSet[0]; 1935 SceneObjectPart newRoot = newSet[0];
1756 newSet.RemoveAt(0); 1936 newSet.RemoveAt(0);
1757 1937
1758 foreach (SceneObjectPart newChild in newSet) 1938 foreach (SceneObjectPart newChild in newSet)
1759 newChild.ClearUpdateSchedule(); 1939 newChild.ClearUpdateSchedule();
1760 1940
1761 LinkObjects(newRoot, newSet); 1941 newRoot.ParentGroup.areUpdatesSuspended = true;
1762 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1942 LinkObjects(newRoot, newSet);
1763 affectedGroups.Add(newRoot.ParentGroup); 1943 if (!affectedGroups.Contains(newRoot.ParentGroup))
1764 } 1944 affectedGroups.Add(newRoot.ParentGroup);
1765 } 1945 }
1766 } 1946 }
1767 1947
@@ -1769,8 +1949,14 @@ namespace OpenSim.Region.Framework.Scenes
1769 // 1949 //
1770 foreach (SceneObjectGroup g in affectedGroups) 1950 foreach (SceneObjectGroup g in affectedGroups)
1771 { 1951 {
1952 // Child prims that have been unlinked and deleted will
1953 // return unless the root is deleted. This will remove them
1954 // from the database. They will be rewritten immediately,
1955 // minus the rows for the unlinked child prims.
1956 m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
1772 g.TriggerScriptChangedEvent(Changed.LINK); 1957 g.TriggerScriptChangedEvent(Changed.LINK);
1773 g.HasGroupChanged = true; // Persist 1958 g.HasGroupChanged = true; // Persist
1959 g.areUpdatesSuspended = false;
1774 g.ScheduleGroupForFullUpdate(); 1960 g.ScheduleGroupForFullUpdate();
1775 } 1961 }
1776 } 1962 }
@@ -1872,9 +2058,6 @@ namespace OpenSim.Region.Framework.Scenes
1872 child.ApplyNextOwnerPermissions(); 2058 child.ApplyNextOwnerPermissions();
1873 } 2059 }
1874 } 2060 }
1875
1876 copy.RootPart.ObjectSaleType = 0;
1877 copy.RootPart.SalePrice = 10;
1878 } 2061 }
1879 2062
1880 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 2063 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()