diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 519 |
1 files changed, 340 insertions, 179 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ec41ac7..768ceb5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -106,6 +106,72 @@ namespace OpenSim.Region.Framework.Scenes | |||
106 | private bool m_hasGroupChanged = false; | 106 | private bool m_hasGroupChanged = false; |
107 | private long timeFirstChanged; | 107 | private long timeFirstChanged; |
108 | private long timeLastChanged; | 108 | private long timeLastChanged; |
109 | private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
110 | |||
111 | public void lockPartsForRead(bool locked) | ||
112 | { | ||
113 | if (locked) | ||
114 | { | ||
115 | if (m_partsLock.RecursiveReadCount > 0) | ||
116 | { | ||
117 | 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."); | ||
118 | m_partsLock.ExitReadLock(); | ||
119 | } | ||
120 | if (m_partsLock.RecursiveWriteCount > 0) | ||
121 | { | ||
122 | m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed."); | ||
123 | m_partsLock.ExitWriteLock(); | ||
124 | } | ||
125 | |||
126 | while (!m_partsLock.TryEnterReadLock(60000)) | ||
127 | { | ||
128 | 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."); | ||
129 | if (m_partsLock.IsWriteLockHeld) | ||
130 | { | ||
131 | m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | if (m_partsLock.RecursiveReadCount > 0) | ||
138 | { | ||
139 | m_partsLock.ExitReadLock(); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | public void lockPartsForWrite(bool locked) | ||
144 | { | ||
145 | if (locked) | ||
146 | { | ||
147 | if (m_partsLock.RecursiveReadCount > 0) | ||
148 | { | ||
149 | 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."); | ||
150 | m_partsLock.ExitReadLock(); | ||
151 | } | ||
152 | if (m_partsLock.RecursiveWriteCount > 0) | ||
153 | { | ||
154 | m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
155 | m_partsLock.ExitWriteLock(); | ||
156 | } | ||
157 | |||
158 | while (!m_partsLock.TryEnterWriteLock(60000)) | ||
159 | { | ||
160 | 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."); | ||
161 | if (m_partsLock.IsWriteLockHeld) | ||
162 | { | ||
163 | m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | if (m_partsLock.RecursiveWriteCount > 0) | ||
170 | { | ||
171 | m_partsLock.ExitWriteLock(); | ||
172 | } | ||
173 | } | ||
174 | } | ||
109 | 175 | ||
110 | public bool HasGroupChanged | 176 | public bool HasGroupChanged |
111 | { | 177 | { |
@@ -255,13 +321,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
255 | set | 321 | set |
256 | { | 322 | { |
257 | m_regionHandle = value; | 323 | m_regionHandle = value; |
258 | lock (m_parts) | 324 | lockPartsForRead(true); |
259 | { | 325 | { |
260 | foreach (SceneObjectPart part in m_parts.Values) | 326 | foreach (SceneObjectPart part in m_parts.Values) |
261 | { | 327 | { |
328 | |||
262 | part.RegionHandle = m_regionHandle; | 329 | part.RegionHandle = m_regionHandle; |
330 | |||
263 | } | 331 | } |
264 | } | 332 | } |
333 | lockPartsForRead(false); | ||
265 | } | 334 | } |
266 | } | 335 | } |
267 | 336 | ||
@@ -287,13 +356,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
287 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 356 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
288 | } | 357 | } |
289 | 358 | ||
290 | lock (m_parts) | 359 | lockPartsForRead(true); |
291 | { | 360 | { |
292 | foreach (SceneObjectPart part in m_parts.Values) | 361 | foreach (SceneObjectPart part in m_parts.Values) |
293 | { | 362 | { |
363 | |||
294 | part.GroupPosition = val; | 364 | part.GroupPosition = val; |
365 | |||
295 | } | 366 | } |
296 | } | 367 | } |
368 | lockPartsForRead(false); | ||
297 | 369 | ||
298 | //if (m_rootPart.PhysActor != null) | 370 | //if (m_rootPart.PhysActor != null) |
299 | //{ | 371 | //{ |
@@ -455,13 +527,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
455 | 527 | ||
456 | public void SetFromItemID(UUID AssetId) | 528 | public void SetFromItemID(UUID AssetId) |
457 | { | 529 | { |
458 | lock (m_parts) | 530 | lockPartsForRead(true); |
459 | { | 531 | { |
460 | foreach (SceneObjectPart part in m_parts.Values) | 532 | foreach (SceneObjectPart part in m_parts.Values) |
461 | { | 533 | { |
534 | |||
462 | part.FromItemID = AssetId; | 535 | part.FromItemID = AssetId; |
536 | |||
463 | } | 537 | } |
464 | } | 538 | } |
539 | lockPartsForRead(false); | ||
465 | } | 540 | } |
466 | 541 | ||
467 | public UUID GetFromItemID() | 542 | public UUID GetFromItemID() |
@@ -528,10 +603,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
528 | Vector3 maxScale = Vector3.Zero; | 603 | Vector3 maxScale = Vector3.Zero; |
529 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | 604 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); |
530 | 605 | ||
531 | lock (m_parts) | 606 | lockPartsForRead(true); |
532 | { | 607 | { |
533 | foreach (SceneObjectPart part in m_parts.Values) | 608 | foreach (SceneObjectPart part in m_parts.Values) |
534 | { | 609 | { |
610 | |||
535 | Vector3 partscale = part.Scale; | 611 | Vector3 partscale = part.Scale; |
536 | Vector3 partoffset = part.OffsetPosition; | 612 | Vector3 partoffset = part.OffsetPosition; |
537 | 613 | ||
@@ -542,8 +618,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
542 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | 618 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; |
543 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | 619 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; |
544 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | 620 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; |
621 | |||
545 | } | 622 | } |
546 | } | 623 | } |
624 | lockPartsForRead(false); | ||
625 | |||
547 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | 626 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; |
548 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | 627 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; |
549 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | 628 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; |
@@ -559,10 +638,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
559 | 638 | ||
560 | EntityIntersection result = new EntityIntersection(); | 639 | EntityIntersection result = new EntityIntersection(); |
561 | 640 | ||
562 | lock (m_parts) | 641 | lockPartsForRead(true); |
563 | { | 642 | { |
564 | foreach (SceneObjectPart part in m_parts.Values) | 643 | foreach (SceneObjectPart part in m_parts.Values) |
565 | { | 644 | { |
645 | |||
566 | // Temporary commented to stop compiler warning | 646 | // Temporary commented to stop compiler warning |
567 | //Vector3 partPosition = | 647 | //Vector3 partPosition = |
568 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); | 648 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); |
@@ -590,8 +670,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
590 | result.distance = inter.distance; | 670 | result.distance = inter.distance; |
591 | } | 671 | } |
592 | } | 672 | } |
673 | |||
593 | } | 674 | } |
594 | } | 675 | } |
676 | lockPartsForRead(false); | ||
595 | return result; | 677 | return result; |
596 | } | 678 | } |
597 | 679 | ||
@@ -604,10 +686,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
604 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) | 686 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) |
605 | { | 687 | { |
606 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; | 688 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; |
607 | lock (m_parts) | 689 | lockPartsForRead(true); |
608 | { | 690 | { |
609 | foreach (SceneObjectPart part in m_parts.Values) | 691 | foreach (SceneObjectPart part in m_parts.Values) |
610 | { | 692 | { |
693 | |||
611 | Vector3 worldPos = part.GetWorldPosition(); | 694 | Vector3 worldPos = part.GetWorldPosition(); |
612 | Vector3 offset = worldPos - AbsolutePosition; | 695 | Vector3 offset = worldPos - AbsolutePosition; |
613 | Quaternion worldRot; | 696 | Quaternion worldRot; |
@@ -666,6 +749,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
666 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); | 749 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); |
667 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); | 750 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); |
668 | 751 | ||
752 | |||
753 | |||
669 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); | 754 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); |
670 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); | 755 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); |
671 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); | 756 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); |
@@ -837,6 +922,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
837 | minZ = backBottomLeft.Z; | 922 | minZ = backBottomLeft.Z; |
838 | } | 923 | } |
839 | } | 924 | } |
925 | lockPartsForRead(false); | ||
840 | 926 | ||
841 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); | 927 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); |
842 | 928 | ||
@@ -865,17 +951,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
865 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); | 951 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); |
866 | 952 | ||
867 | // Capture script state while holding the lock | 953 | // Capture script state while holding the lock |
868 | lock (m_parts) | 954 | lockPartsForRead(true); |
869 | { | 955 | { |
870 | foreach (SceneObjectPart part in m_parts.Values) | 956 | foreach (SceneObjectPart part in m_parts.Values) |
871 | { | 957 | { |
958 | |||
872 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); | 959 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); |
873 | foreach (UUID itemid in pstates.Keys) | 960 | foreach (UUID itemid in pstates.Keys) |
874 | { | 961 | { |
875 | states.Add(itemid, pstates[itemid]); | 962 | states.Add(itemid, pstates[itemid]); |
876 | } | 963 | } |
964 | |||
877 | } | 965 | } |
878 | } | 966 | } |
967 | lockPartsForRead(false); | ||
879 | 968 | ||
880 | if (states.Count > 0) | 969 | if (states.Count > 0) |
881 | { | 970 | { |
@@ -1037,13 +1126,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1037 | 1126 | ||
1038 | public override void UpdateMovement() | 1127 | public override void UpdateMovement() |
1039 | { | 1128 | { |
1040 | lock (m_parts) | 1129 | lockPartsForRead(true); |
1041 | { | 1130 | { |
1042 | foreach (SceneObjectPart part in m_parts.Values) | 1131 | foreach (SceneObjectPart part in m_parts.Values) |
1043 | { | 1132 | { |
1133 | |||
1044 | part.UpdateMovement(); | 1134 | part.UpdateMovement(); |
1135 | |||
1045 | } | 1136 | } |
1046 | } | 1137 | } |
1138 | lockPartsForRead(false); | ||
1047 | } | 1139 | } |
1048 | 1140 | ||
1049 | public ushort GetTimeDilation() | 1141 | public ushort GetTimeDilation() |
@@ -1087,7 +1179,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1087 | /// <param name="part"></param> | 1179 | /// <param name="part"></param> |
1088 | public void AddPart(SceneObjectPart part) | 1180 | public void AddPart(SceneObjectPart part) |
1089 | { | 1181 | { |
1090 | lock (m_parts) | 1182 | lockPartsForWrite(true); |
1091 | { | 1183 | { |
1092 | part.SetParent(this); | 1184 | part.SetParent(this); |
1093 | m_parts.Add(part.UUID, part); | 1185 | m_parts.Add(part.UUID, part); |
@@ -1097,6 +1189,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1097 | if (part.LinkNum == 2 && RootPart != null) | 1189 | if (part.LinkNum == 2 && RootPart != null) |
1098 | RootPart.LinkNum = 1; | 1190 | RootPart.LinkNum = 1; |
1099 | } | 1191 | } |
1192 | lockPartsForWrite(false); | ||
1100 | } | 1193 | } |
1101 | 1194 | ||
1102 | /// <summary> | 1195 | /// <summary> |
@@ -1104,28 +1197,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1104 | /// </summary> | 1197 | /// </summary> |
1105 | private void UpdateParentIDs() | 1198 | private void UpdateParentIDs() |
1106 | { | 1199 | { |
1107 | lock (m_parts) | 1200 | lockPartsForRead(true); |
1108 | { | 1201 | { |
1109 | foreach (SceneObjectPart part in m_parts.Values) | 1202 | foreach (SceneObjectPart part in m_parts.Values) |
1110 | { | 1203 | { |
1204 | |||
1111 | if (part.UUID != m_rootPart.UUID) | 1205 | if (part.UUID != m_rootPart.UUID) |
1112 | { | 1206 | { |
1113 | part.ParentID = m_rootPart.LocalId; | 1207 | part.ParentID = m_rootPart.LocalId; |
1114 | } | 1208 | } |
1209 | |||
1115 | } | 1210 | } |
1116 | } | 1211 | } |
1212 | lockPartsForRead(false); | ||
1117 | } | 1213 | } |
1118 | 1214 | ||
1119 | public void RegenerateFullIDs() | 1215 | public void RegenerateFullIDs() |
1120 | { | 1216 | { |
1121 | lock (m_parts) | 1217 | lockPartsForRead(true); |
1122 | { | 1218 | { |
1123 | foreach (SceneObjectPart part in m_parts.Values) | 1219 | foreach (SceneObjectPart part in m_parts.Values) |
1124 | { | 1220 | { |
1221 | |||
1125 | part.UUID = UUID.Random(); | 1222 | part.UUID = UUID.Random(); |
1126 | 1223 | ||
1127 | } | 1224 | } |
1128 | } | 1225 | } |
1226 | lockPartsForRead(false); | ||
1129 | } | 1227 | } |
1130 | 1228 | ||
1131 | // helper provided for parts. | 1229 | // helper provided for parts. |
@@ -1206,29 +1304,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1206 | 1304 | ||
1207 | DetachFromBackup(); | 1305 | DetachFromBackup(); |
1208 | 1306 | ||
1209 | lock (m_parts) | 1307 | lockPartsForRead(true); |
1308 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1309 | lockPartsForRead(false); | ||
1310 | |||
1311 | foreach (SceneObjectPart part in values) | ||
1210 | { | 1312 | { |
1211 | foreach (SceneObjectPart part in m_parts.Values) | ||
1212 | { | ||
1213 | // part.Inventory.RemoveScriptInstances(); | 1313 | // part.Inventory.RemoveScriptInstances(); |
1214 | 1314 | ||
1215 | ScenePresence[] avatars = Scene.GetScenePresences(); | 1315 | ScenePresence[] avatars = Scene.GetScenePresences(); |
1216 | for (int i = 0; i < avatars.Length; i++) | 1316 | for (int i = 0; i < avatars.Length; i++) |
1317 | { | ||
1318 | if (avatars[i].ParentID == LocalId) | ||
1217 | { | 1319 | { |
1218 | if (avatars[i].ParentID == LocalId) | 1320 | avatars[i].StandUp(); |
1219 | { | 1321 | } |
1220 | avatars[i].StandUp(); | ||
1221 | } | ||
1222 | 1322 | ||
1223 | if (!silent) | 1323 | if (!silent) |
1224 | { | 1324 | { |
1225 | part.UpdateFlag = 0; | 1325 | part.UpdateFlag = 0; |
1226 | if (part == m_rootPart) | 1326 | if (part == m_rootPart) |
1227 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); | 1327 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); |
1228 | } | ||
1229 | } | 1328 | } |
1230 | } | 1329 | } |
1330 | |||
1231 | } | 1331 | } |
1332 | |||
1333 | |||
1232 | } | 1334 | } |
1233 | 1335 | ||
1234 | public void AddScriptLPS(int count) | 1336 | public void AddScriptLPS(int count) |
@@ -1253,17 +1355,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1253 | 1355 | ||
1254 | scriptEvents aggregateScriptEvents=0; | 1356 | scriptEvents aggregateScriptEvents=0; |
1255 | 1357 | ||
1256 | lock (m_parts) | 1358 | lockPartsForRead(true); |
1257 | { | 1359 | { |
1258 | foreach (SceneObjectPart part in m_parts.Values) | 1360 | foreach (SceneObjectPart part in m_parts.Values) |
1259 | { | 1361 | { |
1362 | |||
1260 | if (part == null) | 1363 | if (part == null) |
1261 | continue; | 1364 | continue; |
1262 | if (part != RootPart) | 1365 | if (part != RootPart) |
1263 | part.ObjectFlags = objectflagupdate; | 1366 | part.ObjectFlags = objectflagupdate; |
1264 | aggregateScriptEvents |= part.AggregateScriptEvents; | 1367 | aggregateScriptEvents |= part.AggregateScriptEvents; |
1368 | |||
1265 | } | 1369 | } |
1266 | } | 1370 | } |
1371 | lockPartsForRead(false); | ||
1267 | 1372 | ||
1268 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); | 1373 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); |
1269 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); | 1374 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); |
@@ -1305,42 +1410,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
1305 | /// <param name="m_physicalPrim"></param> | 1410 | /// <param name="m_physicalPrim"></param> |
1306 | public void ApplyPhysics(bool m_physicalPrim) | 1411 | public void ApplyPhysics(bool m_physicalPrim) |
1307 | { | 1412 | { |
1308 | lock (m_parts) | 1413 | lockPartsForRead(true); |
1414 | |||
1415 | if (m_parts.Count > 1) | ||
1309 | { | 1416 | { |
1310 | if (m_parts.Count > 1) | 1417 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); |
1418 | lockPartsForRead(false); | ||
1419 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1420 | foreach (SceneObjectPart part in values) | ||
1311 | { | 1421 | { |
1312 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | 1422 | |
1313 | foreach (SceneObjectPart part in m_parts.Values) | 1423 | if (part.LocalId != m_rootPart.LocalId) |
1314 | { | 1424 | { |
1315 | if (part.LocalId != m_rootPart.LocalId) | 1425 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); |
1316 | { | ||
1317 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); | ||
1318 | } | ||
1319 | } | 1426 | } |
1320 | 1427 | ||
1321 | // Hack to get the physics scene geometries in the right spot | ||
1322 | ResetChildPrimPhysicsPositions(); | ||
1323 | } | ||
1324 | else | ||
1325 | { | ||
1326 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1327 | } | 1428 | } |
1429 | // Hack to get the physics scene geometries in the right spot | ||
1430 | ResetChildPrimPhysicsPositions(); | ||
1431 | } | ||
1432 | else | ||
1433 | { | ||
1434 | lockPartsForRead(false); | ||
1435 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1328 | } | 1436 | } |
1329 | } | 1437 | } |
1330 | 1438 | ||
1331 | public void SetOwnerId(UUID userId) | 1439 | public void SetOwnerId(UUID userId) |
1332 | { | 1440 | { |
1333 | ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); | 1441 | ForEachPart(delegate(SceneObjectPart part) |
1442 | { | ||
1443 | |||
1444 | part.OwnerID = userId; | ||
1445 | |||
1446 | }); | ||
1334 | } | 1447 | } |
1335 | 1448 | ||
1336 | public void ForEachPart(Action<SceneObjectPart> whatToDo) | 1449 | public void ForEachPart(Action<SceneObjectPart> whatToDo) |
1337 | { | 1450 | { |
1338 | lock (m_parts) | 1451 | lockPartsForRead(true); |
1452 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1453 | lockPartsForRead(false); | ||
1454 | foreach (SceneObjectPart part in values) | ||
1339 | { | 1455 | { |
1340 | foreach (SceneObjectPart part in m_parts.Values) | 1456 | |
1341 | { | 1457 | whatToDo(part); |
1342 | whatToDo(part); | 1458 | |
1343 | } | ||
1344 | } | 1459 | } |
1345 | } | 1460 | } |
1346 | 1461 | ||
@@ -1439,14 +1554,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1439 | { | 1554 | { |
1440 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); | 1555 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); |
1441 | 1556 | ||
1442 | lock (m_parts) | 1557 | lockPartsForRead(true); |
1443 | { | 1558 | { |
1444 | foreach (SceneObjectPart part in m_parts.Values) | 1559 | foreach (SceneObjectPart part in m_parts.Values) |
1445 | { | 1560 | { |
1561 | |||
1446 | if (part != RootPart) | 1562 | if (part != RootPart) |
1447 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | 1563 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); |
1564 | |||
1448 | } | 1565 | } |
1449 | } | 1566 | } |
1567 | lockPartsForRead(false); | ||
1450 | } | 1568 | } |
1451 | 1569 | ||
1452 | /// <summary> | 1570 | /// <summary> |
@@ -1541,10 +1659,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1541 | 1659 | ||
1542 | List<SceneObjectPart> partList; | 1660 | List<SceneObjectPart> partList; |
1543 | 1661 | ||
1544 | lock (m_parts) | 1662 | lockPartsForRead(true); |
1545 | { | 1663 | |
1546 | partList = new List<SceneObjectPart>(m_parts.Values); | 1664 | partList = new List<SceneObjectPart>(m_parts.Values); |
1547 | } | 1665 | |
1666 | lockPartsForRead(false); | ||
1548 | 1667 | ||
1549 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) | 1668 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) |
1550 | { | 1669 | { |
@@ -1793,6 +1912,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1793 | } | 1912 | } |
1794 | } | 1913 | } |
1795 | } | 1914 | } |
1915 | |||
1796 | public void stopLookAt() | 1916 | public void stopLookAt() |
1797 | { | 1917 | { |
1798 | SceneObjectPart rootpart = m_rootPart; | 1918 | SceneObjectPart rootpart = m_rootPart; |
@@ -1867,10 +1987,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1867 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 1987 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); |
1868 | newPart.SetParent(this); | 1988 | newPart.SetParent(this); |
1869 | 1989 | ||
1870 | lock (m_parts) | 1990 | lockPartsForWrite(true); |
1871 | { | 1991 | { |
1872 | m_parts.Add(newPart.UUID, newPart); | 1992 | m_parts.Add(newPart.UUID, newPart); |
1873 | } | 1993 | } |
1994 | lockPartsForWrite(false); | ||
1874 | 1995 | ||
1875 | SetPartAsNonRoot(newPart); | 1996 | SetPartAsNonRoot(newPart); |
1876 | 1997 | ||
@@ -1933,7 +2054,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1933 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 2054 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
1934 | // return; | 2055 | // return; |
1935 | 2056 | ||
1936 | lock (m_parts) | 2057 | lockPartsForRead(true); |
1937 | { | 2058 | { |
1938 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 2059 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); |
1939 | 2060 | ||
@@ -1951,34 +2072,43 @@ namespace OpenSim.Region.Framework.Scenes | |||
1951 | 2072 | ||
1952 | foreach (SceneObjectPart part in m_parts.Values) | 2073 | foreach (SceneObjectPart part in m_parts.Values) |
1953 | { | 2074 | { |
2075 | |||
1954 | part.SendScheduledUpdates(); | 2076 | part.SendScheduledUpdates(); |
2077 | |||
1955 | } | 2078 | } |
1956 | } | 2079 | } |
2080 | lockPartsForRead(false); | ||
1957 | } | 2081 | } |
1958 | 2082 | ||
1959 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) | 2083 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) |
1960 | { | 2084 | { |
1961 | RootPart.AddFullUpdateToAvatar(presence); | 2085 | RootPart.AddFullUpdateToAvatar(presence); |
1962 | 2086 | ||
1963 | lock (m_parts) | 2087 | lockPartsForRead(true); |
1964 | { | 2088 | { |
1965 | foreach (SceneObjectPart part in m_parts.Values) | 2089 | foreach (SceneObjectPart part in m_parts.Values) |
1966 | { | 2090 | { |
2091 | |||
1967 | if (part != RootPart) | 2092 | if (part != RootPart) |
1968 | part.AddFullUpdateToAvatar(presence); | 2093 | part.AddFullUpdateToAvatar(presence); |
2094 | |||
1969 | } | 2095 | } |
1970 | } | 2096 | } |
2097 | lockPartsForRead(false); | ||
1971 | } | 2098 | } |
1972 | 2099 | ||
1973 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) | 2100 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) |
1974 | { | 2101 | { |
1975 | lock (m_parts) | 2102 | lockPartsForRead(true); |
1976 | { | 2103 | { |
1977 | foreach (SceneObjectPart part in m_parts.Values) | 2104 | foreach (SceneObjectPart part in m_parts.Values) |
1978 | { | 2105 | { |
2106 | |||
1979 | part.AddTerseUpdateToAvatar(presence); | 2107 | part.AddTerseUpdateToAvatar(presence); |
2108 | |||
1980 | } | 2109 | } |
1981 | } | 2110 | } |
2111 | lockPartsForRead(false); | ||
1982 | } | 2112 | } |
1983 | 2113 | ||
1984 | /// <summary> | 2114 | /// <summary> |
@@ -1989,14 +2119,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1989 | checkAtTargets(); | 2119 | checkAtTargets(); |
1990 | RootPart.ScheduleFullUpdate(); | 2120 | RootPart.ScheduleFullUpdate(); |
1991 | 2121 | ||
1992 | lock (m_parts) | 2122 | lockPartsForRead(true); |
1993 | { | 2123 | { |
1994 | foreach (SceneObjectPart part in m_parts.Values) | 2124 | foreach (SceneObjectPart part in m_parts.Values) |
1995 | { | 2125 | { |
2126 | |||
1996 | if (part != RootPart) | 2127 | if (part != RootPart) |
1997 | part.ScheduleFullUpdate(); | 2128 | part.ScheduleFullUpdate(); |
2129 | |||
1998 | } | 2130 | } |
1999 | } | 2131 | } |
2132 | lockPartsForRead(false); | ||
2000 | } | 2133 | } |
2001 | 2134 | ||
2002 | /// <summary> | 2135 | /// <summary> |
@@ -2004,13 +2137,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2004 | /// </summary> | 2137 | /// </summary> |
2005 | public void ScheduleGroupForTerseUpdate() | 2138 | public void ScheduleGroupForTerseUpdate() |
2006 | { | 2139 | { |
2007 | lock (m_parts) | 2140 | lockPartsForRead(true); |
2008 | { | 2141 | { |
2009 | foreach (SceneObjectPart part in m_parts.Values) | 2142 | foreach (SceneObjectPart part in m_parts.Values) |
2010 | { | 2143 | { |
2144 | |||
2011 | part.ScheduleTerseUpdate(); | 2145 | part.ScheduleTerseUpdate(); |
2146 | |||
2012 | } | 2147 | } |
2013 | } | 2148 | } |
2149 | lockPartsForRead(false); | ||
2014 | } | 2150 | } |
2015 | 2151 | ||
2016 | /// <summary> | 2152 | /// <summary> |
@@ -2023,14 +2159,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2023 | 2159 | ||
2024 | RootPart.SendFullUpdateToAllClients(); | 2160 | RootPart.SendFullUpdateToAllClients(); |
2025 | 2161 | ||
2026 | lock (m_parts) | 2162 | lockPartsForRead(true); |
2027 | { | 2163 | { |
2028 | foreach (SceneObjectPart part in m_parts.Values) | 2164 | foreach (SceneObjectPart part in m_parts.Values) |
2029 | { | 2165 | { |
2166 | |||
2030 | if (part != RootPart) | 2167 | if (part != RootPart) |
2031 | part.SendFullUpdateToAllClients(); | 2168 | part.SendFullUpdateToAllClients(); |
2169 | |||
2032 | } | 2170 | } |
2033 | } | 2171 | } |
2172 | lockPartsForRead(false); | ||
2034 | } | 2173 | } |
2035 | 2174 | ||
2036 | /// <summary> | 2175 | /// <summary> |
@@ -2061,14 +2200,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2061 | { | 2200 | { |
2062 | if (IsDeleted) | 2201 | if (IsDeleted) |
2063 | return; | 2202 | return; |
2064 | 2203 | ||
2065 | lock (m_parts) | 2204 | lockPartsForRead(true); |
2066 | { | 2205 | { |
2067 | foreach (SceneObjectPart part in m_parts.Values) | 2206 | foreach (SceneObjectPart part in m_parts.Values) |
2068 | { | 2207 | { |
2069 | part.SendTerseUpdateToAllClients(); | 2208 | part.SendTerseUpdateToAllClients(); |
2070 | } | 2209 | } |
2071 | } | 2210 | } |
2211 | lockPartsForRead(false); | ||
2072 | } | 2212 | } |
2073 | 2213 | ||
2074 | #endregion | 2214 | #endregion |
@@ -2082,16 +2222,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2082 | /// <returns>null if no child part with that linknum or child part</returns> | 2222 | /// <returns>null if no child part with that linknum or child part</returns> |
2083 | public SceneObjectPart GetLinkNumPart(int linknum) | 2223 | public SceneObjectPart GetLinkNumPart(int linknum) |
2084 | { | 2224 | { |
2085 | lock (m_parts) | 2225 | lockPartsForRead(true); |
2086 | { | 2226 | { |
2087 | foreach (SceneObjectPart part in m_parts.Values) | 2227 | foreach (SceneObjectPart part in m_parts.Values) |
2088 | { | 2228 | { |
2089 | if (part.LinkNum == linknum) | 2229 | if (part.LinkNum == linknum) |
2090 | { | 2230 | { |
2231 | lockPartsForRead(false); | ||
2091 | return part; | 2232 | return part; |
2092 | } | 2233 | } |
2093 | } | 2234 | } |
2094 | } | 2235 | } |
2236 | lockPartsForRead(false); | ||
2095 | 2237 | ||
2096 | return null; | 2238 | return null; |
2097 | } | 2239 | } |
@@ -2119,17 +2261,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2119 | public SceneObjectPart GetChildPart(uint localID) | 2261 | public SceneObjectPart GetChildPart(uint localID) |
2120 | { | 2262 | { |
2121 | //m_log.DebugFormat("Entered looking for {0}", localID); | 2263 | //m_log.DebugFormat("Entered looking for {0}", localID); |
2122 | lock (m_parts) | 2264 | lockPartsForRead(true); |
2123 | { | 2265 | { |
2124 | foreach (SceneObjectPart part in m_parts.Values) | 2266 | foreach (SceneObjectPart part in m_parts.Values) |
2125 | { | 2267 | { |
2126 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2268 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2127 | if (part.LocalId == localID) | 2269 | if (part.LocalId == localID) |
2128 | { | 2270 | { |
2271 | lockPartsForRead(false); | ||
2129 | return part; | 2272 | return part; |
2130 | } | 2273 | } |
2131 | } | 2274 | } |
2132 | } | 2275 | } |
2276 | lockPartsForRead(false); | ||
2133 | 2277 | ||
2134 | return null; | 2278 | return null; |
2135 | } | 2279 | } |
@@ -2159,17 +2303,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2159 | public bool HasChildPrim(uint localID) | 2303 | public bool HasChildPrim(uint localID) |
2160 | { | 2304 | { |
2161 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); | 2305 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); |
2162 | lock (m_parts) | 2306 | lockPartsForRead(true); |
2163 | { | 2307 | { |
2164 | foreach (SceneObjectPart part in m_parts.Values) | 2308 | foreach (SceneObjectPart part in m_parts.Values) |
2165 | { | 2309 | { |
2166 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2310 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2167 | if (part.LocalId == localID) | 2311 | if (part.LocalId == localID) |
2168 | { | 2312 | { |
2313 | lockPartsForRead(false); | ||
2169 | return true; | 2314 | return true; |
2170 | } | 2315 | } |
2171 | } | 2316 | } |
2172 | } | 2317 | } |
2318 | lockPartsForRead(false); | ||
2173 | 2319 | ||
2174 | return false; | 2320 | return false; |
2175 | } | 2321 | } |
@@ -2219,53 +2365,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
2219 | if (m_rootPart.LinkNum == 0) | 2365 | if (m_rootPart.LinkNum == 0) |
2220 | m_rootPart.LinkNum = 1; | 2366 | m_rootPart.LinkNum = 1; |
2221 | 2367 | ||
2222 | lock (m_parts) | 2368 | lockPartsForWrite(true); |
2223 | { | 2369 | |
2224 | m_parts.Add(linkPart.UUID, linkPart); | 2370 | m_parts.Add(linkPart.UUID, linkPart); |
2225 | 2371 | ||
2226 | // Insert in terms of link numbers, the new links | 2372 | lockPartsForWrite(false); |
2227 | // before the current ones (with the exception of | 2373 | |
2228 | // the root prim. Shuffle the old ones up | 2374 | // Insert in terms of link numbers, the new links |
2229 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | 2375 | // before the current ones (with the exception of |
2376 | // the root prim. Shuffle the old ones up | ||
2377 | lockPartsForRead(true); | ||
2378 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | ||
2379 | { | ||
2380 | if (kvp.Value.LinkNum != 1) | ||
2230 | { | 2381 | { |
2231 | if (kvp.Value.LinkNum != 1) | 2382 | // Don't update root prim link number |
2232 | { | 2383 | kvp.Value.LinkNum += objectGroup.PrimCount; |
2233 | // Don't update root prim link number | ||
2234 | kvp.Value.LinkNum += objectGroup.PrimCount; | ||
2235 | } | ||
2236 | } | 2384 | } |
2385 | } | ||
2386 | lockPartsForRead(false); | ||
2237 | 2387 | ||
2238 | linkPart.LinkNum = 2; | 2388 | linkPart.LinkNum = 2; |
2239 | 2389 | ||
2240 | linkPart.SetParent(this); | 2390 | linkPart.SetParent(this); |
2241 | linkPart.AddFlag(PrimFlags.CreateSelected); | 2391 | linkPart.AddFlag(PrimFlags.CreateSelected); |
2242 | 2392 | ||
2243 | //if (linkPart.PhysActor != null) | 2393 | //if (linkPart.PhysActor != null) |
2244 | //{ | 2394 | //{ |
2245 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); | 2395 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); |
2246 | 2396 | ||
2247 | //linkPart.PhysActor = null; | 2397 | //linkPart.PhysActor = null; |
2248 | //} | 2398 | //} |
2249 | 2399 | ||
2250 | //TODO: rest of parts | 2400 | //TODO: rest of parts |
2251 | int linkNum = 3; | 2401 | int linkNum = 3; |
2252 | foreach (SceneObjectPart part in objectGroup.Children.Values) | 2402 | foreach (SceneObjectPart part in objectGroup.Children.Values) |
2403 | { | ||
2404 | if (part.UUID != objectGroup.m_rootPart.UUID) | ||
2253 | { | 2405 | { |
2254 | if (part.UUID != objectGroup.m_rootPart.UUID) | 2406 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); |
2255 | { | ||
2256 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); | ||
2257 | } | ||
2258 | part.ClearUndoState(); | ||
2259 | } | 2407 | } |
2408 | part.ClearUndoState(); | ||
2260 | } | 2409 | } |
2261 | 2410 | ||
2262 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); | 2411 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); |
2263 | objectGroup.m_isDeleted = true; | 2412 | objectGroup.m_isDeleted = true; |
2413 | |||
2414 | objectGroup.lockPartsForWrite(true); | ||
2264 | 2415 | ||
2265 | lock (objectGroup.m_parts) | 2416 | objectGroup.m_parts.Clear(); |
2266 | { | 2417 | |
2267 | objectGroup.m_parts.Clear(); | 2418 | objectGroup.lockPartsForWrite(false); |
2268 | } | ||
2269 | 2419 | ||
2270 | // Can't do this yet since backup still makes use of the root part without any synchronization | 2420 | // Can't do this yet since backup still makes use of the root part without any synchronization |
2271 | // objectGroup.m_rootPart = null; | 2421 | // objectGroup.m_rootPart = null; |
@@ -2324,11 +2474,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2324 | Quaternion worldRot = linkPart.GetWorldRotation(); | 2474 | Quaternion worldRot = linkPart.GetWorldRotation(); |
2325 | 2475 | ||
2326 | // Remove the part from this object | 2476 | // Remove the part from this object |
2327 | lock (m_parts) | 2477 | lockPartsForWrite(true); |
2328 | { | 2478 | { |
2329 | m_parts.Remove(linkPart.UUID); | 2479 | m_parts.Remove(linkPart.UUID); |
2330 | } | 2480 | } |
2331 | 2481 | lockPartsForWrite(false); | |
2482 | lockPartsForRead(true); | ||
2332 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | 2483 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left |
2333 | RootPart.LinkNum = 0; | 2484 | RootPart.LinkNum = 0; |
2334 | else | 2485 | else |
@@ -2339,6 +2490,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2339 | p.LinkNum--; | 2490 | p.LinkNum--; |
2340 | } | 2491 | } |
2341 | } | 2492 | } |
2493 | lockPartsForRead(false); | ||
2342 | 2494 | ||
2343 | linkPart.ParentID = 0; | 2495 | linkPart.ParentID = 0; |
2344 | linkPart.LinkNum = 0; | 2496 | linkPart.LinkNum = 0; |
@@ -2656,9 +2808,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2656 | 2808 | ||
2657 | if (selectionPart != null) | 2809 | if (selectionPart != null) |
2658 | { | 2810 | { |
2659 | lock (m_parts) | 2811 | lockPartsForRead(true); |
2812 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | ||
2813 | lockPartsForRead(false); | ||
2814 | foreach (SceneObjectPart part in parts) | ||
2660 | { | 2815 | { |
2661 | foreach (SceneObjectPart part in m_parts.Values) | 2816 | if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) |
2662 | { | 2817 | { |
2663 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | 2818 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || |
2664 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | 2819 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || |
@@ -2668,12 +2823,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2668 | break; | 2823 | break; |
2669 | } | 2824 | } |
2670 | } | 2825 | } |
2826 | } | ||
2671 | 2827 | ||
2672 | foreach (SceneObjectPart part in m_parts.Values) | 2828 | foreach (SceneObjectPart part in parts) |
2673 | { | 2829 | { |
2674 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2830 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
2675 | } | ||
2676 | } | 2831 | } |
2832 | |||
2677 | } | 2833 | } |
2678 | } | 2834 | } |
2679 | 2835 | ||
@@ -2759,11 +2915,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2759 | scale.Y = m_scene.m_maxNonphys; | 2915 | scale.Y = m_scene.m_maxNonphys; |
2760 | if (scale.Z > m_scene.m_maxNonphys) | 2916 | if (scale.Z > m_scene.m_maxNonphys) |
2761 | scale.Z = m_scene.m_maxNonphys; | 2917 | scale.Z = m_scene.m_maxNonphys; |
2762 | |||
2763 | SceneObjectPart part = GetChildPart(localID); | 2918 | SceneObjectPart part = GetChildPart(localID); |
2764 | if (part != null) | 2919 | if (part != null) |
2765 | { | 2920 | { |
2766 | part.Resize(scale); | ||
2767 | if (part.PhysActor != null) | 2921 | if (part.PhysActor != null) |
2768 | { | 2922 | { |
2769 | if (part.PhysActor.IsPhysical) | 2923 | if (part.PhysActor.IsPhysical) |
@@ -2778,7 +2932,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2778 | part.PhysActor.Size = scale; | 2932 | part.PhysActor.Size = scale; |
2779 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 2933 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); |
2780 | } | 2934 | } |
2781 | //if (part.UUID != m_rootPart.UUID) | 2935 | part.Resize(scale); |
2782 | 2936 | ||
2783 | HasGroupChanged = true; | 2937 | HasGroupChanged = true; |
2784 | ScheduleGroupForFullUpdate(); | 2938 | ScheduleGroupForFullUpdate(); |
@@ -2819,77 +2973,76 @@ namespace OpenSim.Region.Framework.Scenes | |||
2819 | float y = (scale.Y / part.Scale.Y); | 2973 | float y = (scale.Y / part.Scale.Y); |
2820 | float z = (scale.Z / part.Scale.Z); | 2974 | float z = (scale.Z / part.Scale.Z); |
2821 | 2975 | ||
2822 | lock (m_parts) | 2976 | lockPartsForRead(true); |
2977 | if (x > 1.0f || y > 1.0f || z > 1.0f) | ||
2823 | { | 2978 | { |
2824 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 2979 | foreach (SceneObjectPart obPart in m_parts.Values) |
2825 | { | 2980 | { |
2826 | foreach (SceneObjectPart obPart in m_parts.Values) | 2981 | if (obPart.UUID != m_rootPart.UUID) |
2827 | { | 2982 | { |
2828 | if (obPart.UUID != m_rootPart.UUID) | 2983 | Vector3 oldSize = new Vector3(obPart.Scale); |
2829 | { | ||
2830 | Vector3 oldSize = new Vector3(obPart.Scale); | ||
2831 | 2984 | ||
2832 | float f = 1.0f; | 2985 | float f = 1.0f; |
2833 | float a = 1.0f; | 2986 | float a = 1.0f; |
2834 | 2987 | ||
2835 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | 2988 | if (part.PhysActor != null && part.PhysActor.IsPhysical) |
2989 | { | ||
2990 | if (oldSize.X*x > m_scene.m_maxPhys) | ||
2836 | { | 2991 | { |
2837 | if (oldSize.X*x > m_scene.m_maxPhys) | 2992 | f = m_scene.m_maxPhys / oldSize.X; |
2838 | { | 2993 | a = f / x; |
2839 | f = m_scene.m_maxPhys / oldSize.X; | 2994 | x *= a; |
2840 | a = f / x; | 2995 | y *= a; |
2841 | x *= a; | 2996 | z *= a; |
2842 | y *= a; | ||
2843 | z *= a; | ||
2844 | } | ||
2845 | if (oldSize.Y*y > m_scene.m_maxPhys) | ||
2846 | { | ||
2847 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2848 | a = f / y; | ||
2849 | x *= a; | ||
2850 | y *= a; | ||
2851 | z *= a; | ||
2852 | } | ||
2853 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
2854 | { | ||
2855 | f = m_scene.m_maxPhys / oldSize.Z; | ||
2856 | a = f / z; | ||
2857 | x *= a; | ||
2858 | y *= a; | ||
2859 | z *= a; | ||
2860 | } | ||
2861 | } | 2997 | } |
2862 | else | 2998 | if (oldSize.Y*y > m_scene.m_maxPhys) |
2999 | { | ||
3000 | f = m_scene.m_maxPhys / oldSize.Y; | ||
3001 | a = f / y; | ||
3002 | x *= a; | ||
3003 | y *= a; | ||
3004 | z *= a; | ||
3005 | } | ||
3006 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
3007 | { | ||
3008 | f = m_scene.m_maxPhys / oldSize.Z; | ||
3009 | a = f / z; | ||
3010 | x *= a; | ||
3011 | y *= a; | ||
3012 | z *= a; | ||
3013 | } | ||
3014 | } | ||
3015 | else | ||
3016 | { | ||
3017 | if (oldSize.X*x > m_scene.m_maxNonphys) | ||
3018 | { | ||
3019 | f = m_scene.m_maxNonphys / oldSize.X; | ||
3020 | a = f / x; | ||
3021 | x *= a; | ||
3022 | y *= a; | ||
3023 | z *= a; | ||
3024 | } | ||
3025 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
3026 | { | ||
3027 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
3028 | a = f / y; | ||
3029 | x *= a; | ||
3030 | y *= a; | ||
3031 | z *= a; | ||
3032 | } | ||
3033 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2863 | { | 3034 | { |
2864 | if (oldSize.X*x > m_scene.m_maxNonphys) | 3035 | f = m_scene.m_maxNonphys / oldSize.Z; |
2865 | { | 3036 | a = f / z; |
2866 | f = m_scene.m_maxNonphys / oldSize.X; | 3037 | x *= a; |
2867 | a = f / x; | 3038 | y *= a; |
2868 | x *= a; | 3039 | z *= a; |
2869 | y *= a; | ||
2870 | z *= a; | ||
2871 | } | ||
2872 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
2873 | { | ||
2874 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
2875 | a = f / y; | ||
2876 | x *= a; | ||
2877 | y *= a; | ||
2878 | z *= a; | ||
2879 | } | ||
2880 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2881 | { | ||
2882 | f = m_scene.m_maxNonphys / oldSize.Z; | ||
2883 | a = f / z; | ||
2884 | x *= a; | ||
2885 | y *= a; | ||
2886 | z *= a; | ||
2887 | } | ||
2888 | } | 3040 | } |
2889 | } | 3041 | } |
2890 | } | 3042 | } |
2891 | } | 3043 | } |
2892 | } | 3044 | } |
3045 | lockPartsForRead(false); | ||
2893 | 3046 | ||
2894 | Vector3 prevScale = part.Scale; | 3047 | Vector3 prevScale = part.Scale; |
2895 | prevScale.X *= x; | 3048 | prevScale.X *= x; |
@@ -2897,7 +3050,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2897 | prevScale.Z *= z; | 3050 | prevScale.Z *= z; |
2898 | part.Resize(prevScale); | 3051 | part.Resize(prevScale); |
2899 | 3052 | ||
2900 | lock (m_parts) | 3053 | lockPartsForRead(true); |
2901 | { | 3054 | { |
2902 | foreach (SceneObjectPart obPart in m_parts.Values) | 3055 | foreach (SceneObjectPart obPart in m_parts.Values) |
2903 | { | 3056 | { |
@@ -2916,6 +3069,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2916 | } | 3069 | } |
2917 | } | 3070 | } |
2918 | } | 3071 | } |
3072 | lockPartsForRead(false); | ||
2919 | 3073 | ||
2920 | if (part.PhysActor != null) | 3074 | if (part.PhysActor != null) |
2921 | { | 3075 | { |
@@ -2996,7 +3150,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2996 | axDiff *= Quaternion.Inverse(partRotation); | 3150 | axDiff *= Quaternion.Inverse(partRotation); |
2997 | diff = axDiff; | 3151 | diff = axDiff; |
2998 | 3152 | ||
2999 | lock (m_parts) | 3153 | lockPartsForRead(true); |
3000 | { | 3154 | { |
3001 | foreach (SceneObjectPart obPart in m_parts.Values) | 3155 | foreach (SceneObjectPart obPart in m_parts.Values) |
3002 | { | 3156 | { |
@@ -3006,6 +3160,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3006 | } | 3160 | } |
3007 | } | 3161 | } |
3008 | } | 3162 | } |
3163 | lockPartsForRead(false); | ||
3009 | 3164 | ||
3010 | AbsolutePosition = newPos; | 3165 | AbsolutePosition = newPos; |
3011 | 3166 | ||
@@ -3123,7 +3278,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3123 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 3278 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); |
3124 | } | 3279 | } |
3125 | 3280 | ||
3126 | lock (m_parts) | 3281 | lockPartsForRead(true); |
3127 | { | 3282 | { |
3128 | foreach (SceneObjectPart prim in m_parts.Values) | 3283 | foreach (SceneObjectPart prim in m_parts.Values) |
3129 | { | 3284 | { |
@@ -3141,6 +3296,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3141 | } | 3296 | } |
3142 | } | 3297 | } |
3143 | } | 3298 | } |
3299 | lockPartsForRead(false); | ||
3144 | 3300 | ||
3145 | m_rootPart.ScheduleTerseUpdate(); | 3301 | m_rootPart.ScheduleTerseUpdate(); |
3146 | } | 3302 | } |
@@ -3263,7 +3419,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3263 | if (atTargets.Count > 0) | 3419 | if (atTargets.Count > 0) |
3264 | { | 3420 | { |
3265 | uint[] localids = new uint[0]; | 3421 | uint[] localids = new uint[0]; |
3266 | lock (m_parts) | 3422 | lockPartsForRead(true); |
3267 | { | 3423 | { |
3268 | localids = new uint[m_parts.Count]; | 3424 | localids = new uint[m_parts.Count]; |
3269 | int cntr = 0; | 3425 | int cntr = 0; |
@@ -3273,6 +3429,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3273 | cntr++; | 3429 | cntr++; |
3274 | } | 3430 | } |
3275 | } | 3431 | } |
3432 | lockPartsForRead(false); | ||
3276 | 3433 | ||
3277 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3434 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3278 | { | 3435 | { |
@@ -3291,7 +3448,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3291 | { | 3448 | { |
3292 | //trigger not_at_target | 3449 | //trigger not_at_target |
3293 | uint[] localids = new uint[0]; | 3450 | uint[] localids = new uint[0]; |
3294 | lock (m_parts) | 3451 | lockPartsForRead(true); |
3295 | { | 3452 | { |
3296 | localids = new uint[m_parts.Count]; | 3453 | localids = new uint[m_parts.Count]; |
3297 | int cntr = 0; | 3454 | int cntr = 0; |
@@ -3301,7 +3458,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3301 | cntr++; | 3458 | cntr++; |
3302 | } | 3459 | } |
3303 | } | 3460 | } |
3304 | 3461 | lockPartsForRead(false); | |
3462 | |||
3305 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3463 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3306 | { | 3464 | { |
3307 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); | 3465 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); |
@@ -3393,19 +3551,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3393 | public float GetMass() | 3551 | public float GetMass() |
3394 | { | 3552 | { |
3395 | float retmass = 0f; | 3553 | float retmass = 0f; |
3396 | lock (m_parts) | 3554 | lockPartsForRead(true); |
3397 | { | 3555 | { |
3398 | foreach (SceneObjectPart part in m_parts.Values) | 3556 | foreach (SceneObjectPart part in m_parts.Values) |
3399 | { | 3557 | { |
3400 | retmass += part.GetMass(); | 3558 | retmass += part.GetMass(); |
3401 | } | 3559 | } |
3402 | } | 3560 | } |
3561 | lockPartsForRead(false); | ||
3403 | return retmass; | 3562 | return retmass; |
3404 | } | 3563 | } |
3405 | 3564 | ||
3406 | public void CheckSculptAndLoad() | 3565 | public void CheckSculptAndLoad() |
3407 | { | 3566 | { |
3408 | lock (m_parts) | 3567 | lockPartsForRead(true); |
3409 | { | 3568 | { |
3410 | if (!IsDeleted) | 3569 | if (!IsDeleted) |
3411 | { | 3570 | { |
@@ -3430,6 +3589,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3430 | } | 3589 | } |
3431 | } | 3590 | } |
3432 | } | 3591 | } |
3592 | lockPartsForRead(false); | ||
3433 | } | 3593 | } |
3434 | 3594 | ||
3435 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 3595 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
@@ -3450,7 +3610,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3450 | /// <param name="client"></param> | 3610 | /// <param name="client"></param> |
3451 | public void SetGroup(UUID GroupID, IClientAPI client) | 3611 | public void SetGroup(UUID GroupID, IClientAPI client) |
3452 | { | 3612 | { |
3453 | lock (m_parts) | 3613 | lockPartsForRead(true); |
3454 | { | 3614 | { |
3455 | foreach (SceneObjectPart part in m_parts.Values) | 3615 | foreach (SceneObjectPart part in m_parts.Values) |
3456 | { | 3616 | { |
@@ -3460,7 +3620,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3460 | 3620 | ||
3461 | HasGroupChanged = true; | 3621 | HasGroupChanged = true; |
3462 | } | 3622 | } |
3463 | 3623 | lockPartsForRead(false); | |
3464 | ScheduleGroupForFullUpdate(); | 3624 | ScheduleGroupForFullUpdate(); |
3465 | } | 3625 | } |
3466 | 3626 | ||
@@ -3479,11 +3639,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3479 | 3639 | ||
3480 | public void SetAttachmentPoint(byte point) | 3640 | public void SetAttachmentPoint(byte point) |
3481 | { | 3641 | { |
3482 | lock (m_parts) | 3642 | lockPartsForRead(true); |
3483 | { | 3643 | { |
3484 | foreach (SceneObjectPart part in m_parts.Values) | 3644 | foreach (SceneObjectPart part in m_parts.Values) |
3485 | part.SetAttachmentPoint(point); | 3645 | part.SetAttachmentPoint(point); |
3486 | } | 3646 | } |
3647 | lockPartsForRead(false); | ||
3487 | } | 3648 | } |
3488 | 3649 | ||
3489 | #region ISceneObject | 3650 | #region ISceneObject |