From eb41ec00c94170305fd764d5e0ad5bee04018551 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Tue, 13 Nov 2007 19:57:11 +0000 Subject: first pass on unlinking of objects. From Jay Clarke (IBM) --- .../Region/Environment/Scenes/SceneObjectGroup.cs | 105 +++++++++++++++++++-- 1 file changed, 99 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs') diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index e2415b9..a9f0bb3 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -222,6 +222,27 @@ namespace OpenSim.Region.Environment.Scenes public SceneObjectGroup() { } + + /// + /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. + /// The original SceneObjectPart will be used rather than a copy, preserving + /// its existing localID and UUID. + /// + public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part) + { + m_scene = scene; + m_regionHandle = regionHandle; + + part.SetParent(this); + part.ParentID = 0; + + m_parts.Add(part.UUID, part); + SetPartAsRoot(part); + + AttachToBackup(); + + ScheduleGroupForFullUpdate(); + } /// /// @@ -594,10 +615,10 @@ namespace OpenSim.Region.Environment.Scenes #region SceneGroupPart Methods /// - /// + /// Get a child part with a given UUID /// /// - /// + /// null if a child part with the primID was not found public SceneObjectPart GetChildPart(LLUUID primID) { SceneObjectPart childPart = null; @@ -609,10 +630,10 @@ namespace OpenSim.Region.Environment.Scenes } /// - /// + /// Get a child part with a given local ID /// /// - /// + /// null if a child part with the local ID was not found public SceneObjectPart GetChildPart(uint localID) { foreach (SceneObjectPart part in m_parts.Values) @@ -717,13 +738,85 @@ namespace OpenSim.Region.Environment.Scenes objectGroup.DeleteParts(); ScheduleGroupForFullUpdate(); } + + /// + /// Delink the given prim from this group. The delinked prim is established as + /// an independent SceneObjectGroup. + /// + /// + public void DelinkFromGroup(uint partID) + { + SceneObjectPart linkPart = GetChildPart(partID); + + if (null != linkPart) + { + // Remove the part from this object + m_parts.Remove(linkPart.UUID); + + // We need to reset the child part's position + // ready for life as a separate object after being a part of another object + Quaternion parentRot + = new Quaternion( + m_rootPart.RotationOffset.W, + m_rootPart.RotationOffset.X, + m_rootPart.RotationOffset.Y, + m_rootPart.RotationOffset.Z); + + Vector3 axPos + = new Vector3( + linkPart.OffsetPosition.X, + linkPart.OffsetPosition.Y, + linkPart.OffsetPosition.Z); + + axPos = parentRot * axPos; + linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); + linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; + linkPart.OffsetPosition = new LLVector3(0, 0, 0); + + Quaternion oldRot + = new Quaternion( + linkPart.RotationOffset.W, + linkPart.RotationOffset.X, + linkPart.RotationOffset.Y, + linkPart.RotationOffset.Z); + Quaternion newRot = parentRot * oldRot; + linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); + + // Add physics information back to delinked part if appropriate + // XXX This is messy and should be refactorable with the similar section in + // SceneObjectPart.UpdatePrimFlags() + if (m_rootPart.PhysActor != null) + { + linkPart.PhysActor = m_scene.PhysScene.AddPrimShape( + linkPart.Name, + linkPart.Shape, + new PhysicsVector(linkPart.AbsolutePosition.X, linkPart.AbsolutePosition.Y, + linkPart.AbsolutePosition.Z), + new PhysicsVector(linkPart.Scale.X, linkPart.Scale.Y, linkPart.Scale.Z), + new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, + linkPart.RotationOffset.Y, linkPart.RotationOffset.Z), + m_rootPart.PhysActor.IsPhysical); + } + + SceneObjectGroup objectGroup = new SceneObjectGroup(m_scene, m_regionHandle, linkPart); + + m_scene.AddEntity(objectGroup); + + ScheduleGroupForFullUpdate(); + } + else + { + OpenSim.Framework.Console.MainLog.Instance.Verbose( + "DelinkFromGroup(): Child prim local id {0} not found in object with root prim id {1}", + partID, LocalId); + } + } private void DetachFromBackup(SceneObjectGroup objectGroup) { m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup; } - private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation) { part.SetParent(this); @@ -1431,4 +1524,4 @@ namespace OpenSim.Region.Environment.Scenes Text = text; } } -} \ No newline at end of file +} -- cgit v1.1