aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs152
1 files changed, 93 insertions, 59 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 9b66fad..5a586d4 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -360,7 +360,7 @@ namespace OpenSim.Region.Framework.Scenes
360 /// </summary> 360 /// </summary>
361 public int PrimCount 361 public int PrimCount
362 { 362 {
363 get { return m_parts.Count; } 363 get { lock (m_parts) { return m_parts.Count; } }
364 } 364 }
365 365
366 protected Quaternion m_rotation = Quaternion.Identity; 366 protected Quaternion m_rotation = Quaternion.Identity;
@@ -398,6 +398,9 @@ namespace OpenSim.Region.Framework.Scenes
398 398
399 /// <value> 399 /// <value>
400 /// The parts of this scene object group. You must lock this property before using it. 400 /// The parts of this scene object group. You must lock this property before using it.
401 /// If you're doing anything other than reading values, please take a copy of the values rather than locking
402 /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock
403 /// If you want to know the number of children, consider using the PrimCount property instead
401 /// </value> 404 /// </value>
402 public Dictionary<UUID, SceneObjectPart> Children 405 public Dictionary<UUID, SceneObjectPart> Children
403 { 406 {
@@ -521,7 +524,16 @@ namespace OpenSim.Region.Framework.Scenes
521 public override UUID UUID 524 public override UUID UUID
522 { 525 {
523 get { return m_rootPart.UUID; } 526 get { return m_rootPart.UUID; }
524 set { m_rootPart.UUID = value; } 527 set
528 {
529 m_rootPart.UUID = value;
530
531 lock (m_parts)
532 {
533 m_parts.Remove(m_rootPart.UUID);
534 m_parts.Add(m_rootPart.UUID, m_rootPart);
535 }
536 }
525 } 537 }
526 538
527 public UUID OwnerID 539 public UUID OwnerID
@@ -742,21 +754,23 @@ namespace OpenSim.Region.Framework.Scenes
742 if (m_rootPart.LocalId == 0) 754 if (m_rootPart.LocalId == 0)
743 m_rootPart.LocalId = m_scene.AllocateLocalId(); 755 m_rootPart.LocalId = m_scene.AllocateLocalId();
744 756
745 // No need to lock here since the object isn't yet in a scene 757 lock (m_parts)
746 foreach (SceneObjectPart part in m_parts.Values)
747 { 758 {
748 if (Object.ReferenceEquals(part, m_rootPart)) 759 foreach (SceneObjectPart part in m_parts.Values)
749 {
750 continue;
751 }
752
753 if (part.LocalId == 0)
754 { 760 {
755 part.LocalId = m_scene.AllocateLocalId(); 761 if (Object.ReferenceEquals(part, m_rootPart))
762 {
763 continue;
764 }
765
766 if (part.LocalId == 0)
767 {
768 part.LocalId = m_scene.AllocateLocalId();
769 }
770
771 part.ParentID = m_rootPart.LocalId;
772 //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);
756 } 773 }
757
758 part.ParentID = m_rootPart.LocalId;
759 //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);
760 } 774 }
761 775
762 ApplyPhysics(m_scene.m_physicalPrim); 776 ApplyPhysics(m_scene.m_physicalPrim);
@@ -1238,9 +1252,12 @@ namespace OpenSim.Region.Framework.Scenes
1238 m_rootPart.AttachedAvatar = agentID; 1252 m_rootPart.AttachedAvatar = agentID;
1239 1253
1240 //Anakin Lohner bug #3839 1254 //Anakin Lohner bug #3839
1241 foreach (SceneObjectPart p in m_parts.Values) 1255 lock (m_parts)
1242 { 1256 {
1243 p.AttachedAvatar = agentID; 1257 foreach (SceneObjectPart p in m_parts.Values)
1258 {
1259 p.AttachedAvatar = agentID;
1260 }
1244 } 1261 }
1245 1262
1246 if (m_rootPart.PhysActor != null) 1263 if (m_rootPart.PhysActor != null)
@@ -1308,10 +1325,14 @@ namespace OpenSim.Region.Framework.Scenes
1308 1325
1309 AbsolutePosition = detachedpos; 1326 AbsolutePosition = detachedpos;
1310 m_rootPart.AttachedAvatar = UUID.Zero; 1327 m_rootPart.AttachedAvatar = UUID.Zero;
1311 //Anakin Lohner bug #3839 1328
1312 foreach (SceneObjectPart p in m_parts.Values) 1329 //Anakin Lohner bug #3839
1330 lock (m_parts)
1313 { 1331 {
1314 p.AttachedAvatar = UUID.Zero; 1332 foreach (SceneObjectPart p in m_parts.Values)
1333 {
1334 p.AttachedAvatar = UUID.Zero;
1335 }
1315 } 1336 }
1316 1337
1317 m_rootPart.SetParentLocalId(0); 1338 m_rootPart.SetParentLocalId(0);
@@ -1337,10 +1358,14 @@ namespace OpenSim.Region.Framework.Scenes
1337 } 1358 }
1338 1359
1339 m_rootPart.AttachedAvatar = UUID.Zero; 1360 m_rootPart.AttachedAvatar = UUID.Zero;
1361
1340 //Anakin Lohner bug #3839 1362 //Anakin Lohner bug #3839
1341 foreach (SceneObjectPart p in m_parts.Values) 1363 lock (m_parts)
1342 { 1364 {
1343 p.AttachedAvatar = UUID.Zero; 1365 foreach (SceneObjectPart p in m_parts.Values)
1366 {
1367 p.AttachedAvatar = UUID.Zero;
1368 }
1344 } 1369 }
1345 1370
1346 m_rootPart.SetParentLocalId(0); 1371 m_rootPart.SetParentLocalId(0);
@@ -1406,9 +1431,8 @@ namespace OpenSim.Region.Framework.Scenes
1406 part.ParentID = 0; 1431 part.ParentID = 0;
1407 part.LinkNum = 0; 1432 part.LinkNum = 0;
1408 1433
1409 // No locking required since the SOG should not be in the scene yet - one can't change root parts after 1434 lock (m_parts)
1410 // the scene object has been attached to the scene 1435 m_parts.Add(m_rootPart.UUID, m_rootPart);
1411 m_parts.Add(m_rootPart.UUID, m_rootPart);
1412 } 1436 }
1413 1437
1414 /// <summary> 1438 /// <summary>
@@ -1928,14 +1952,14 @@ namespace OpenSim.Region.Framework.Scenes
1928 } 1952 }
1929 1953
1930 /// <summary> 1954 /// <summary>
1931 /// 1955 /// Copy the given part as the root part of this scene object.
1932 /// </summary> 1956 /// </summary>
1933 /// <param name="part"></param> 1957 /// <param name="part"></param>
1934 /// <param name="cAgentID"></param> 1958 /// <param name="cAgentID"></param>
1935 /// <param name="cGroupID"></param> 1959 /// <param name="cGroupID"></param>
1936 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 1960 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1937 { 1961 {
1938 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed)); 1962 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1939 } 1963 }
1940 1964
1941 public void ScriptSetPhysicsStatus(bool UsePhysics) 1965 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -2234,14 +2258,15 @@ namespace OpenSim.Region.Framework.Scenes
2234 /// </summary> 2258 /// </summary>
2235 public void ResetIDs() 2259 public void ResetIDs()
2236 { 2260 {
2237 // As this is only ever called for prims which are not currently part of the scene (and hence 2261 lock (m_parts)
2238 // not accessible by clients), there should be no need to lock
2239 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
2240 m_parts.Clear();
2241 foreach (SceneObjectPart part in partsList)
2242 { 2262 {
2243 part.ResetIDs(part.LinkNum); // Don't change link nums 2263 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
2244 m_parts.Add(part.UUID, part); 2264 m_parts.Clear();
2265 foreach (SceneObjectPart part in partsList)
2266 {
2267 part.ResetIDs(part.LinkNum); // Don't change link nums
2268 m_parts.Add(part.UUID, part);
2269 }
2245 } 2270 }
2246 } 2271 }
2247 2272
@@ -2283,29 +2308,29 @@ namespace OpenSim.Region.Framework.Scenes
2283 // return; 2308 // return;
2284 2309
2285 lockPartsForRead(true); 2310 lockPartsForRead(true);
2286 {
2287 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
2288 2311
2289 if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) 2312 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
2290 {
2291 m_rootPart.UpdateFlag = 1;
2292 lastPhysGroupPos = AbsolutePosition;
2293 }
2294 2313
2295 if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) 2314 if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f))
2296 { 2315 {
2297 m_rootPart.UpdateFlag = 1; 2316 m_rootPart.UpdateFlag = 1;
2298 lastPhysGroupRot = GroupRotation; 2317 lastPhysGroupPos = AbsolutePosition;
2299 } 2318 }
2300 2319
2301 foreach (SceneObjectPart part in m_parts.Values) 2320 if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f))
2302 { 2321 {
2303 if (!IsSelected) 2322 m_rootPart.UpdateFlag = 1;
2304 part.UpdateLookAt(); 2323 lastPhysGroupRot = GroupRotation;
2324 }
2305 2325
2306 part.SendScheduledUpdates(); 2326 List<SceneObjectPart> partList = null;
2307 2327 partList = new List<SceneObjectPart>(m_parts.Values);
2308 } 2328
2329 foreach (SceneObjectPart part in partList)
2330 {
2331 if (!IsSelected)
2332 part.UpdateLookAt();
2333 part.SendScheduledUpdates();
2309 } 2334 }
2310 lockPartsForRead(false); 2335 lockPartsForRead(false);
2311 } 2336 }
@@ -2479,10 +2504,15 @@ namespace OpenSim.Region.Framework.Scenes
2479 public SceneObjectPart GetChildPart(UUID primID) 2504 public SceneObjectPart GetChildPart(UUID primID)
2480 { 2505 {
2481 SceneObjectPart childPart = null; 2506 SceneObjectPart childPart = null;
2482 if (m_parts.ContainsKey(primID)) 2507
2508 lock (m_parts)
2483 { 2509 {
2484 childPart = m_parts[primID]; 2510 if (m_parts.ContainsKey(primID))
2511 {
2512 childPart = m_parts[primID];
2513 }
2485 } 2514 }
2515
2486 return childPart; 2516 return childPart;
2487 } 2517 }
2488 2518
@@ -2519,9 +2549,10 @@ namespace OpenSim.Region.Framework.Scenes
2519 /// <returns></returns> 2549 /// <returns></returns>
2520 public bool HasChildPrim(UUID primID) 2550 public bool HasChildPrim(UUID primID)
2521 { 2551 {
2522 if (m_parts.ContainsKey(primID)) 2552 lock (m_parts)
2523 { 2553 {
2524 return true; 2554 if (m_parts.ContainsKey(primID))
2555 return true;
2525 } 2556 }
2526 2557
2527 return false; 2558 return false;
@@ -3132,9 +3163,12 @@ namespace OpenSim.Region.Framework.Scenes
3132 public void UpdatePermissions(UUID AgentID, byte field, uint localID, 3163 public void UpdatePermissions(UUID AgentID, byte field, uint localID,
3133 uint mask, byte addRemTF) 3164 uint mask, byte addRemTF)
3134 { 3165 {
3135 foreach (SceneObjectPart part in m_parts.Values) 3166 List<SceneObjectPart> partList = null;
3136 part.UpdatePermissions(AgentID, field, localID, mask, 3167 lock (m_parts)
3137 addRemTF); 3168 partList = new List<SceneObjectPart>(m_parts.Values);
3169
3170 foreach (SceneObjectPart part in partList)
3171 part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
3138 3172
3139 HasGroupChanged = true; 3173 HasGroupChanged = true;
3140 } 3174 }