From 860b2a502f797e5822c6705d4639f370f3ac5861 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 16 Sep 2010 17:30:46 -0700 Subject: Changed SceneObjectGroup to store parts with the fast and thread-safe MapAndArray collection --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 1409 ++++++++------------ 1 file changed, 591 insertions(+), 818 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs') 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 } } - public float scriptScore = 0f; + public float scriptScore; private Vector3 lastPhysGroupPos; private Quaternion lastPhysGroupRot; - private bool m_isBackedUp = false; + private bool m_isBackedUp; - /// - /// The constituent parts of this group - /// - protected Dictionary m_parts = new Dictionary(); + protected MapAndArray m_parts = new MapAndArray(); protected ulong m_regionHandle; protected SceneObjectPart m_rootPart; @@ -177,13 +174,13 @@ namespace OpenSim.Region.Framework.Scenes private Dictionary m_targets = new Dictionary(); private Dictionary m_rotTargets = new Dictionary(); - private bool m_scriptListens_atTarget = false; - private bool m_scriptListens_notAtTarget = false; + private bool m_scriptListens_atTarget; + private bool m_scriptListens_notAtTarget; - private bool m_scriptListens_atRotTarget = false; - private bool m_scriptListens_notAtRotTarget = false; + private bool m_scriptListens_atRotTarget; + private bool m_scriptListens_notAtRotTarget; - internal Dictionary m_savedScriptState = null; + internal Dictionary m_savedScriptState; #region Properties @@ -194,7 +191,7 @@ namespace OpenSim.Region.Framework.Scenes { get { if (RootPart == null) - return ""; + return String.Empty; return RootPart.Name; } set { RootPart.Name = value; } @@ -214,7 +211,7 @@ namespace OpenSim.Region.Framework.Scenes /// public int PrimCount { - get { lock (m_parts) { return m_parts.Count; } } + get { return m_parts.Count; } } protected Quaternion m_rotation = Quaternion.Identity; @@ -236,16 +233,14 @@ namespace OpenSim.Region.Framework.Scenes set { m_rootPart.GroupID = value; } } - /// - /// The parts of this scene object group. You must lock this property before using it. - /// If you're doing anything other than reading values, please take a copy of the values rather than locking - /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock - /// If you want to know the number of children, consider using the PrimCount property instead - /// - public Dictionary Children + public SceneObjectPart[] Parts + { + get { return m_parts.GetArray(); } + } + + public bool ContainsPart(UUID partID) { - get { return m_parts; } - set { m_parts = value; } + return m_parts.ContainsKey(partID); } /// @@ -262,13 +257,9 @@ namespace OpenSim.Region.Framework.Scenes set { m_regionHandle = value; - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.RegionHandle = m_regionHandle; - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].RegionHandle = value; } } @@ -313,14 +304,10 @@ namespace OpenSim.Region.Framework.Scenes return; } } - - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.GroupPosition = val; - } - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].GroupPosition = val; //if (m_rootPart.PhysActor != null) //{ @@ -342,14 +329,9 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_rootPart.UUID; } set - { - m_rootPart.UUID = value; - - lock (m_parts) - { - m_parts.Remove(m_rootPart.UUID); - m_parts.Add(m_rootPart.UUID, m_rootPart); - } + { + m_rootPart.UUID = value; + m_parts.AddOrReplace(value, m_rootPart); } } @@ -411,12 +393,12 @@ namespace OpenSim.Region.Framework.Scenes { m_rootPart.PhysActor.Selected = value; // Pass it on to the children. - foreach (SceneObjectPart child in Children.Values) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { + SceneObjectPart child = parts[i]; if (child.PhysActor != null) - { child.PhysActor.Selected = value; - } } } } @@ -519,13 +501,9 @@ namespace OpenSim.Region.Framework.Scenes public void SetFromItemID(UUID AssetId) { - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.FromItemID = AssetId; - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].FromItemID = AssetId; } public UUID GetFromItemID() @@ -564,23 +542,18 @@ namespace OpenSim.Region.Framework.Scenes if (m_rootPart.LocalId == 0) m_rootPart.LocalId = m_scene.AllocateLocalId(); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (Object.ReferenceEquals(part, m_rootPart)) - { - continue; - } - - if (part.LocalId == 0) - { - part.LocalId = m_scene.AllocateLocalId(); - } - - part.ParentID = m_rootPart.LocalId; - //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); - } + SceneObjectPart part = parts[i]; + if (Object.ReferenceEquals(part, m_rootPart)) + continue; + + if (part.LocalId == 0) + part.LocalId = m_scene.AllocateLocalId(); + + part.ParentID = m_rootPart.LocalId; + //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); } ApplyPhysics(m_scene.m_physicalPrim); @@ -596,22 +569,22 @@ namespace OpenSim.Region.Framework.Scenes Vector3 maxScale = Vector3.Zero; Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - Vector3 partscale = part.Scale; - Vector3 partoffset = part.OffsetPosition; + SceneObjectPart part = parts[i]; + Vector3 partscale = part.Scale; + Vector3 partoffset = part.OffsetPosition; - minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; - minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; - minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; + minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; + minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; + minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; - maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; - maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; - maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; - } + maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; + maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; + maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; } + finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; @@ -627,39 +600,40 @@ namespace OpenSim.Region.Framework.Scenes EntityIntersection result = new EntityIntersection(); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - // Temporary commented to stop compiler warning - //Vector3 partPosition = - // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); - Quaternion parentrotation = GroupRotation; + SceneObjectPart part = parts[i]; - // Telling the prim to raytrace. - //EntityIntersection inter = part.TestIntersection(hRay, parentrotation); + // Temporary commented to stop compiler warning + //Vector3 partPosition = + // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); + Quaternion parentrotation = GroupRotation; - EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation,frontFacesOnly, faceCenters); + // Telling the prim to raytrace. + //EntityIntersection inter = part.TestIntersection(hRay, parentrotation); - // This may need to be updated to the maximum draw distance possible.. - // We might (and probably will) be checking for prim creation from other sims - // when the camera crosses the border. - float idist = Constants.RegionSize; + EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation, frontFacesOnly, faceCenters); - if (inter.HitTF) + // This may need to be updated to the maximum draw distance possible.. + // We might (and probably will) be checking for prim creation from other sims + // when the camera crosses the border. + float idist = Constants.RegionSize; + + if (inter.HitTF) + { + // We need to find the closest prim to return to the testcaller along the ray + if (inter.distance < idist) { - // We need to find the closest prim to return to the testcaller along the ray - if (inter.distance < idist) - { - result.HitTF = true; - result.ipoint = inter.ipoint; - result.obj = part; - result.normal = inter.normal; - result.distance = inter.distance; - } + result.HitTF = true; + result.ipoint = inter.ipoint; + result.obj = part; + result.normal = inter.normal; + result.distance = inter.distance; } } } + return result; } @@ -678,238 +652,193 @@ namespace OpenSim.Region.Framework.Scenes minY = 256f; minZ = 8192f; - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - Vector3 worldPos = part.GetWorldPosition(); - Vector3 offset = worldPos - AbsolutePosition; - Quaternion worldRot; - if (part.ParentID == 0) - { - worldRot = part.RotationOffset; - } - else - { - worldRot = part.GetWorldRotation(); - } + SceneObjectPart part = parts[i]; - Vector3 frontTopLeft; - Vector3 frontTopRight; - Vector3 frontBottomLeft; - Vector3 frontBottomRight; - - Vector3 backTopLeft; - Vector3 backTopRight; - Vector3 backBottomLeft; - Vector3 backBottomRight; - - // Vector3[] corners = new Vector3[8]; - - Vector3 orig = Vector3.Zero; - - frontTopLeft.X = orig.X - (part.Scale.X / 2); - frontTopLeft.Y = orig.Y - (part.Scale.Y / 2); - frontTopLeft.Z = orig.Z + (part.Scale.Z / 2); - - frontTopRight.X = orig.X - (part.Scale.X / 2); - frontTopRight.Y = orig.Y + (part.Scale.Y / 2); - frontTopRight.Z = orig.Z + (part.Scale.Z / 2); - - frontBottomLeft.X = orig.X - (part.Scale.X / 2); - frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2); - frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2); - - frontBottomRight.X = orig.X - (part.Scale.X / 2); - frontBottomRight.Y = orig.Y + (part.Scale.Y / 2); - frontBottomRight.Z = orig.Z - (part.Scale.Z / 2); - - backTopLeft.X = orig.X + (part.Scale.X / 2); - backTopLeft.Y = orig.Y - (part.Scale.Y / 2); - backTopLeft.Z = orig.Z + (part.Scale.Z / 2); - - backTopRight.X = orig.X + (part.Scale.X / 2); - backTopRight.Y = orig.Y + (part.Scale.Y / 2); - backTopRight.Z = orig.Z + (part.Scale.Z / 2); - - backBottomLeft.X = orig.X + (part.Scale.X / 2); - backBottomLeft.Y = orig.Y - (part.Scale.Y / 2); - backBottomLeft.Z = orig.Z - (part.Scale.Z / 2); - - backBottomRight.X = orig.X + (part.Scale.X / 2); - backBottomRight.Y = orig.Y + (part.Scale.Y / 2); - backBottomRight.Z = orig.Z - (part.Scale.Z / 2); - - //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); - //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); - //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); - //m_log.InfoFormat("pre corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); - //m_log.InfoFormat("pre corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); - //m_log.InfoFormat("pre corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); - //m_log.InfoFormat("pre corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); - //m_log.InfoFormat("pre corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); - - //for (int i = 0; i < 8; i++) - //{ - // corners[i] = corners[i] * worldRot; - // corners[i] += offset; - - // if (corners[i].X > maxX) - // maxX = corners[i].X; - // if (corners[i].X < minX) - // minX = corners[i].X; - - // if (corners[i].Y > maxY) - // maxY = corners[i].Y; - // if (corners[i].Y < minY) - // minY = corners[i].Y; - - // if (corners[i].Z > maxZ) - // maxZ = corners[i].Y; - // if (corners[i].Z < minZ) - // minZ = corners[i].Z; - //} - - frontTopLeft = frontTopLeft * worldRot; - frontTopRight = frontTopRight * worldRot; - frontBottomLeft = frontBottomLeft * worldRot; - frontBottomRight = frontBottomRight * worldRot; - - backBottomLeft = backBottomLeft * worldRot; - backBottomRight = backBottomRight * worldRot; - backTopLeft = backTopLeft * worldRot; - backTopRight = backTopRight * worldRot; - - - frontTopLeft += offset; - frontTopRight += offset; - frontBottomLeft += offset; - frontBottomRight += offset; - - backBottomLeft += offset; - backBottomRight += offset; - backTopLeft += offset; - backTopRight += offset; - - //m_log.InfoFormat("corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); - //m_log.InfoFormat("corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); - //m_log.InfoFormat("corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); - //m_log.InfoFormat("corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); - //m_log.InfoFormat("corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); - //m_log.InfoFormat("corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); - //m_log.InfoFormat("corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); - //m_log.InfoFormat("corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); - - if (frontTopRight.X > maxX) - maxX = frontTopRight.X; - if (frontTopLeft.X > maxX) - maxX = frontTopLeft.X; - if (frontBottomRight.X > maxX) - maxX = frontBottomRight.X; - if (frontBottomLeft.X > maxX) - maxX = frontBottomLeft.X; - - if (backTopRight.X > maxX) - maxX = backTopRight.X; - if (backTopLeft.X > maxX) - maxX = backTopLeft.X; - if (backBottomRight.X > maxX) - maxX = backBottomRight.X; - if (backBottomLeft.X > maxX) - maxX = backBottomLeft.X; - - if (frontTopRight.X < minX) - minX = frontTopRight.X; - if (frontTopLeft.X < minX) - minX = frontTopLeft.X; - if (frontBottomRight.X < minX) - minX = frontBottomRight.X; - if (frontBottomLeft.X < minX) - minX = frontBottomLeft.X; - - if (backTopRight.X < minX) - minX = backTopRight.X; - if (backTopLeft.X < minX) - minX = backTopLeft.X; - if (backBottomRight.X < minX) - minX = backBottomRight.X; - if (backBottomLeft.X < minX) - minX = backBottomLeft.X; - - // - if (frontTopRight.Y > maxY) - maxY = frontTopRight.Y; - if (frontTopLeft.Y > maxY) - maxY = frontTopLeft.Y; - if (frontBottomRight.Y > maxY) - maxY = frontBottomRight.Y; - if (frontBottomLeft.Y > maxY) - maxY = frontBottomLeft.Y; - - if (backTopRight.Y > maxY) - maxY = backTopRight.Y; - if (backTopLeft.Y > maxY) - maxY = backTopLeft.Y; - if (backBottomRight.Y > maxY) - maxY = backBottomRight.Y; - if (backBottomLeft.Y > maxY) - maxY = backBottomLeft.Y; - - if (frontTopRight.Y < minY) - minY = frontTopRight.Y; - if (frontTopLeft.Y < minY) - minY = frontTopLeft.Y; - if (frontBottomRight.Y < minY) - minY = frontBottomRight.Y; - if (frontBottomLeft.Y < minY) - minY = frontBottomLeft.Y; - - if (backTopRight.Y < minY) - minY = backTopRight.Y; - if (backTopLeft.Y < minY) - minY = backTopLeft.Y; - if (backBottomRight.Y < minY) - minY = backBottomRight.Y; - if (backBottomLeft.Y < minY) - minY = backBottomLeft.Y; - - // - if (frontTopRight.Z > maxZ) - maxZ = frontTopRight.Z; - if (frontTopLeft.Z > maxZ) - maxZ = frontTopLeft.Z; - if (frontBottomRight.Z > maxZ) - maxZ = frontBottomRight.Z; - if (frontBottomLeft.Z > maxZ) - maxZ = frontBottomLeft.Z; - - if (backTopRight.Z > maxZ) - maxZ = backTopRight.Z; - if (backTopLeft.Z > maxZ) - maxZ = backTopLeft.Z; - if (backBottomRight.Z > maxZ) - maxZ = backBottomRight.Z; - if (backBottomLeft.Z > maxZ) - maxZ = backBottomLeft.Z; - - if (frontTopRight.Z < minZ) - minZ = frontTopRight.Z; - if (frontTopLeft.Z < minZ) - minZ = frontTopLeft.Z; - if (frontBottomRight.Z < minZ) - minZ = frontBottomRight.Z; - if (frontBottomLeft.Z < minZ) - minZ = frontBottomLeft.Z; - - if (backTopRight.Z < minZ) - minZ = backTopRight.Z; - if (backTopLeft.Z < minZ) - minZ = backTopLeft.Z; - if (backBottomRight.Z < minZ) - minZ = backBottomRight.Z; - if (backBottomLeft.Z < minZ) - minZ = backBottomLeft.Z; - } + Vector3 worldPos = part.GetWorldPosition(); + Vector3 offset = worldPos - AbsolutePosition; + Quaternion worldRot; + if (part.ParentID == 0) + worldRot = part.RotationOffset; + else + worldRot = part.GetWorldRotation(); + + Vector3 frontTopLeft; + Vector3 frontTopRight; + Vector3 frontBottomLeft; + Vector3 frontBottomRight; + + Vector3 backTopLeft; + Vector3 backTopRight; + Vector3 backBottomLeft; + Vector3 backBottomRight; + + Vector3 orig = Vector3.Zero; + + frontTopLeft.X = orig.X - (part.Scale.X / 2); + frontTopLeft.Y = orig.Y - (part.Scale.Y / 2); + frontTopLeft.Z = orig.Z + (part.Scale.Z / 2); + + frontTopRight.X = orig.X - (part.Scale.X / 2); + frontTopRight.Y = orig.Y + (part.Scale.Y / 2); + frontTopRight.Z = orig.Z + (part.Scale.Z / 2); + + frontBottomLeft.X = orig.X - (part.Scale.X / 2); + frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2); + frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2); + + frontBottomRight.X = orig.X - (part.Scale.X / 2); + frontBottomRight.Y = orig.Y + (part.Scale.Y / 2); + frontBottomRight.Z = orig.Z - (part.Scale.Z / 2); + + backTopLeft.X = orig.X + (part.Scale.X / 2); + backTopLeft.Y = orig.Y - (part.Scale.Y / 2); + backTopLeft.Z = orig.Z + (part.Scale.Z / 2); + + backTopRight.X = orig.X + (part.Scale.X / 2); + backTopRight.Y = orig.Y + (part.Scale.Y / 2); + backTopRight.Z = orig.Z + (part.Scale.Z / 2); + + backBottomLeft.X = orig.X + (part.Scale.X / 2); + backBottomLeft.Y = orig.Y - (part.Scale.Y / 2); + backBottomLeft.Z = orig.Z - (part.Scale.Z / 2); + + backBottomRight.X = orig.X + (part.Scale.X / 2); + backBottomRight.Y = orig.Y + (part.Scale.Y / 2); + backBottomRight.Z = orig.Z - (part.Scale.Z / 2); + + frontTopLeft = frontTopLeft * worldRot; + frontTopRight = frontTopRight * worldRot; + frontBottomLeft = frontBottomLeft * worldRot; + frontBottomRight = frontBottomRight * worldRot; + + backBottomLeft = backBottomLeft * worldRot; + backBottomRight = backBottomRight * worldRot; + backTopLeft = backTopLeft * worldRot; + backTopRight = backTopRight * worldRot; + + + frontTopLeft += offset; + frontTopRight += offset; + frontBottomLeft += offset; + frontBottomRight += offset; + + backBottomLeft += offset; + backBottomRight += offset; + backTopLeft += offset; + backTopRight += offset; + + if (frontTopRight.X > maxX) + maxX = frontTopRight.X; + if (frontTopLeft.X > maxX) + maxX = frontTopLeft.X; + if (frontBottomRight.X > maxX) + maxX = frontBottomRight.X; + if (frontBottomLeft.X > maxX) + maxX = frontBottomLeft.X; + + if (backTopRight.X > maxX) + maxX = backTopRight.X; + if (backTopLeft.X > maxX) + maxX = backTopLeft.X; + if (backBottomRight.X > maxX) + maxX = backBottomRight.X; + if (backBottomLeft.X > maxX) + maxX = backBottomLeft.X; + + if (frontTopRight.X < minX) + minX = frontTopRight.X; + if (frontTopLeft.X < minX) + minX = frontTopLeft.X; + if (frontBottomRight.X < minX) + minX = frontBottomRight.X; + if (frontBottomLeft.X < minX) + minX = frontBottomLeft.X; + + if (backTopRight.X < minX) + minX = backTopRight.X; + if (backTopLeft.X < minX) + minX = backTopLeft.X; + if (backBottomRight.X < minX) + minX = backBottomRight.X; + if (backBottomLeft.X < minX) + minX = backBottomLeft.X; + + // + if (frontTopRight.Y > maxY) + maxY = frontTopRight.Y; + if (frontTopLeft.Y > maxY) + maxY = frontTopLeft.Y; + if (frontBottomRight.Y > maxY) + maxY = frontBottomRight.Y; + if (frontBottomLeft.Y > maxY) + maxY = frontBottomLeft.Y; + + if (backTopRight.Y > maxY) + maxY = backTopRight.Y; + if (backTopLeft.Y > maxY) + maxY = backTopLeft.Y; + if (backBottomRight.Y > maxY) + maxY = backBottomRight.Y; + if (backBottomLeft.Y > maxY) + maxY = backBottomLeft.Y; + + if (frontTopRight.Y < minY) + minY = frontTopRight.Y; + if (frontTopLeft.Y < minY) + minY = frontTopLeft.Y; + if (frontBottomRight.Y < minY) + minY = frontBottomRight.Y; + if (frontBottomLeft.Y < minY) + minY = frontBottomLeft.Y; + + if (backTopRight.Y < minY) + minY = backTopRight.Y; + if (backTopLeft.Y < minY) + minY = backTopLeft.Y; + if (backBottomRight.Y < minY) + minY = backBottomRight.Y; + if (backBottomLeft.Y < minY) + minY = backBottomLeft.Y; + + // + if (frontTopRight.Z > maxZ) + maxZ = frontTopRight.Z; + if (frontTopLeft.Z > maxZ) + maxZ = frontTopLeft.Z; + if (frontBottomRight.Z > maxZ) + maxZ = frontBottomRight.Z; + if (frontBottomLeft.Z > maxZ) + maxZ = frontBottomLeft.Z; + + if (backTopRight.Z > maxZ) + maxZ = backTopRight.Z; + if (backTopLeft.Z > maxZ) + maxZ = backTopLeft.Z; + if (backBottomRight.Z > maxZ) + maxZ = backBottomRight.Z; + if (backBottomLeft.Z > maxZ) + maxZ = backBottomLeft.Z; + + if (frontTopRight.Z < minZ) + minZ = frontTopRight.Z; + if (frontTopLeft.Z < minZ) + minZ = frontTopLeft.Z; + if (frontBottomRight.Z < minZ) + minZ = frontBottomRight.Z; + if (frontBottomLeft.Z < minZ) + minZ = frontBottomLeft.Z; + + if (backTopRight.Z < minZ) + minZ = backTopRight.Z; + if (backTopLeft.Z < minZ) + minZ = backTopLeft.Z; + if (backBottomRight.Z < minZ) + minZ = backBottomRight.Z; + if (backBottomLeft.Z < minZ) + minZ = backBottomLeft.Z; } } @@ -949,17 +878,12 @@ namespace OpenSim.Region.Framework.Scenes XmlDocument doc = new XmlDocument(); Dictionary states = new Dictionary(); - // Capture script state while holding the lock - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - Dictionary pstates = part.Inventory.GetScriptStates(); - foreach (UUID itemid in pstates.Keys) - { - states.Add(itemid, pstates[itemid]); - } - } + Dictionary pstates = parts[i].Inventory.GetScriptStates(); + foreach (KeyValuePair kvp in pstates) + states.Add(kvp.Key, kvp.Value); } if (states.Count > 0) @@ -1005,15 +929,10 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = detachedpos; m_rootPart.AttachedAvatar = UUID.Zero; - - //Anakin Lohner bug #3839 - lock (m_parts) - { - foreach (SceneObjectPart p in m_parts.Values) - { - p.AttachedAvatar = UUID.Zero; - } - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].AttachedAvatar = UUID.Zero; m_rootPart.SetParentLocalId(0); SetAttachmentPoint((byte)0); @@ -1038,15 +957,10 @@ namespace OpenSim.Region.Framework.Scenes } m_rootPart.AttachedAvatar = UUID.Zero; - - //Anakin Lohner bug #3839 - lock (m_parts) - { - foreach (SceneObjectPart p in m_parts.Values) - { - p.AttachedAvatar = UUID.Zero; - } - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].AttachedAvatar = UUID.Zero; m_rootPart.SetParentLocalId(0); //m_rootPart.SetAttachmentPoint((byte)0); @@ -1069,13 +983,9 @@ namespace OpenSim.Region.Framework.Scenes public override void UpdateMovement() { - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.UpdateMovement(); - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].UpdateMovement(); } public ushort GetTimeDilation() @@ -1108,8 +1018,7 @@ namespace OpenSim.Region.Framework.Scenes part.ParentID = 0; part.LinkNum = 0; - lock (m_parts) - m_parts.Add(m_rootPart.UUID, m_rootPart); + m_parts.Add(m_rootPart.UUID, m_rootPart); } /// @@ -1118,16 +1027,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddPart(SceneObjectPart part) { - lock (m_parts) - { - part.SetParent(this); - m_parts.Add(part.UUID, part); - - part.LinkNum = m_parts.Count; - - if (part.LinkNum == 2 && RootPart != null) - RootPart.LinkNum = 1; - } + part.SetParent(this); + part.LinkNum = m_parts.Add(part.UUID, part); + if (part.LinkNum == 2 && RootPart != null) + RootPart.LinkNum = 1; } /// @@ -1135,28 +1038,20 @@ namespace OpenSim.Region.Framework.Scenes /// private void UpdateParentIDs() { - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part.UUID != m_rootPart.UUID) - { - part.ParentID = m_rootPart.LocalId; - } - } + SceneObjectPart part = parts[i]; + if (part.UUID != m_rootPart.UUID) + part.ParentID = m_rootPart.LocalId; } } public void RegenerateFullIDs() { - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.UUID = UUID.Random(); - - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].UUID = UUID.Random(); } // helper provided for parts. @@ -1189,7 +1084,7 @@ namespace OpenSim.Region.Framework.Scenes // teravus: AbsolutePosition is NOT a normal property! // the code in the getter of AbsolutePosition is significantly different then the code in the setter! - + // jhurliman: Then why is it a property instead of two methods? } public UUID GetPartsFullID(uint localID) @@ -1237,19 +1132,15 @@ namespace OpenSim.Region.Framework.Scenes /// If true then deletion is not broadcast to clients public void DeleteGroupFromScene(bool silent) { - List parts; - - lock (m_parts) - parts = m_parts.Values.ToList(); - - foreach (SceneObjectPart part in parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { + SceneObjectPart part = parts[i]; + Scene.ForEachScenePresence(delegate(ScenePresence avatar) { if (avatar.ParentID == LocalId) - { avatar.StandUp(); - } if (!silent) { @@ -1283,16 +1174,15 @@ namespace OpenSim.Region.Framework.Scenes scriptEvents aggregateScriptEvents = 0; - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part == null) - continue; - if (part != RootPart) - part.Flags = objectflagupdate; - aggregateScriptEvents |= part.AggregateScriptEvents; - } + SceneObjectPart part = parts[i]; + if (part == null) + continue; + if (part != RootPart) + part.Flags = objectflagupdate; + aggregateScriptEvents |= part.AggregateScriptEvents; } m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); @@ -1335,26 +1225,22 @@ namespace OpenSim.Region.Framework.Scenes /// public void ApplyPhysics(bool m_physicalPrim) { - lock (m_parts) + // Apply physics to the root prim + m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); + + // Apply physics to child prims + SceneObjectPart[] parts = m_parts.GetArray(); + if (parts.Length > 1) { - if (m_parts.Count > 1) - { - m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); - foreach (SceneObjectPart part in m_parts.Values) - { - if (part.LocalId != m_rootPart.LocalId) - { - part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); - } - } - - // Hack to get the physics scene geometries in the right spot - ResetChildPrimPhysicsPositions(); - } - else + for (int i = 0; i < parts.Length; i++) { - m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); + SceneObjectPart part = parts[i]; + if (part.LocalId != m_rootPart.LocalId) + part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); } + + // Hack to get the physics scene geometries in the right spot + ResetChildPrimPhysicsPositions(); } } @@ -1365,13 +1251,9 @@ namespace OpenSim.Region.Framework.Scenes public void ForEachPart(Action whatToDo) { - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - whatToDo(part); - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + whatToDo(parts[i]); } #region Events @@ -1476,14 +1358,12 @@ namespace OpenSim.Region.Framework.Scenes RootPart.SendFullUpdate( remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part != RootPart) - part.SendFullUpdate( - remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); - } + SceneObjectPart part = parts[i]; + if (part != RootPart) + part.SendFullUpdate(remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); } } @@ -1498,7 +1378,7 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); dupe.m_isBackedUp = false; - dupe.m_parts = new Dictionary(); + dupe.m_parts.Clear(); // Warning, The following code related to previousAttachmentStatus is needed so that clones of // attachments do not bordercross while they're being duplicated. This is hacktastic! @@ -1527,12 +1407,7 @@ namespace OpenSim.Region.Framework.Scenes if (userExposed) dupe.m_rootPart.TrimPermissions(); - List partList; - - lock (m_parts) - { - partList = new List(m_parts.Values); - } + List partList = new List(m_parts.GetArray()); partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) { @@ -1837,17 +1712,10 @@ namespace OpenSim.Region.Framework.Scenes /// public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) { - SceneObjectPart newPart = null; - - lock (m_parts) - { - newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); - newPart.SetParent(this); - m_parts.Add(newPart.UUID, newPart); - } + SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); + AddPart(newPart); SetPartAsNonRoot(newPart); - return newPart; } @@ -1859,9 +1727,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void ResetIDs() { - lock (m_parts) + lock (m_parts.SyncRoot) { - List partsList = new List(m_parts.Values); + List partsList = new List(m_parts.GetArray()); m_parts.Clear(); foreach (SceneObjectPart part in partsList) { @@ -1877,7 +1745,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) { - remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, @@ -1922,12 +1789,10 @@ namespace OpenSim.Region.Framework.Scenes lastPhysGroupRot = GroupRotation; } - List partList = null; - lock (m_parts) - partList = new List(m_parts.Values); - - foreach (SceneObjectPart part in partList) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { + SceneObjectPart part = parts[i]; if (!IsSelected) part.UpdateLookAt(); part.SendScheduledUpdates(); @@ -1940,27 +1805,22 @@ namespace OpenSim.Region.Framework.Scenes RootPart.AddFullUpdateToAvatar(presence); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part != RootPart) - part.AddFullUpdateToAvatar(presence); - } + SceneObjectPart part = parts[i]; + if (part != RootPart) + part.AddFullUpdateToAvatar(presence); } } public void ScheduleTerseUpdateToAvatar(ScenePresence presence) { // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); - - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.AddTerseUpdateToAvatar(presence); - } - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].AddTerseUpdateToAvatar(presence); } /// @@ -1974,13 +1834,12 @@ namespace OpenSim.Region.Framework.Scenes checkAtTargets(); RootPart.ScheduleFullUpdate(); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part != RootPart) - part.ScheduleFullUpdate(); - } + SceneObjectPart part = parts[i]; + if (part != RootPart) + part.ScheduleFullUpdate(); } } @@ -1990,14 +1849,10 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleGroupForTerseUpdate() { // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); - - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.ScheduleTerseUpdate(); - } - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].ScheduleTerseUpdate(); } /// @@ -2012,13 +1867,12 @@ namespace OpenSim.Region.Framework.Scenes RootPart.SendFullUpdateToAllClients(); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part != RootPart) - part.SendFullUpdateToAllClients(); - } + SceneObjectPart part = parts[i]; + if (part != RootPart) + part.SendFullUpdateToAllClients(); } } @@ -2051,14 +1905,10 @@ namespace OpenSim.Region.Framework.Scenes { if (IsDeleted) return; - - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - part.SendTerseUpdateToAllClients(); - } - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].SendTerseUpdateToAllClients(); } #endregion @@ -2072,15 +1922,11 @@ namespace OpenSim.Region.Framework.Scenes /// null if no child part with that linknum or child part public SceneObjectPart GetLinkNumPart(int linknum) { - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part.LinkNum == linknum) - { - return part; - } - } + if (parts[i].LinkNum == linknum) + return parts[i]; } return null; @@ -2094,8 +1940,7 @@ namespace OpenSim.Region.Framework.Scenes public SceneObjectPart GetChildPart(UUID primID) { SceneObjectPart childPart; - lock (m_parts) - m_parts.TryGetValue(primID, out childPart); + m_parts.TryGetValue(primID, out childPart); return childPart; } @@ -2106,17 +1951,11 @@ namespace OpenSim.Region.Framework.Scenes /// null if a child part with the local ID was not found public SceneObjectPart GetChildPart(uint localID) { - //m_log.DebugFormat("Entered looking for {0}", localID); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - //m_log.DebugFormat("Found {0}", part.LocalId); - if (part.LocalId == localID) - { - return part; - } - } + if (parts[i].LocalId == localID) + return parts[i]; } return null; @@ -2130,13 +1969,7 @@ namespace OpenSim.Region.Framework.Scenes /// public bool HasChildPrim(UUID primID) { - lock (m_parts) - { - if (m_parts.ContainsKey(primID)) - return true; - } - - return false; + return m_parts.ContainsKey(primID); } /// @@ -2147,17 +1980,11 @@ namespace OpenSim.Region.Framework.Scenes /// public bool HasChildPrim(uint localID) { - //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - //m_log.DebugFormat("Found {0}", part.LocalId); - if (part.LocalId == localID) - { - return true; - } - } + if (parts[i].LocalId == localID) + return true; } return false; @@ -2208,19 +2035,21 @@ namespace OpenSim.Region.Framework.Scenes if (m_rootPart.LinkNum == 0) m_rootPart.LinkNum = 1; - lock (m_parts) + lock (m_parts.SyncRoot) { m_parts.Add(linkPart.UUID, linkPart); // Insert in terms of link numbers, the new links // before the current ones (with the exception of // the root prim. Shuffle the old ones up - foreach (KeyValuePair kvp in m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - if (kvp.Value.LinkNum != 1) + SceneObjectPart part = parts[i]; + if (part.LinkNum != 1) { // Don't update root prim link number - kvp.Value.LinkNum += objectGroup.PrimCount; + part.LinkNum += objectGroup.PrimCount; } } @@ -2232,29 +2061,26 @@ namespace OpenSim.Region.Framework.Scenes //if (linkPart.PhysActor != null) //{ // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); - + //linkPart.PhysActor = null; //} //TODO: rest of parts int linkNum = 3; - foreach (SceneObjectPart part in objectGroup.Children.Values) + SceneObjectPart[] ogParts = objectGroup.Parts; + for (int i = 0; i < ogParts.Length; i++) { + SceneObjectPart part = ogParts[i]; if (part.UUID != objectGroup.m_rootPart.UUID) - { LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); - } part.ClearUndoState(); } } m_scene.UnlinkSceneObject(objectGroup, true); objectGroup.m_isDeleted = true; - - lock (objectGroup.m_parts) - { - objectGroup.m_parts.Clear(); - } + + objectGroup.m_parts.Clear(); // Can't do this yet since backup still makes use of the root part without any synchronization // objectGroup.m_rootPart = null; @@ -2324,20 +2150,24 @@ namespace OpenSim.Region.Framework.Scenes Quaternion worldRot = linkPart.GetWorldRotation(); // Remove the part from this object - lock (m_parts) + lock (m_parts.SyncRoot) { m_parts.Remove(linkPart.UUID); - - if (m_parts.Count == 1 && RootPart != null) //Single prim is left + + SceneObjectPart[] parts = m_parts.GetArray(); + + if (parts.Length == 1 && RootPart != null) { + // Single prim left RootPart.LinkNum = 0; } else { - foreach (SceneObjectPart p in m_parts.Values) + for (int i = 0; i < parts.Length; i++) { - if (p.LinkNum > linkPart.LinkNum) - p.LinkNum--; + SceneObjectPart part = parts[i]; + if (part.LinkNum > linkPart.LinkNum) + part.LinkNum--; } } } @@ -2409,7 +2239,6 @@ namespace OpenSim.Region.Framework.Scenes part.SetParent(this); part.ParentID = m_rootPart.LocalId; - // Caller locks m_parts for us m_parts.Add(part.UUID, part); part.LinkNum = linkNum; @@ -2662,24 +2491,21 @@ namespace OpenSim.Region.Framework.Scenes if (selectionPart != null) { - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) + SceneObjectPart part = parts[i]; + if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || + part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || + part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) { - if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || - part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || - part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) - { - UsePhysics = false; // Reset physics - break; - } - } - - foreach (SceneObjectPart part in m_parts.Values) - { - part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); + UsePhysics = false; // Reset physics + break; } } + + for (int i = 0; i < parts.Length; i++) + parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); } } @@ -2693,18 +2519,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Get the parts of this scene object - /// - /// - public SceneObjectPart[] GetParts() - { - int numParts = Children.Count; - SceneObjectPart[] partArray = new SceneObjectPart[numParts]; - Children.Values.CopyTo(partArray, 0); - return partArray; - } - - /// /// Update the texture entry for this part /// /// @@ -2721,12 +2535,9 @@ namespace OpenSim.Region.Framework.Scenes public void UpdatePermissions(UUID AgentID, byte field, uint localID, uint mask, byte addRemTF) { - List partList = null; - lock (m_parts) - partList = new List(m_parts.Values); - - foreach (SceneObjectPart part in partList) - part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].UpdatePermissions(AgentID, field, localID, mask, addRemTF); HasGroupChanged = true; } @@ -2829,77 +2640,77 @@ namespace OpenSim.Region.Framework.Scenes float y = (scale.Y / part.Scale.Y); float z = (scale.Z / part.Scale.Z); - lock (m_parts) + SceneObjectPart[] parts; + if (x > 1.0f || y > 1.0f || z > 1.0f) { - if (x > 1.0f || y > 1.0f || z > 1.0f) + parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart obPart in m_parts.Values) + SceneObjectPart obPart = parts[i]; + if (obPart.UUID != m_rootPart.UUID) { - if (obPart.UUID != m_rootPart.UUID) - { - obPart.IgnoreUndoUpdate = true; - Vector3 oldSize = new Vector3(obPart.Scale); + obPart.IgnoreUndoUpdate = true; + Vector3 oldSize = new Vector3(obPart.Scale); - float f = 1.0f; - float a = 1.0f; + float f = 1.0f; + float a = 1.0f; - if (part.PhysActor != null && part.PhysActor.IsPhysical) + if (part.PhysActor != null && part.PhysActor.IsPhysical) + { + if (oldSize.X * x > m_scene.m_maxPhys) + { + f = m_scene.m_maxPhys / oldSize.X; + a = f / x; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Y * y > m_scene.m_maxPhys) + { + f = m_scene.m_maxPhys / oldSize.Y; + a = f / y; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Z * z > m_scene.m_maxPhys) + { + f = m_scene.m_maxPhys / oldSize.Z; + a = f / z; + x *= a; + y *= a; + z *= a; + } + } + else + { + if (oldSize.X * x > m_scene.m_maxNonphys) + { + f = m_scene.m_maxNonphys / oldSize.X; + a = f / x; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Y * y > m_scene.m_maxNonphys) { - if (oldSize.X*x > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.X; - a = f / x; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Y*y > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.Y; - a = f / y; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Z*z > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.Z; - a = f / z; - x *= a; - y *= a; - z *= a; - } + f = m_scene.m_maxNonphys / oldSize.Y; + a = f / y; + x *= a; + y *= a; + z *= a; } - else + if (oldSize.Z * z > m_scene.m_maxNonphys) { - if (oldSize.X*x > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.X; - a = f / x; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Y*y > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.Y; - a = f / y; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Z*z > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.Z; - a = f / z; - x *= a; - y *= a; - z *= a; - } + f = m_scene.m_maxNonphys / oldSize.Z; + a = f / z; + x *= a; + y *= a; + z *= a; } - obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); } + obPart.IgnoreUndoUpdate = false; + obPart.StoreUndoState(); } } } @@ -2910,27 +2721,26 @@ namespace OpenSim.Region.Framework.Scenes prevScale.Z *= z; part.Resize(prevScale); - lock (m_parts) + parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart obPart in m_parts.Values) + SceneObjectPart obPart = parts[i]; + obPart.IgnoreUndoUpdate = true; + if (obPart.UUID != m_rootPart.UUID) { - obPart.IgnoreUndoUpdate = true; - if (obPart.UUID != m_rootPart.UUID) - { - Vector3 currentpos = new Vector3(obPart.OffsetPosition); - currentpos.X *= x; - currentpos.Y *= y; - currentpos.Z *= z; - Vector3 newSize = new Vector3(obPart.Scale); - newSize.X *= x; - newSize.Y *= y; - newSize.Z *= z; - obPart.Resize(newSize); - obPart.UpdateOffSet(currentpos); - } - obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); + Vector3 currentpos = new Vector3(obPart.OffsetPosition); + currentpos.X *= x; + currentpos.Y *= y; + currentpos.Z *= z; + Vector3 newSize = new Vector3(obPart.Scale); + newSize.X *= x; + newSize.Y *= y; + newSize.Z *= z; + obPart.Resize(newSize); + obPart.UpdateOffSet(currentpos); } + obPart.IgnoreUndoUpdate = false; + obPart.StoreUndoState(); } if (part.PhysActor != null) @@ -2956,10 +2766,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupPosition(Vector3 pos) { - foreach (SceneObjectPart part in Children.Values) - { - part.StoreUndoState(); - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].StoreUndoState(); + if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) { if (IsAttachment) @@ -2994,10 +2804,11 @@ namespace OpenSim.Region.Framework.Scenes public void UpdateSinglePosition(Vector3 pos, uint localID) { SceneObjectPart part = GetChildPart(localID); - foreach (SceneObjectPart parts in Children.Values) - { - parts.StoreUndoState(); - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].StoreUndoState(); + if (part != null) { if (part.UUID == m_rootPart.UUID) @@ -3019,10 +2830,10 @@ namespace OpenSim.Region.Framework.Scenes /// private void UpdateRootPosition(Vector3 pos) { - foreach (SceneObjectPart part in Children.Values) - { - part.StoreUndoState(); - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].StoreUndoState(); + Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); Vector3 oldPos = new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, @@ -3034,15 +2845,12 @@ namespace OpenSim.Region.Framework.Scenes axDiff *= Quaternion.Inverse(partRotation); diff = axDiff; - lock (m_parts) + parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart obPart in m_parts.Values) - { - if (obPart.UUID != m_rootPart.UUID) - { - obPart.OffsetPosition = obPart.OffsetPosition + diff; - } - } + SceneObjectPart obPart = parts[i]; + if (obPart.UUID != m_rootPart.UUID) + obPart.OffsetPosition = obPart.OffsetPosition + diff; } AbsolutePosition = newPos; @@ -3066,10 +2874,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupRotationR(Quaternion rot) { - foreach (SceneObjectPart parts in Children.Values) - { - parts.StoreUndoState(); - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].StoreUndoState(); + m_rootPart.UpdateRotation(rot); PhysicsActor actor = m_rootPart.PhysActor; @@ -3090,10 +2898,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) { - foreach (SceneObjectPart parts in Children.Values) - { - parts.StoreUndoState(); - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].StoreUndoState(); + m_rootPart.UpdateRotation(rot); PhysicsActor actor = m_rootPart.PhysActor; @@ -3117,10 +2925,11 @@ namespace OpenSim.Region.Framework.Scenes public void UpdateSingleRotation(Quaternion rot, uint localID) { SceneObjectPart part = GetChildPart(localID); - foreach (SceneObjectPart parts in Children.Values) - { - parts.StoreUndoState(); - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].StoreUndoState(); + if (part != null) { if (part.UUID == m_rootPart.UUID) @@ -3177,33 +2986,35 @@ namespace OpenSim.Region.Framework.Scenes m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); } - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart prim in m_parts.Values) + SceneObjectPart prim = parts[i]; + if (prim.UUID != m_rootPart.UUID) { - if (prim.UUID != m_rootPart.UUID) - { - prim.IgnoreUndoUpdate = true; - Vector3 axPos = prim.OffsetPosition; - axPos *= oldParentRot; - axPos *= Quaternion.Inverse(axRot); - prim.OffsetPosition = axPos; - Quaternion primsRot = prim.RotationOffset; - Quaternion newRot = primsRot * oldParentRot; - newRot *= Quaternion.Inverse(axRot); - prim.RotationOffset = newRot; - prim.ScheduleTerseUpdate(); - } + prim.IgnoreUndoUpdate = true; + Vector3 axPos = prim.OffsetPosition; + axPos *= oldParentRot; + axPos *= Quaternion.Inverse(axRot); + prim.OffsetPosition = axPos; + Quaternion primsRot = prim.RotationOffset; + Quaternion newRot = primsRot * oldParentRot; + newRot *= Quaternion.Inverse(axRot); + prim.RotationOffset = newRot; + prim.ScheduleTerseUpdate(); } } - foreach (SceneObjectPart childpart in Children.Values) + + for (int i = 0; i < parts.Length; i++) { + SceneObjectPart childpart = parts[i]; if (childpart != m_rootPart) { childpart.IgnoreUndoUpdate = false; childpart.StoreUndoState(); } } + m_rootPart.ScheduleTerseUpdate(); } @@ -3324,17 +3135,10 @@ namespace OpenSim.Region.Framework.Scenes if (atTargets.Count > 0) { - uint[] localids = new uint[0]; - lock (m_parts) - { - localids = new uint[m_parts.Count]; - int cntr = 0; - foreach (SceneObjectPart part in m_parts.Values) - { - localids[cntr] = part.LocalId; - cntr++; - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + uint[] localids = new uint[parts.Length]; + for (int i = 0; i < parts.Length; i++) + localids[i] = parts[i].LocalId; for (int ctr = 0; ctr < localids.Length; ctr++) { @@ -3352,17 +3156,10 @@ namespace OpenSim.Region.Framework.Scenes if (m_scriptListens_notAtTarget && !at_target) { //trigger not_at_target - uint[] localids = new uint[0]; - lock (m_parts) - { - localids = new uint[m_parts.Count]; - int cntr = 0; - foreach (SceneObjectPart part in m_parts.Values) - { - localids[cntr] = part.LocalId; - cntr++; - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + uint[] localids = new uint[parts.Length]; + for (int i = 0; i < parts.Length; i++) + localids[i] = parts[i].LocalId; for (int ctr = 0; ctr < localids.Length; ctr++) { @@ -3403,17 +3200,10 @@ namespace OpenSim.Region.Framework.Scenes if (atRotTargets.Count > 0) { - uint[] localids = new uint[0]; - lock (m_parts) - { - localids = new uint[m_parts.Count]; - int cntr = 0; - foreach (SceneObjectPart part in m_parts.Values) - { - localids[cntr] = part.LocalId; - cntr++; - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + uint[] localids = new uint[parts.Length]; + for (int i = 0; i < parts.Length; i++) + localids[i] = parts[i].LocalId; for (int ctr = 0; ctr < localids.Length; ctr++) { @@ -3431,17 +3221,10 @@ namespace OpenSim.Region.Framework.Scenes if (m_scriptListens_notAtRotTarget && !at_Rottarget) { //trigger not_at_target - uint[] localids = new uint[0]; - lock (m_parts) - { - localids = new uint[m_parts.Count]; - int cntr = 0; - foreach (SceneObjectPart part in m_parts.Values) - { - localids[cntr] = part.LocalId; - cntr++; - } - } + SceneObjectPart[] parts = m_parts.GetArray(); + uint[] localids = new uint[parts.Length]; + for (int i = 0; i < parts.Length; i++) + localids[i] = parts[i].LocalId; for (int ctr = 0; ctr < localids.Length; ctr++) { @@ -3455,40 +3238,36 @@ namespace OpenSim.Region.Framework.Scenes public float GetMass() { float retmass = 0f; - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - { - retmass += part.GetMass(); - } - } + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + retmass += parts[i].GetMass(); + return retmass; } public void CheckSculptAndLoad() { - lock (m_parts) + if (IsDeleted) + return; + if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) + return; + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - if (!IsDeleted) + SceneObjectPart part = parts[i]; + if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero) { - if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0) + // check if a previously decoded sculpt map has been cached + if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString()))) { - foreach (SceneObjectPart part in m_parts.Values) - { - if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero) - { - // check if a previously decoded sculpt map has been cached - if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString()))) - { - part.SculptTextureCallback(part.Shape.SculptTexture, null); - } - else - { - m_scene.AssetService.Get( - part.Shape.SculptTexture.ToString(), part, AssetReceived); - } - } - } + part.SculptTextureCallback(part.Shape.SculptTexture, null); + } + else + { + m_scene.AssetService.Get( + part.Shape.SculptTexture.ToString(), part, AssetReceived); } } } @@ -3512,15 +3291,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetGroup(UUID GroupID, IClientAPI client) { - lock (m_parts) + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in m_parts.Values) - { - part.SetGroup(GroupID, client); - part.Inventory.ChangeInventoryGroup(GroupID); - } - - HasGroupChanged = true; + SceneObjectPart part = parts[i]; + part.SetGroup(GroupID, client); + part.Inventory.ChangeInventoryGroup(GroupID); } // 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 public void TriggerScriptChangedEvent(Changed val) { - foreach (SceneObjectPart part in Children.Values) - { - part.TriggerScriptChangedEvent(val); - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].TriggerScriptChangedEvent(val); } public override string ToString() @@ -3543,11 +3318,9 @@ namespace OpenSim.Region.Framework.Scenes public void SetAttachmentPoint(byte point) { - lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - part.SetAttachmentPoint(point); - } + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].SetAttachmentPoint(point); } #region ISceneObject -- cgit v1.1