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.cs160
1 files changed, 81 insertions, 79 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 1e6955a..4b4461f 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1588,106 +1588,108 @@ namespace OpenSim.Region.Framework.Scenes
1588 1588
1589 protected internal void DelinkObjects(List<uint> primIds, bool sendEvents) 1589 protected internal void DelinkObjects(List<uint> primIds, bool sendEvents)
1590 { 1590 {
1591 SceneObjectGroup parentPrim = null; 1591 List<SceneObjectPart> childParts = new List<SceneObjectPart>();
1592 // Find the root prim among the prim ids we've been given 1592 List<SceneObjectPart> rootParts = new List<SceneObjectPart>();
1593 for (int i = 0; i < primIds.Count; i++) 1593 List<SceneObjectGroup> affectedGroups = new List<SceneObjectGroup>();
1594 // Look them all up in one go, since that is comparatively expensive
1595 //
1596 foreach (uint primID in primIds)
1594 { 1597 {
1595 // Get the group for this prim and check that it is the parent 1598 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID);
1596 parentPrim = GetGroupByPrim(primIds[i]); 1599 if (part != null)
1597 if (parentPrim != null && parentPrim.LocalId == primIds[i])
1598 { 1600 {
1599 primIds.RemoveAt(i); 1601 if (part.LinkNum < 2) // Root or single
1600 break; 1602 rootParts.Add(part);
1603 else
1604 childParts.Add(part);
1605
1606 SceneObjectGroup group = part.ParentGroup;
1607 if (!affectedGroups.Contains(group))
1608 affectedGroups.Add(group);
1609 }
1610 else
1611 {
1612 m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID);
1601 } 1613 }
1602 } 1614 }
1603 1615
1604 if (parentPrim != null) 1616 foreach (SceneObjectPart child in childParts)
1605 { 1617 {
1606 foreach (uint childPrimId in primIds) 1618 // Unlink all child parts from their groups
1607 { 1619 //
1608 parentPrim.DelinkFromGroup(childPrimId, sendEvents); 1620 child.ParentGroup.DelinkFromGroup(child, sendEvents);
1609 } 1621 }
1610 1622
1611 if (parentPrim.Children.Count == 1) 1623 foreach (SceneObjectPart root in rootParts)
1612 { 1624 {
1613 // The link set has been completely torn down 1625 // In most cases, this will run only one time, and the prim
1614 // This is the case if you select a link set and delink 1626 // will be a solo prim
1615 // 1627 // However, editing linked parts and unlinking may be different
1616 parentPrim.RootPart.LinkNum = 0; 1628 //
1617 if (sendEvents) 1629 SceneObjectGroup group = root.ParentGroup;
1618 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 1630 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values);
1619 } 1631 int numChildren = group.Children.Count;
1620 else 1632
1633 // If there are prims left in a link set, but the root is
1634 // slated for unlink, we need to do this
1635 //
1636 if (numChildren != 1)
1621 { 1637 {
1622 // The link set has prims remaining. This path is taken 1638 // Unlink the remaining set
1623 // when a subset of a link set's prims are selected
1624 // and the root prim is part of that selection
1625 // 1639 //
1626 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 1640 bool sendEventsToRemainder = true;
1641 if (numChildren > 1)
1642 sendEventsToRemainder = false;
1627 1643
1628 List<uint> unlink_ids = new List<uint>(); 1644 foreach (SceneObjectPart p in newSet)
1629 foreach (SceneObjectPart unlink_part in parts) 1645 {
1630 unlink_ids.Add(unlink_part.LocalId); 1646 if (p != group.RootPart)
1647 group.DelinkFromGroup(p, sendEventsToRemainder);
1648 }
1631 1649
1632 // Tear down the remaining link set 1650 // If there is more than one prim remaining, we
1651 // need to re-link
1633 // 1652 //
1634 if (unlink_ids.Count == 2) 1653 if (numChildren > 2)
1635 { 1654 {
1636 DelinkObjects(unlink_ids, true); 1655 // Remove old root
1637 return; 1656 //
1638 } 1657 if (newSet.Contains(root))
1658 newSet.Remove(root);
1659
1660 // Preserve link ordering
1661 //
1662 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1663 {
1664 return a.LinkNum.CompareTo(b.LinkNum);
1665 });
1639 1666
1640 DelinkObjects(unlink_ids, false); 1667 // Determine new root
1668 //
1669 SceneObjectPart newRoot = newSet[0];
1670 newSet.RemoveAt(0);
1641 1671
1642 // Send event to root prim, then we're done with it 1672 List<uint> linkIDs = new List<uint>();
1643 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
1644 1673
1645 unlink_ids.Remove(parentPrim.RootPart.LocalId); 1674 foreach (SceneObjectPart newChild in newSet)
1675 {
1676 newChild.UpdateFlag = 0;
1677 linkIDs.Add(newChild.LocalId);
1678 }
1646 1679
1647 foreach (uint localId in unlink_ids) 1680 LinkObjects(null, newRoot.LocalId, linkIDs);
1648 { 1681 if (!affectedGroups.Contains(newRoot.ParentGroup))
1649 SceneObjectPart nr = GetSceneObjectPart(localId); 1682 affectedGroups.Add(newRoot.ParentGroup);
1650 nr.UpdateFlag = 0;
1651 } 1683 }
1652
1653 uint newRoot = unlink_ids[0];
1654 unlink_ids.Remove(newRoot);
1655
1656 LinkObjects(null, newRoot, unlink_ids);
1657 } 1684 }
1658 } 1685 }
1659 else
1660 {
1661 // The selected prims were all child prims. Edit linked parts
1662 // without the root prim selected will get us here
1663 //
1664 List<SceneObjectGroup> parentGroups = new List<SceneObjectGroup>();
1665 1686
1666 // If the first scan failed, we need to do a /deep/ scan of the linkages. This is /really/ slow 1687 // Finally, trigger events in the roots
1667 // We know that this is not the root prim now essentially, so we don't have to worry about remapping 1688 //
1668 // which one is the root prim 1689 foreach (SceneObjectGroup g in affectedGroups)
1669 bool delinkedSomething = false; 1690 {
1670 for (int i = 0; i < primIds.Count; i++) 1691 g.TriggerScriptChangedEvent(Changed.LINK);
1671 { 1692 g.ScheduleGroupForFullUpdate();
1672 SceneObjectGroup parent = GetGroupByPrim(primIds[i]);
1673 parent.DelinkFromGroup(primIds[i]);
1674 delinkedSomething = true;
1675 if (!parentGroups.Contains(parent))
1676 parentGroups.Add(parent);
1677 }
1678 if (!delinkedSomething)
1679 {
1680 m_log.InfoFormat("[SCENE]: " +
1681 "DelinkObjects(): Could not find a root prim out of {0} as given to a delink request!",
1682 primIds);
1683 }
1684 else
1685 {
1686 foreach (SceneObjectGroup g in parentGroups)
1687 {
1688 g.TriggerScriptChangedEvent(Changed.LINK);
1689 }
1690 }
1691 } 1693 }
1692 } 1694 }
1693 1695