aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs105
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}