diff options
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs | 105 |
1 files changed, 99 insertions, 6 deletions
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 | |||
222 | public SceneObjectGroup() | 222 | public SceneObjectGroup() |
223 | { | 223 | { |
224 | } | 224 | } |
225 | |||
226 | /// <summary> | ||
227 | /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. | ||
228 | /// The original SceneObjectPart will be used rather than a copy, preserving | ||
229 | /// its existing localID and UUID. | ||
230 | /// </summary> | ||
231 | public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part) | ||
232 | { | ||
233 | m_scene = scene; | ||
234 | m_regionHandle = regionHandle; | ||
235 | |||
236 | part.SetParent(this); | ||
237 | part.ParentID = 0; | ||
238 | |||
239 | m_parts.Add(part.UUID, part); | ||
240 | SetPartAsRoot(part); | ||
241 | |||
242 | AttachToBackup(); | ||
243 | |||
244 | ScheduleGroupForFullUpdate(); | ||
245 | } | ||
225 | 246 | ||
226 | /// <summary> | 247 | /// <summary> |
227 | /// | 248 | /// |
@@ -594,10 +615,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
594 | #region SceneGroupPart Methods | 615 | #region SceneGroupPart Methods |
595 | 616 | ||
596 | /// <summary> | 617 | /// <summary> |
597 | /// | 618 | /// Get a child part with a given UUID |
598 | /// </summary> | 619 | /// </summary> |
599 | /// <param name="primID"></param> | 620 | /// <param name="primID"></param> |
600 | /// <returns></returns> | 621 | /// <returns>null if a child part with the primID was not found</returns> |
601 | public SceneObjectPart GetChildPart(LLUUID primID) | 622 | public SceneObjectPart GetChildPart(LLUUID primID) |
602 | { | 623 | { |
603 | SceneObjectPart childPart = null; | 624 | SceneObjectPart childPart = null; |
@@ -609,10 +630,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
609 | } | 630 | } |
610 | 631 | ||
611 | /// <summary> | 632 | /// <summary> |
612 | /// | 633 | /// Get a child part with a given local ID |
613 | /// </summary> | 634 | /// </summary> |
614 | /// <param name="localID"></param> | 635 | /// <param name="localID"></param> |
615 | /// <returns></returns> | 636 | /// <returns>null if a child part with the local ID was not found</returns> |
616 | public SceneObjectPart GetChildPart(uint localID) | 637 | public SceneObjectPart GetChildPart(uint localID) |
617 | { | 638 | { |
618 | foreach (SceneObjectPart part in m_parts.Values) | 639 | foreach (SceneObjectPart part in m_parts.Values) |
@@ -717,13 +738,85 @@ namespace OpenSim.Region.Environment.Scenes | |||
717 | objectGroup.DeleteParts(); | 738 | objectGroup.DeleteParts(); |
718 | ScheduleGroupForFullUpdate(); | 739 | ScheduleGroupForFullUpdate(); |
719 | } | 740 | } |
741 | |||
742 | /// <summary> | ||
743 | /// Delink the given prim from this group. The delinked prim is established as | ||
744 | /// an independent SceneObjectGroup. | ||
745 | /// </summary> | ||
746 | /// <param name="partID"></param> | ||
747 | public void DelinkFromGroup(uint partID) | ||
748 | { | ||
749 | SceneObjectPart linkPart = GetChildPart(partID); | ||
750 | |||
751 | if (null != linkPart) | ||
752 | { | ||
753 | // Remove the part from this object | ||
754 | m_parts.Remove(linkPart.UUID); | ||
755 | |||
756 | // We need to reset the child part's position | ||
757 | // ready for life as a separate object after being a part of another object | ||
758 | Quaternion parentRot | ||
759 | = new Quaternion( | ||
760 | m_rootPart.RotationOffset.W, | ||
761 | m_rootPart.RotationOffset.X, | ||
762 | m_rootPart.RotationOffset.Y, | ||
763 | m_rootPart.RotationOffset.Z); | ||
764 | |||
765 | Vector3 axPos | ||
766 | = new Vector3( | ||
767 | linkPart.OffsetPosition.X, | ||
768 | linkPart.OffsetPosition.Y, | ||
769 | linkPart.OffsetPosition.Z); | ||
770 | |||
771 | axPos = parentRot * axPos; | ||
772 | linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); | ||
773 | linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; | ||
774 | linkPart.OffsetPosition = new LLVector3(0, 0, 0); | ||
775 | |||
776 | Quaternion oldRot | ||
777 | = new Quaternion( | ||
778 | linkPart.RotationOffset.W, | ||
779 | linkPart.RotationOffset.X, | ||
780 | linkPart.RotationOffset.Y, | ||
781 | linkPart.RotationOffset.Z); | ||
782 | Quaternion newRot = parentRot * oldRot; | ||
783 | linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); | ||
784 | |||
785 | // Add physics information back to delinked part if appropriate | ||
786 | // XXX This is messy and should be refactorable with the similar section in | ||
787 | // SceneObjectPart.UpdatePrimFlags() | ||
788 | if (m_rootPart.PhysActor != null) | ||
789 | { | ||
790 | linkPart.PhysActor = m_scene.PhysScene.AddPrimShape( | ||
791 | linkPart.Name, | ||
792 | linkPart.Shape, | ||
793 | new PhysicsVector(linkPart.AbsolutePosition.X, linkPart.AbsolutePosition.Y, | ||
794 | linkPart.AbsolutePosition.Z), | ||
795 | new PhysicsVector(linkPart.Scale.X, linkPart.Scale.Y, linkPart.Scale.Z), | ||
796 | new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, | ||
797 | linkPart.RotationOffset.Y, linkPart.RotationOffset.Z), | ||
798 | m_rootPart.PhysActor.IsPhysical); | ||
799 | } | ||
800 | |||
801 | SceneObjectGroup objectGroup = new SceneObjectGroup(m_scene, m_regionHandle, linkPart); | ||
802 | |||
803 | m_scene.AddEntity(objectGroup); | ||
804 | |||
805 | ScheduleGroupForFullUpdate(); | ||
806 | } | ||
807 | else | ||
808 | { | ||
809 | OpenSim.Framework.Console.MainLog.Instance.Verbose( | ||
810 | "DelinkFromGroup(): Child prim local id {0} not found in object with root prim id {1}", | ||
811 | partID, LocalId); | ||
812 | } | ||
813 | } | ||
720 | 814 | ||
721 | private void DetachFromBackup(SceneObjectGroup objectGroup) | 815 | private void DetachFromBackup(SceneObjectGroup objectGroup) |
722 | { | 816 | { |
723 | m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup; | 817 | m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup; |
724 | } | 818 | } |
725 | 819 | ||
726 | |||
727 | private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation) | 820 | private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation) |
728 | { | 821 | { |
729 | part.SetParent(this); | 822 | part.SetParent(this); |
@@ -1431,4 +1524,4 @@ namespace OpenSim.Region.Environment.Scenes | |||
1431 | Text = text; | 1524 | Text = text; |
1432 | } | 1525 | } |
1433 | } | 1526 | } |
1434 | } \ No newline at end of file | 1527 | } |