fix linknumbers when unlink the root prim
parent
9e074988f0
commit
6779f41e21
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue