public void LinkToGroup(ISceneEntity grp)
{
//MainConsole.Instance.DebugFormat(
// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
if (!(grp is SceneObjectGroup))
return;
SceneObjectGroup objectGroup = (SceneObjectGroup) grp;
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.BlockPhysicalReconstruction = true;
SceneObjectPart linkPart = objectGroup.m_rootPart;
Vector3 oldGroupPosition = linkPart.GroupPosition;
Quaternion oldRootRotation = linkPart.GetRotationOffset();
Quaternion parentRot = m_rootPart.GetRotationOffset();
linkPart.SetGroupPosition(AbsolutePosition); // just change it without doing anything else
Vector3 axPos = oldGroupPosition - AbsolutePosition;
axPos *= Quaternion.Inverse(parentRot);
linkPart.SetOffsetPosition(axPos);
Quaternion newRot = Quaternion.Inverse(parentRot)*oldRootRotation;
linkPart.SetRotationOffset(false, newRot, false);
//Fix the link number for the root
if (m_rootPart.LinkNum == 0)
m_rootPart.LinkNum = 1;
SceneObjectPart[] objectGroupChildren = new SceneObjectPart[objectGroup.ChildrenList.Count];
objectGroup.ChildrenList.CopyTo(objectGroupChildren, 0);
//Destroy the old group
m_scene.SceneGraph.DeleteEntity(objectGroup);
objectGroup.IsDeleted = true;
objectGroup.ClearChildren();
lock (m_partsLock)
{
int linkNum = 2;
//Add the root part to our group!
m_scene.SceneGraph.LinkPartToSOG(this, linkPart, linkNum++);
linkPart.CreateSelected = true;
linkPart.FixOffsetPosition(linkPart.OffsetPosition, true); // nasty let all know about where this is
// let physics link it
if (linkPart.PhysActor != null && m_rootPart.PhysActor != null)
{
if (linkPart.PhysicsType != (byte) PhysicsShapeType.None)
linkPart.PhysActor.Link(m_rootPart.PhysActor);
}
//rest of parts
foreach (
SceneObjectPart part in objectGroupChildren.Where(part => part.UUID != objectGroup.m_rootPart.UUID))
{
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
part.FixOffsetPosition(part.OffsetPosition, true);
if (part.PhysActor != null && m_rootPart.PhysActor != null)
part.PhysActor.Link(m_rootPart.PhysActor);
}
}
// Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the
// position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and
// unmoved prims!
m_ValidgrpOOB = false;
ResetChildPrimPhysicsPositions();
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.BlockPhysicalReconstruction = false;
}