fix linknumbers when unlink the root prim

0.9.0-post-fixes
UbitUmarov 2016-09-24 22:21:51 +01:00
parent 9e074988f0
commit 6779f41e21
2 changed files with 158 additions and 71 deletions

View File

@ -1913,31 +1913,36 @@ namespace OpenSim.Region.Framework.Scenes
// //
foreach (SceneObjectPart part in prims) foreach (SceneObjectPart part in prims)
{ {
if (part != null) if(part == null)
{ continue;
if (part.KeyframeMotion != null) SceneObjectGroup parentSOG = part.ParentGroup;
{ if(parentSOG == null ||
part.KeyframeMotion.Stop(); parentSOG.IsDeleted ||
part.KeyframeMotion = null; parentSOG.inTransit ||
} parentSOG.PrimCount == 1)
if (part.ParentGroup.PrimCount != 1) // Skip single continue;
{
if (part.LinkNum < 2) // Root
{
rootParts.Add(part);
}
else
{
part.LastOwnerID = part.ParentGroup.RootPart.LastOwnerID;
childParts.Add(part);
}
SceneObjectGroup group = part.ParentGroup; if (!affectedGroups.Contains(parentSOG))
if (!affectedGroups.Contains(group)) {
{ affectedGroups.Add(parentSOG);
affectedGroups.Add(group); if(parentSOG.RootPart.PhysActor != null)
} parentSOG.RootPart.PhysActor.Building = true;
} }
if (part.KeyframeMotion != null)
{
part.KeyframeMotion.Stop();
part.KeyframeMotion = null;
}
if (part.LinkNum < 2) // Root
{
rootParts.Add(part);
}
else
{
part.LastOwnerID = part.ParentGroup.RootPart.LastOwnerID;
childParts.Add(part);
} }
} }
@ -1946,8 +1951,8 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart child in childParts) foreach (SceneObjectPart child in childParts)
{ {
// Unlink all child parts from their groups // Unlink all child parts from their groups
//
child.ParentGroup.DelinkFromGroup(child, true); child.ParentGroup.DelinkFromGroup(child, true);
//child.ParentGroup is now other
child.ParentGroup.HasGroupChanged = true; child.ParentGroup.HasGroupChanged = true;
child.ParentGroup.ScheduleGroupForFullUpdate(); child.ParentGroup.ScheduleGroupForFullUpdate();
} }
@ -1960,74 +1965,51 @@ namespace OpenSim.Region.Framework.Scenes
// However, editing linked parts and unlinking may be different // However, editing linked parts and unlinking may be different
// //
SceneObjectGroup group = root.ParentGroup; SceneObjectGroup group = root.ParentGroup;
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
int numChildren = newSet.Count;
if (numChildren == 1) newSet.Remove(root);
int numChildren = newSet.Count;
if(numChildren == 0)
break; break;
// If there are prims left in a link set, but the root is
// slated for unlink, we need to do this
// Unlink the remaining set
//
bool sendEventsToRemainder = false;
if (numChildren == 2) // only one child prim no re-link needed
sendEventsToRemainder = true;
foreach (SceneObjectPart p in newSet) foreach (SceneObjectPart p in newSet)
{ group.DelinkFromGroup(p, false);
if (p != group.RootPart)
{
group.DelinkFromGroup(p, sendEventsToRemainder);
if (sendEventsToRemainder) // finish single child prim now
{
p.ParentGroup.HasGroupChanged = true;
p.ParentGroup.ScheduleGroupForFullUpdate();
}
}
}
SceneObjectPart newRoot = newSet[0];
// If there is more than one prim remaining, we // If there is more than one prim remaining, we
// need to re-link // need to re-link
// //
if (numChildren > 2) if (numChildren > 1)
{ {
// Remove old root
//
if (newSet.Contains(root))
newSet.Remove(root);
// Preserve link ordering
//
newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
{
return a.LinkNum.CompareTo(b.LinkNum);
});
// Determine new root // Determine new root
// //
SceneObjectPart newRoot = newSet[0];
newSet.RemoveAt(0); newSet.RemoveAt(0);
foreach (SceneObjectPart newChild in newSet)
foreach (SceneObjectPart newChild in newSet) newChild.ClearUpdateSchedule();
newChild.ClearUpdateSchedule();
LinkObjects(newRoot, newSet); LinkObjects(newRoot, newSet);
// if (!affectedGroups.Contains(newRoot.ParentGroup)) }
// affectedGroups.Add(newRoot.ParentGroup); else
{
newRoot.TriggerScriptChangedEvent(Changed.LINK);
newRoot.ParentGroup.HasGroupChanged = true;
newRoot.ParentGroup.ScheduleGroupForFullUpdate();
} }
} }
// Finally, trigger events in the roots // trigger events in the roots
// //
foreach (SceneObjectGroup g in affectedGroups) foreach (SceneObjectGroup g in affectedGroups)
{ {
if(g.RootPart.PhysActor != null)
g.RootPart.PhysActor.Building = false;
g.AdjustChildPrimPermissions(false);
// Child prims that have been unlinked and deleted will // Child prims that have been unlinked and deleted will
// return unless the root is deleted. This will remove them // return unless the root is deleted. This will remove them
// from the database. They will be rewritten immediately, // from the database. They will be rewritten immediately,
// minus the rows for the unlinked child prims. // minus the rows for the unlinked child prims.
g.AdjustChildPrimPermissions(false);
m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID); m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
g.TriggerScriptChangedEvent(Changed.LINK); g.TriggerScriptChangedEvent(Changed.LINK);
g.HasGroupChanged = true; // Persist g.HasGroupChanged = true; // Persist

View File

@ -3168,10 +3168,11 @@ namespace OpenSim.Region.Framework.Scenes
if (insert) if (insert)
{ {
linkNum = 2; linkNum = 2;
int insertSize = objectGroup.PrimCount;
foreach (SceneObjectPart part in Parts) foreach (SceneObjectPart part in Parts)
{ {
if (part.LinkNum > 1) if (part.LinkNum > 1)
part.LinkNum++; part.LinkNum += insertSize;
} }
} }
else else
@ -3200,14 +3201,14 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.LinkNum = linkNum++; linkPart.LinkNum = linkNum++;
linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false); linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
// Get a list of the SOP's in the old group in order of their linknum's. // Get a list of the SOP's in the source group in order of their linknum's.
SceneObjectPart[] ogParts = objectGroup.Parts; SceneObjectPart[] ogParts = objectGroup.Parts;
Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
{ {
return a.LinkNum - b.LinkNum; return a.LinkNum - b.LinkNum;
}); });
// Add each of the SOP's from the old linkset to our linkset // Add each of the SOP's from the source linkset to our linkset
for (int i = 0; i < ogParts.Length; i++) for (int i = 0; i < ogParts.Length; i++)
{ {
SceneObjectPart part = ogParts[i]; SceneObjectPart part = ogParts[i];
@ -3415,6 +3416,110 @@ namespace OpenSim.Region.Framework.Scenes
return objectGroup; return objectGroup;
} }
/* working on it
public void DelinkFromGroup(List<SceneObjectPart> linkParts, bool sendEvents)
{
// m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
if(PrimCount == 1)
return;
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
bool unlinkroot = false;
foreach(SceneObjectPart linkPart in linkParts)
{
// first we only remove child parts
if(linkPart.LocalId == m_rootPart.LocalId)
{
unlinkroot = true;
continue;
}
lock (m_parts.SyncRoot)
if(!m_parts.Remove(linkPart.UUID))
continue;
linkPart.ClearUndoState();
Vector3 worldPos = linkPart.GetWorldPosition();
Quaternion worldRot = linkPart.GetWorldRotation();
linkPart.ParentID = 0;
linkPart.LinkNum = 0;
PhysicsActor linkPartPa = linkPart.PhysActor;
// Remove the SOP from the physical scene.
// If the new SOG is physical, it is re-created later.
// (There is a problem here in that we have not yet told the physics
// engine about the delink. Someday, linksets should be made first
// class objects in the physics engine interface).
if (linkPartPa != null)
{
m_scene.PhysicsScene.RemovePrim(linkPartPa);
linkPart.PhysActor = null;
}
linkPart.setGroupPosition(worldPos);
linkPart.setOffsetPosition(Vector3.Zero);
linkPart.setRotationOffset(worldRot);
// Create a new SOG to go around this unlinked and unattached SOP
SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);
m_scene.AddNewSceneObject(objectGroup, true);
linkPart.Rezzed = RootPart.Rezzed;
// this is as it seems to be in sl now
if(linkPart.PhysicsShapeType == (byte)PhysShapeType.none)
linkPart.PhysicsShapeType = linkPart.DefaultPhysicsShapeType(); // root prims can't have type none for now
objectGroup.HasGroupChangedDueToDelink = true;
if (sendEvents)
linkPart.TriggerScriptChangedEvent(Changed.LINK);
}
if(unlinkroot)
{
//TODO
}
lock (m_parts.SyncRoot)
{
SceneObjectPart[] parts = m_parts.GetArray();
if (parts.Length == 1)
{
// Single prim left
m_rootPart.LinkNum = 0;
}
else
{
m_rootPart.LinkNum = 1;
int linknum = 2;
for (int i = 1; i < parts.Length; i++)
parts[i].LinkNum = linknum++;
}
}
InvalidBoundsRadius();
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
// When we delete a group, we currently have to force persist to the database if the object id has changed
// (since delete works by deleting all rows which have a given object id)
Scene.SimulationDataService.RemoveObject(UUID, Scene.RegionInfo.RegionID);
HasGroupChangedDueToDelink = true;
TriggerScriptChangedEvent(Changed.LINK);
return;
}
*/
/// <summary> /// <summary>
/// Stop this object from being persisted over server restarts. /// Stop this object from being persisted over server restarts.
/// </summary> /// </summary>