aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs360
1 files changed, 235 insertions, 125 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index 8b30b58..327956e 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -48,6 +48,10 @@ namespace OpenSim.Region.Environment.Scenes
48 private Encoding enc = Encoding.ASCII; 48 private Encoding enc = Encoding.ASCII;
49 49
50 protected SceneObjectPart m_rootPart; 50 protected SceneObjectPart m_rootPart;
51
52 /// <summary>
53 /// The constituent parts of this group
54 /// </summary>
51 protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>(); 55 protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>();
52 56
53 protected ulong m_regionHandle; 57 protected ulong m_regionHandle;
@@ -389,34 +393,37 @@ namespace OpenSim.Region.Environment.Scenes
389 393
390 EntityIntersection returnresult = new EntityIntersection(); 394 EntityIntersection returnresult = new EntityIntersection();
391 395
392 foreach (SceneObjectPart part in m_parts.Values) 396 lock (m_parts)
393 { 397 {
394 // Temporary commented to stop compiler warning 398 foreach (SceneObjectPart part in m_parts.Values)
395 //Vector3 partPosition = 399 {
396 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 400 // Temporary commented to stop compiler warning
397 Quaternion parentrotation = 401 //Vector3 partPosition =
398 new Quaternion(GroupRotation.W, GroupRotation.X, GroupRotation.Y, GroupRotation.Z); 402 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
403 Quaternion parentrotation =
404 new Quaternion(GroupRotation.W, GroupRotation.X, GroupRotation.Y, GroupRotation.Z);
399 405
400 // Telling the prim to raytrace. 406 // Telling the prim to raytrace.
401 EntityIntersection inter = part.TestIntersection(hRay, parentrotation); 407 EntityIntersection inter = part.TestIntersection(hRay, parentrotation);
402 408
403 // This may need to be updated to the maximum draw distance possible.. 409 // This may need to be updated to the maximum draw distance possible..
404 // We might (and probably will) be checking for prim creation from other sims 410 // We might (and probably will) be checking for prim creation from other sims
405 // when the camera crosses the border. 411 // when the camera crosses the border.
406 float idist = (float)Constants.RegionSize; 412 float idist = (float)Constants.RegionSize;
407 413
408 414
409 if (inter.HitTF) 415 if (inter.HitTF)
410 {
411 // We need to find the closest prim to return to the testcaller along the ray
412 if (inter.distance < idist)
413 { 416 {
414 idist = inter.distance; 417 // We need to find the closest prim to return to the testcaller along the ray
415 returnresult.HitTF = true; 418 if (inter.distance < idist)
416 returnresult.ipoint = inter.ipoint; 419 {
417 returnresult.obj = part; 420 idist = inter.distance;
418 returnresult.normal = inter.normal; 421 returnresult.HitTF = true;
419 returnresult.distance = inter.distance; 422 returnresult.ipoint = inter.ipoint;
423 returnresult.obj = part;
424 returnresult.normal = inter.normal;
425 returnresult.distance = inter.distance;
426 }
420 } 427 }
421 } 428 }
422 } 429 }
@@ -476,15 +483,20 @@ namespace OpenSim.Region.Environment.Scenes
476 m_rootPart.ToXml(writer); 483 m_rootPart.ToXml(writer);
477 writer.WriteEndElement(); 484 writer.WriteEndElement();
478 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); 485 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
479 foreach (SceneObjectPart part in m_parts.Values) 486
487 lock (m_parts)
480 { 488 {
481 if (part.UUID != m_rootPart.UUID) 489 foreach (SceneObjectPart part in m_parts.Values)
482 { 490 {
483 writer.WriteStartElement(String.Empty, "Part", String.Empty); 491 if (part.UUID != m_rootPart.UUID)
484 part.ToXml(writer); 492 {
485 writer.WriteEndElement(); 493 writer.WriteStartElement(String.Empty, "Part", String.Empty);
494 part.ToXml(writer);
495 writer.WriteEndElement();
496 }
486 } 497 }
487 } 498 }
499
488 writer.WriteEndElement(); 500 writer.WriteEndElement();
489 writer.WriteEndElement(); 501 writer.WriteEndElement();
490 } 502 }
@@ -507,13 +519,18 @@ namespace OpenSim.Region.Environment.Scenes
507 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); 519 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
508 m_rootPart.ToXml(writer); 520 m_rootPart.ToXml(writer);
509 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); 521 writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
510 foreach (SceneObjectPart part in m_parts.Values) 522
523 lock (m_parts)
511 { 524 {
512 if (part.UUID != m_rootPart.UUID) 525 foreach (SceneObjectPart part in m_parts.Values)
513 { 526 {
514 part.ToXml(writer); 527 if (part.UUID != m_rootPart.UUID)
528 {
529 part.ToXml(writer);
530 }
515 } 531 }
516 } 532 }
533
517 writer.WriteEndElement(); 534 writer.WriteEndElement();
518 writer.WriteEndElement(); 535 writer.WriteEndElement();
519 } 536 }
@@ -593,7 +610,12 @@ namespace OpenSim.Region.Environment.Scenes
593 { 610 {
594 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count); 611 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
595 newPart.SetParent(this); 612 newPart.SetParent(this);
596 m_parts.Add(newPart.UUID, newPart); 613
614 lock (m_parts)
615 {
616 m_parts.Add(newPart.UUID, newPart);
617 }
618
597 SetPartAsRoot(newPart); 619 SetPartAsRoot(newPart);
598 } 620 }
599 621
@@ -685,7 +707,12 @@ namespace OpenSim.Region.Environment.Scenes
685 { 707 {
686 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count); 708 SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
687 newPart.SetParent(this); 709 newPart.SetParent(this);
688 m_parts.Add(newPart.UUID, newPart); 710
711 lock (m_parts)
712 {
713 m_parts.Add(newPart.UUID, newPart);
714 }
715
689 SetPartAsNonRoot(newPart); 716 SetPartAsNonRoot(newPart);
690 } 717 }
691 718
@@ -697,6 +724,8 @@ namespace OpenSim.Region.Environment.Scenes
697 /// </summary> 724 /// </summary>
698 public void ResetIDs() 725 public void ResetIDs()
699 { 726 {
727 // As this is only ever called for prims which are not currently part of the scene (and hence
728 // not accessible by clients), there should be no need to lock
700 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); 729 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
701 m_parts.Clear(); 730 m_parts.Clear();
702 foreach (SceneObjectPart part in partsList) 731 foreach (SceneObjectPart part in partsList)
@@ -754,46 +783,57 @@ namespace OpenSim.Region.Environment.Scenes
754 /// </summary> 783 /// </summary>
755 public override void Update() 784 public override void Update()
756 { 785 {
757 if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02) 786 lock (m_parts)
758 { 787 {
759 foreach (SceneObjectPart part in m_parts.Values) 788 if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02)
789 {
790 foreach (SceneObjectPart part in m_parts.Values)
791 {
792 if (part.UpdateFlag == 0) part.UpdateFlag = 1;
793 }
794
795 lastPhysGroupPos = AbsolutePosition;
796 }
797
798 if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
799 || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
800 || (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
801 || (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1))
760 { 802 {
761 if (part.UpdateFlag == 0) part.UpdateFlag = 1; 803 foreach (SceneObjectPart part in m_parts.Values)
804 {
805 if (part.UpdateFlag == 0) part.UpdateFlag = 1;
806 }
807
808 lastPhysGroupRot = GroupRotation;
762 } 809 }
763 lastPhysGroupPos = AbsolutePosition; 810
764 }
765
766 if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
767 || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
768 || (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
769 || (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1))
770 {
771 foreach (SceneObjectPart part in m_parts.Values) 811 foreach (SceneObjectPart part in m_parts.Values)
772 { 812 {
773 if (part.UpdateFlag == 0) part.UpdateFlag = 1; 813 part.SendScheduledUpdates();
774 } 814 }
775 lastPhysGroupRot = GroupRotation;
776 }
777
778 foreach (SceneObjectPart part in m_parts.Values)
779 {
780 part.SendScheduledUpdates();
781 } 815 }
782 } 816 }
783 817
784 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 818 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
785 { 819 {
786 foreach (SceneObjectPart part in m_parts.Values) 820 lock (m_parts)
787 { 821 {
788 part.AddFullUpdateToAvatar(presence); 822 foreach (SceneObjectPart part in m_parts.Values)
823 {
824 part.AddFullUpdateToAvatar(presence);
825 }
789 } 826 }
790 } 827 }
791 828
792 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 829 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
793 { 830 {
794 foreach (SceneObjectPart part in m_parts.Values) 831 lock (m_parts)
795 { 832 {
796 part.AddTerseUpdateToAvatar(presence); 833 foreach (SceneObjectPart part in m_parts.Values)
834 {
835 part.AddTerseUpdateToAvatar(presence);
836 }
797 } 837 }
798 } 838 }
799 839
@@ -803,9 +843,13 @@ namespace OpenSim.Region.Environment.Scenes
803 public void ScheduleGroupForFullUpdate() 843 public void ScheduleGroupForFullUpdate()
804 { 844 {
805 HasGroupChanged = true; 845 HasGroupChanged = true;
806 foreach (SceneObjectPart part in m_parts.Values) 846
847 lock (m_parts)
807 { 848 {
808 part.ScheduleFullUpdate(); 849 foreach (SceneObjectPart part in m_parts.Values)
850 {
851 part.ScheduleFullUpdate();
852 }
809 } 853 }
810 } 854 }
811 855
@@ -815,9 +859,13 @@ namespace OpenSim.Region.Environment.Scenes
815 public void ScheduleGroupForTerseUpdate() 859 public void ScheduleGroupForTerseUpdate()
816 { 860 {
817 HasGroupChanged = true; 861 HasGroupChanged = true;
818 foreach (SceneObjectPart part in m_parts.Values) 862
863 lock (m_parts)
819 { 864 {
820 part.ScheduleTerseUpdate(); 865 foreach (SceneObjectPart part in m_parts.Values)
866 {
867 part.ScheduleTerseUpdate();
868 }
821 } 869 }
822 } 870 }
823 871
@@ -827,9 +875,13 @@ namespace OpenSim.Region.Environment.Scenes
827 public void SendGroupFullUpdate() 875 public void SendGroupFullUpdate()
828 { 876 {
829 HasGroupChanged = true; 877 HasGroupChanged = true;
830 foreach (SceneObjectPart part in m_parts.Values) 878
879 lock (m_parts)
831 { 880 {
832 part.SendFullUpdateToAllClients(); 881 foreach (SceneObjectPart part in m_parts.Values)
882 {
883 part.SendFullUpdateToAllClients();
884 }
833 } 885 }
834 } 886 }
835 887
@@ -844,9 +896,13 @@ namespace OpenSim.Region.Environment.Scenes
844 public void SendGroupTerseUpdate() 896 public void SendGroupTerseUpdate()
845 { 897 {
846 HasGroupChanged = true; 898 HasGroupChanged = true;
847 foreach (SceneObjectPart part in m_parts.Values) 899
900 lock (m_parts)
848 { 901 {
849 part.SendTerseUpdateToAllClients(); 902 foreach (SceneObjectPart part in m_parts.Values)
903 {
904 part.SendTerseUpdateToAllClients();
905 }
850 } 906 }
851 } 907 }
852 908
@@ -861,13 +917,17 @@ namespace OpenSim.Region.Environment.Scenes
861 /// <returns>null if no child part with that linknum or child part</returns> 917 /// <returns>null if no child part with that linknum or child part</returns>
862 public SceneObjectPart GetLinkNumPart(int linknum) 918 public SceneObjectPart GetLinkNumPart(int linknum)
863 { 919 {
864 foreach (SceneObjectPart part in m_parts.Values) 920 lock (m_parts)
865 { 921 {
866 if (part.LinkNum == linknum) 922 foreach (SceneObjectPart part in m_parts.Values)
867 { 923 {
868 return part; 924 if (part.LinkNum == linknum)
925 {
926 return part;
927 }
869 } 928 }
870 } 929 }
930
871 return null; 931 return null;
872 } 932 }
873 933
@@ -893,13 +953,17 @@ namespace OpenSim.Region.Environment.Scenes
893 /// <returns>null if a child part with the local ID was not found</returns> 953 /// <returns>null if a child part with the local ID was not found</returns>
894 public SceneObjectPart GetChildPart(uint localID) 954 public SceneObjectPart GetChildPart(uint localID)
895 { 955 {
896 foreach (SceneObjectPart part in m_parts.Values) 956 lock (m_parts)
897 { 957 {
898 if (part.LocalId == localID) 958 foreach (SceneObjectPart part in m_parts.Values)
899 { 959 {
900 return part; 960 if (part.LocalId == localID)
961 {
962 return part;
963 }
901 } 964 }
902 } 965 }
966
903 return null; 967 return null;
904 } 968 }
905 969
@@ -926,11 +990,14 @@ namespace OpenSim.Region.Environment.Scenes
926 /// <returns></returns> 990 /// <returns></returns>
927 public bool HasChildPrim(uint localID) 991 public bool HasChildPrim(uint localID)
928 { 992 {
929 foreach (SceneObjectPart part in m_parts.Values) 993 lock (m_parts)
930 { 994 {
931 if (part.LocalId == localID) 995 foreach (SceneObjectPart part in m_parts.Values)
932 { 996 {
933 return true; 997 if (part.LocalId == localID)
998 {
999 return true;
1000 }
934 } 1001 }
935 } 1002 }
936 return false; 1003 return false;
@@ -988,7 +1055,11 @@ namespace OpenSim.Region.Environment.Scenes
988 1055
989 linkPart.LinkNum = m_parts.Count; 1056 linkPart.LinkNum = m_parts.Count;
990 1057
991 m_parts.Add(linkPart.UUID, linkPart); 1058 lock (m_parts)
1059 {
1060 m_parts.Add(linkPart.UUID, linkPart);
1061 }
1062
992 linkPart.SetParent(this); 1063 linkPart.SetParent(this);
993 1064
994 //if (linkPart.PhysActor != null) 1065 //if (linkPart.PhysActor != null)
@@ -1038,7 +1109,11 @@ namespace OpenSim.Region.Environment.Scenes
1038 LLQuaternion worldRot = linkPart.GetWorldRotation(); 1109 LLQuaternion worldRot = linkPart.GetWorldRotation();
1039 1110
1040 // Remove the part from this object 1111 // Remove the part from this object
1041 m_parts.Remove(linkPart.UUID); 1112 lock (m_parts)
1113 {
1114 m_parts.Remove(linkPart.UUID);
1115 }
1116
1042 linkPart.ParentID = 0; 1117 linkPart.ParentID = 0;
1043 1118
1044 if (linkPart.PhysActor != null) 1119 if (linkPart.PhysActor != null)
@@ -1121,7 +1196,11 @@ namespace OpenSim.Region.Environment.Scenes
1121 part.SetParent(this); 1196 part.SetParent(this);
1122 part.ParentID = m_rootPart.LocalId; 1197 part.ParentID = m_rootPart.LocalId;
1123 part.LinkNum = m_parts.Count; 1198 part.LinkNum = m_parts.Count;
1124 m_parts.Add(part.UUID, part); 1199
1200 lock (m_parts)
1201 {
1202 m_parts.Add(part.UUID, part);
1203 }
1125 1204
1126 Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z); 1205 Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
1127 axiomOldPos = oldGroupRotation*axiomOldPos; 1206 axiomOldPos = oldGroupRotation*axiomOldPos;
@@ -1297,16 +1376,19 @@ namespace OpenSim.Region.Environment.Scenes
1297 if (part != null) 1376 if (part != null)
1298 { 1377 {
1299 // If we have children 1378 // If we have children
1300 if (m_parts.Count > 1) 1379 lock (m_parts)
1301 { 1380 {
1302 foreach (SceneObjectPart parts in m_parts.Values) 1381 if (m_parts.Count > 1)
1303 { 1382 {
1304 parts.UpdatePrimFlags(type, inUse, data); 1383 foreach (SceneObjectPart parts in m_parts.Values)
1384 {
1385 parts.UpdatePrimFlags(type, inUse, data);
1386 }
1387 }
1388 else
1389 {
1390 part.UpdatePrimFlags(type, inUse, data);
1305 } 1391 }
1306 }
1307 else
1308 {
1309 part.UpdatePrimFlags(type, inUse, data);
1310 } 1392 }
1311 } 1393 }
1312 } 1394 }
@@ -1465,13 +1547,17 @@ namespace OpenSim.Region.Environment.Scenes
1465 diff.Y = axDiff.y; 1547 diff.Y = axDiff.y;
1466 diff.Z = axDiff.z; 1548 diff.Z = axDiff.z;
1467 1549
1468 foreach (SceneObjectPart obPart in m_parts.Values) 1550 lock (m_parts)
1469 { 1551 {
1470 if (obPart.UUID != m_rootPart.UUID) 1552 foreach (SceneObjectPart obPart in m_parts.Values)
1471 { 1553 {
1472 obPart.OffsetPosition = obPart.OffsetPosition + diff; 1554 if (obPart.UUID != m_rootPart.UUID)
1555 {
1556 obPart.OffsetPosition = obPart.OffsetPosition + diff;
1557 }
1473 } 1558 }
1474 } 1559 }
1560
1475 AbsolutePosition = newPos; 1561 AbsolutePosition = newPos;
1476 ScheduleGroupForTerseUpdate(); 1562 ScheduleGroupForTerseUpdate();
1477 } 1563 }
@@ -1562,23 +1648,27 @@ namespace OpenSim.Region.Environment.Scenes
1562 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 1648 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
1563 } 1649 }
1564 1650
1565 foreach (SceneObjectPart prim in m_parts.Values) 1651 lock (m_parts)
1566 { 1652 {
1567 if (prim.UUID != m_rootPart.UUID) 1653 foreach (SceneObjectPart prim in m_parts.Values)
1568 { 1654 {
1569 Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z); 1655 if (prim.UUID != m_rootPart.UUID)
1570 axPos = oldParentRot*axPos; 1656 {
1571 axPos = axRot.Inverse()*axPos; 1657 Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z);
1572 prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); 1658 axPos = oldParentRot*axPos;
1573 Quaternion primsRot = 1659 axPos = axRot.Inverse()*axPos;
1574 new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y, 1660 prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
1575 prim.RotationOffset.Z); 1661 Quaternion primsRot =
1576 Quaternion newRot = oldParentRot*primsRot; 1662 new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y,
1577 newRot = axRot.Inverse()*newRot; 1663 prim.RotationOffset.Z);
1578 prim.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); 1664 Quaternion newRot = oldParentRot*primsRot;
1579 prim.ScheduleTerseUpdate(); 1665 newRot = axRot.Inverse()*newRot;
1666 prim.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
1667 prim.ScheduleTerseUpdate();
1668 }
1580 } 1669 }
1581 } 1670 }
1671
1582 m_rootPart.ScheduleTerseUpdate(); 1672 m_rootPart.ScheduleTerseUpdate();
1583 } 1673 }
1584 1674
@@ -1693,15 +1783,20 @@ namespace OpenSim.Region.Environment.Scenes
1693 1783
1694 public override void UpdateMovement() 1784 public override void UpdateMovement()
1695 { 1785 {
1696 foreach (SceneObjectPart part in m_parts.Values) 1786 lock (m_parts)
1697 { 1787 {
1698 part.UpdateMovement(); 1788 foreach (SceneObjectPart part in m_parts.Values)
1789 {
1790 part.UpdateMovement();
1791 }
1699 } 1792 }
1700 } 1793 }
1794
1701 public float GetTimeDilation() 1795 public float GetTimeDilation()
1702 { 1796 {
1703 return m_scene.TimeDilation; 1797 return m_scene.TimeDilation;
1704 } 1798 }
1799
1705 /// <summary> 1800 /// <summary>
1706 /// Added as a way for the storage provider to reset the scene, 1801 /// Added as a way for the storage provider to reset the scene,
1707 /// most likely a better way to do this sort of thing but for now... 1802 /// most likely a better way to do this sort of thing but for now...
@@ -1719,12 +1814,17 @@ namespace OpenSim.Region.Environment.Scenes
1719 /// <param name="part"></param> 1814 /// <param name="part"></param>
1720 public void AddPart(SceneObjectPart part) 1815 public void AddPart(SceneObjectPart part)
1721 { 1816 {
1722 lock (m_parts) { 1817 lock (m_parts)
1818 {
1723 part.SetParent(this); 1819 part.SetParent(this);
1724 part.LinkNum = m_parts.Count; 1820 part.LinkNum = m_parts.Count;
1725 try { 1821
1822 try
1823 {
1726 m_parts.Add(part.UUID, part); 1824 m_parts.Add(part.UUID, part);
1727 } catch (Exception e) { 1825 }
1826 catch (Exception e)
1827 {
1728 m_log.Error("Failed to add scened object part", e); 1828 m_log.Error("Failed to add scened object part", e);
1729 } 1829 }
1730 } 1830 }
@@ -1735,20 +1835,26 @@ namespace OpenSim.Region.Environment.Scenes
1735 /// </summary> 1835 /// </summary>
1736 public void UpdateParentIDs() 1836 public void UpdateParentIDs()
1737 { 1837 {
1738 foreach (SceneObjectPart part in m_parts.Values) 1838 lock (m_parts)
1739 { 1839 {
1740 if (part.UUID != m_rootPart.UUID) 1840 foreach (SceneObjectPart part in m_parts.Values)
1741 { 1841 {
1742 part.ParentID = m_rootPart.LocalId; 1842 if (part.UUID != m_rootPart.UUID)
1843 {
1844 part.ParentID = m_rootPart.LocalId;
1845 }
1743 } 1846 }
1744 } 1847 }
1745 } 1848 }
1746 1849
1747 public void RegenerateFullIDs() 1850 public void RegenerateFullIDs()
1748 { 1851 {
1749 foreach (SceneObjectPart part in m_parts.Values) 1852 lock (m_parts)
1750 { 1853 {
1751 part.UUID = LLUUID.Random(); 1854 foreach (SceneObjectPart part in m_parts.Values)
1855 {
1856 part.UUID = LLUUID.Random();
1857 }
1752 } 1858 }
1753 } 1859 }
1754 1860
@@ -1803,17 +1909,21 @@ namespace OpenSim.Region.Environment.Scenes
1803 public void DeleteGroup() 1909 public void DeleteGroup()
1804 { 1910 {
1805 DetachFromBackup(this); 1911 DetachFromBackup(this);
1806 foreach (SceneObjectPart part in m_parts.Values) 1912
1913 lock (m_parts)
1807 { 1914 {
1808 List<ScenePresence> avatars = GetScenePresences(); 1915 foreach (SceneObjectPart part in m_parts.Values)
1809 for (int i = 0; i < avatars.Count; i++)
1810 { 1916 {
1811 if (avatars[i].ParentID == LocalId) 1917 List<ScenePresence> avatars = GetScenePresences();
1918 for (int i = 0; i < avatars.Count; i++)
1812 { 1919 {
1813 avatars[i].StandUp(); 1920 if (avatars[i].ParentID == LocalId)
1814 } 1921 {
1922 avatars[i].StandUp();
1923 }
1815 1924
1816 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1925 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1926 }
1817 } 1927 }
1818 } 1928 }
1819 } 1929 }
@@ -1829,10 +1939,10 @@ namespace OpenSim.Region.Environment.Scenes
1829 { 1939 {
1830 part.StopScripts(); 1940 part.StopScripts();
1831 } 1941 }
1942
1943 m_rootPart = null;
1944 m_parts.Clear();
1832 } 1945 }
1833
1834 m_rootPart = null;
1835 m_parts.Clear();
1836 } 1946 }
1837 1947
1838 public void AddScriptLPS(int count) 1948 public void AddScriptLPS(int count)
@@ -1858,9 +1968,9 @@ namespace OpenSim.Region.Environment.Scenes
1858 1968
1859 public void ApplyPhysics(bool m_physicalPrim) 1969 public void ApplyPhysics(bool m_physicalPrim)
1860 { 1970 {
1861 if (m_parts.Count > 1) 1971 lock (m_parts)
1862 { 1972 {
1863 lock (m_parts) 1973 if (m_parts.Count > 1)
1864 { 1974 {
1865 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim); 1975 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
1866 foreach (SceneObjectPart part in m_parts.Values) 1976 foreach (SceneObjectPart part in m_parts.Values)
@@ -1874,10 +1984,10 @@ namespace OpenSim.Region.Environment.Scenes
1874 1984
1875 } 1985 }
1876 } 1986 }
1877 } 1987 else
1878 else 1988 {
1879 { 1989 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
1880 m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim); 1990 }
1881 } 1991 }
1882 } 1992 }
1883 1993