aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs1409
1 files changed, 591 insertions, 818 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index f9a8d41..c984afc 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -158,17 +158,14 @@ namespace OpenSim.Region.Framework.Scenes
158 } 158 }
159 } 159 }
160 160
161 public float scriptScore = 0f; 161 public float scriptScore;
162 162
163 private Vector3 lastPhysGroupPos; 163 private Vector3 lastPhysGroupPos;
164 private Quaternion lastPhysGroupRot; 164 private Quaternion lastPhysGroupRot;
165 165
166 private bool m_isBackedUp = false; 166 private bool m_isBackedUp;
167 167
168 /// <summary> 168 protected MapAndArray<UUID, SceneObjectPart> m_parts = new MapAndArray<UUID, SceneObjectPart>();
169 /// The constituent parts of this group
170 /// </summary>
171 protected Dictionary<UUID, SceneObjectPart> m_parts = new Dictionary<UUID, SceneObjectPart>();
172 169
173 protected ulong m_regionHandle; 170 protected ulong m_regionHandle;
174 protected SceneObjectPart m_rootPart; 171 protected SceneObjectPart m_rootPart;
@@ -177,13 +174,13 @@ namespace OpenSim.Region.Framework.Scenes
177 private Dictionary<uint, scriptPosTarget> m_targets = new Dictionary<uint, scriptPosTarget>(); 174 private Dictionary<uint, scriptPosTarget> m_targets = new Dictionary<uint, scriptPosTarget>();
178 private Dictionary<uint, scriptRotTarget> m_rotTargets = new Dictionary<uint, scriptRotTarget>(); 175 private Dictionary<uint, scriptRotTarget> m_rotTargets = new Dictionary<uint, scriptRotTarget>();
179 176
180 private bool m_scriptListens_atTarget = false; 177 private bool m_scriptListens_atTarget;
181 private bool m_scriptListens_notAtTarget = false; 178 private bool m_scriptListens_notAtTarget;
182 179
183 private bool m_scriptListens_atRotTarget = false; 180 private bool m_scriptListens_atRotTarget;
184 private bool m_scriptListens_notAtRotTarget = false; 181 private bool m_scriptListens_notAtRotTarget;
185 182
186 internal Dictionary<UUID, string> m_savedScriptState = null; 183 internal Dictionary<UUID, string> m_savedScriptState;
187 184
188 #region Properties 185 #region Properties
189 186
@@ -194,7 +191,7 @@ namespace OpenSim.Region.Framework.Scenes
194 { 191 {
195 get { 192 get {
196 if (RootPart == null) 193 if (RootPart == null)
197 return ""; 194 return String.Empty;
198 return RootPart.Name; 195 return RootPart.Name;
199 } 196 }
200 set { RootPart.Name = value; } 197 set { RootPart.Name = value; }
@@ -214,7 +211,7 @@ namespace OpenSim.Region.Framework.Scenes
214 /// </summary> 211 /// </summary>
215 public int PrimCount 212 public int PrimCount
216 { 213 {
217 get { lock (m_parts) { return m_parts.Count; } } 214 get { return m_parts.Count; }
218 } 215 }
219 216
220 protected Quaternion m_rotation = Quaternion.Identity; 217 protected Quaternion m_rotation = Quaternion.Identity;
@@ -236,16 +233,14 @@ namespace OpenSim.Region.Framework.Scenes
236 set { m_rootPart.GroupID = value; } 233 set { m_rootPart.GroupID = value; }
237 } 234 }
238 235
239 /// <value> 236 public SceneObjectPart[] Parts
240 /// The parts of this scene object group. You must lock this property before using it. 237 {
241 /// If you're doing anything other than reading values, please take a copy of the values rather than locking 238 get { return m_parts.GetArray(); }
242 /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock 239 }
243 /// If you want to know the number of children, consider using the PrimCount property instead 240
244 /// </value> 241 public bool ContainsPart(UUID partID)
245 public Dictionary<UUID, SceneObjectPart> Children
246 { 242 {
247 get { return m_parts; } 243 return m_parts.ContainsKey(partID);
248 set { m_parts = value; }
249 } 244 }
250 245
251 /// <value> 246 /// <value>
@@ -262,13 +257,9 @@ namespace OpenSim.Region.Framework.Scenes
262 set 257 set
263 { 258 {
264 m_regionHandle = value; 259 m_regionHandle = value;
265 lock (m_parts) 260 SceneObjectPart[] parts = m_parts.GetArray();
266 { 261 for (int i = 0; i < parts.Length; i++)
267 foreach (SceneObjectPart part in m_parts.Values) 262 parts[i].RegionHandle = value;
268 {
269 part.RegionHandle = m_regionHandle;
270 }
271 }
272 } 263 }
273 } 264 }
274 265
@@ -313,14 +304,10 @@ namespace OpenSim.Region.Framework.Scenes
313 return; 304 return;
314 } 305 }
315 } 306 }
316 307
317 lock (m_parts) 308 SceneObjectPart[] parts = m_parts.GetArray();
318 { 309 for (int i = 0; i < parts.Length; i++)
319 foreach (SceneObjectPart part in m_parts.Values) 310 parts[i].GroupPosition = val;
320 {
321 part.GroupPosition = val;
322 }
323 }
324 311
325 //if (m_rootPart.PhysActor != null) 312 //if (m_rootPart.PhysActor != null)
326 //{ 313 //{
@@ -342,14 +329,9 @@ namespace OpenSim.Region.Framework.Scenes
342 { 329 {
343 get { return m_rootPart.UUID; } 330 get { return m_rootPart.UUID; }
344 set 331 set
345 { 332 {
346 m_rootPart.UUID = value; 333 m_rootPart.UUID = value;
347 334 m_parts.AddOrReplace(value, m_rootPart);
348 lock (m_parts)
349 {
350 m_parts.Remove(m_rootPart.UUID);
351 m_parts.Add(m_rootPart.UUID, m_rootPart);
352 }
353 } 335 }
354 } 336 }
355 337
@@ -411,12 +393,12 @@ namespace OpenSim.Region.Framework.Scenes
411 { 393 {
412 m_rootPart.PhysActor.Selected = value; 394 m_rootPart.PhysActor.Selected = value;
413 // Pass it on to the children. 395 // Pass it on to the children.
414 foreach (SceneObjectPart child in Children.Values) 396 SceneObjectPart[] parts = m_parts.GetArray();
397 for (int i = 0; i < parts.Length; i++)
415 { 398 {
399 SceneObjectPart child = parts[i];
416 if (child.PhysActor != null) 400 if (child.PhysActor != null)
417 {
418 child.PhysActor.Selected = value; 401 child.PhysActor.Selected = value;
419 }
420 } 402 }
421 } 403 }
422 } 404 }
@@ -519,13 +501,9 @@ namespace OpenSim.Region.Framework.Scenes
519 501
520 public void SetFromItemID(UUID AssetId) 502 public void SetFromItemID(UUID AssetId)
521 { 503 {
522 lock (m_parts) 504 SceneObjectPart[] parts = m_parts.GetArray();
523 { 505 for (int i = 0; i < parts.Length; i++)
524 foreach (SceneObjectPart part in m_parts.Values) 506 parts[i].FromItemID = AssetId;
525 {
526 part.FromItemID = AssetId;
527 }
528 }
529 } 507 }
530 508
531 public UUID GetFromItemID() 509 public UUID GetFromItemID()
@@ -564,23 +542,18 @@ namespace OpenSim.Region.Framework.Scenes
564 if (m_rootPart.LocalId == 0) 542 if (m_rootPart.LocalId == 0)
565 m_rootPart.LocalId = m_scene.AllocateLocalId(); 543 m_rootPart.LocalId = m_scene.AllocateLocalId();
566 544
567 lock (m_parts) 545 SceneObjectPart[] parts = m_parts.GetArray();
546 for (int i = 0; i < parts.Length; i++)
568 { 547 {
569 foreach (SceneObjectPart part in m_parts.Values) 548 SceneObjectPart part = parts[i];
570 { 549 if (Object.ReferenceEquals(part, m_rootPart))
571 if (Object.ReferenceEquals(part, m_rootPart)) 550 continue;
572 { 551
573 continue; 552 if (part.LocalId == 0)
574 } 553 part.LocalId = m_scene.AllocateLocalId();
575 554
576 if (part.LocalId == 0) 555 part.ParentID = m_rootPart.LocalId;
577 { 556 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
578 part.LocalId = m_scene.AllocateLocalId();
579 }
580
581 part.ParentID = m_rootPart.LocalId;
582 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
583 }
584 } 557 }
585 558
586 ApplyPhysics(m_scene.m_physicalPrim); 559 ApplyPhysics(m_scene.m_physicalPrim);
@@ -596,22 +569,22 @@ namespace OpenSim.Region.Framework.Scenes
596 Vector3 maxScale = Vector3.Zero; 569 Vector3 maxScale = Vector3.Zero;
597 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 570 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
598 571
599 lock (m_parts) 572 SceneObjectPart[] parts = m_parts.GetArray();
573 for (int i = 0; i < parts.Length; i++)
600 { 574 {
601 foreach (SceneObjectPart part in m_parts.Values) 575 SceneObjectPart part = parts[i];
602 { 576 Vector3 partscale = part.Scale;
603 Vector3 partscale = part.Scale; 577 Vector3 partoffset = part.OffsetPosition;
604 Vector3 partoffset = part.OffsetPosition;
605 578
606 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; 579 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
607 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; 580 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
608 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; 581 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
609 582
610 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 583 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
611 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 584 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
612 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 585 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
613 }
614 } 586 }
587
615 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 588 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
616 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 589 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
617 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 590 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -627,39 +600,40 @@ namespace OpenSim.Region.Framework.Scenes
627 600
628 EntityIntersection result = new EntityIntersection(); 601 EntityIntersection result = new EntityIntersection();
629 602
630 lock (m_parts) 603 SceneObjectPart[] parts = m_parts.GetArray();
604 for (int i = 0; i < parts.Length; i++)
631 { 605 {
632 foreach (SceneObjectPart part in m_parts.Values) 606 SceneObjectPart part = parts[i];
633 {
634 // Temporary commented to stop compiler warning
635 //Vector3 partPosition =
636 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
637 Quaternion parentrotation = GroupRotation;
638 607
639 // Telling the prim to raytrace. 608 // Temporary commented to stop compiler warning
640 //EntityIntersection inter = part.TestIntersection(hRay, parentrotation); 609 //Vector3 partPosition =
610 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
611 Quaternion parentrotation = GroupRotation;
641 612
642 EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation,frontFacesOnly, faceCenters); 613 // Telling the prim to raytrace.
614 //EntityIntersection inter = part.TestIntersection(hRay, parentrotation);
643 615
644 // This may need to be updated to the maximum draw distance possible.. 616 EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation, frontFacesOnly, faceCenters);
645 // We might (and probably will) be checking for prim creation from other sims
646 // when the camera crosses the border.
647 float idist = Constants.RegionSize;
648 617
649 if (inter.HitTF) 618 // This may need to be updated to the maximum draw distance possible..
619 // We might (and probably will) be checking for prim creation from other sims
620 // when the camera crosses the border.
621 float idist = Constants.RegionSize;
622
623 if (inter.HitTF)
624 {
625 // We need to find the closest prim to return to the testcaller along the ray
626 if (inter.distance < idist)
650 { 627 {
651 // We need to find the closest prim to return to the testcaller along the ray 628 result.HitTF = true;
652 if (inter.distance < idist) 629 result.ipoint = inter.ipoint;
653 { 630 result.obj = part;
654 result.HitTF = true; 631 result.normal = inter.normal;
655 result.ipoint = inter.ipoint; 632 result.distance = inter.distance;
656 result.obj = part;
657 result.normal = inter.normal;
658 result.distance = inter.distance;
659 }
660 } 633 }
661 } 634 }
662 } 635 }
636
663 return result; 637 return result;
664 } 638 }
665 639
@@ -678,238 +652,193 @@ namespace OpenSim.Region.Framework.Scenes
678 minY = 256f; 652 minY = 256f;
679 minZ = 8192f; 653 minZ = 8192f;
680 654
681 lock (m_parts) 655 SceneObjectPart[] parts = m_parts.GetArray();
656 for (int i = 0; i < parts.Length; i++)
682 { 657 {
683 foreach (SceneObjectPart part in m_parts.Values) 658 SceneObjectPart part = parts[i];
684 {
685 Vector3 worldPos = part.GetWorldPosition();
686 Vector3 offset = worldPos - AbsolutePosition;
687 Quaternion worldRot;
688 if (part.ParentID == 0)
689 {
690 worldRot = part.RotationOffset;
691 }
692 else
693 {
694 worldRot = part.GetWorldRotation();
695 }
696 659
697 Vector3 frontTopLeft; 660 Vector3 worldPos = part.GetWorldPosition();
698 Vector3 frontTopRight; 661 Vector3 offset = worldPos - AbsolutePosition;
699 Vector3 frontBottomLeft; 662 Quaternion worldRot;
700 Vector3 frontBottomRight; 663 if (part.ParentID == 0)
701 664 worldRot = part.RotationOffset;
702 Vector3 backTopLeft; 665 else
703 Vector3 backTopRight; 666 worldRot = part.GetWorldRotation();
704 Vector3 backBottomLeft; 667
705 Vector3 backBottomRight; 668 Vector3 frontTopLeft;
706 669 Vector3 frontTopRight;
707 // Vector3[] corners = new Vector3[8]; 670 Vector3 frontBottomLeft;
708 671 Vector3 frontBottomRight;
709 Vector3 orig = Vector3.Zero; 672
710 673 Vector3 backTopLeft;
711 frontTopLeft.X = orig.X - (part.Scale.X / 2); 674 Vector3 backTopRight;
712 frontTopLeft.Y = orig.Y - (part.Scale.Y / 2); 675 Vector3 backBottomLeft;
713 frontTopLeft.Z = orig.Z + (part.Scale.Z / 2); 676 Vector3 backBottomRight;
714 677
715 frontTopRight.X = orig.X - (part.Scale.X / 2); 678 Vector3 orig = Vector3.Zero;
716 frontTopRight.Y = orig.Y + (part.Scale.Y / 2); 679
717 frontTopRight.Z = orig.Z + (part.Scale.Z / 2); 680 frontTopLeft.X = orig.X - (part.Scale.X / 2);
718 681 frontTopLeft.Y = orig.Y - (part.Scale.Y / 2);
719 frontBottomLeft.X = orig.X - (part.Scale.X / 2); 682 frontTopLeft.Z = orig.Z + (part.Scale.Z / 2);
720 frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2); 683
721 frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2); 684 frontTopRight.X = orig.X - (part.Scale.X / 2);
722 685 frontTopRight.Y = orig.Y + (part.Scale.Y / 2);
723 frontBottomRight.X = orig.X - (part.Scale.X / 2); 686 frontTopRight.Z = orig.Z + (part.Scale.Z / 2);
724 frontBottomRight.Y = orig.Y + (part.Scale.Y / 2); 687
725 frontBottomRight.Z = orig.Z - (part.Scale.Z / 2); 688 frontBottomLeft.X = orig.X - (part.Scale.X / 2);
726 689 frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
727 backTopLeft.X = orig.X + (part.Scale.X / 2); 690 frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
728 backTopLeft.Y = orig.Y - (part.Scale.Y / 2); 691
729 backTopLeft.Z = orig.Z + (part.Scale.Z / 2); 692 frontBottomRight.X = orig.X - (part.Scale.X / 2);
730 693 frontBottomRight.Y = orig.Y + (part.Scale.Y / 2);
731 backTopRight.X = orig.X + (part.Scale.X / 2); 694 frontBottomRight.Z = orig.Z - (part.Scale.Z / 2);
732 backTopRight.Y = orig.Y + (part.Scale.Y / 2); 695
733 backTopRight.Z = orig.Z + (part.Scale.Z / 2); 696 backTopLeft.X = orig.X + (part.Scale.X / 2);
734 697 backTopLeft.Y = orig.Y - (part.Scale.Y / 2);
735 backBottomLeft.X = orig.X + (part.Scale.X / 2); 698 backTopLeft.Z = orig.Z + (part.Scale.Z / 2);
736 backBottomLeft.Y = orig.Y - (part.Scale.Y / 2); 699
737 backBottomLeft.Z = orig.Z - (part.Scale.Z / 2); 700 backTopRight.X = orig.X + (part.Scale.X / 2);
738 701 backTopRight.Y = orig.Y + (part.Scale.Y / 2);
739 backBottomRight.X = orig.X + (part.Scale.X / 2); 702 backTopRight.Z = orig.Z + (part.Scale.Z / 2);
740 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 703
741 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 704 backBottomLeft.X = orig.X + (part.Scale.X / 2);
742 705 backBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
743 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 706 backBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
744 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 707
745 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 708 backBottomRight.X = orig.X + (part.Scale.X / 2);
746 //m_log.InfoFormat("pre corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); 709 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
747 //m_log.InfoFormat("pre corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); 710 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
748 //m_log.InfoFormat("pre corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); 711
749 //m_log.InfoFormat("pre corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); 712 frontTopLeft = frontTopLeft * worldRot;
750 //m_log.InfoFormat("pre corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); 713 frontTopRight = frontTopRight * worldRot;
751 714 frontBottomLeft = frontBottomLeft * worldRot;
752 //for (int i = 0; i < 8; i++) 715 frontBottomRight = frontBottomRight * worldRot;
753 //{ 716
754 // corners[i] = corners[i] * worldRot; 717 backBottomLeft = backBottomLeft * worldRot;
755 // corners[i] += offset; 718 backBottomRight = backBottomRight * worldRot;
756 719 backTopLeft = backTopLeft * worldRot;
757 // if (corners[i].X > maxX) 720 backTopRight = backTopRight * worldRot;
758 // maxX = corners[i].X; 721
759 // if (corners[i].X < minX) 722
760 // minX = corners[i].X; 723 frontTopLeft += offset;
761 724 frontTopRight += offset;
762 // if (corners[i].Y > maxY) 725 frontBottomLeft += offset;
763 // maxY = corners[i].Y; 726 frontBottomRight += offset;
764 // if (corners[i].Y < minY) 727
765 // minY = corners[i].Y; 728 backBottomLeft += offset;
766 729 backBottomRight += offset;
767 // if (corners[i].Z > maxZ) 730 backTopLeft += offset;
768 // maxZ = corners[i].Y; 731 backTopRight += offset;
769 // if (corners[i].Z < minZ) 732
770 // minZ = corners[i].Z; 733 if (frontTopRight.X > maxX)
771 //} 734 maxX = frontTopRight.X;
772 735 if (frontTopLeft.X > maxX)
773 frontTopLeft = frontTopLeft * worldRot; 736 maxX = frontTopLeft.X;
774 frontTopRight = frontTopRight * worldRot; 737 if (frontBottomRight.X > maxX)
775 frontBottomLeft = frontBottomLeft * worldRot; 738 maxX = frontBottomRight.X;
776 frontBottomRight = frontBottomRight * worldRot; 739 if (frontBottomLeft.X > maxX)
777 740 maxX = frontBottomLeft.X;
778 backBottomLeft = backBottomLeft * worldRot; 741
779 backBottomRight = backBottomRight * worldRot; 742 if (backTopRight.X > maxX)
780 backTopLeft = backTopLeft * worldRot; 743 maxX = backTopRight.X;
781 backTopRight = backTopRight * worldRot; 744 if (backTopLeft.X > maxX)
782 745 maxX = backTopLeft.X;
783 746 if (backBottomRight.X > maxX)
784 frontTopLeft += offset; 747 maxX = backBottomRight.X;
785 frontTopRight += offset; 748 if (backBottomLeft.X > maxX)
786 frontBottomLeft += offset; 749 maxX = backBottomLeft.X;
787 frontBottomRight += offset; 750
788 751 if (frontTopRight.X < minX)
789 backBottomLeft += offset; 752 minX = frontTopRight.X;
790 backBottomRight += offset; 753 if (frontTopLeft.X < minX)
791 backTopLeft += offset; 754 minX = frontTopLeft.X;
792 backTopRight += offset; 755 if (frontBottomRight.X < minX)
793 756 minX = frontBottomRight.X;
794 //m_log.InfoFormat("corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 757 if (frontBottomLeft.X < minX)
795 //m_log.InfoFormat("corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 758 minX = frontBottomLeft.X;
796 //m_log.InfoFormat("corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 759
797 //m_log.InfoFormat("corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); 760 if (backTopRight.X < minX)
798 //m_log.InfoFormat("corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); 761 minX = backTopRight.X;
799 //m_log.InfoFormat("corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); 762 if (backTopLeft.X < minX)
800 //m_log.InfoFormat("corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); 763 minX = backTopLeft.X;
801 //m_log.InfoFormat("corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); 764 if (backBottomRight.X < minX)
802 765 minX = backBottomRight.X;
803 if (frontTopRight.X > maxX) 766 if (backBottomLeft.X < minX)
804 maxX = frontTopRight.X; 767 minX = backBottomLeft.X;
805 if (frontTopLeft.X > maxX) 768
806 maxX = frontTopLeft.X; 769 //
807 if (frontBottomRight.X > maxX) 770 if (frontTopRight.Y > maxY)
808 maxX = frontBottomRight.X; 771 maxY = frontTopRight.Y;
809 if (frontBottomLeft.X > maxX) 772 if (frontTopLeft.Y > maxY)
810 maxX = frontBottomLeft.X; 773 maxY = frontTopLeft.Y;
811 774 if (frontBottomRight.Y > maxY)
812 if (backTopRight.X > maxX) 775 maxY = frontBottomRight.Y;
813 maxX = backTopRight.X; 776 if (frontBottomLeft.Y > maxY)
814 if (backTopLeft.X > maxX) 777 maxY = frontBottomLeft.Y;
815 maxX = backTopLeft.X; 778
816 if (backBottomRight.X > maxX) 779 if (backTopRight.Y > maxY)
817 maxX = backBottomRight.X; 780 maxY = backTopRight.Y;
818 if (backBottomLeft.X > maxX) 781 if (backTopLeft.Y > maxY)
819 maxX = backBottomLeft.X; 782 maxY = backTopLeft.Y;
820 783 if (backBottomRight.Y > maxY)
821 if (frontTopRight.X < minX) 784 maxY = backBottomRight.Y;
822 minX = frontTopRight.X; 785 if (backBottomLeft.Y > maxY)
823 if (frontTopLeft.X < minX) 786 maxY = backBottomLeft.Y;
824 minX = frontTopLeft.X; 787
825 if (frontBottomRight.X < minX) 788 if (frontTopRight.Y < minY)
826 minX = frontBottomRight.X; 789 minY = frontTopRight.Y;
827 if (frontBottomLeft.X < minX) 790 if (frontTopLeft.Y < minY)
828 minX = frontBottomLeft.X; 791 minY = frontTopLeft.Y;
829 792 if (frontBottomRight.Y < minY)
830 if (backTopRight.X < minX) 793 minY = frontBottomRight.Y;
831 minX = backTopRight.X; 794 if (frontBottomLeft.Y < minY)
832 if (backTopLeft.X < minX) 795 minY = frontBottomLeft.Y;
833 minX = backTopLeft.X; 796
834 if (backBottomRight.X < minX) 797 if (backTopRight.Y < minY)
835 minX = backBottomRight.X; 798 minY = backTopRight.Y;
836 if (backBottomLeft.X < minX) 799 if (backTopLeft.Y < minY)
837 minX = backBottomLeft.X; 800 minY = backTopLeft.Y;
838 801 if (backBottomRight.Y < minY)
839 // 802 minY = backBottomRight.Y;
840 if (frontTopRight.Y > maxY) 803 if (backBottomLeft.Y < minY)
841 maxY = frontTopRight.Y; 804 minY = backBottomLeft.Y;
842 if (frontTopLeft.Y > maxY) 805
843 maxY = frontTopLeft.Y; 806 //
844 if (frontBottomRight.Y > maxY) 807 if (frontTopRight.Z > maxZ)
845 maxY = frontBottomRight.Y; 808 maxZ = frontTopRight.Z;
846 if (frontBottomLeft.Y > maxY) 809 if (frontTopLeft.Z > maxZ)
847 maxY = frontBottomLeft.Y; 810 maxZ = frontTopLeft.Z;
848 811 if (frontBottomRight.Z > maxZ)
849 if (backTopRight.Y > maxY) 812 maxZ = frontBottomRight.Z;
850 maxY = backTopRight.Y; 813 if (frontBottomLeft.Z > maxZ)
851 if (backTopLeft.Y > maxY) 814 maxZ = frontBottomLeft.Z;
852 maxY = backTopLeft.Y; 815
853 if (backBottomRight.Y > maxY) 816 if (backTopRight.Z > maxZ)
854 maxY = backBottomRight.Y; 817 maxZ = backTopRight.Z;
855 if (backBottomLeft.Y > maxY) 818 if (backTopLeft.Z > maxZ)
856 maxY = backBottomLeft.Y; 819 maxZ = backTopLeft.Z;
857 820 if (backBottomRight.Z > maxZ)
858 if (frontTopRight.Y < minY) 821 maxZ = backBottomRight.Z;
859 minY = frontTopRight.Y; 822 if (backBottomLeft.Z > maxZ)
860 if (frontTopLeft.Y < minY) 823 maxZ = backBottomLeft.Z;
861 minY = frontTopLeft.Y; 824
862 if (frontBottomRight.Y < minY) 825 if (frontTopRight.Z < minZ)
863 minY = frontBottomRight.Y; 826 minZ = frontTopRight.Z;
864 if (frontBottomLeft.Y < minY) 827 if (frontTopLeft.Z < minZ)
865 minY = frontBottomLeft.Y; 828 minZ = frontTopLeft.Z;
866 829 if (frontBottomRight.Z < minZ)
867 if (backTopRight.Y < minY) 830 minZ = frontBottomRight.Z;
868 minY = backTopRight.Y; 831 if (frontBottomLeft.Z < minZ)
869 if (backTopLeft.Y < minY) 832 minZ = frontBottomLeft.Z;
870 minY = backTopLeft.Y; 833
871 if (backBottomRight.Y < minY) 834 if (backTopRight.Z < minZ)
872 minY = backBottomRight.Y; 835 minZ = backTopRight.Z;
873 if (backBottomLeft.Y < minY) 836 if (backTopLeft.Z < minZ)
874 minY = backBottomLeft.Y; 837 minZ = backTopLeft.Z;
875 838 if (backBottomRight.Z < minZ)
876 // 839 minZ = backBottomRight.Z;
877 if (frontTopRight.Z > maxZ) 840 if (backBottomLeft.Z < minZ)
878 maxZ = frontTopRight.Z; 841 minZ = backBottomLeft.Z;
879 if (frontTopLeft.Z > maxZ)
880 maxZ = frontTopLeft.Z;
881 if (frontBottomRight.Z > maxZ)
882 maxZ = frontBottomRight.Z;
883 if (frontBottomLeft.Z > maxZ)
884 maxZ = frontBottomLeft.Z;
885
886 if (backTopRight.Z > maxZ)
887 maxZ = backTopRight.Z;
888 if (backTopLeft.Z > maxZ)
889 maxZ = backTopLeft.Z;
890 if (backBottomRight.Z > maxZ)
891 maxZ = backBottomRight.Z;
892 if (backBottomLeft.Z > maxZ)
893 maxZ = backBottomLeft.Z;
894
895 if (frontTopRight.Z < minZ)
896 minZ = frontTopRight.Z;
897 if (frontTopLeft.Z < minZ)
898 minZ = frontTopLeft.Z;
899 if (frontBottomRight.Z < minZ)
900 minZ = frontBottomRight.Z;
901 if (frontBottomLeft.Z < minZ)
902 minZ = frontBottomLeft.Z;
903
904 if (backTopRight.Z < minZ)
905 minZ = backTopRight.Z;
906 if (backTopLeft.Z < minZ)
907 minZ = backTopLeft.Z;
908 if (backBottomRight.Z < minZ)
909 minZ = backBottomRight.Z;
910 if (backBottomLeft.Z < minZ)
911 minZ = backBottomLeft.Z;
912 }
913 } 842 }
914 } 843 }
915 844
@@ -949,17 +878,12 @@ namespace OpenSim.Region.Framework.Scenes
949 XmlDocument doc = new XmlDocument(); 878 XmlDocument doc = new XmlDocument();
950 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 879 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
951 880
952 // Capture script state while holding the lock 881 SceneObjectPart[] parts = m_parts.GetArray();
953 lock (m_parts) 882 for (int i = 0; i < parts.Length; i++)
954 { 883 {
955 foreach (SceneObjectPart part in m_parts.Values) 884 Dictionary<UUID, string> pstates = parts[i].Inventory.GetScriptStates();
956 { 885 foreach (KeyValuePair<UUID, string> kvp in pstates)
957 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 886 states.Add(kvp.Key, kvp.Value);
958 foreach (UUID itemid in pstates.Keys)
959 {
960 states.Add(itemid, pstates[itemid]);
961 }
962 }
963 } 887 }
964 888
965 if (states.Count > 0) 889 if (states.Count > 0)
@@ -1005,15 +929,10 @@ namespace OpenSim.Region.Framework.Scenes
1005 929
1006 AbsolutePosition = detachedpos; 930 AbsolutePosition = detachedpos;
1007 m_rootPart.AttachedAvatar = UUID.Zero; 931 m_rootPart.AttachedAvatar = UUID.Zero;
1008 932
1009 //Anakin Lohner bug #3839 933 SceneObjectPart[] parts = m_parts.GetArray();
1010 lock (m_parts) 934 for (int i = 0; i < parts.Length; i++)
1011 { 935 parts[i].AttachedAvatar = UUID.Zero;
1012 foreach (SceneObjectPart p in m_parts.Values)
1013 {
1014 p.AttachedAvatar = UUID.Zero;
1015 }
1016 }
1017 936
1018 m_rootPart.SetParentLocalId(0); 937 m_rootPart.SetParentLocalId(0);
1019 SetAttachmentPoint((byte)0); 938 SetAttachmentPoint((byte)0);
@@ -1038,15 +957,10 @@ namespace OpenSim.Region.Framework.Scenes
1038 } 957 }
1039 958
1040 m_rootPart.AttachedAvatar = UUID.Zero; 959 m_rootPart.AttachedAvatar = UUID.Zero;
1041 960
1042 //Anakin Lohner bug #3839 961 SceneObjectPart[] parts = m_parts.GetArray();
1043 lock (m_parts) 962 for (int i = 0; i < parts.Length; i++)
1044 { 963 parts[i].AttachedAvatar = UUID.Zero;
1045 foreach (SceneObjectPart p in m_parts.Values)
1046 {
1047 p.AttachedAvatar = UUID.Zero;
1048 }
1049 }
1050 964
1051 m_rootPart.SetParentLocalId(0); 965 m_rootPart.SetParentLocalId(0);
1052 //m_rootPart.SetAttachmentPoint((byte)0); 966 //m_rootPart.SetAttachmentPoint((byte)0);
@@ -1069,13 +983,9 @@ namespace OpenSim.Region.Framework.Scenes
1069 983
1070 public override void UpdateMovement() 984 public override void UpdateMovement()
1071 { 985 {
1072 lock (m_parts) 986 SceneObjectPart[] parts = m_parts.GetArray();
1073 { 987 for (int i = 0; i < parts.Length; i++)
1074 foreach (SceneObjectPart part in m_parts.Values) 988 parts[i].UpdateMovement();
1075 {
1076 part.UpdateMovement();
1077 }
1078 }
1079 } 989 }
1080 990
1081 public ushort GetTimeDilation() 991 public ushort GetTimeDilation()
@@ -1108,8 +1018,7 @@ namespace OpenSim.Region.Framework.Scenes
1108 part.ParentID = 0; 1018 part.ParentID = 0;
1109 part.LinkNum = 0; 1019 part.LinkNum = 0;
1110 1020
1111 lock (m_parts) 1021 m_parts.Add(m_rootPart.UUID, m_rootPart);
1112 m_parts.Add(m_rootPart.UUID, m_rootPart);
1113 } 1022 }
1114 1023
1115 /// <summary> 1024 /// <summary>
@@ -1118,16 +1027,10 @@ namespace OpenSim.Region.Framework.Scenes
1118 /// <param name="part"></param> 1027 /// <param name="part"></param>
1119 public void AddPart(SceneObjectPart part) 1028 public void AddPart(SceneObjectPart part)
1120 { 1029 {
1121 lock (m_parts) 1030 part.SetParent(this);
1122 { 1031 part.LinkNum = m_parts.Add(part.UUID, part);
1123 part.SetParent(this); 1032 if (part.LinkNum == 2 && RootPart != null)
1124 m_parts.Add(part.UUID, part); 1033 RootPart.LinkNum = 1;
1125
1126 part.LinkNum = m_parts.Count;
1127
1128 if (part.LinkNum == 2 && RootPart != null)
1129 RootPart.LinkNum = 1;
1130 }
1131 } 1034 }
1132 1035
1133 /// <summary> 1036 /// <summary>
@@ -1135,28 +1038,20 @@ namespace OpenSim.Region.Framework.Scenes
1135 /// </summary> 1038 /// </summary>
1136 private void UpdateParentIDs() 1039 private void UpdateParentIDs()
1137 { 1040 {
1138 lock (m_parts) 1041 SceneObjectPart[] parts = m_parts.GetArray();
1042 for (int i = 0; i < parts.Length; i++)
1139 { 1043 {
1140 foreach (SceneObjectPart part in m_parts.Values) 1044 SceneObjectPart part = parts[i];
1141 { 1045 if (part.UUID != m_rootPart.UUID)
1142 if (part.UUID != m_rootPart.UUID) 1046 part.ParentID = m_rootPart.LocalId;
1143 {
1144 part.ParentID = m_rootPart.LocalId;
1145 }
1146 }
1147 } 1047 }
1148 } 1048 }
1149 1049
1150 public void RegenerateFullIDs() 1050 public void RegenerateFullIDs()
1151 { 1051 {
1152 lock (m_parts) 1052 SceneObjectPart[] parts = m_parts.GetArray();
1153 { 1053 for (int i = 0; i < parts.Length; i++)
1154 foreach (SceneObjectPart part in m_parts.Values) 1054 parts[i].UUID = UUID.Random();
1155 {
1156 part.UUID = UUID.Random();
1157
1158 }
1159 }
1160 } 1055 }
1161 1056
1162 // helper provided for parts. 1057 // helper provided for parts.
@@ -1189,7 +1084,7 @@ namespace OpenSim.Region.Framework.Scenes
1189 1084
1190 // teravus: AbsolutePosition is NOT a normal property! 1085 // teravus: AbsolutePosition is NOT a normal property!
1191 // the code in the getter of AbsolutePosition is significantly different then the code in the setter! 1086 // the code in the getter of AbsolutePosition is significantly different then the code in the setter!
1192 1087 // jhurliman: Then why is it a property instead of two methods?
1193 } 1088 }
1194 1089
1195 public UUID GetPartsFullID(uint localID) 1090 public UUID GetPartsFullID(uint localID)
@@ -1237,19 +1132,15 @@ namespace OpenSim.Region.Framework.Scenes
1237 /// <param name="silent">If true then deletion is not broadcast to clients</param> 1132 /// <param name="silent">If true then deletion is not broadcast to clients</param>
1238 public void DeleteGroupFromScene(bool silent) 1133 public void DeleteGroupFromScene(bool silent)
1239 { 1134 {
1240 List<SceneObjectPart> parts; 1135 SceneObjectPart[] parts = m_parts.GetArray();
1241 1136 for (int i = 0; i < parts.Length; i++)
1242 lock (m_parts)
1243 parts = m_parts.Values.ToList();
1244
1245 foreach (SceneObjectPart part in parts)
1246 { 1137 {
1138 SceneObjectPart part = parts[i];
1139
1247 Scene.ForEachScenePresence(delegate(ScenePresence avatar) 1140 Scene.ForEachScenePresence(delegate(ScenePresence avatar)
1248 { 1141 {
1249 if (avatar.ParentID == LocalId) 1142 if (avatar.ParentID == LocalId)
1250 {
1251 avatar.StandUp(); 1143 avatar.StandUp();
1252 }
1253 1144
1254 if (!silent) 1145 if (!silent)
1255 { 1146 {
@@ -1283,16 +1174,15 @@ namespace OpenSim.Region.Framework.Scenes
1283 1174
1284 scriptEvents aggregateScriptEvents = 0; 1175 scriptEvents aggregateScriptEvents = 0;
1285 1176
1286 lock (m_parts) 1177 SceneObjectPart[] parts = m_parts.GetArray();
1178 for (int i = 0; i < parts.Length; i++)
1287 { 1179 {
1288 foreach (SceneObjectPart part in m_parts.Values) 1180 SceneObjectPart part = parts[i];
1289 { 1181 if (part == null)
1290 if (part == null) 1182 continue;
1291 continue; 1183 if (part != RootPart)
1292 if (part != RootPart) 1184 part.Flags = objectflagupdate;
1293 part.Flags = objectflagupdate; 1185 aggregateScriptEvents |= part.AggregateScriptEvents;
1294 aggregateScriptEvents |= part.AggregateScriptEvents;
1295 }
1296 } 1186 }
1297 1187
1298 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1188 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
@@ -1335,26 +1225,22 @@ namespace OpenSim.Region.Framework.Scenes
1335 /// <param name="m_physicalPrim"></param> 1225 /// <param name="m_physicalPrim"></param>
1336 public void ApplyPhysics(bool m_physicalPrim) 1226 public void ApplyPhysics(bool m_physicalPrim)
1337 { 1227 {
1338 lock (m_parts) 1228 // Apply physics to the root prim
1229 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1230
1231 // Apply physics to child prims
1232 SceneObjectPart[] parts = m_parts.GetArray();
1233 if (parts.Length > 1)
1339 { 1234 {
1340 if (m_parts.Count > 1) 1235 for (int i = 0; i < parts.Length; i++)
1341 {
1342 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1343 foreach (SceneObjectPart part in m_parts.Values)
1344 {
1345 if (part.LocalId != m_rootPart.LocalId)
1346 {
1347 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1348 }
1349 }
1350
1351 // Hack to get the physics scene geometries in the right spot
1352 ResetChildPrimPhysicsPositions();
1353 }
1354 else
1355 { 1236 {
1356 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1237 SceneObjectPart part = parts[i];
1238 if (part.LocalId != m_rootPart.LocalId)
1239 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1357 } 1240 }
1241
1242 // Hack to get the physics scene geometries in the right spot
1243 ResetChildPrimPhysicsPositions();
1358 } 1244 }
1359 } 1245 }
1360 1246
@@ -1365,13 +1251,9 @@ namespace OpenSim.Region.Framework.Scenes
1365 1251
1366 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1252 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1367 { 1253 {
1368 lock (m_parts) 1254 SceneObjectPart[] parts = m_parts.GetArray();
1369 { 1255 for (int i = 0; i < parts.Length; i++)
1370 foreach (SceneObjectPart part in m_parts.Values) 1256 whatToDo(parts[i]);
1371 {
1372 whatToDo(part);
1373 }
1374 }
1375 } 1257 }
1376 1258
1377 #region Events 1259 #region Events
@@ -1476,14 +1358,12 @@ namespace OpenSim.Region.Framework.Scenes
1476 RootPart.SendFullUpdate( 1358 RootPart.SendFullUpdate(
1477 remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1359 remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1478 1360
1479 lock (m_parts) 1361 SceneObjectPart[] parts = m_parts.GetArray();
1362 for (int i = 0; i < parts.Length; i++)
1480 { 1363 {
1481 foreach (SceneObjectPart part in m_parts.Values) 1364 SceneObjectPart part = parts[i];
1482 { 1365 if (part != RootPart)
1483 if (part != RootPart) 1366 part.SendFullUpdate(remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1484 part.SendFullUpdate(
1485 remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1486 }
1487 } 1367 }
1488 } 1368 }
1489 1369
@@ -1498,7 +1378,7 @@ namespace OpenSim.Region.Framework.Scenes
1498 { 1378 {
1499 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); 1379 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
1500 dupe.m_isBackedUp = false; 1380 dupe.m_isBackedUp = false;
1501 dupe.m_parts = new Dictionary<UUID, SceneObjectPart>(); 1381 dupe.m_parts.Clear();
1502 1382
1503 // Warning, The following code related to previousAttachmentStatus is needed so that clones of 1383 // Warning, The following code related to previousAttachmentStatus is needed so that clones of
1504 // attachments do not bordercross while they're being duplicated. This is hacktastic! 1384 // attachments do not bordercross while they're being duplicated. This is hacktastic!
@@ -1527,12 +1407,7 @@ namespace OpenSim.Region.Framework.Scenes
1527 if (userExposed) 1407 if (userExposed)
1528 dupe.m_rootPart.TrimPermissions(); 1408 dupe.m_rootPart.TrimPermissions();
1529 1409
1530 List<SceneObjectPart> partList; 1410 List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray());
1531
1532 lock (m_parts)
1533 {
1534 partList = new List<SceneObjectPart>(m_parts.Values);
1535 }
1536 1411
1537 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1412 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1538 { 1413 {
@@ -1837,17 +1712,10 @@ namespace OpenSim.Region.Framework.Scenes
1837 /// <param name="cGroupID"></param> 1712 /// <param name="cGroupID"></param>
1838 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 1713 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1839 { 1714 {
1840 SceneObjectPart newPart = null; 1715 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1841 1716 AddPart(newPart);
1842 lock (m_parts)
1843 {
1844 newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1845 newPart.SetParent(this);
1846 m_parts.Add(newPart.UUID, newPart);
1847 }
1848 1717
1849 SetPartAsNonRoot(newPart); 1718 SetPartAsNonRoot(newPart);
1850
1851 return newPart; 1719 return newPart;
1852 } 1720 }
1853 1721
@@ -1859,9 +1727,9 @@ namespace OpenSim.Region.Framework.Scenes
1859 /// </summary> 1727 /// </summary>
1860 public void ResetIDs() 1728 public void ResetIDs()
1861 { 1729 {
1862 lock (m_parts) 1730 lock (m_parts.SyncRoot)
1863 { 1731 {
1864 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); 1732 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.GetArray());
1865 m_parts.Clear(); 1733 m_parts.Clear();
1866 foreach (SceneObjectPart part in partsList) 1734 foreach (SceneObjectPart part in partsList)
1867 { 1735 {
@@ -1877,7 +1745,6 @@ namespace OpenSim.Region.Framework.Scenes
1877 /// <param name="part"></param> 1745 /// <param name="part"></param>
1878 public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) 1746 public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags)
1879 { 1747 {
1880
1881 remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, 1748 remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask,
1882 RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, 1749 RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask,
1883 RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, 1750 RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category,
@@ -1922,12 +1789,10 @@ namespace OpenSim.Region.Framework.Scenes
1922 lastPhysGroupRot = GroupRotation; 1789 lastPhysGroupRot = GroupRotation;
1923 } 1790 }
1924 1791
1925 List<SceneObjectPart> partList = null; 1792 SceneObjectPart[] parts = m_parts.GetArray();
1926 lock (m_parts) 1793 for (int i = 0; i < parts.Length; i++)
1927 partList = new List<SceneObjectPart>(m_parts.Values);
1928
1929 foreach (SceneObjectPart part in partList)
1930 { 1794 {
1795 SceneObjectPart part = parts[i];
1931 if (!IsSelected) 1796 if (!IsSelected)
1932 part.UpdateLookAt(); 1797 part.UpdateLookAt();
1933 part.SendScheduledUpdates(); 1798 part.SendScheduledUpdates();
@@ -1940,27 +1805,22 @@ namespace OpenSim.Region.Framework.Scenes
1940 1805
1941 RootPart.AddFullUpdateToAvatar(presence); 1806 RootPart.AddFullUpdateToAvatar(presence);
1942 1807
1943 lock (m_parts) 1808 SceneObjectPart[] parts = m_parts.GetArray();
1809 for (int i = 0; i < parts.Length; i++)
1944 { 1810 {
1945 foreach (SceneObjectPart part in m_parts.Values) 1811 SceneObjectPart part = parts[i];
1946 { 1812 if (part != RootPart)
1947 if (part != RootPart) 1813 part.AddFullUpdateToAvatar(presence);
1948 part.AddFullUpdateToAvatar(presence);
1949 }
1950 } 1814 }
1951 } 1815 }
1952 1816
1953 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 1817 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1954 { 1818 {
1955// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); 1819// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
1956 1820
1957 lock (m_parts) 1821 SceneObjectPart[] parts = m_parts.GetArray();
1958 { 1822 for (int i = 0; i < parts.Length; i++)
1959 foreach (SceneObjectPart part in m_parts.Values) 1823 parts[i].AddTerseUpdateToAvatar(presence);
1960 {
1961 part.AddTerseUpdateToAvatar(presence);
1962 }
1963 }
1964 } 1824 }
1965 1825
1966 /// <summary> 1826 /// <summary>
@@ -1974,13 +1834,12 @@ namespace OpenSim.Region.Framework.Scenes
1974 checkAtTargets(); 1834 checkAtTargets();
1975 RootPart.ScheduleFullUpdate(); 1835 RootPart.ScheduleFullUpdate();
1976 1836
1977 lock (m_parts) 1837 SceneObjectPart[] parts = m_parts.GetArray();
1838 for (int i = 0; i < parts.Length; i++)
1978 { 1839 {
1979 foreach (SceneObjectPart part in m_parts.Values) 1840 SceneObjectPart part = parts[i];
1980 { 1841 if (part != RootPart)
1981 if (part != RootPart) 1842 part.ScheduleFullUpdate();
1982 part.ScheduleFullUpdate();
1983 }
1984 } 1843 }
1985 } 1844 }
1986 1845
@@ -1990,14 +1849,10 @@ namespace OpenSim.Region.Framework.Scenes
1990 public void ScheduleGroupForTerseUpdate() 1849 public void ScheduleGroupForTerseUpdate()
1991 { 1850 {
1992// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); 1851// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID);
1993 1852
1994 lock (m_parts) 1853 SceneObjectPart[] parts = m_parts.GetArray();
1995 { 1854 for (int i = 0; i < parts.Length; i++)
1996 foreach (SceneObjectPart part in m_parts.Values) 1855 parts[i].ScheduleTerseUpdate();
1997 {
1998 part.ScheduleTerseUpdate();
1999 }
2000 }
2001 } 1856 }
2002 1857
2003 /// <summary> 1858 /// <summary>
@@ -2012,13 +1867,12 @@ namespace OpenSim.Region.Framework.Scenes
2012 1867
2013 RootPart.SendFullUpdateToAllClients(); 1868 RootPart.SendFullUpdateToAllClients();
2014 1869
2015 lock (m_parts) 1870 SceneObjectPart[] parts = m_parts.GetArray();
1871 for (int i = 0; i < parts.Length; i++)
2016 { 1872 {
2017 foreach (SceneObjectPart part in m_parts.Values) 1873 SceneObjectPart part = parts[i];
2018 { 1874 if (part != RootPart)
2019 if (part != RootPart) 1875 part.SendFullUpdateToAllClients();
2020 part.SendFullUpdateToAllClients();
2021 }
2022 } 1876 }
2023 } 1877 }
2024 1878
@@ -2051,14 +1905,10 @@ namespace OpenSim.Region.Framework.Scenes
2051 { 1905 {
2052 if (IsDeleted) 1906 if (IsDeleted)
2053 return; 1907 return;
2054 1908
2055 lock (m_parts) 1909 SceneObjectPart[] parts = m_parts.GetArray();
2056 { 1910 for (int i = 0; i < parts.Length; i++)
2057 foreach (SceneObjectPart part in m_parts.Values) 1911 parts[i].SendTerseUpdateToAllClients();
2058 {
2059 part.SendTerseUpdateToAllClients();
2060 }
2061 }
2062 } 1912 }
2063 1913
2064 #endregion 1914 #endregion
@@ -2072,15 +1922,11 @@ namespace OpenSim.Region.Framework.Scenes
2072 /// <returns>null if no child part with that linknum or child part</returns> 1922 /// <returns>null if no child part with that linknum or child part</returns>
2073 public SceneObjectPart GetLinkNumPart(int linknum) 1923 public SceneObjectPart GetLinkNumPart(int linknum)
2074 { 1924 {
2075 lock (m_parts) 1925 SceneObjectPart[] parts = m_parts.GetArray();
1926 for (int i = 0; i < parts.Length; i++)
2076 { 1927 {
2077 foreach (SceneObjectPart part in m_parts.Values) 1928 if (parts[i].LinkNum == linknum)
2078 { 1929 return parts[i];
2079 if (part.LinkNum == linknum)
2080 {
2081 return part;
2082 }
2083 }
2084 } 1930 }
2085 1931
2086 return null; 1932 return null;
@@ -2094,8 +1940,7 @@ namespace OpenSim.Region.Framework.Scenes
2094 public SceneObjectPart GetChildPart(UUID primID) 1940 public SceneObjectPart GetChildPart(UUID primID)
2095 { 1941 {
2096 SceneObjectPart childPart; 1942 SceneObjectPart childPart;
2097 lock (m_parts) 1943 m_parts.TryGetValue(primID, out childPart);
2098 m_parts.TryGetValue(primID, out childPart);
2099 return childPart; 1944 return childPart;
2100 } 1945 }
2101 1946
@@ -2106,17 +1951,11 @@ namespace OpenSim.Region.Framework.Scenes
2106 /// <returns>null if a child part with the local ID was not found</returns> 1951 /// <returns>null if a child part with the local ID was not found</returns>
2107 public SceneObjectPart GetChildPart(uint localID) 1952 public SceneObjectPart GetChildPart(uint localID)
2108 { 1953 {
2109 //m_log.DebugFormat("Entered looking for {0}", localID); 1954 SceneObjectPart[] parts = m_parts.GetArray();
2110 lock (m_parts) 1955 for (int i = 0; i < parts.Length; i++)
2111 { 1956 {
2112 foreach (SceneObjectPart part in m_parts.Values) 1957 if (parts[i].LocalId == localID)
2113 { 1958 return parts[i];
2114 //m_log.DebugFormat("Found {0}", part.LocalId);
2115 if (part.LocalId == localID)
2116 {
2117 return part;
2118 }
2119 }
2120 } 1959 }
2121 1960
2122 return null; 1961 return null;
@@ -2130,13 +1969,7 @@ namespace OpenSim.Region.Framework.Scenes
2130 /// <returns></returns> 1969 /// <returns></returns>
2131 public bool HasChildPrim(UUID primID) 1970 public bool HasChildPrim(UUID primID)
2132 { 1971 {
2133 lock (m_parts) 1972 return m_parts.ContainsKey(primID);
2134 {
2135 if (m_parts.ContainsKey(primID))
2136 return true;
2137 }
2138
2139 return false;
2140 } 1973 }
2141 1974
2142 /// <summary> 1975 /// <summary>
@@ -2147,17 +1980,11 @@ namespace OpenSim.Region.Framework.Scenes
2147 /// <returns></returns> 1980 /// <returns></returns>
2148 public bool HasChildPrim(uint localID) 1981 public bool HasChildPrim(uint localID)
2149 { 1982 {
2150 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 1983 SceneObjectPart[] parts = m_parts.GetArray();
2151 lock (m_parts) 1984 for (int i = 0; i < parts.Length; i++)
2152 { 1985 {
2153 foreach (SceneObjectPart part in m_parts.Values) 1986 if (parts[i].LocalId == localID)
2154 { 1987 return true;
2155 //m_log.DebugFormat("Found {0}", part.LocalId);
2156 if (part.LocalId == localID)
2157 {
2158 return true;
2159 }
2160 }
2161 } 1988 }
2162 1989
2163 return false; 1990 return false;
@@ -2208,19 +2035,21 @@ namespace OpenSim.Region.Framework.Scenes
2208 if (m_rootPart.LinkNum == 0) 2035 if (m_rootPart.LinkNum == 0)
2209 m_rootPart.LinkNum = 1; 2036 m_rootPart.LinkNum = 1;
2210 2037
2211 lock (m_parts) 2038 lock (m_parts.SyncRoot)
2212 { 2039 {
2213 m_parts.Add(linkPart.UUID, linkPart); 2040 m_parts.Add(linkPart.UUID, linkPart);
2214 2041
2215 // Insert in terms of link numbers, the new links 2042 // Insert in terms of link numbers, the new links
2216 // before the current ones (with the exception of 2043 // before the current ones (with the exception of
2217 // the root prim. Shuffle the old ones up 2044 // the root prim. Shuffle the old ones up
2218 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2045 SceneObjectPart[] parts = m_parts.GetArray();
2046 for (int i = 0; i < parts.Length; i++)
2219 { 2047 {
2220 if (kvp.Value.LinkNum != 1) 2048 SceneObjectPart part = parts[i];
2049 if (part.LinkNum != 1)
2221 { 2050 {
2222 // Don't update root prim link number 2051 // Don't update root prim link number
2223 kvp.Value.LinkNum += objectGroup.PrimCount; 2052 part.LinkNum += objectGroup.PrimCount;
2224 } 2053 }
2225 } 2054 }
2226 2055
@@ -2232,29 +2061,26 @@ namespace OpenSim.Region.Framework.Scenes
2232 //if (linkPart.PhysActor != null) 2061 //if (linkPart.PhysActor != null)
2233 //{ 2062 //{
2234 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2063 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2235 2064
2236 //linkPart.PhysActor = null; 2065 //linkPart.PhysActor = null;
2237 //} 2066 //}
2238 2067
2239 //TODO: rest of parts 2068 //TODO: rest of parts
2240 int linkNum = 3; 2069 int linkNum = 3;
2241 foreach (SceneObjectPart part in objectGroup.Children.Values) 2070 SceneObjectPart[] ogParts = objectGroup.Parts;
2071 for (int i = 0; i < ogParts.Length; i++)
2242 { 2072 {
2073 SceneObjectPart part = ogParts[i];
2243 if (part.UUID != objectGroup.m_rootPart.UUID) 2074 if (part.UUID != objectGroup.m_rootPart.UUID)
2244 {
2245 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); 2075 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2246 }
2247 part.ClearUndoState(); 2076 part.ClearUndoState();
2248 } 2077 }
2249 } 2078 }
2250 2079
2251 m_scene.UnlinkSceneObject(objectGroup, true); 2080 m_scene.UnlinkSceneObject(objectGroup, true);
2252 objectGroup.m_isDeleted = true; 2081 objectGroup.m_isDeleted = true;
2253 2082
2254 lock (objectGroup.m_parts) 2083 objectGroup.m_parts.Clear();
2255 {
2256 objectGroup.m_parts.Clear();
2257 }
2258 2084
2259 // Can't do this yet since backup still makes use of the root part without any synchronization 2085 // Can't do this yet since backup still makes use of the root part without any synchronization
2260// objectGroup.m_rootPart = null; 2086// objectGroup.m_rootPart = null;
@@ -2324,20 +2150,24 @@ namespace OpenSim.Region.Framework.Scenes
2324 Quaternion worldRot = linkPart.GetWorldRotation(); 2150 Quaternion worldRot = linkPart.GetWorldRotation();
2325 2151
2326 // Remove the part from this object 2152 // Remove the part from this object
2327 lock (m_parts) 2153 lock (m_parts.SyncRoot)
2328 { 2154 {
2329 m_parts.Remove(linkPart.UUID); 2155 m_parts.Remove(linkPart.UUID);
2330 2156
2331 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2157 SceneObjectPart[] parts = m_parts.GetArray();
2158
2159 if (parts.Length == 1 && RootPart != null)
2332 { 2160 {
2161 // Single prim left
2333 RootPart.LinkNum = 0; 2162 RootPart.LinkNum = 0;
2334 } 2163 }
2335 else 2164 else
2336 { 2165 {
2337 foreach (SceneObjectPart p in m_parts.Values) 2166 for (int i = 0; i < parts.Length; i++)
2338 { 2167 {
2339 if (p.LinkNum > linkPart.LinkNum) 2168 SceneObjectPart part = parts[i];
2340 p.LinkNum--; 2169 if (part.LinkNum > linkPart.LinkNum)
2170 part.LinkNum--;
2341 } 2171 }
2342 } 2172 }
2343 } 2173 }
@@ -2409,7 +2239,6 @@ namespace OpenSim.Region.Framework.Scenes
2409 part.SetParent(this); 2239 part.SetParent(this);
2410 part.ParentID = m_rootPart.LocalId; 2240 part.ParentID = m_rootPart.LocalId;
2411 2241
2412 // Caller locks m_parts for us
2413 m_parts.Add(part.UUID, part); 2242 m_parts.Add(part.UUID, part);
2414 2243
2415 part.LinkNum = linkNum; 2244 part.LinkNum = linkNum;
@@ -2662,24 +2491,21 @@ namespace OpenSim.Region.Framework.Scenes
2662 2491
2663 if (selectionPart != null) 2492 if (selectionPart != null)
2664 { 2493 {
2665 lock (m_parts) 2494 SceneObjectPart[] parts = m_parts.GetArray();
2495 for (int i = 0; i < parts.Length; i++)
2666 { 2496 {
2667 foreach (SceneObjectPart part in m_parts.Values) 2497 SceneObjectPart part = parts[i];
2498 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2499 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2500 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2668 { 2501 {
2669 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2502 UsePhysics = false; // Reset physics
2670 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2503 break;
2671 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2672 {
2673 UsePhysics = false; // Reset physics
2674 break;
2675 }
2676 }
2677
2678 foreach (SceneObjectPart part in m_parts.Values)
2679 {
2680 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2681 } 2504 }
2682 } 2505 }
2506
2507 for (int i = 0; i < parts.Length; i++)
2508 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2683 } 2509 }
2684 } 2510 }
2685 2511
@@ -2693,18 +2519,6 @@ namespace OpenSim.Region.Framework.Scenes
2693 } 2519 }
2694 2520
2695 /// <summary> 2521 /// <summary>
2696 /// Get the parts of this scene object
2697 /// </summary>
2698 /// <returns></returns>
2699 public SceneObjectPart[] GetParts()
2700 {
2701 int numParts = Children.Count;
2702 SceneObjectPart[] partArray = new SceneObjectPart[numParts];
2703 Children.Values.CopyTo(partArray, 0);
2704 return partArray;
2705 }
2706
2707 /// <summary>
2708 /// Update the texture entry for this part 2522 /// Update the texture entry for this part
2709 /// </summary> 2523 /// </summary>
2710 /// <param name="localID"></param> 2524 /// <param name="localID"></param>
@@ -2721,12 +2535,9 @@ namespace OpenSim.Region.Framework.Scenes
2721 public void UpdatePermissions(UUID AgentID, byte field, uint localID, 2535 public void UpdatePermissions(UUID AgentID, byte field, uint localID,
2722 uint mask, byte addRemTF) 2536 uint mask, byte addRemTF)
2723 { 2537 {
2724 List<SceneObjectPart> partList = null; 2538 SceneObjectPart[] parts = m_parts.GetArray();
2725 lock (m_parts) 2539 for (int i = 0; i < parts.Length; i++)
2726 partList = new List<SceneObjectPart>(m_parts.Values); 2540 parts[i].UpdatePermissions(AgentID, field, localID, mask, addRemTF);
2727
2728 foreach (SceneObjectPart part in partList)
2729 part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
2730 2541
2731 HasGroupChanged = true; 2542 HasGroupChanged = true;
2732 } 2543 }
@@ -2829,77 +2640,77 @@ namespace OpenSim.Region.Framework.Scenes
2829 float y = (scale.Y / part.Scale.Y); 2640 float y = (scale.Y / part.Scale.Y);
2830 float z = (scale.Z / part.Scale.Z); 2641 float z = (scale.Z / part.Scale.Z);
2831 2642
2832 lock (m_parts) 2643 SceneObjectPart[] parts;
2644 if (x > 1.0f || y > 1.0f || z > 1.0f)
2833 { 2645 {
2834 if (x > 1.0f || y > 1.0f || z > 1.0f) 2646 parts = m_parts.GetArray();
2647 for (int i = 0; i < parts.Length; i++)
2835 { 2648 {
2836 foreach (SceneObjectPart obPart in m_parts.Values) 2649 SceneObjectPart obPart = parts[i];
2650 if (obPart.UUID != m_rootPart.UUID)
2837 { 2651 {
2838 if (obPart.UUID != m_rootPart.UUID) 2652 obPart.IgnoreUndoUpdate = true;
2839 { 2653 Vector3 oldSize = new Vector3(obPart.Scale);
2840 obPart.IgnoreUndoUpdate = true;
2841 Vector3 oldSize = new Vector3(obPart.Scale);
2842 2654
2843 float f = 1.0f; 2655 float f = 1.0f;
2844 float a = 1.0f; 2656 float a = 1.0f;
2845 2657
2846 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2658 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2659 {
2660 if (oldSize.X * x > m_scene.m_maxPhys)
2661 {
2662 f = m_scene.m_maxPhys / oldSize.X;
2663 a = f / x;
2664 x *= a;
2665 y *= a;
2666 z *= a;
2667 }
2668 if (oldSize.Y * y > m_scene.m_maxPhys)
2669 {
2670 f = m_scene.m_maxPhys / oldSize.Y;
2671 a = f / y;
2672 x *= a;
2673 y *= a;
2674 z *= a;
2675 }
2676 if (oldSize.Z * z > m_scene.m_maxPhys)
2677 {
2678 f = m_scene.m_maxPhys / oldSize.Z;
2679 a = f / z;
2680 x *= a;
2681 y *= a;
2682 z *= a;
2683 }
2684 }
2685 else
2686 {
2687 if (oldSize.X * x > m_scene.m_maxNonphys)
2688 {
2689 f = m_scene.m_maxNonphys / oldSize.X;
2690 a = f / x;
2691 x *= a;
2692 y *= a;
2693 z *= a;
2694 }
2695 if (oldSize.Y * y > m_scene.m_maxNonphys)
2847 { 2696 {
2848 if (oldSize.X*x > m_scene.m_maxPhys) 2697 f = m_scene.m_maxNonphys / oldSize.Y;
2849 { 2698 a = f / y;
2850 f = m_scene.m_maxPhys / oldSize.X; 2699 x *= a;
2851 a = f / x; 2700 y *= a;
2852 x *= a; 2701 z *= a;
2853 y *= a;
2854 z *= a;
2855 }
2856 if (oldSize.Y*y > m_scene.m_maxPhys)
2857 {
2858 f = m_scene.m_maxPhys / oldSize.Y;
2859 a = f / y;
2860 x *= a;
2861 y *= a;
2862 z *= a;
2863 }
2864 if (oldSize.Z*z > m_scene.m_maxPhys)
2865 {
2866 f = m_scene.m_maxPhys / oldSize.Z;
2867 a = f / z;
2868 x *= a;
2869 y *= a;
2870 z *= a;
2871 }
2872 } 2702 }
2873 else 2703 if (oldSize.Z * z > m_scene.m_maxNonphys)
2874 { 2704 {
2875 if (oldSize.X*x > m_scene.m_maxNonphys) 2705 f = m_scene.m_maxNonphys / oldSize.Z;
2876 { 2706 a = f / z;
2877 f = m_scene.m_maxNonphys / oldSize.X; 2707 x *= a;
2878 a = f / x; 2708 y *= a;
2879 x *= a; 2709 z *= a;
2880 y *= a;
2881 z *= a;
2882 }
2883 if (oldSize.Y*y > m_scene.m_maxNonphys)
2884 {
2885 f = m_scene.m_maxNonphys / oldSize.Y;
2886 a = f / y;
2887 x *= a;
2888 y *= a;
2889 z *= a;
2890 }
2891 if (oldSize.Z*z > m_scene.m_maxNonphys)
2892 {
2893 f = m_scene.m_maxNonphys / oldSize.Z;
2894 a = f / z;
2895 x *= a;
2896 y *= a;
2897 z *= a;
2898 }
2899 } 2710 }
2900 obPart.IgnoreUndoUpdate = false;
2901 obPart.StoreUndoState();
2902 } 2711 }
2712 obPart.IgnoreUndoUpdate = false;
2713 obPart.StoreUndoState();
2903 } 2714 }
2904 } 2715 }
2905 } 2716 }
@@ -2910,27 +2721,26 @@ namespace OpenSim.Region.Framework.Scenes
2910 prevScale.Z *= z; 2721 prevScale.Z *= z;
2911 part.Resize(prevScale); 2722 part.Resize(prevScale);
2912 2723
2913 lock (m_parts) 2724 parts = m_parts.GetArray();
2725 for (int i = 0; i < parts.Length; i++)
2914 { 2726 {
2915 foreach (SceneObjectPart obPart in m_parts.Values) 2727 SceneObjectPart obPart = parts[i];
2728 obPart.IgnoreUndoUpdate = true;
2729 if (obPart.UUID != m_rootPart.UUID)
2916 { 2730 {
2917 obPart.IgnoreUndoUpdate = true; 2731 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
2918 if (obPart.UUID != m_rootPart.UUID) 2732 currentpos.X *= x;
2919 { 2733 currentpos.Y *= y;
2920 Vector3 currentpos = new Vector3(obPart.OffsetPosition); 2734 currentpos.Z *= z;
2921 currentpos.X *= x; 2735 Vector3 newSize = new Vector3(obPart.Scale);
2922 currentpos.Y *= y; 2736 newSize.X *= x;
2923 currentpos.Z *= z; 2737 newSize.Y *= y;
2924 Vector3 newSize = new Vector3(obPart.Scale); 2738 newSize.Z *= z;
2925 newSize.X *= x; 2739 obPart.Resize(newSize);
2926 newSize.Y *= y; 2740 obPart.UpdateOffSet(currentpos);
2927 newSize.Z *= z;
2928 obPart.Resize(newSize);
2929 obPart.UpdateOffSet(currentpos);
2930 }
2931 obPart.IgnoreUndoUpdate = false;
2932 obPart.StoreUndoState();
2933 } 2741 }
2742 obPart.IgnoreUndoUpdate = false;
2743 obPart.StoreUndoState();
2934 } 2744 }
2935 2745
2936 if (part.PhysActor != null) 2746 if (part.PhysActor != null)
@@ -2956,10 +2766,10 @@ namespace OpenSim.Region.Framework.Scenes
2956 /// <param name="pos"></param> 2766 /// <param name="pos"></param>
2957 public void UpdateGroupPosition(Vector3 pos) 2767 public void UpdateGroupPosition(Vector3 pos)
2958 { 2768 {
2959 foreach (SceneObjectPart part in Children.Values) 2769 SceneObjectPart[] parts = m_parts.GetArray();
2960 { 2770 for (int i = 0; i < parts.Length; i++)
2961 part.StoreUndoState(); 2771 parts[i].StoreUndoState();
2962 } 2772
2963 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 2773 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
2964 { 2774 {
2965 if (IsAttachment) 2775 if (IsAttachment)
@@ -2994,10 +2804,11 @@ namespace OpenSim.Region.Framework.Scenes
2994 public void UpdateSinglePosition(Vector3 pos, uint localID) 2804 public void UpdateSinglePosition(Vector3 pos, uint localID)
2995 { 2805 {
2996 SceneObjectPart part = GetChildPart(localID); 2806 SceneObjectPart part = GetChildPart(localID);
2997 foreach (SceneObjectPart parts in Children.Values) 2807
2998 { 2808 SceneObjectPart[] parts = m_parts.GetArray();
2999 parts.StoreUndoState(); 2809 for (int i = 0; i < parts.Length; i++)
3000 } 2810 parts[i].StoreUndoState();
2811
3001 if (part != null) 2812 if (part != null)
3002 { 2813 {
3003 if (part.UUID == m_rootPart.UUID) 2814 if (part.UUID == m_rootPart.UUID)
@@ -3019,10 +2830,10 @@ namespace OpenSim.Region.Framework.Scenes
3019 /// <param name="pos"></param> 2830 /// <param name="pos"></param>
3020 private void UpdateRootPosition(Vector3 pos) 2831 private void UpdateRootPosition(Vector3 pos)
3021 { 2832 {
3022 foreach (SceneObjectPart part in Children.Values) 2833 SceneObjectPart[] parts = m_parts.GetArray();
3023 { 2834 for (int i = 0; i < parts.Length; i++)
3024 part.StoreUndoState(); 2835 parts[i].StoreUndoState();
3025 } 2836
3026 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 2837 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
3027 Vector3 oldPos = 2838 Vector3 oldPos =
3028 new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, 2839 new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X,
@@ -3034,15 +2845,12 @@ namespace OpenSim.Region.Framework.Scenes
3034 axDiff *= Quaternion.Inverse(partRotation); 2845 axDiff *= Quaternion.Inverse(partRotation);
3035 diff = axDiff; 2846 diff = axDiff;
3036 2847
3037 lock (m_parts) 2848 parts = m_parts.GetArray();
2849 for (int i = 0; i < parts.Length; i++)
3038 { 2850 {
3039 foreach (SceneObjectPart obPart in m_parts.Values) 2851 SceneObjectPart obPart = parts[i];
3040 { 2852 if (obPart.UUID != m_rootPart.UUID)
3041 if (obPart.UUID != m_rootPart.UUID) 2853 obPart.OffsetPosition = obPart.OffsetPosition + diff;
3042 {
3043 obPart.OffsetPosition = obPart.OffsetPosition + diff;
3044 }
3045 }
3046 } 2854 }
3047 2855
3048 AbsolutePosition = newPos; 2856 AbsolutePosition = newPos;
@@ -3066,10 +2874,10 @@ namespace OpenSim.Region.Framework.Scenes
3066 /// <param name="rot"></param> 2874 /// <param name="rot"></param>
3067 public void UpdateGroupRotationR(Quaternion rot) 2875 public void UpdateGroupRotationR(Quaternion rot)
3068 { 2876 {
3069 foreach (SceneObjectPart parts in Children.Values) 2877 SceneObjectPart[] parts = m_parts.GetArray();
3070 { 2878 for (int i = 0; i < parts.Length; i++)
3071 parts.StoreUndoState(); 2879 parts[i].StoreUndoState();
3072 } 2880
3073 m_rootPart.UpdateRotation(rot); 2881 m_rootPart.UpdateRotation(rot);
3074 2882
3075 PhysicsActor actor = m_rootPart.PhysActor; 2883 PhysicsActor actor = m_rootPart.PhysActor;
@@ -3090,10 +2898,10 @@ namespace OpenSim.Region.Framework.Scenes
3090 /// <param name="rot"></param> 2898 /// <param name="rot"></param>
3091 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 2899 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
3092 { 2900 {
3093 foreach (SceneObjectPart parts in Children.Values) 2901 SceneObjectPart[] parts = m_parts.GetArray();
3094 { 2902 for (int i = 0; i < parts.Length; i++)
3095 parts.StoreUndoState(); 2903 parts[i].StoreUndoState();
3096 } 2904
3097 m_rootPart.UpdateRotation(rot); 2905 m_rootPart.UpdateRotation(rot);
3098 2906
3099 PhysicsActor actor = m_rootPart.PhysActor; 2907 PhysicsActor actor = m_rootPart.PhysActor;
@@ -3117,10 +2925,11 @@ namespace OpenSim.Region.Framework.Scenes
3117 public void UpdateSingleRotation(Quaternion rot, uint localID) 2925 public void UpdateSingleRotation(Quaternion rot, uint localID)
3118 { 2926 {
3119 SceneObjectPart part = GetChildPart(localID); 2927 SceneObjectPart part = GetChildPart(localID);
3120 foreach (SceneObjectPart parts in Children.Values) 2928
3121 { 2929 SceneObjectPart[] parts = m_parts.GetArray();
3122 parts.StoreUndoState(); 2930 for (int i = 0; i < parts.Length; i++)
3123 } 2931 parts[i].StoreUndoState();
2932
3124 if (part != null) 2933 if (part != null)
3125 { 2934 {
3126 if (part.UUID == m_rootPart.UUID) 2935 if (part.UUID == m_rootPart.UUID)
@@ -3177,33 +2986,35 @@ namespace OpenSim.Region.Framework.Scenes
3177 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 2986 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3178 } 2987 }
3179 2988
3180 lock (m_parts) 2989 SceneObjectPart[] parts = m_parts.GetArray();
2990 for (int i = 0; i < parts.Length; i++)
3181 { 2991 {
3182 foreach (SceneObjectPart prim in m_parts.Values) 2992 SceneObjectPart prim = parts[i];
2993 if (prim.UUID != m_rootPart.UUID)
3183 { 2994 {
3184 if (prim.UUID != m_rootPart.UUID) 2995 prim.IgnoreUndoUpdate = true;
3185 { 2996 Vector3 axPos = prim.OffsetPosition;
3186 prim.IgnoreUndoUpdate = true; 2997 axPos *= oldParentRot;
3187 Vector3 axPos = prim.OffsetPosition; 2998 axPos *= Quaternion.Inverse(axRot);
3188 axPos *= oldParentRot; 2999 prim.OffsetPosition = axPos;
3189 axPos *= Quaternion.Inverse(axRot); 3000 Quaternion primsRot = prim.RotationOffset;
3190 prim.OffsetPosition = axPos; 3001 Quaternion newRot = primsRot * oldParentRot;
3191 Quaternion primsRot = prim.RotationOffset; 3002 newRot *= Quaternion.Inverse(axRot);
3192 Quaternion newRot = primsRot * oldParentRot; 3003 prim.RotationOffset = newRot;
3193 newRot *= Quaternion.Inverse(axRot); 3004 prim.ScheduleTerseUpdate();
3194 prim.RotationOffset = newRot;
3195 prim.ScheduleTerseUpdate();
3196 }
3197 } 3005 }
3198 } 3006 }
3199 foreach (SceneObjectPart childpart in Children.Values) 3007
3008 for (int i = 0; i < parts.Length; i++)
3200 { 3009 {
3010 SceneObjectPart childpart = parts[i];
3201 if (childpart != m_rootPart) 3011 if (childpart != m_rootPart)
3202 { 3012 {
3203 childpart.IgnoreUndoUpdate = false; 3013 childpart.IgnoreUndoUpdate = false;
3204 childpart.StoreUndoState(); 3014 childpart.StoreUndoState();
3205 } 3015 }
3206 } 3016 }
3017
3207 m_rootPart.ScheduleTerseUpdate(); 3018 m_rootPart.ScheduleTerseUpdate();
3208 } 3019 }
3209 3020
@@ -3324,17 +3135,10 @@ namespace OpenSim.Region.Framework.Scenes
3324 3135
3325 if (atTargets.Count > 0) 3136 if (atTargets.Count > 0)
3326 { 3137 {
3327 uint[] localids = new uint[0]; 3138 SceneObjectPart[] parts = m_parts.GetArray();
3328 lock (m_parts) 3139 uint[] localids = new uint[parts.Length];
3329 { 3140 for (int i = 0; i < parts.Length; i++)
3330 localids = new uint[m_parts.Count]; 3141 localids[i] = parts[i].LocalId;
3331 int cntr = 0;
3332 foreach (SceneObjectPart part in m_parts.Values)
3333 {
3334 localids[cntr] = part.LocalId;
3335 cntr++;
3336 }
3337 }
3338 3142
3339 for (int ctr = 0; ctr < localids.Length; ctr++) 3143 for (int ctr = 0; ctr < localids.Length; ctr++)
3340 { 3144 {
@@ -3352,17 +3156,10 @@ namespace OpenSim.Region.Framework.Scenes
3352 if (m_scriptListens_notAtTarget && !at_target) 3156 if (m_scriptListens_notAtTarget && !at_target)
3353 { 3157 {
3354 //trigger not_at_target 3158 //trigger not_at_target
3355 uint[] localids = new uint[0]; 3159 SceneObjectPart[] parts = m_parts.GetArray();
3356 lock (m_parts) 3160 uint[] localids = new uint[parts.Length];
3357 { 3161 for (int i = 0; i < parts.Length; i++)
3358 localids = new uint[m_parts.Count]; 3162 localids[i] = parts[i].LocalId;
3359 int cntr = 0;
3360 foreach (SceneObjectPart part in m_parts.Values)
3361 {
3362 localids[cntr] = part.LocalId;
3363 cntr++;
3364 }
3365 }
3366 3163
3367 for (int ctr = 0; ctr < localids.Length; ctr++) 3164 for (int ctr = 0; ctr < localids.Length; ctr++)
3368 { 3165 {
@@ -3403,17 +3200,10 @@ namespace OpenSim.Region.Framework.Scenes
3403 3200
3404 if (atRotTargets.Count > 0) 3201 if (atRotTargets.Count > 0)
3405 { 3202 {
3406 uint[] localids = new uint[0]; 3203 SceneObjectPart[] parts = m_parts.GetArray();
3407 lock (m_parts) 3204 uint[] localids = new uint[parts.Length];
3408 { 3205 for (int i = 0; i < parts.Length; i++)
3409 localids = new uint[m_parts.Count]; 3206 localids[i] = parts[i].LocalId;
3410 int cntr = 0;
3411 foreach (SceneObjectPart part in m_parts.Values)
3412 {
3413 localids[cntr] = part.LocalId;
3414 cntr++;
3415 }
3416 }
3417 3207
3418 for (int ctr = 0; ctr < localids.Length; ctr++) 3208 for (int ctr = 0; ctr < localids.Length; ctr++)
3419 { 3209 {
@@ -3431,17 +3221,10 @@ namespace OpenSim.Region.Framework.Scenes
3431 if (m_scriptListens_notAtRotTarget && !at_Rottarget) 3221 if (m_scriptListens_notAtRotTarget && !at_Rottarget)
3432 { 3222 {
3433 //trigger not_at_target 3223 //trigger not_at_target
3434 uint[] localids = new uint[0]; 3224 SceneObjectPart[] parts = m_parts.GetArray();
3435 lock (m_parts) 3225 uint[] localids = new uint[parts.Length];
3436 { 3226 for (int i = 0; i < parts.Length; i++)
3437 localids = new uint[m_parts.Count]; 3227 localids[i] = parts[i].LocalId;
3438 int cntr = 0;
3439 foreach (SceneObjectPart part in m_parts.Values)
3440 {
3441 localids[cntr] = part.LocalId;
3442 cntr++;
3443 }
3444 }
3445 3228
3446 for (int ctr = 0; ctr < localids.Length; ctr++) 3229 for (int ctr = 0; ctr < localids.Length; ctr++)
3447 { 3230 {
@@ -3455,40 +3238,36 @@ namespace OpenSim.Region.Framework.Scenes
3455 public float GetMass() 3238 public float GetMass()
3456 { 3239 {
3457 float retmass = 0f; 3240 float retmass = 0f;
3458 lock (m_parts) 3241
3459 { 3242 SceneObjectPart[] parts = m_parts.GetArray();
3460 foreach (SceneObjectPart part in m_parts.Values) 3243 for (int i = 0; i < parts.Length; i++)
3461 { 3244 retmass += parts[i].GetMass();
3462 retmass += part.GetMass(); 3245
3463 }
3464 }
3465 return retmass; 3246 return retmass;
3466 } 3247 }
3467 3248
3468 public void CheckSculptAndLoad() 3249 public void CheckSculptAndLoad()
3469 { 3250 {
3470 lock (m_parts) 3251 if (IsDeleted)
3252 return;
3253 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
3254 return;
3255
3256 SceneObjectPart[] parts = m_parts.GetArray();
3257 for (int i = 0; i < parts.Length; i++)
3471 { 3258 {
3472 if (!IsDeleted) 3259 SceneObjectPart part = parts[i];
3260 if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero)
3473 { 3261 {
3474 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0) 3262 // check if a previously decoded sculpt map has been cached
3263 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString())))
3475 { 3264 {
3476 foreach (SceneObjectPart part in m_parts.Values) 3265 part.SculptTextureCallback(part.Shape.SculptTexture, null);
3477 { 3266 }
3478 if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero) 3267 else
3479 { 3268 {
3480 // check if a previously decoded sculpt map has been cached 3269 m_scene.AssetService.Get(
3481 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString()))) 3270 part.Shape.SculptTexture.ToString(), part, AssetReceived);
3482 {
3483 part.SculptTextureCallback(part.Shape.SculptTexture, null);
3484 }
3485 else
3486 {
3487 m_scene.AssetService.Get(
3488 part.Shape.SculptTexture.ToString(), part, AssetReceived);
3489 }
3490 }
3491 }
3492 } 3271 }
3493 } 3272 }
3494 } 3273 }
@@ -3512,15 +3291,12 @@ namespace OpenSim.Region.Framework.Scenes
3512 /// <param name="client"></param> 3291 /// <param name="client"></param>
3513 public void SetGroup(UUID GroupID, IClientAPI client) 3292 public void SetGroup(UUID GroupID, IClientAPI client)
3514 { 3293 {
3515 lock (m_parts) 3294 SceneObjectPart[] parts = m_parts.GetArray();
3295 for (int i = 0; i < parts.Length; i++)
3516 { 3296 {
3517 foreach (SceneObjectPart part in m_parts.Values) 3297 SceneObjectPart part = parts[i];
3518 { 3298 part.SetGroup(GroupID, client);
3519 part.SetGroup(GroupID, client); 3299 part.Inventory.ChangeInventoryGroup(GroupID);
3520 part.Inventory.ChangeInventoryGroup(GroupID);
3521 }
3522
3523 HasGroupChanged = true;
3524 } 3300 }
3525 3301
3526 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled 3302 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
@@ -3530,10 +3306,9 @@ namespace OpenSim.Region.Framework.Scenes
3530 3306
3531 public void TriggerScriptChangedEvent(Changed val) 3307 public void TriggerScriptChangedEvent(Changed val)
3532 { 3308 {
3533 foreach (SceneObjectPart part in Children.Values) 3309 SceneObjectPart[] parts = m_parts.GetArray();
3534 { 3310 for (int i = 0; i < parts.Length; i++)
3535 part.TriggerScriptChangedEvent(val); 3311 parts[i].TriggerScriptChangedEvent(val);
3536 }
3537 } 3312 }
3538 3313
3539 public override string ToString() 3314 public override string ToString()
@@ -3543,11 +3318,9 @@ namespace OpenSim.Region.Framework.Scenes
3543 3318
3544 public void SetAttachmentPoint(byte point) 3319 public void SetAttachmentPoint(byte point)
3545 { 3320 {
3546 lock (m_parts) 3321 SceneObjectPart[] parts = m_parts.GetArray();
3547 { 3322 for (int i = 0; i < parts.Length; i++)
3548 foreach (SceneObjectPart part in m_parts.Values) 3323 parts[i].SetAttachmentPoint(point);
3549 part.SetAttachmentPoint(point);
3550 }
3551 } 3324 }
3552 3325
3553 #region ISceneObject 3326 #region ISceneObject