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.cs558
1 files changed, 374 insertions, 184 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 7359011..42481ff 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -98,6 +98,66 @@ 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 m_partsLock.ExitReadLock();
130 }
131 }
132 public void lockPartsForWrite(bool locked)
133 {
134 if (locked)
135 {
136 if (m_partsLock.RecursiveReadCount > 0)
137 {
138 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.");
139 m_partsLock.ExitReadLock();
140 }
141 if (m_partsLock.RecursiveWriteCount > 0)
142 {
143 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
144 m_partsLock.ExitWriteLock();
145 }
146
147 while (!m_partsLock.TryEnterWriteLock(60000))
148 {
149 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.");
150 if (m_partsLock.IsWriteLockHeld)
151 {
152 m_partsLock = new System.Threading.ReaderWriterLockSlim();
153 }
154 }
155 }
156 else
157 {
158 m_partsLock.ExitWriteLock();
159 }
160 }
101 161
102 public bool HasGroupChanged 162 public bool HasGroupChanged
103 { 163 {
@@ -243,13 +303,16 @@ namespace OpenSim.Region.Framework.Scenes
243 set 303 set
244 { 304 {
245 m_regionHandle = value; 305 m_regionHandle = value;
246 lock (m_parts) 306 lockPartsForRead(true);
247 { 307 {
248 foreach (SceneObjectPart part in m_parts.Values) 308 foreach (SceneObjectPart part in m_parts.Values)
249 { 309 {
310
250 part.RegionHandle = m_regionHandle; 311 part.RegionHandle = m_regionHandle;
312
251 } 313 }
252 } 314 }
315 lockPartsForRead(false);
253 } 316 }
254 } 317 }
255 318
@@ -275,13 +338,16 @@ namespace OpenSim.Region.Framework.Scenes
275 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 338 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
276 } 339 }
277 340
278 lock (m_parts) 341 lockPartsForRead(true);
279 { 342 {
280 foreach (SceneObjectPart part in m_parts.Values) 343 foreach (SceneObjectPart part in m_parts.Values)
281 { 344 {
345
282 part.GroupPosition = val; 346 part.GroupPosition = val;
347
283 } 348 }
284 } 349 }
350 lockPartsForRead(false);
285 351
286 //if (m_rootPart.PhysActor != null) 352 //if (m_rootPart.PhysActor != null)
287 //{ 353 //{
@@ -432,13 +498,16 @@ namespace OpenSim.Region.Framework.Scenes
432 498
433 public void SetFromItemID(UUID AssetId) 499 public void SetFromItemID(UUID AssetId)
434 { 500 {
435 lock (m_parts) 501 lockPartsForRead(true);
436 { 502 {
437 foreach (SceneObjectPart part in m_parts.Values) 503 foreach (SceneObjectPart part in m_parts.Values)
438 { 504 {
505
439 part.FromItemID = AssetId; 506 part.FromItemID = AssetId;
507
440 } 508 }
441 } 509 }
510 lockPartsForRead(false);
442 } 511 }
443 512
444 public UUID GetFromItemID() 513 public UUID GetFromItemID()
@@ -505,10 +574,11 @@ namespace OpenSim.Region.Framework.Scenes
505 Vector3 maxScale = Vector3.Zero; 574 Vector3 maxScale = Vector3.Zero;
506 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 575 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
507 576
508 lock (m_parts) 577 lockPartsForRead(true);
509 { 578 {
510 foreach (SceneObjectPart part in m_parts.Values) 579 foreach (SceneObjectPart part in m_parts.Values)
511 { 580 {
581
512 Vector3 partscale = part.Scale; 582 Vector3 partscale = part.Scale;
513 Vector3 partoffset = part.OffsetPosition; 583 Vector3 partoffset = part.OffsetPosition;
514 584
@@ -519,8 +589,11 @@ namespace OpenSim.Region.Framework.Scenes
519 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 589 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; 590 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; 591 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
592
522 } 593 }
523 } 594 }
595 lockPartsForRead(false);
596
524 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 597 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
525 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 598 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
526 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 599 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -536,10 +609,11 @@ namespace OpenSim.Region.Framework.Scenes
536 609
537 EntityIntersection result = new EntityIntersection(); 610 EntityIntersection result = new EntityIntersection();
538 611
539 lock (m_parts) 612 lockPartsForRead(true);
540 { 613 {
541 foreach (SceneObjectPart part in m_parts.Values) 614 foreach (SceneObjectPart part in m_parts.Values)
542 { 615 {
616
543 // Temporary commented to stop compiler warning 617 // Temporary commented to stop compiler warning
544 //Vector3 partPosition = 618 //Vector3 partPosition =
545 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 619 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -567,8 +641,10 @@ namespace OpenSim.Region.Framework.Scenes
567 result.distance = inter.distance; 641 result.distance = inter.distance;
568 } 642 }
569 } 643 }
644
570 } 645 }
571 } 646 }
647 lockPartsForRead(false);
572 return result; 648 return result;
573 } 649 }
574 650
@@ -581,10 +657,11 @@ namespace OpenSim.Region.Framework.Scenes
581 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 657 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
582 { 658 {
583 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 659 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
584 lock (m_parts) 660 lockPartsForRead(true);
585 { 661 {
586 foreach (SceneObjectPart part in m_parts.Values) 662 foreach (SceneObjectPart part in m_parts.Values)
587 { 663 {
664
588 Vector3 worldPos = part.GetWorldPosition(); 665 Vector3 worldPos = part.GetWorldPosition();
589 Vector3 offset = worldPos - AbsolutePosition; 666 Vector3 offset = worldPos - AbsolutePosition;
590 Quaternion worldRot; 667 Quaternion worldRot;
@@ -643,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes
643 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 720 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
644 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 721 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
645 722
723
724
646 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 725 //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); 726 //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); 727 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -814,6 +893,7 @@ namespace OpenSim.Region.Framework.Scenes
814 minZ = backBottomLeft.Z; 893 minZ = backBottomLeft.Z;
815 } 894 }
816 } 895 }
896 lockPartsForRead(false);
817 897
818 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 898 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
819 899
@@ -842,17 +922,20 @@ namespace OpenSim.Region.Framework.Scenes
842 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 922 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
843 923
844 // Capture script state while holding the lock 924 // Capture script state while holding the lock
845 lock (m_parts) 925 lockPartsForRead(true);
846 { 926 {
847 foreach (SceneObjectPart part in m_parts.Values) 927 foreach (SceneObjectPart part in m_parts.Values)
848 { 928 {
929
849 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 930 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
850 foreach (UUID itemid in pstates.Keys) 931 foreach (UUID itemid in pstates.Keys)
851 { 932 {
852 states.Add(itemid, pstates[itemid]); 933 states.Add(itemid, pstates[itemid]);
853 } 934 }
935
854 } 936 }
855 } 937 }
938 lockPartsForRead(false);
856 939
857 if (states.Count > 0) 940 if (states.Count > 0)
858 { 941 {
@@ -1014,13 +1097,16 @@ namespace OpenSim.Region.Framework.Scenes
1014 1097
1015 public override void UpdateMovement() 1098 public override void UpdateMovement()
1016 { 1099 {
1017 lock (m_parts) 1100 lockPartsForRead(true);
1018 { 1101 {
1019 foreach (SceneObjectPart part in m_parts.Values) 1102 foreach (SceneObjectPart part in m_parts.Values)
1020 { 1103 {
1104
1021 part.UpdateMovement(); 1105 part.UpdateMovement();
1106
1022 } 1107 }
1023 } 1108 }
1109 lockPartsForRead(false);
1024 } 1110 }
1025 1111
1026 public ushort GetTimeDilation() 1112 public ushort GetTimeDilation()
@@ -1064,7 +1150,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 /// <param name="part"></param> 1150 /// <param name="part"></param>
1065 public void AddPart(SceneObjectPart part) 1151 public void AddPart(SceneObjectPart part)
1066 { 1152 {
1067 lock (m_parts) 1153 lockPartsForWrite(true);
1068 { 1154 {
1069 part.SetParent(this); 1155 part.SetParent(this);
1070 m_parts.Add(part.UUID, part); 1156 m_parts.Add(part.UUID, part);
@@ -1074,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (part.LinkNum == 2 && RootPart != null) 1160 if (part.LinkNum == 2 && RootPart != null)
1075 RootPart.LinkNum = 1; 1161 RootPart.LinkNum = 1;
1076 } 1162 }
1163 lockPartsForWrite(false);
1077 } 1164 }
1078 1165
1079 /// <summary> 1166 /// <summary>
@@ -1081,28 +1168,33 @@ namespace OpenSim.Region.Framework.Scenes
1081 /// </summary> 1168 /// </summary>
1082 private void UpdateParentIDs() 1169 private void UpdateParentIDs()
1083 { 1170 {
1084 lock (m_parts) 1171 lockPartsForRead(true);
1085 { 1172 {
1086 foreach (SceneObjectPart part in m_parts.Values) 1173 foreach (SceneObjectPart part in m_parts.Values)
1087 { 1174 {
1175
1088 if (part.UUID != m_rootPart.UUID) 1176 if (part.UUID != m_rootPart.UUID)
1089 { 1177 {
1090 part.ParentID = m_rootPart.LocalId; 1178 part.ParentID = m_rootPart.LocalId;
1091 } 1179 }
1180
1092 } 1181 }
1093 } 1182 }
1183 lockPartsForRead(false);
1094 } 1184 }
1095 1185
1096 public void RegenerateFullIDs() 1186 public void RegenerateFullIDs()
1097 { 1187 {
1098 lock (m_parts) 1188 lockPartsForRead(true);
1099 { 1189 {
1100 foreach (SceneObjectPart part in m_parts.Values) 1190 foreach (SceneObjectPart part in m_parts.Values)
1101 { 1191 {
1192
1102 part.UUID = UUID.Random(); 1193 part.UUID = UUID.Random();
1103 1194
1104 } 1195 }
1105 } 1196 }
1197 lockPartsForRead(false);
1106 } 1198 }
1107 1199
1108 // helper provided for parts. 1200 // helper provided for parts.
@@ -1183,29 +1275,33 @@ namespace OpenSim.Region.Framework.Scenes
1183 1275
1184 DetachFromBackup(); 1276 DetachFromBackup();
1185 1277
1186 lock (m_parts) 1278 lockPartsForRead(true);
1279 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1280 lockPartsForRead(false);
1281
1282 foreach (SceneObjectPart part in values)
1187 { 1283 {
1188 foreach (SceneObjectPart part in m_parts.Values)
1189 {
1190// part.Inventory.RemoveScriptInstances(); 1284// part.Inventory.RemoveScriptInstances();
1191 1285
1192 ScenePresence[] avatars = Scene.GetScenePresences(); 1286 ScenePresence[] avatars = Scene.GetScenePresences();
1193 for (int i = 0; i < avatars.Length; i++) 1287 for (int i = 0; i < avatars.Length; i++)
1288 {
1289 if (avatars[i].ParentID == LocalId)
1194 { 1290 {
1195 if (avatars[i].ParentID == LocalId) 1291 avatars[i].StandUp();
1196 { 1292 }
1197 avatars[i].StandUp();
1198 }
1199 1293
1200 if (!silent) 1294 if (!silent)
1201 { 1295 {
1202 part.UpdateFlag = 0; 1296 part.UpdateFlag = 0;
1203 if (part == m_rootPart) 1297 if (part == m_rootPart)
1204 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1298 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1205 }
1206 } 1299 }
1207 } 1300 }
1301
1208 } 1302 }
1303
1304
1209 } 1305 }
1210 1306
1211 public void AddScriptLPS(int count) 1307 public void AddScriptLPS(int count)
@@ -1230,17 +1326,20 @@ namespace OpenSim.Region.Framework.Scenes
1230 1326
1231 scriptEvents aggregateScriptEvents=0; 1327 scriptEvents aggregateScriptEvents=0;
1232 1328
1233 lock (m_parts) 1329 lockPartsForRead(true);
1234 { 1330 {
1235 foreach (SceneObjectPart part in m_parts.Values) 1331 foreach (SceneObjectPart part in m_parts.Values)
1236 { 1332 {
1333
1237 if (part == null) 1334 if (part == null)
1238 continue; 1335 continue;
1239 if (part != RootPart) 1336 if (part != RootPart)
1240 part.ObjectFlags = objectflagupdate; 1337 part.ObjectFlags = objectflagupdate;
1241 aggregateScriptEvents |= part.AggregateScriptEvents; 1338 aggregateScriptEvents |= part.AggregateScriptEvents;
1339
1242 } 1340 }
1243 } 1341 }
1342 lockPartsForRead(false);
1244 1343
1245 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1344 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1246 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1345 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1273,42 +1372,52 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <param name="m_physicalPrim"></param> 1372 /// <param name="m_physicalPrim"></param>
1274 public void ApplyPhysics(bool m_physicalPrim) 1373 public void ApplyPhysics(bool m_physicalPrim)
1275 { 1374 {
1276 lock (m_parts) 1375 lockPartsForRead(true);
1376
1377 if (m_parts.Count > 1)
1277 { 1378 {
1278 if (m_parts.Count > 1) 1379 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1380 lockPartsForRead(false);
1381 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1382 foreach (SceneObjectPart part in values)
1279 { 1383 {
1280 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1384
1281 foreach (SceneObjectPart part in m_parts.Values) 1385 if (part.LocalId != m_rootPart.LocalId)
1282 { 1386 {
1283 if (part.LocalId != m_rootPart.LocalId) 1387 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1284 {
1285 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1286 }
1287 } 1388 }
1288 1389
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 } 1390 }
1391 // Hack to get the physics scene geometries in the right spot
1392 ResetChildPrimPhysicsPositions();
1393 }
1394 else
1395 {
1396 lockPartsForRead(false);
1397 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1296 } 1398 }
1297 } 1399 }
1298 1400
1299 public void SetOwnerId(UUID userId) 1401 public void SetOwnerId(UUID userId)
1300 { 1402 {
1301 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1403 ForEachPart(delegate(SceneObjectPart part)
1404 {
1405
1406 part.OwnerID = userId;
1407
1408 });
1302 } 1409 }
1303 1410
1304 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1411 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1305 { 1412 {
1306 lock (m_parts) 1413 lockPartsForRead(true);
1414 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1415 lockPartsForRead(false);
1416 foreach (SceneObjectPart part in values)
1307 { 1417 {
1308 foreach (SceneObjectPart part in m_parts.Values) 1418
1309 { 1419 whatToDo(part);
1310 whatToDo(part); 1420
1311 }
1312 } 1421 }
1313 } 1422 }
1314 1423
@@ -1407,14 +1516,17 @@ namespace OpenSim.Region.Framework.Scenes
1407 { 1516 {
1408 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1517 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1409 1518
1410 lock (m_parts) 1519 lockPartsForRead(true);
1411 { 1520 {
1412 foreach (SceneObjectPart part in m_parts.Values) 1521 foreach (SceneObjectPart part in m_parts.Values)
1413 { 1522 {
1523
1414 if (part != RootPart) 1524 if (part != RootPart)
1415 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1525 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1526
1416 } 1527 }
1417 } 1528 }
1529 lockPartsForRead(false);
1418 } 1530 }
1419 1531
1420 /// <summary> 1532 /// <summary>
@@ -1509,10 +1621,11 @@ namespace OpenSim.Region.Framework.Scenes
1509 1621
1510 List<SceneObjectPart> partList; 1622 List<SceneObjectPart> partList;
1511 1623
1512 lock (m_parts) 1624 lockPartsForRead(true);
1513 { 1625
1514 partList = new List<SceneObjectPart>(m_parts.Values); 1626 partList = new List<SceneObjectPart>(m_parts.Values);
1515 } 1627
1628 lockPartsForRead(false);
1516 1629
1517 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1630 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1518 { 1631 {
@@ -1735,6 +1848,45 @@ namespace OpenSim.Region.Framework.Scenes
1735 } 1848 }
1736 } 1849 }
1737 1850
1851 public void rotLookAt(Quaternion target, float strength, float damping)
1852 {
1853 SceneObjectPart rootpart = m_rootPart;
1854 if (rootpart != null)
1855 {
1856 if (IsAttachment)
1857 {
1858 /*
1859 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1860 if (avatar != null)
1861 {
1862 Rotate the Av?
1863 } */
1864 }
1865 else
1866 {
1867 if (rootpart.PhysActor != null)
1868 {
1869 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1870 rootpart.PhysActor.APIDStrength = strength;
1871 rootpart.PhysActor.APIDDamping = damping;
1872 rootpart.PhysActor.APIDActive = true;
1873 }
1874 }
1875 }
1876 }
1877 public void stopLookAt()
1878 {
1879 SceneObjectPart rootpart = m_rootPart;
1880 if (rootpart != null)
1881 {
1882 if (rootpart.PhysActor != null)
1883 {
1884 rootpart.PhysActor.APIDActive = false;
1885 }
1886 }
1887
1888 }
1889
1738 /// <summary> 1890 /// <summary>
1739 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1891 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1740 /// </summary> 1892 /// </summary>
@@ -1796,10 +1948,11 @@ namespace OpenSim.Region.Framework.Scenes
1796 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1948 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1797 newPart.SetParent(this); 1949 newPart.SetParent(this);
1798 1950
1799 lock (m_parts) 1951 lockPartsForWrite(true);
1800 { 1952 {
1801 m_parts.Add(newPart.UUID, newPart); 1953 m_parts.Add(newPart.UUID, newPart);
1802 } 1954 }
1955 lockPartsForWrite(false);
1803 1956
1804 SetPartAsNonRoot(newPart); 1957 SetPartAsNonRoot(newPart);
1805 1958
@@ -1862,7 +2015,7 @@ namespace OpenSim.Region.Framework.Scenes
1862 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2015 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1863 // return; 2016 // return;
1864 2017
1865 lock (m_parts) 2018 lockPartsForRead(true);
1866 { 2019 {
1867 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2020 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1868 2021
@@ -1880,34 +2033,43 @@ namespace OpenSim.Region.Framework.Scenes
1880 2033
1881 foreach (SceneObjectPart part in m_parts.Values) 2034 foreach (SceneObjectPart part in m_parts.Values)
1882 { 2035 {
2036
1883 part.SendScheduledUpdates(); 2037 part.SendScheduledUpdates();
2038
1884 } 2039 }
1885 } 2040 }
2041 lockPartsForRead(false);
1886 } 2042 }
1887 2043
1888 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2044 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1889 { 2045 {
1890 RootPart.AddFullUpdateToAvatar(presence); 2046 RootPart.AddFullUpdateToAvatar(presence);
1891 2047
1892 lock (m_parts) 2048 lockPartsForRead(true);
1893 { 2049 {
1894 foreach (SceneObjectPart part in m_parts.Values) 2050 foreach (SceneObjectPart part in m_parts.Values)
1895 { 2051 {
2052
1896 if (part != RootPart) 2053 if (part != RootPart)
1897 part.AddFullUpdateToAvatar(presence); 2054 part.AddFullUpdateToAvatar(presence);
2055
1898 } 2056 }
1899 } 2057 }
2058 lockPartsForRead(false);
1900 } 2059 }
1901 2060
1902 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2061 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1903 { 2062 {
1904 lock (m_parts) 2063 lockPartsForRead(true);
1905 { 2064 {
1906 foreach (SceneObjectPart part in m_parts.Values) 2065 foreach (SceneObjectPart part in m_parts.Values)
1907 { 2066 {
2067
1908 part.AddTerseUpdateToAvatar(presence); 2068 part.AddTerseUpdateToAvatar(presence);
2069
1909 } 2070 }
1910 } 2071 }
2072 lockPartsForRead(false);
1911 } 2073 }
1912 2074
1913 /// <summary> 2075 /// <summary>
@@ -1918,14 +2080,17 @@ namespace OpenSim.Region.Framework.Scenes
1918 checkAtTargets(); 2080 checkAtTargets();
1919 RootPart.ScheduleFullUpdate(); 2081 RootPart.ScheduleFullUpdate();
1920 2082
1921 lock (m_parts) 2083 lockPartsForRead(true);
1922 { 2084 {
1923 foreach (SceneObjectPart part in m_parts.Values) 2085 foreach (SceneObjectPart part in m_parts.Values)
1924 { 2086 {
2087
1925 if (part != RootPart) 2088 if (part != RootPart)
1926 part.ScheduleFullUpdate(); 2089 part.ScheduleFullUpdate();
2090
1927 } 2091 }
1928 } 2092 }
2093 lockPartsForRead(false);
1929 } 2094 }
1930 2095
1931 /// <summary> 2096 /// <summary>
@@ -1933,13 +2098,16 @@ namespace OpenSim.Region.Framework.Scenes
1933 /// </summary> 2098 /// </summary>
1934 public void ScheduleGroupForTerseUpdate() 2099 public void ScheduleGroupForTerseUpdate()
1935 { 2100 {
1936 lock (m_parts) 2101 lockPartsForRead(true);
1937 { 2102 {
1938 foreach (SceneObjectPart part in m_parts.Values) 2103 foreach (SceneObjectPart part in m_parts.Values)
1939 { 2104 {
2105
1940 part.ScheduleTerseUpdate(); 2106 part.ScheduleTerseUpdate();
2107
1941 } 2108 }
1942 } 2109 }
2110 lockPartsForRead(false);
1943 } 2111 }
1944 2112
1945 /// <summary> 2113 /// <summary>
@@ -1952,14 +2120,17 @@ namespace OpenSim.Region.Framework.Scenes
1952 2120
1953 RootPart.SendFullUpdateToAllClients(); 2121 RootPart.SendFullUpdateToAllClients();
1954 2122
1955 lock (m_parts) 2123 lockPartsForRead(true);
1956 { 2124 {
1957 foreach (SceneObjectPart part in m_parts.Values) 2125 foreach (SceneObjectPart part in m_parts.Values)
1958 { 2126 {
2127
1959 if (part != RootPart) 2128 if (part != RootPart)
1960 part.SendFullUpdateToAllClients(); 2129 part.SendFullUpdateToAllClients();
2130
1961 } 2131 }
1962 } 2132 }
2133 lockPartsForRead(false);
1963 } 2134 }
1964 2135
1965 /// <summary> 2136 /// <summary>
@@ -1990,14 +2161,15 @@ namespace OpenSim.Region.Framework.Scenes
1990 { 2161 {
1991 if (IsDeleted) 2162 if (IsDeleted)
1992 return; 2163 return;
1993 2164
1994 lock (m_parts) 2165 lockPartsForRead(true);
1995 { 2166 {
1996 foreach (SceneObjectPart part in m_parts.Values) 2167 foreach (SceneObjectPart part in m_parts.Values)
1997 { 2168 {
1998 part.SendTerseUpdateToAllClients(); 2169 part.SendTerseUpdateToAllClients();
1999 } 2170 }
2000 } 2171 }
2172 lockPartsForRead(false);
2001 } 2173 }
2002 2174
2003 #endregion 2175 #endregion
@@ -2011,16 +2183,18 @@ namespace OpenSim.Region.Framework.Scenes
2011 /// <returns>null if no child part with that linknum or child part</returns> 2183 /// <returns>null if no child part with that linknum or child part</returns>
2012 public SceneObjectPart GetLinkNumPart(int linknum) 2184 public SceneObjectPart GetLinkNumPart(int linknum)
2013 { 2185 {
2014 lock (m_parts) 2186 lockPartsForRead(true);
2015 { 2187 {
2016 foreach (SceneObjectPart part in m_parts.Values) 2188 foreach (SceneObjectPart part in m_parts.Values)
2017 { 2189 {
2018 if (part.LinkNum == linknum) 2190 if (part.LinkNum == linknum)
2019 { 2191 {
2192 lockPartsForRead(false);
2020 return part; 2193 return part;
2021 } 2194 }
2022 } 2195 }
2023 } 2196 }
2197 lockPartsForRead(false);
2024 2198
2025 return null; 2199 return null;
2026 } 2200 }
@@ -2048,17 +2222,19 @@ namespace OpenSim.Region.Framework.Scenes
2048 public SceneObjectPart GetChildPart(uint localID) 2222 public SceneObjectPart GetChildPart(uint localID)
2049 { 2223 {
2050 //m_log.DebugFormat("Entered looking for {0}", localID); 2224 //m_log.DebugFormat("Entered looking for {0}", localID);
2051 lock (m_parts) 2225 lockPartsForRead(true);
2052 { 2226 {
2053 foreach (SceneObjectPart part in m_parts.Values) 2227 foreach (SceneObjectPart part in m_parts.Values)
2054 { 2228 {
2055 //m_log.DebugFormat("Found {0}", part.LocalId); 2229 //m_log.DebugFormat("Found {0}", part.LocalId);
2056 if (part.LocalId == localID) 2230 if (part.LocalId == localID)
2057 { 2231 {
2232 lockPartsForRead(false);
2058 return part; 2233 return part;
2059 } 2234 }
2060 } 2235 }
2061 } 2236 }
2237 lockPartsForRead(false);
2062 2238
2063 return null; 2239 return null;
2064 } 2240 }
@@ -2088,17 +2264,19 @@ namespace OpenSim.Region.Framework.Scenes
2088 public bool HasChildPrim(uint localID) 2264 public bool HasChildPrim(uint localID)
2089 { 2265 {
2090 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2266 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2091 lock (m_parts) 2267 lockPartsForRead(true);
2092 { 2268 {
2093 foreach (SceneObjectPart part in m_parts.Values) 2269 foreach (SceneObjectPart part in m_parts.Values)
2094 { 2270 {
2095 //m_log.DebugFormat("Found {0}", part.LocalId); 2271 //m_log.DebugFormat("Found {0}", part.LocalId);
2096 if (part.LocalId == localID) 2272 if (part.LocalId == localID)
2097 { 2273 {
2274 lockPartsForRead(false);
2098 return true; 2275 return true;
2099 } 2276 }
2100 } 2277 }
2101 } 2278 }
2279 lockPartsForRead(false);
2102 2280
2103 return false; 2281 return false;
2104 } 2282 }
@@ -2148,53 +2326,57 @@ namespace OpenSim.Region.Framework.Scenes
2148 if (m_rootPart.LinkNum == 0) 2326 if (m_rootPart.LinkNum == 0)
2149 m_rootPart.LinkNum = 1; 2327 m_rootPart.LinkNum = 1;
2150 2328
2151 lock (m_parts) 2329 lockPartsForWrite(true);
2152 { 2330
2153 m_parts.Add(linkPart.UUID, linkPart); 2331 m_parts.Add(linkPart.UUID, linkPart);
2332
2333 lockPartsForWrite(false);
2154 2334
2155 // Insert in terms of link numbers, the new links 2335 // Insert in terms of link numbers, the new links
2156 // before the current ones (with the exception of 2336 // before the current ones (with the exception of
2157 // the root prim. Shuffle the old ones up 2337 // the root prim. Shuffle the old ones up
2158 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2338 lockPartsForRead(true);
2339 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2340 {
2341 if (kvp.Value.LinkNum != 1)
2159 { 2342 {
2160 if (kvp.Value.LinkNum != 1) 2343 // Don't update root prim link number
2161 { 2344 kvp.Value.LinkNum += objectGroup.PrimCount;
2162 // Don't update root prim link number
2163 kvp.Value.LinkNum += objectGroup.PrimCount;
2164 }
2165 } 2345 }
2346 }
2347 lockPartsForRead(false);
2166 2348
2167 linkPart.LinkNum = 2; 2349 linkPart.LinkNum = 2;
2168 2350
2169 linkPart.SetParent(this); 2351 linkPart.SetParent(this);
2170 linkPart.AddFlag(PrimFlags.CreateSelected); 2352 linkPart.AddFlag(PrimFlags.CreateSelected);
2171 2353
2172 //if (linkPart.PhysActor != null) 2354 //if (linkPart.PhysActor != null)
2173 //{ 2355 //{
2174 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2356 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2175 2357
2176 //linkPart.PhysActor = null; 2358 //linkPart.PhysActor = null;
2177 //} 2359 //}
2178 2360
2179 //TODO: rest of parts 2361 //TODO: rest of parts
2180 int linkNum = 3; 2362 int linkNum = 3;
2181 foreach (SceneObjectPart part in objectGroup.Children.Values) 2363 foreach (SceneObjectPart part in objectGroup.Children.Values)
2364 {
2365 if (part.UUID != objectGroup.m_rootPart.UUID)
2182 { 2366 {
2183 if (part.UUID != objectGroup.m_rootPart.UUID) 2367 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2184 {
2185 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2186 }
2187 part.ClearUndoState();
2188 } 2368 }
2369 part.ClearUndoState();
2189 } 2370 }
2190 2371
2191 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2372 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2192 objectGroup.m_isDeleted = true; 2373 objectGroup.m_isDeleted = true;
2374
2375 objectGroup.lockPartsForWrite(true);
2193 2376
2194 lock (objectGroup.m_parts) 2377 objectGroup.m_parts.Clear();
2195 { 2378
2196 objectGroup.m_parts.Clear(); 2379 objectGroup.lockPartsForWrite(false);
2197 }
2198 2380
2199 // Can't do this yet since backup still makes use of the root part without any synchronization 2381 // Can't do this yet since backup still makes use of the root part without any synchronization
2200// objectGroup.m_rootPart = null; 2382// objectGroup.m_rootPart = null;
@@ -2253,11 +2435,12 @@ namespace OpenSim.Region.Framework.Scenes
2253 Quaternion worldRot = linkPart.GetWorldRotation(); 2435 Quaternion worldRot = linkPart.GetWorldRotation();
2254 2436
2255 // Remove the part from this object 2437 // Remove the part from this object
2256 lock (m_parts) 2438 lockPartsForWrite(true);
2257 { 2439 {
2258 m_parts.Remove(linkPart.UUID); 2440 m_parts.Remove(linkPart.UUID);
2259 } 2441 }
2260 2442 lockPartsForWrite(false);
2443 lockPartsForRead(true);
2261 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2444 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2262 RootPart.LinkNum = 0; 2445 RootPart.LinkNum = 0;
2263 else 2446 else
@@ -2268,6 +2451,7 @@ namespace OpenSim.Region.Framework.Scenes
2268 p.LinkNum--; 2451 p.LinkNum--;
2269 } 2452 }
2270 } 2453 }
2454 lockPartsForRead(false);
2271 2455
2272 linkPart.ParentID = 0; 2456 linkPart.ParentID = 0;
2273 linkPart.LinkNum = 0; 2457 linkPart.LinkNum = 0;
@@ -2585,22 +2769,23 @@ namespace OpenSim.Region.Framework.Scenes
2585 2769
2586 if (selectionPart != null) 2770 if (selectionPart != null)
2587 { 2771 {
2588 lock (m_parts) 2772 lockPartsForRead(true);
2773 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2774 lockPartsForRead(false);
2775 foreach (SceneObjectPart part in parts)
2589 { 2776 {
2590 foreach (SceneObjectPart part in m_parts.Values) 2777 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2591 { 2778 {
2592 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) 2779 UsePhysics = false; // Reset physics
2593 { 2780 break;
2594 UsePhysics = false; // Reset physics
2595 break;
2596 }
2597 } 2781 }
2782 }
2598 2783
2599 foreach (SceneObjectPart part in m_parts.Values) 2784 foreach (SceneObjectPart part in parts)
2600 { 2785 {
2601 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2786 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2602 }
2603 } 2787 }
2788
2604 } 2789 }
2605 } 2790 }
2606 2791
@@ -2686,11 +2871,9 @@ namespace OpenSim.Region.Framework.Scenes
2686 scale.Y = m_scene.m_maxNonphys; 2871 scale.Y = m_scene.m_maxNonphys;
2687 if (scale.Z > m_scene.m_maxNonphys) 2872 if (scale.Z > m_scene.m_maxNonphys)
2688 scale.Z = m_scene.m_maxNonphys; 2873 scale.Z = m_scene.m_maxNonphys;
2689
2690 SceneObjectPart part = GetChildPart(localID); 2874 SceneObjectPart part = GetChildPart(localID);
2691 if (part != null) 2875 if (part != null)
2692 { 2876 {
2693 part.Resize(scale);
2694 if (part.PhysActor != null) 2877 if (part.PhysActor != null)
2695 { 2878 {
2696 if (part.PhysActor.IsPhysical) 2879 if (part.PhysActor.IsPhysical)
@@ -2705,7 +2888,7 @@ namespace OpenSim.Region.Framework.Scenes
2705 part.PhysActor.Size = scale; 2888 part.PhysActor.Size = scale;
2706 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2889 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2707 } 2890 }
2708 //if (part.UUID != m_rootPart.UUID) 2891 part.Resize(scale);
2709 2892
2710 HasGroupChanged = true; 2893 HasGroupChanged = true;
2711 ScheduleGroupForFullUpdate(); 2894 ScheduleGroupForFullUpdate();
@@ -2746,77 +2929,76 @@ namespace OpenSim.Region.Framework.Scenes
2746 float y = (scale.Y / part.Scale.Y); 2929 float y = (scale.Y / part.Scale.Y);
2747 float z = (scale.Z / part.Scale.Z); 2930 float z = (scale.Z / part.Scale.Z);
2748 2931
2749 lock (m_parts) 2932 lockPartsForRead(true);
2933 if (x > 1.0f || y > 1.0f || z > 1.0f)
2750 { 2934 {
2751 if (x > 1.0f || y > 1.0f || z > 1.0f) 2935 foreach (SceneObjectPart obPart in m_parts.Values)
2752 { 2936 {
2753 foreach (SceneObjectPart obPart in m_parts.Values) 2937 if (obPart.UUID != m_rootPart.UUID)
2754 { 2938 {
2755 if (obPart.UUID != m_rootPart.UUID) 2939 Vector3 oldSize = new Vector3(obPart.Scale);
2756 {
2757 Vector3 oldSize = new Vector3(obPart.Scale);
2758 2940
2759 float f = 1.0f; 2941 float f = 1.0f;
2760 float a = 1.0f; 2942 float a = 1.0f;
2761 2943
2762 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2944 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2945 {
2946 if (oldSize.X*x > m_scene.m_maxPhys)
2763 { 2947 {
2764 if (oldSize.X*x > m_scene.m_maxPhys) 2948 f = m_scene.m_maxPhys / oldSize.X;
2765 { 2949 a = f / x;
2766 f = m_scene.m_maxPhys / oldSize.X; 2950 x *= a;
2767 a = f / x; 2951 y *= a;
2768 x *= a; 2952 z *= a;
2769 y *= a;
2770 z *= a;
2771 }
2772 if (oldSize.Y*y > m_scene.m_maxPhys)
2773 {
2774 f = m_scene.m_maxPhys / oldSize.Y;
2775 a = f / y;
2776 x *= a;
2777 y *= a;
2778 z *= a;
2779 }
2780 if (oldSize.Z*z > m_scene.m_maxPhys)
2781 {
2782 f = m_scene.m_maxPhys / oldSize.Z;
2783 a = f / z;
2784 x *= a;
2785 y *= a;
2786 z *= a;
2787 }
2788 } 2953 }
2789 else 2954 if (oldSize.Y*y > m_scene.m_maxPhys)
2955 {
2956 f = m_scene.m_maxPhys / oldSize.Y;
2957 a = f / y;
2958 x *= a;
2959 y *= a;
2960 z *= a;
2961 }
2962 if (oldSize.Z*z > m_scene.m_maxPhys)
2790 { 2963 {
2791 if (oldSize.X*x > m_scene.m_maxNonphys) 2964 f = m_scene.m_maxPhys / oldSize.Z;
2792 { 2965 a = f / z;
2793 f = m_scene.m_maxNonphys / oldSize.X; 2966 x *= a;
2794 a = f / x; 2967 y *= a;
2795 x *= a; 2968 z *= a;
2796 y *= a; 2969 }
2797 z *= a; 2970 }
2798 } 2971 else
2799 if (oldSize.Y*y > m_scene.m_maxNonphys) 2972 {
2800 { 2973 if (oldSize.X*x > m_scene.m_maxNonphys)
2801 f = m_scene.m_maxNonphys / oldSize.Y; 2974 {
2802 a = f / y; 2975 f = m_scene.m_maxNonphys / oldSize.X;
2803 x *= a; 2976 a = f / x;
2804 y *= a; 2977 x *= a;
2805 z *= a; 2978 y *= a;
2806 } 2979 z *= a;
2807 if (oldSize.Z*z > m_scene.m_maxNonphys) 2980 }
2808 { 2981 if (oldSize.Y*y > m_scene.m_maxNonphys)
2809 f = m_scene.m_maxNonphys / oldSize.Z; 2982 {
2810 a = f / z; 2983 f = m_scene.m_maxNonphys / oldSize.Y;
2811 x *= a; 2984 a = f / y;
2812 y *= a; 2985 x *= a;
2813 z *= a; 2986 y *= a;
2814 } 2987 z *= a;
2988 }
2989 if (oldSize.Z*z > m_scene.m_maxNonphys)
2990 {
2991 f = m_scene.m_maxNonphys / oldSize.Z;
2992 a = f / z;
2993 x *= a;
2994 y *= a;
2995 z *= a;
2815 } 2996 }
2816 } 2997 }
2817 } 2998 }
2818 } 2999 }
2819 } 3000 }
3001 lockPartsForRead(false);
2820 3002
2821 Vector3 prevScale = part.Scale; 3003 Vector3 prevScale = part.Scale;
2822 prevScale.X *= x; 3004 prevScale.X *= x;
@@ -2824,7 +3006,7 @@ namespace OpenSim.Region.Framework.Scenes
2824 prevScale.Z *= z; 3006 prevScale.Z *= z;
2825 part.Resize(prevScale); 3007 part.Resize(prevScale);
2826 3008
2827 lock (m_parts) 3009 lockPartsForRead(true);
2828 { 3010 {
2829 foreach (SceneObjectPart obPart in m_parts.Values) 3011 foreach (SceneObjectPart obPart in m_parts.Values)
2830 { 3012 {
@@ -2843,6 +3025,7 @@ namespace OpenSim.Region.Framework.Scenes
2843 } 3025 }
2844 } 3026 }
2845 } 3027 }
3028 lockPartsForRead(false);
2846 3029
2847 if (part.PhysActor != null) 3030 if (part.PhysActor != null)
2848 { 3031 {
@@ -2923,7 +3106,7 @@ namespace OpenSim.Region.Framework.Scenes
2923 axDiff *= Quaternion.Inverse(partRotation); 3106 axDiff *= Quaternion.Inverse(partRotation);
2924 diff = axDiff; 3107 diff = axDiff;
2925 3108
2926 lock (m_parts) 3109 lockPartsForRead(true);
2927 { 3110 {
2928 foreach (SceneObjectPart obPart in m_parts.Values) 3111 foreach (SceneObjectPart obPart in m_parts.Values)
2929 { 3112 {
@@ -2933,6 +3116,7 @@ namespace OpenSim.Region.Framework.Scenes
2933 } 3116 }
2934 } 3117 }
2935 } 3118 }
3119 lockPartsForRead(false);
2936 3120
2937 AbsolutePosition = newPos; 3121 AbsolutePosition = newPos;
2938 3122
@@ -3050,7 +3234,7 @@ namespace OpenSim.Region.Framework.Scenes
3050 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3234 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3051 } 3235 }
3052 3236
3053 lock (m_parts) 3237 lockPartsForRead(true);
3054 { 3238 {
3055 foreach (SceneObjectPart prim in m_parts.Values) 3239 foreach (SceneObjectPart prim in m_parts.Values)
3056 { 3240 {
@@ -3068,6 +3252,7 @@ namespace OpenSim.Region.Framework.Scenes
3068 } 3252 }
3069 } 3253 }
3070 } 3254 }
3255 lockPartsForRead(false);
3071 3256
3072 m_rootPart.ScheduleTerseUpdate(); 3257 m_rootPart.ScheduleTerseUpdate();
3073 } 3258 }
@@ -3166,7 +3351,7 @@ namespace OpenSim.Region.Framework.Scenes
3166 if (atTargets.Count > 0) 3351 if (atTargets.Count > 0)
3167 { 3352 {
3168 uint[] localids = new uint[0]; 3353 uint[] localids = new uint[0];
3169 lock (m_parts) 3354 lockPartsForRead(true);
3170 { 3355 {
3171 localids = new uint[m_parts.Count]; 3356 localids = new uint[m_parts.Count];
3172 int cntr = 0; 3357 int cntr = 0;
@@ -3176,6 +3361,7 @@ namespace OpenSim.Region.Framework.Scenes
3176 cntr++; 3361 cntr++;
3177 } 3362 }
3178 } 3363 }
3364 lockPartsForRead(false);
3179 3365
3180 for (int ctr = 0; ctr < localids.Length; ctr++) 3366 for (int ctr = 0; ctr < localids.Length; ctr++)
3181 { 3367 {
@@ -3194,7 +3380,7 @@ namespace OpenSim.Region.Framework.Scenes
3194 { 3380 {
3195 //trigger not_at_target 3381 //trigger not_at_target
3196 uint[] localids = new uint[0]; 3382 uint[] localids = new uint[0];
3197 lock (m_parts) 3383 lockPartsForRead(true);
3198 { 3384 {
3199 localids = new uint[m_parts.Count]; 3385 localids = new uint[m_parts.Count];
3200 int cntr = 0; 3386 int cntr = 0;
@@ -3204,7 +3390,8 @@ namespace OpenSim.Region.Framework.Scenes
3204 cntr++; 3390 cntr++;
3205 } 3391 }
3206 } 3392 }
3207 3393 lockPartsForRead(false);
3394
3208 for (int ctr = 0; ctr < localids.Length; ctr++) 3395 for (int ctr = 0; ctr < localids.Length; ctr++)
3209 { 3396 {
3210 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3397 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3217,19 +3404,20 @@ namespace OpenSim.Region.Framework.Scenes
3217 public float GetMass() 3404 public float GetMass()
3218 { 3405 {
3219 float retmass = 0f; 3406 float retmass = 0f;
3220 lock (m_parts) 3407 lockPartsForRead(true);
3221 { 3408 {
3222 foreach (SceneObjectPart part in m_parts.Values) 3409 foreach (SceneObjectPart part in m_parts.Values)
3223 { 3410 {
3224 retmass += part.GetMass(); 3411 retmass += part.GetMass();
3225 } 3412 }
3226 } 3413 }
3414 lockPartsForRead(false);
3227 return retmass; 3415 return retmass;
3228 } 3416 }
3229 3417
3230 public void CheckSculptAndLoad() 3418 public void CheckSculptAndLoad()
3231 { 3419 {
3232 lock (m_parts) 3420 lockPartsForRead(true);
3233 { 3421 {
3234 if (!IsDeleted) 3422 if (!IsDeleted)
3235 { 3423 {
@@ -3254,6 +3442,7 @@ namespace OpenSim.Region.Framework.Scenes
3254 } 3442 }
3255 } 3443 }
3256 } 3444 }
3445 lockPartsForRead(false);
3257 } 3446 }
3258 3447
3259 protected void AssetReceived(string id, Object sender, AssetBase asset) 3448 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3274,7 +3463,7 @@ namespace OpenSim.Region.Framework.Scenes
3274 /// <param name="client"></param> 3463 /// <param name="client"></param>
3275 public void SetGroup(UUID GroupID, IClientAPI client) 3464 public void SetGroup(UUID GroupID, IClientAPI client)
3276 { 3465 {
3277 lock (m_parts) 3466 lockPartsForRead(true);
3278 { 3467 {
3279 foreach (SceneObjectPart part in m_parts.Values) 3468 foreach (SceneObjectPart part in m_parts.Values)
3280 { 3469 {
@@ -3284,7 +3473,7 @@ namespace OpenSim.Region.Framework.Scenes
3284 3473
3285 HasGroupChanged = true; 3474 HasGroupChanged = true;
3286 } 3475 }
3287 3476 lockPartsForRead(false);
3288 ScheduleGroupForFullUpdate(); 3477 ScheduleGroupForFullUpdate();
3289 } 3478 }
3290 3479
@@ -3303,11 +3492,12 @@ namespace OpenSim.Region.Framework.Scenes
3303 3492
3304 public void SetAttachmentPoint(byte point) 3493 public void SetAttachmentPoint(byte point)
3305 { 3494 {
3306 lock (m_parts) 3495 lockPartsForRead(true);
3307 { 3496 {
3308 foreach (SceneObjectPart part in m_parts.Values) 3497 foreach (SceneObjectPart part in m_parts.Values)
3309 part.SetAttachmentPoint(point); 3498 part.SetAttachmentPoint(point);
3310 } 3499 }
3500 lockPartsForRead(false);
3311 } 3501 }
3312 3502
3313 #region ISceneObject 3503 #region ISceneObject