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.cs557
1 files changed, 378 insertions, 179 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index cb87212..eacd219 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -98,6 +98,72 @@ namespace OpenSim.Region.Framework.Scenes
98 private bool m_hasGroupChanged = false; 98 private bool m_hasGroupChanged = false;
99 private long timeFirstChanged; 99 private long timeFirstChanged;
100 private long timeLastChanged; 100 private long timeLastChanged;
101 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
102
103 public void lockPartsForRead(bool locked)
104 {
105 if (locked)
106 {
107 if (m_partsLock.RecursiveReadCount > 0)
108 {
109 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
110 m_partsLock.ExitReadLock();
111 }
112 if (m_partsLock.RecursiveWriteCount > 0)
113 {
114 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
115 m_partsLock.ExitWriteLock();
116 }
117
118 while (!m_partsLock.TryEnterReadLock(60000))
119 {
120 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
121 if (m_partsLock.IsWriteLockHeld)
122 {
123 m_partsLock = new System.Threading.ReaderWriterLockSlim();
124 }
125 }
126 }
127 else
128 {
129 if (m_partsLock.RecursiveReadCount > 0)
130 {
131 m_partsLock.ExitReadLock();
132 }
133 }
134 }
135 public void lockPartsForWrite(bool locked)
136 {
137 if (locked)
138 {
139 if (m_partsLock.RecursiveReadCount > 0)
140 {
141 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
142 m_partsLock.ExitReadLock();
143 }
144 if (m_partsLock.RecursiveWriteCount > 0)
145 {
146 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
147 m_partsLock.ExitWriteLock();
148 }
149
150 while (!m_partsLock.TryEnterWriteLock(60000))
151 {
152 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
153 if (m_partsLock.IsWriteLockHeld)
154 {
155 m_partsLock = new System.Threading.ReaderWriterLockSlim();
156 }
157 }
158 }
159 else
160 {
161 if (m_partsLock.RecursiveWriteCount > 0)
162 {
163 m_partsLock.ExitWriteLock();
164 }
165 }
166 }
101 167
102 public bool HasGroupChanged 168 public bool HasGroupChanged
103 { 169 {
@@ -243,13 +309,16 @@ namespace OpenSim.Region.Framework.Scenes
243 set 309 set
244 { 310 {
245 m_regionHandle = value; 311 m_regionHandle = value;
246 lock (m_parts) 312 lockPartsForRead(true);
247 { 313 {
248 foreach (SceneObjectPart part in m_parts.Values) 314 foreach (SceneObjectPart part in m_parts.Values)
249 { 315 {
316
250 part.RegionHandle = m_regionHandle; 317 part.RegionHandle = m_regionHandle;
318
251 } 319 }
252 } 320 }
321 lockPartsForRead(false);
253 } 322 }
254 } 323 }
255 324
@@ -275,13 +344,16 @@ namespace OpenSim.Region.Framework.Scenes
275 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 344 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
276 } 345 }
277 346
278 lock (m_parts) 347 lockPartsForRead(true);
279 { 348 {
280 foreach (SceneObjectPart part in m_parts.Values) 349 foreach (SceneObjectPart part in m_parts.Values)
281 { 350 {
351
282 part.GroupPosition = val; 352 part.GroupPosition = val;
353
283 } 354 }
284 } 355 }
356 lockPartsForRead(false);
285 357
286 //if (m_rootPart.PhysActor != null) 358 //if (m_rootPart.PhysActor != null)
287 //{ 359 //{
@@ -432,13 +504,16 @@ namespace OpenSim.Region.Framework.Scenes
432 504
433 public void SetFromItemID(UUID AssetId) 505 public void SetFromItemID(UUID AssetId)
434 { 506 {
435 lock (m_parts) 507 lockPartsForRead(true);
436 { 508 {
437 foreach (SceneObjectPart part in m_parts.Values) 509 foreach (SceneObjectPart part in m_parts.Values)
438 { 510 {
511
439 part.FromItemID = AssetId; 512 part.FromItemID = AssetId;
513
440 } 514 }
441 } 515 }
516 lockPartsForRead(false);
442 } 517 }
443 518
444 public UUID GetFromItemID() 519 public UUID GetFromItemID()
@@ -505,10 +580,11 @@ namespace OpenSim.Region.Framework.Scenes
505 Vector3 maxScale = Vector3.Zero; 580 Vector3 maxScale = Vector3.Zero;
506 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 581 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
507 582
508 lock (m_parts) 583 lockPartsForRead(true);
509 { 584 {
510 foreach (SceneObjectPart part in m_parts.Values) 585 foreach (SceneObjectPart part in m_parts.Values)
511 { 586 {
587
512 Vector3 partscale = part.Scale; 588 Vector3 partscale = part.Scale;
513 Vector3 partoffset = part.OffsetPosition; 589 Vector3 partoffset = part.OffsetPosition;
514 590
@@ -519,8 +595,11 @@ namespace OpenSim.Region.Framework.Scenes
519 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 595 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
520 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 596 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
521 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 597 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
598
522 } 599 }
523 } 600 }
601 lockPartsForRead(false);
602
524 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 603 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
525 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 604 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
526 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 605 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -536,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes
536 615
537 EntityIntersection result = new EntityIntersection(); 616 EntityIntersection result = new EntityIntersection();
538 617
539 lock (m_parts) 618 lockPartsForRead(true);
540 { 619 {
541 foreach (SceneObjectPart part in m_parts.Values) 620 foreach (SceneObjectPart part in m_parts.Values)
542 { 621 {
622
543 // Temporary commented to stop compiler warning 623 // Temporary commented to stop compiler warning
544 //Vector3 partPosition = 624 //Vector3 partPosition =
545 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 625 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -567,8 +647,10 @@ namespace OpenSim.Region.Framework.Scenes
567 result.distance = inter.distance; 647 result.distance = inter.distance;
568 } 648 }
569 } 649 }
650
570 } 651 }
571 } 652 }
653 lockPartsForRead(false);
572 return result; 654 return result;
573 } 655 }
574 656
@@ -581,10 +663,11 @@ namespace OpenSim.Region.Framework.Scenes
581 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 663 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
582 { 664 {
583 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 665 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
584 lock (m_parts) 666 lockPartsForRead(true);
585 { 667 {
586 foreach (SceneObjectPart part in m_parts.Values) 668 foreach (SceneObjectPart part in m_parts.Values)
587 { 669 {
670
588 Vector3 worldPos = part.GetWorldPosition(); 671 Vector3 worldPos = part.GetWorldPosition();
589 Vector3 offset = worldPos - AbsolutePosition; 672 Vector3 offset = worldPos - AbsolutePosition;
590 Quaternion worldRot; 673 Quaternion worldRot;
@@ -643,6 +726,8 @@ namespace OpenSim.Region.Framework.Scenes
643 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 726 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
644 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 727 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
645 728
729
730
646 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 731 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
647 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 732 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
648 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 733 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -814,6 +899,7 @@ namespace OpenSim.Region.Framework.Scenes
814 minZ = backBottomLeft.Z; 899 minZ = backBottomLeft.Z;
815 } 900 }
816 } 901 }
902 lockPartsForRead(false);
817 903
818 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 904 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
819 905
@@ -842,17 +928,20 @@ namespace OpenSim.Region.Framework.Scenes
842 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 928 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
843 929
844 // Capture script state while holding the lock 930 // Capture script state while holding the lock
845 lock (m_parts) 931 lockPartsForRead(true);
846 { 932 {
847 foreach (SceneObjectPart part in m_parts.Values) 933 foreach (SceneObjectPart part in m_parts.Values)
848 { 934 {
935
849 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 936 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
850 foreach (UUID itemid in pstates.Keys) 937 foreach (UUID itemid in pstates.Keys)
851 { 938 {
852 states.Add(itemid, pstates[itemid]); 939 states.Add(itemid, pstates[itemid]);
853 } 940 }
941
854 } 942 }
855 } 943 }
944 lockPartsForRead(false);
856 945
857 if (states.Count > 0) 946 if (states.Count > 0)
858 { 947 {
@@ -1014,13 +1103,16 @@ namespace OpenSim.Region.Framework.Scenes
1014 1103
1015 public override void UpdateMovement() 1104 public override void UpdateMovement()
1016 { 1105 {
1017 lock (m_parts) 1106 lockPartsForRead(true);
1018 { 1107 {
1019 foreach (SceneObjectPart part in m_parts.Values) 1108 foreach (SceneObjectPart part in m_parts.Values)
1020 { 1109 {
1110
1021 part.UpdateMovement(); 1111 part.UpdateMovement();
1112
1022 } 1113 }
1023 } 1114 }
1115 lockPartsForRead(false);
1024 } 1116 }
1025 1117
1026 public ushort GetTimeDilation() 1118 public ushort GetTimeDilation()
@@ -1064,7 +1156,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 /// <param name="part"></param> 1156 /// <param name="part"></param>
1065 public void AddPart(SceneObjectPart part) 1157 public void AddPart(SceneObjectPart part)
1066 { 1158 {
1067 lock (m_parts) 1159 lockPartsForWrite(true);
1068 { 1160 {
1069 part.SetParent(this); 1161 part.SetParent(this);
1070 m_parts.Add(part.UUID, part); 1162 m_parts.Add(part.UUID, part);
@@ -1074,6 +1166,7 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (part.LinkNum == 2 && RootPart != null) 1166 if (part.LinkNum == 2 && RootPart != null)
1075 RootPart.LinkNum = 1; 1167 RootPart.LinkNum = 1;
1076 } 1168 }
1169 lockPartsForWrite(false);
1077 } 1170 }
1078 1171
1079 /// <summary> 1172 /// <summary>
@@ -1081,28 +1174,33 @@ namespace OpenSim.Region.Framework.Scenes
1081 /// </summary> 1174 /// </summary>
1082 private void UpdateParentIDs() 1175 private void UpdateParentIDs()
1083 { 1176 {
1084 lock (m_parts) 1177 lockPartsForRead(true);
1085 { 1178 {
1086 foreach (SceneObjectPart part in m_parts.Values) 1179 foreach (SceneObjectPart part in m_parts.Values)
1087 { 1180 {
1181
1088 if (part.UUID != m_rootPart.UUID) 1182 if (part.UUID != m_rootPart.UUID)
1089 { 1183 {
1090 part.ParentID = m_rootPart.LocalId; 1184 part.ParentID = m_rootPart.LocalId;
1091 } 1185 }
1186
1092 } 1187 }
1093 } 1188 }
1189 lockPartsForRead(false);
1094 } 1190 }
1095 1191
1096 public void RegenerateFullIDs() 1192 public void RegenerateFullIDs()
1097 { 1193 {
1098 lock (m_parts) 1194 lockPartsForRead(true);
1099 { 1195 {
1100 foreach (SceneObjectPart part in m_parts.Values) 1196 foreach (SceneObjectPart part in m_parts.Values)
1101 { 1197 {
1198
1102 part.UUID = UUID.Random(); 1199 part.UUID = UUID.Random();
1103 1200
1104 } 1201 }
1105 } 1202 }
1203 lockPartsForRead(false);
1106 } 1204 }
1107 1205
1108 // helper provided for parts. 1206 // helper provided for parts.
@@ -1183,29 +1281,33 @@ namespace OpenSim.Region.Framework.Scenes
1183 1281
1184 DetachFromBackup(); 1282 DetachFromBackup();
1185 1283
1186 lock (m_parts) 1284 lockPartsForRead(true);
1285 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1286 lockPartsForRead(false);
1287
1288 foreach (SceneObjectPart part in values)
1187 { 1289 {
1188 foreach (SceneObjectPart part in m_parts.Values)
1189 {
1190// part.Inventory.RemoveScriptInstances(); 1290// part.Inventory.RemoveScriptInstances();
1191 1291
1192 ScenePresence[] avatars = Scene.GetScenePresences(); 1292 ScenePresence[] avatars = Scene.GetScenePresences();
1193 for (int i = 0; i < avatars.Length; i++) 1293 for (int i = 0; i < avatars.Length; i++)
1294 {
1295 if (avatars[i].ParentID == LocalId)
1194 { 1296 {
1195 if (avatars[i].ParentID == LocalId) 1297 avatars[i].StandUp();
1196 { 1298 }
1197 avatars[i].StandUp();
1198 }
1199 1299
1200 if (!silent) 1300 if (!silent)
1201 { 1301 {
1202 part.UpdateFlag = 0; 1302 part.UpdateFlag = 0;
1203 if (part == m_rootPart) 1303 if (part == m_rootPart)
1204 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1304 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1205 }
1206 } 1305 }
1207 } 1306 }
1307
1208 } 1308 }
1309
1310
1209 } 1311 }
1210 1312
1211 public void AddScriptLPS(int count) 1313 public void AddScriptLPS(int count)
@@ -1230,17 +1332,20 @@ namespace OpenSim.Region.Framework.Scenes
1230 1332
1231 scriptEvents aggregateScriptEvents=0; 1333 scriptEvents aggregateScriptEvents=0;
1232 1334
1233 lock (m_parts) 1335 lockPartsForRead(true);
1234 { 1336 {
1235 foreach (SceneObjectPart part in m_parts.Values) 1337 foreach (SceneObjectPart part in m_parts.Values)
1236 { 1338 {
1339
1237 if (part == null) 1340 if (part == null)
1238 continue; 1341 continue;
1239 if (part != RootPart) 1342 if (part != RootPart)
1240 part.ObjectFlags = objectflagupdate; 1343 part.ObjectFlags = objectflagupdate;
1241 aggregateScriptEvents |= part.AggregateScriptEvents; 1344 aggregateScriptEvents |= part.AggregateScriptEvents;
1345
1242 } 1346 }
1243 } 1347 }
1348 lockPartsForRead(false);
1244 1349
1245 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1350 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1246 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1351 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1273,42 +1378,52 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <param name="m_physicalPrim"></param> 1378 /// <param name="m_physicalPrim"></param>
1274 public void ApplyPhysics(bool m_physicalPrim) 1379 public void ApplyPhysics(bool m_physicalPrim)
1275 { 1380 {
1276 lock (m_parts) 1381 lockPartsForRead(true);
1382
1383 if (m_parts.Count > 1)
1277 { 1384 {
1278 if (m_parts.Count > 1) 1385 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1386 lockPartsForRead(false);
1387 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1388 foreach (SceneObjectPart part in values)
1279 { 1389 {
1280 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1390
1281 foreach (SceneObjectPart part in m_parts.Values) 1391 if (part.LocalId != m_rootPart.LocalId)
1282 { 1392 {
1283 if (part.LocalId != m_rootPart.LocalId) 1393 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1284 {
1285 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1286 }
1287 } 1394 }
1288 1395
1289 // Hack to get the physics scene geometries in the right spot
1290 ResetChildPrimPhysicsPositions();
1291 }
1292 else
1293 {
1294 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1295 } 1396 }
1397 // Hack to get the physics scene geometries in the right spot
1398 ResetChildPrimPhysicsPositions();
1399 }
1400 else
1401 {
1402 lockPartsForRead(false);
1403 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1296 } 1404 }
1297 } 1405 }
1298 1406
1299 public void SetOwnerId(UUID userId) 1407 public void SetOwnerId(UUID userId)
1300 { 1408 {
1301 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1409 ForEachPart(delegate(SceneObjectPart part)
1410 {
1411
1412 part.OwnerID = userId;
1413
1414 });
1302 } 1415 }
1303 1416
1304 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1417 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1305 { 1418 {
1306 lock (m_parts) 1419 lockPartsForRead(true);
1420 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1421 lockPartsForRead(false);
1422 foreach (SceneObjectPart part in values)
1307 { 1423 {
1308 foreach (SceneObjectPart part in m_parts.Values) 1424
1309 { 1425 whatToDo(part);
1310 whatToDo(part); 1426
1311 }
1312 } 1427 }
1313 } 1428 }
1314 1429
@@ -1407,14 +1522,17 @@ namespace OpenSim.Region.Framework.Scenes
1407 { 1522 {
1408 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1523 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1409 1524
1410 lock (m_parts) 1525 lockPartsForRead(true);
1411 { 1526 {
1412 foreach (SceneObjectPart part in m_parts.Values) 1527 foreach (SceneObjectPart part in m_parts.Values)
1413 { 1528 {
1529
1414 if (part != RootPart) 1530 if (part != RootPart)
1415 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1531 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1532
1416 } 1533 }
1417 } 1534 }
1535 lockPartsForRead(false);
1418 } 1536 }
1419 1537
1420 /// <summary> 1538 /// <summary>
@@ -1509,10 +1627,11 @@ namespace OpenSim.Region.Framework.Scenes
1509 1627
1510 List<SceneObjectPart> partList; 1628 List<SceneObjectPart> partList;
1511 1629
1512 lock (m_parts) 1630 lockPartsForRead(true);
1513 { 1631
1514 partList = new List<SceneObjectPart>(m_parts.Values); 1632 partList = new List<SceneObjectPart>(m_parts.Values);
1515 } 1633
1634 lockPartsForRead(false);
1516 1635
1517 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1636 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1518 { 1637 {
@@ -1735,6 +1854,45 @@ namespace OpenSim.Region.Framework.Scenes
1735 } 1854 }
1736 } 1855 }
1737 1856
1857 public void rotLookAt(Quaternion target, float strength, float damping)
1858 {
1859 SceneObjectPart rootpart = m_rootPart;
1860 if (rootpart != null)
1861 {
1862 if (IsAttachment)
1863 {
1864 /*
1865 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1866 if (avatar != null)
1867 {
1868 Rotate the Av?
1869 } */
1870 }
1871 else
1872 {
1873 if (rootpart.PhysActor != null)
1874 {
1875 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1876 rootpart.PhysActor.APIDStrength = strength;
1877 rootpart.PhysActor.APIDDamping = damping;
1878 rootpart.PhysActor.APIDActive = true;
1879 }
1880 }
1881 }
1882 }
1883 public void stopLookAt()
1884 {
1885 SceneObjectPart rootpart = m_rootPart;
1886 if (rootpart != null)
1887 {
1888 if (rootpart.PhysActor != null)
1889 {
1890 rootpart.PhysActor.APIDActive = false;
1891 }
1892 }
1893
1894 }
1895
1738 /// <summary> 1896 /// <summary>
1739 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1897 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1740 /// </summary> 1898 /// </summary>
@@ -1796,10 +1954,11 @@ namespace OpenSim.Region.Framework.Scenes
1796 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1954 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1797 newPart.SetParent(this); 1955 newPart.SetParent(this);
1798 1956
1799 lock (m_parts) 1957 lockPartsForWrite(true);
1800 { 1958 {
1801 m_parts.Add(newPart.UUID, newPart); 1959 m_parts.Add(newPart.UUID, newPart);
1802 } 1960 }
1961 lockPartsForWrite(false);
1803 1962
1804 SetPartAsNonRoot(newPart); 1963 SetPartAsNonRoot(newPart);
1805 1964
@@ -1862,7 +2021,7 @@ namespace OpenSim.Region.Framework.Scenes
1862 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2021 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1863 // return; 2022 // return;
1864 2023
1865 lock (m_parts) 2024 lockPartsForRead(true);
1866 { 2025 {
1867 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2026 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1868 2027
@@ -1880,34 +2039,43 @@ namespace OpenSim.Region.Framework.Scenes
1880 2039
1881 foreach (SceneObjectPart part in m_parts.Values) 2040 foreach (SceneObjectPart part in m_parts.Values)
1882 { 2041 {
2042
1883 part.SendScheduledUpdates(); 2043 part.SendScheduledUpdates();
2044
1884 } 2045 }
1885 } 2046 }
2047 lockPartsForRead(false);
1886 } 2048 }
1887 2049
1888 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2050 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1889 { 2051 {
1890 RootPart.AddFullUpdateToAvatar(presence); 2052 RootPart.AddFullUpdateToAvatar(presence);
1891 2053
1892 lock (m_parts) 2054 lockPartsForRead(true);
1893 { 2055 {
1894 foreach (SceneObjectPart part in m_parts.Values) 2056 foreach (SceneObjectPart part in m_parts.Values)
1895 { 2057 {
2058
1896 if (part != RootPart) 2059 if (part != RootPart)
1897 part.AddFullUpdateToAvatar(presence); 2060 part.AddFullUpdateToAvatar(presence);
2061
1898 } 2062 }
1899 } 2063 }
2064 lockPartsForRead(false);
1900 } 2065 }
1901 2066
1902 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2067 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1903 { 2068 {
1904 lock (m_parts) 2069 lockPartsForRead(true);
1905 { 2070 {
1906 foreach (SceneObjectPart part in m_parts.Values) 2071 foreach (SceneObjectPart part in m_parts.Values)
1907 { 2072 {
2073
1908 part.AddTerseUpdateToAvatar(presence); 2074 part.AddTerseUpdateToAvatar(presence);
2075
1909 } 2076 }
1910 } 2077 }
2078 lockPartsForRead(false);
1911 } 2079 }
1912 2080
1913 /// <summary> 2081 /// <summary>
@@ -1918,14 +2086,17 @@ namespace OpenSim.Region.Framework.Scenes
1918 checkAtTargets(); 2086 checkAtTargets();
1919 RootPart.ScheduleFullUpdate(); 2087 RootPart.ScheduleFullUpdate();
1920 2088
1921 lock (m_parts) 2089 lockPartsForRead(true);
1922 { 2090 {
1923 foreach (SceneObjectPart part in m_parts.Values) 2091 foreach (SceneObjectPart part in m_parts.Values)
1924 { 2092 {
2093
1925 if (part != RootPart) 2094 if (part != RootPart)
1926 part.ScheduleFullUpdate(); 2095 part.ScheduleFullUpdate();
2096
1927 } 2097 }
1928 } 2098 }
2099 lockPartsForRead(false);
1929 } 2100 }
1930 2101
1931 /// <summary> 2102 /// <summary>
@@ -1933,13 +2104,16 @@ namespace OpenSim.Region.Framework.Scenes
1933 /// </summary> 2104 /// </summary>
1934 public void ScheduleGroupForTerseUpdate() 2105 public void ScheduleGroupForTerseUpdate()
1935 { 2106 {
1936 lock (m_parts) 2107 lockPartsForRead(true);
1937 { 2108 {
1938 foreach (SceneObjectPart part in m_parts.Values) 2109 foreach (SceneObjectPart part in m_parts.Values)
1939 { 2110 {
2111
1940 part.ScheduleTerseUpdate(); 2112 part.ScheduleTerseUpdate();
2113
1941 } 2114 }
1942 } 2115 }
2116 lockPartsForRead(false);
1943 } 2117 }
1944 2118
1945 /// <summary> 2119 /// <summary>
@@ -1952,14 +2126,17 @@ namespace OpenSim.Region.Framework.Scenes
1952 2126
1953 RootPart.SendFullUpdateToAllClients(); 2127 RootPart.SendFullUpdateToAllClients();
1954 2128
1955 lock (m_parts) 2129 lockPartsForRead(true);
1956 { 2130 {
1957 foreach (SceneObjectPart part in m_parts.Values) 2131 foreach (SceneObjectPart part in m_parts.Values)
1958 { 2132 {
2133
1959 if (part != RootPart) 2134 if (part != RootPart)
1960 part.SendFullUpdateToAllClients(); 2135 part.SendFullUpdateToAllClients();
2136
1961 } 2137 }
1962 } 2138 }
2139 lockPartsForRead(false);
1963 } 2140 }
1964 2141
1965 /// <summary> 2142 /// <summary>
@@ -1990,14 +2167,15 @@ namespace OpenSim.Region.Framework.Scenes
1990 { 2167 {
1991 if (IsDeleted) 2168 if (IsDeleted)
1992 return; 2169 return;
1993 2170
1994 lock (m_parts) 2171 lockPartsForRead(true);
1995 { 2172 {
1996 foreach (SceneObjectPart part in m_parts.Values) 2173 foreach (SceneObjectPart part in m_parts.Values)
1997 { 2174 {
1998 part.SendTerseUpdateToAllClients(); 2175 part.SendTerseUpdateToAllClients();
1999 } 2176 }
2000 } 2177 }
2178 lockPartsForRead(false);
2001 } 2179 }
2002 2180
2003 #endregion 2181 #endregion
@@ -2011,16 +2189,18 @@ namespace OpenSim.Region.Framework.Scenes
2011 /// <returns>null if no child part with that linknum or child part</returns> 2189 /// <returns>null if no child part with that linknum or child part</returns>
2012 public SceneObjectPart GetLinkNumPart(int linknum) 2190 public SceneObjectPart GetLinkNumPart(int linknum)
2013 { 2191 {
2014 lock (m_parts) 2192 lockPartsForRead(true);
2015 { 2193 {
2016 foreach (SceneObjectPart part in m_parts.Values) 2194 foreach (SceneObjectPart part in m_parts.Values)
2017 { 2195 {
2018 if (part.LinkNum == linknum) 2196 if (part.LinkNum == linknum)
2019 { 2197 {
2198 lockPartsForRead(false);
2020 return part; 2199 return part;
2021 } 2200 }
2022 } 2201 }
2023 } 2202 }
2203 lockPartsForRead(false);
2024 2204
2025 return null; 2205 return null;
2026 } 2206 }
@@ -2048,17 +2228,19 @@ namespace OpenSim.Region.Framework.Scenes
2048 public SceneObjectPart GetChildPart(uint localID) 2228 public SceneObjectPart GetChildPart(uint localID)
2049 { 2229 {
2050 //m_log.DebugFormat("Entered looking for {0}", localID); 2230 //m_log.DebugFormat("Entered looking for {0}", localID);
2051 lock (m_parts) 2231 lockPartsForRead(true);
2052 { 2232 {
2053 foreach (SceneObjectPart part in m_parts.Values) 2233 foreach (SceneObjectPart part in m_parts.Values)
2054 { 2234 {
2055 //m_log.DebugFormat("Found {0}", part.LocalId); 2235 //m_log.DebugFormat("Found {0}", part.LocalId);
2056 if (part.LocalId == localID) 2236 if (part.LocalId == localID)
2057 { 2237 {
2238 lockPartsForRead(false);
2058 return part; 2239 return part;
2059 } 2240 }
2060 } 2241 }
2061 } 2242 }
2243 lockPartsForRead(false);
2062 2244
2063 return null; 2245 return null;
2064 } 2246 }
@@ -2088,17 +2270,19 @@ namespace OpenSim.Region.Framework.Scenes
2088 public bool HasChildPrim(uint localID) 2270 public bool HasChildPrim(uint localID)
2089 { 2271 {
2090 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2272 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2091 lock (m_parts) 2273 lockPartsForRead(true);
2092 { 2274 {
2093 foreach (SceneObjectPart part in m_parts.Values) 2275 foreach (SceneObjectPart part in m_parts.Values)
2094 { 2276 {
2095 //m_log.DebugFormat("Found {0}", part.LocalId); 2277 //m_log.DebugFormat("Found {0}", part.LocalId);
2096 if (part.LocalId == localID) 2278 if (part.LocalId == localID)
2097 { 2279 {
2280 lockPartsForRead(false);
2098 return true; 2281 return true;
2099 } 2282 }
2100 } 2283 }
2101 } 2284 }
2285 lockPartsForRead(false);
2102 2286
2103 return false; 2287 return false;
2104 } 2288 }
@@ -2148,53 +2332,57 @@ namespace OpenSim.Region.Framework.Scenes
2148 if (m_rootPart.LinkNum == 0) 2332 if (m_rootPart.LinkNum == 0)
2149 m_rootPart.LinkNum = 1; 2333 m_rootPart.LinkNum = 1;
2150 2334
2151 lock (m_parts) 2335 lockPartsForWrite(true);
2152 { 2336
2153 m_parts.Add(linkPart.UUID, linkPart); 2337 m_parts.Add(linkPart.UUID, linkPart);
2338
2339 lockPartsForWrite(false);
2154 2340
2155 // Insert in terms of link numbers, the new links 2341 // Insert in terms of link numbers, the new links
2156 // before the current ones (with the exception of 2342 // before the current ones (with the exception of
2157 // the root prim. Shuffle the old ones up 2343 // the root prim. Shuffle the old ones up
2158 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2344 lockPartsForRead(true);
2345 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2346 {
2347 if (kvp.Value.LinkNum != 1)
2159 { 2348 {
2160 if (kvp.Value.LinkNum != 1) 2349 // Don't update root prim link number
2161 { 2350 kvp.Value.LinkNum += objectGroup.PrimCount;
2162 // Don't update root prim link number
2163 kvp.Value.LinkNum += objectGroup.PrimCount;
2164 }
2165 } 2351 }
2352 }
2353 lockPartsForRead(false);
2166 2354
2167 linkPart.LinkNum = 2; 2355 linkPart.LinkNum = 2;
2168 2356
2169 linkPart.SetParent(this); 2357 linkPart.SetParent(this);
2170 linkPart.AddFlag(PrimFlags.CreateSelected); 2358 linkPart.AddFlag(PrimFlags.CreateSelected);
2171 2359
2172 //if (linkPart.PhysActor != null) 2360 //if (linkPart.PhysActor != null)
2173 //{ 2361 //{
2174 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2362 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2175 2363
2176 //linkPart.PhysActor = null; 2364 //linkPart.PhysActor = null;
2177 //} 2365 //}
2178 2366
2179 //TODO: rest of parts 2367 //TODO: rest of parts
2180 int linkNum = 3; 2368 int linkNum = 3;
2181 foreach (SceneObjectPart part in objectGroup.Children.Values) 2369 foreach (SceneObjectPart part in objectGroup.Children.Values)
2370 {
2371 if (part.UUID != objectGroup.m_rootPart.UUID)
2182 { 2372 {
2183 if (part.UUID != objectGroup.m_rootPart.UUID) 2373 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2184 {
2185 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2186 }
2187 part.ClearUndoState();
2188 } 2374 }
2375 part.ClearUndoState();
2189 } 2376 }
2190 2377
2191 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2378 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2192 objectGroup.m_isDeleted = true; 2379 objectGroup.m_isDeleted = true;
2380
2381 objectGroup.lockPartsForWrite(true);
2193 2382
2194 lock (objectGroup.m_parts) 2383 objectGroup.m_parts.Clear();
2195 { 2384
2196 objectGroup.m_parts.Clear(); 2385 objectGroup.lockPartsForWrite(false);
2197 }
2198 2386
2199 // Can't do this yet since backup still makes use of the root part without any synchronization 2387 // Can't do this yet since backup still makes use of the root part without any synchronization
2200// objectGroup.m_rootPart = null; 2388// objectGroup.m_rootPart = null;
@@ -2253,11 +2441,12 @@ namespace OpenSim.Region.Framework.Scenes
2253 Quaternion worldRot = linkPart.GetWorldRotation(); 2441 Quaternion worldRot = linkPart.GetWorldRotation();
2254 2442
2255 // Remove the part from this object 2443 // Remove the part from this object
2256 lock (m_parts) 2444 lockPartsForWrite(true);
2257 { 2445 {
2258 m_parts.Remove(linkPart.UUID); 2446 m_parts.Remove(linkPart.UUID);
2259 } 2447 }
2260 2448 lockPartsForWrite(false);
2449 lockPartsForRead(true);
2261 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2450 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2262 RootPart.LinkNum = 0; 2451 RootPart.LinkNum = 0;
2263 else 2452 else
@@ -2268,6 +2457,7 @@ namespace OpenSim.Region.Framework.Scenes
2268 p.LinkNum--; 2457 p.LinkNum--;
2269 } 2458 }
2270 } 2459 }
2460 lockPartsForRead(false);
2271 2461
2272 linkPart.ParentID = 0; 2462 linkPart.ParentID = 0;
2273 linkPart.LinkNum = 0; 2463 linkPart.LinkNum = 0;
@@ -2585,9 +2775,12 @@ namespace OpenSim.Region.Framework.Scenes
2585 2775
2586 if (selectionPart != null) 2776 if (selectionPart != null)
2587 { 2777 {
2588 lock (m_parts) 2778 lockPartsForRead(true);
2779 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2780 lockPartsForRead(false);
2781 foreach (SceneObjectPart part in parts)
2589 { 2782 {
2590 foreach (SceneObjectPart part in m_parts.Values) 2783 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2591 { 2784 {
2592 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2785 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2593 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2786 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2597,12 +2790,13 @@ namespace OpenSim.Region.Framework.Scenes
2597 break; 2790 break;
2598 } 2791 }
2599 } 2792 }
2793 }
2600 2794
2601 foreach (SceneObjectPart part in m_parts.Values) 2795 foreach (SceneObjectPart part in parts)
2602 { 2796 {
2603 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2797 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2604 }
2605 } 2798 }
2799
2606 } 2800 }
2607 } 2801 }
2608 2802
@@ -2688,11 +2882,9 @@ namespace OpenSim.Region.Framework.Scenes
2688 scale.Y = m_scene.m_maxNonphys; 2882 scale.Y = m_scene.m_maxNonphys;
2689 if (scale.Z > m_scene.m_maxNonphys) 2883 if (scale.Z > m_scene.m_maxNonphys)
2690 scale.Z = m_scene.m_maxNonphys; 2884 scale.Z = m_scene.m_maxNonphys;
2691
2692 SceneObjectPart part = GetChildPart(localID); 2885 SceneObjectPart part = GetChildPart(localID);
2693 if (part != null) 2886 if (part != null)
2694 { 2887 {
2695 part.Resize(scale);
2696 if (part.PhysActor != null) 2888 if (part.PhysActor != null)
2697 { 2889 {
2698 if (part.PhysActor.IsPhysical) 2890 if (part.PhysActor.IsPhysical)
@@ -2707,7 +2899,7 @@ namespace OpenSim.Region.Framework.Scenes
2707 part.PhysActor.Size = scale; 2899 part.PhysActor.Size = scale;
2708 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2900 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2709 } 2901 }
2710 //if (part.UUID != m_rootPart.UUID) 2902 part.Resize(scale);
2711 2903
2712 HasGroupChanged = true; 2904 HasGroupChanged = true;
2713 ScheduleGroupForFullUpdate(); 2905 ScheduleGroupForFullUpdate();
@@ -2748,77 +2940,76 @@ namespace OpenSim.Region.Framework.Scenes
2748 float y = (scale.Y / part.Scale.Y); 2940 float y = (scale.Y / part.Scale.Y);
2749 float z = (scale.Z / part.Scale.Z); 2941 float z = (scale.Z / part.Scale.Z);
2750 2942
2751 lock (m_parts) 2943 lockPartsForRead(true);
2944 if (x > 1.0f || y > 1.0f || z > 1.0f)
2752 { 2945 {
2753 if (x > 1.0f || y > 1.0f || z > 1.0f) 2946 foreach (SceneObjectPart obPart in m_parts.Values)
2754 { 2947 {
2755 foreach (SceneObjectPart obPart in m_parts.Values) 2948 if (obPart.UUID != m_rootPart.UUID)
2756 { 2949 {
2757 if (obPart.UUID != m_rootPart.UUID) 2950 Vector3 oldSize = new Vector3(obPart.Scale);
2758 {
2759 Vector3 oldSize = new Vector3(obPart.Scale);
2760 2951
2761 float f = 1.0f; 2952 float f = 1.0f;
2762 float a = 1.0f; 2953 float a = 1.0f;
2763 2954
2764 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2955 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2956 {
2957 if (oldSize.X*x > m_scene.m_maxPhys)
2765 { 2958 {
2766 if (oldSize.X*x > m_scene.m_maxPhys) 2959 f = m_scene.m_maxPhys / oldSize.X;
2767 { 2960 a = f / x;
2768 f = m_scene.m_maxPhys / oldSize.X; 2961 x *= a;
2769 a = f / x; 2962 y *= a;
2770 x *= a; 2963 z *= a;
2771 y *= a;
2772 z *= a;
2773 }
2774 if (oldSize.Y*y > m_scene.m_maxPhys)
2775 {
2776 f = m_scene.m_maxPhys / oldSize.Y;
2777 a = f / y;
2778 x *= a;
2779 y *= a;
2780 z *= a;
2781 }
2782 if (oldSize.Z*z > m_scene.m_maxPhys)
2783 {
2784 f = m_scene.m_maxPhys / oldSize.Z;
2785 a = f / z;
2786 x *= a;
2787 y *= a;
2788 z *= a;
2789 }
2790 } 2964 }
2791 else 2965 if (oldSize.Y*y > m_scene.m_maxPhys)
2966 {
2967 f = m_scene.m_maxPhys / oldSize.Y;
2968 a = f / y;
2969 x *= a;
2970 y *= a;
2971 z *= a;
2972 }
2973 if (oldSize.Z*z > m_scene.m_maxPhys)
2974 {
2975 f = m_scene.m_maxPhys / oldSize.Z;
2976 a = f / z;
2977 x *= a;
2978 y *= a;
2979 z *= a;
2980 }
2981 }
2982 else
2983 {
2984 if (oldSize.X*x > m_scene.m_maxNonphys)
2985 {
2986 f = m_scene.m_maxNonphys / oldSize.X;
2987 a = f / x;
2988 x *= a;
2989 y *= a;
2990 z *= a;
2991 }
2992 if (oldSize.Y*y > m_scene.m_maxNonphys)
2993 {
2994 f = m_scene.m_maxNonphys / oldSize.Y;
2995 a = f / y;
2996 x *= a;
2997 y *= a;
2998 z *= a;
2999 }
3000 if (oldSize.Z*z > m_scene.m_maxNonphys)
2792 { 3001 {
2793 if (oldSize.X*x > m_scene.m_maxNonphys) 3002 f = m_scene.m_maxNonphys / oldSize.Z;
2794 { 3003 a = f / z;
2795 f = m_scene.m_maxNonphys / oldSize.X; 3004 x *= a;
2796 a = f / x; 3005 y *= a;
2797 x *= a; 3006 z *= a;
2798 y *= a;
2799 z *= a;
2800 }
2801 if (oldSize.Y*y > m_scene.m_maxNonphys)
2802 {
2803 f = m_scene.m_maxNonphys / oldSize.Y;
2804 a = f / y;
2805 x *= a;
2806 y *= a;
2807 z *= a;
2808 }
2809 if (oldSize.Z*z > m_scene.m_maxNonphys)
2810 {
2811 f = m_scene.m_maxNonphys / oldSize.Z;
2812 a = f / z;
2813 x *= a;
2814 y *= a;
2815 z *= a;
2816 }
2817 } 3007 }
2818 } 3008 }
2819 } 3009 }
2820 } 3010 }
2821 } 3011 }
3012 lockPartsForRead(false);
2822 3013
2823 Vector3 prevScale = part.Scale; 3014 Vector3 prevScale = part.Scale;
2824 prevScale.X *= x; 3015 prevScale.X *= x;
@@ -2826,7 +3017,7 @@ namespace OpenSim.Region.Framework.Scenes
2826 prevScale.Z *= z; 3017 prevScale.Z *= z;
2827 part.Resize(prevScale); 3018 part.Resize(prevScale);
2828 3019
2829 lock (m_parts) 3020 lockPartsForRead(true);
2830 { 3021 {
2831 foreach (SceneObjectPart obPart in m_parts.Values) 3022 foreach (SceneObjectPart obPart in m_parts.Values)
2832 { 3023 {
@@ -2845,6 +3036,7 @@ namespace OpenSim.Region.Framework.Scenes
2845 } 3036 }
2846 } 3037 }
2847 } 3038 }
3039 lockPartsForRead(false);
2848 3040
2849 if (part.PhysActor != null) 3041 if (part.PhysActor != null)
2850 { 3042 {
@@ -2925,7 +3117,7 @@ namespace OpenSim.Region.Framework.Scenes
2925 axDiff *= Quaternion.Inverse(partRotation); 3117 axDiff *= Quaternion.Inverse(partRotation);
2926 diff = axDiff; 3118 diff = axDiff;
2927 3119
2928 lock (m_parts) 3120 lockPartsForRead(true);
2929 { 3121 {
2930 foreach (SceneObjectPart obPart in m_parts.Values) 3122 foreach (SceneObjectPart obPart in m_parts.Values)
2931 { 3123 {
@@ -2935,6 +3127,7 @@ namespace OpenSim.Region.Framework.Scenes
2935 } 3127 }
2936 } 3128 }
2937 } 3129 }
3130 lockPartsForRead(false);
2938 3131
2939 AbsolutePosition = newPos; 3132 AbsolutePosition = newPos;
2940 3133
@@ -3052,7 +3245,7 @@ namespace OpenSim.Region.Framework.Scenes
3052 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3245 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3053 } 3246 }
3054 3247
3055 lock (m_parts) 3248 lockPartsForRead(true);
3056 { 3249 {
3057 foreach (SceneObjectPart prim in m_parts.Values) 3250 foreach (SceneObjectPart prim in m_parts.Values)
3058 { 3251 {
@@ -3070,6 +3263,7 @@ namespace OpenSim.Region.Framework.Scenes
3070 } 3263 }
3071 } 3264 }
3072 } 3265 }
3266 lockPartsForRead(false);
3073 3267
3074 m_rootPart.ScheduleTerseUpdate(); 3268 m_rootPart.ScheduleTerseUpdate();
3075 } 3269 }
@@ -3168,7 +3362,7 @@ namespace OpenSim.Region.Framework.Scenes
3168 if (atTargets.Count > 0) 3362 if (atTargets.Count > 0)
3169 { 3363 {
3170 uint[] localids = new uint[0]; 3364 uint[] localids = new uint[0];
3171 lock (m_parts) 3365 lockPartsForRead(true);
3172 { 3366 {
3173 localids = new uint[m_parts.Count]; 3367 localids = new uint[m_parts.Count];
3174 int cntr = 0; 3368 int cntr = 0;
@@ -3178,6 +3372,7 @@ namespace OpenSim.Region.Framework.Scenes
3178 cntr++; 3372 cntr++;
3179 } 3373 }
3180 } 3374 }
3375 lockPartsForRead(false);
3181 3376
3182 for (int ctr = 0; ctr < localids.Length; ctr++) 3377 for (int ctr = 0; ctr < localids.Length; ctr++)
3183 { 3378 {
@@ -3196,7 +3391,7 @@ namespace OpenSim.Region.Framework.Scenes
3196 { 3391 {
3197 //trigger not_at_target 3392 //trigger not_at_target
3198 uint[] localids = new uint[0]; 3393 uint[] localids = new uint[0];
3199 lock (m_parts) 3394 lockPartsForRead(true);
3200 { 3395 {
3201 localids = new uint[m_parts.Count]; 3396 localids = new uint[m_parts.Count];
3202 int cntr = 0; 3397 int cntr = 0;
@@ -3206,7 +3401,8 @@ namespace OpenSim.Region.Framework.Scenes
3206 cntr++; 3401 cntr++;
3207 } 3402 }
3208 } 3403 }
3209 3404 lockPartsForRead(false);
3405
3210 for (int ctr = 0; ctr < localids.Length; ctr++) 3406 for (int ctr = 0; ctr < localids.Length; ctr++)
3211 { 3407 {
3212 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3408 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3219,19 +3415,20 @@ namespace OpenSim.Region.Framework.Scenes
3219 public float GetMass() 3415 public float GetMass()
3220 { 3416 {
3221 float retmass = 0f; 3417 float retmass = 0f;
3222 lock (m_parts) 3418 lockPartsForRead(true);
3223 { 3419 {
3224 foreach (SceneObjectPart part in m_parts.Values) 3420 foreach (SceneObjectPart part in m_parts.Values)
3225 { 3421 {
3226 retmass += part.GetMass(); 3422 retmass += part.GetMass();
3227 } 3423 }
3228 } 3424 }
3425 lockPartsForRead(false);
3229 return retmass; 3426 return retmass;
3230 } 3427 }
3231 3428
3232 public void CheckSculptAndLoad() 3429 public void CheckSculptAndLoad()
3233 { 3430 {
3234 lock (m_parts) 3431 lockPartsForRead(true);
3235 { 3432 {
3236 if (!IsDeleted) 3433 if (!IsDeleted)
3237 { 3434 {
@@ -3256,6 +3453,7 @@ namespace OpenSim.Region.Framework.Scenes
3256 } 3453 }
3257 } 3454 }
3258 } 3455 }
3456 lockPartsForRead(false);
3259 } 3457 }
3260 3458
3261 protected void AssetReceived(string id, Object sender, AssetBase asset) 3459 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3276,7 +3474,7 @@ namespace OpenSim.Region.Framework.Scenes
3276 /// <param name="client"></param> 3474 /// <param name="client"></param>
3277 public void SetGroup(UUID GroupID, IClientAPI client) 3475 public void SetGroup(UUID GroupID, IClientAPI client)
3278 { 3476 {
3279 lock (m_parts) 3477 lockPartsForRead(true);
3280 { 3478 {
3281 foreach (SceneObjectPart part in m_parts.Values) 3479 foreach (SceneObjectPart part in m_parts.Values)
3282 { 3480 {
@@ -3286,7 +3484,7 @@ namespace OpenSim.Region.Framework.Scenes
3286 3484
3287 HasGroupChanged = true; 3485 HasGroupChanged = true;
3288 } 3486 }
3289 3487 lockPartsForRead(false);
3290 ScheduleGroupForFullUpdate(); 3488 ScheduleGroupForFullUpdate();
3291 } 3489 }
3292 3490
@@ -3305,11 +3503,12 @@ namespace OpenSim.Region.Framework.Scenes
3305 3503
3306 public void SetAttachmentPoint(byte point) 3504 public void SetAttachmentPoint(byte point)
3307 { 3505 {
3308 lock (m_parts) 3506 lockPartsForRead(true);
3309 { 3507 {
3310 foreach (SceneObjectPart part in m_parts.Values) 3508 foreach (SceneObjectPart part in m_parts.Values)
3311 part.SetAttachmentPoint(point); 3509 part.SetAttachmentPoint(point);
3312 } 3510 }
3511 lockPartsForRead(false);
3313 } 3512 }
3314 3513
3315 #region ISceneObject 3514 #region ISceneObject