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 34d8b49..e63e8d9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -98,6 +98,72 @@ namespace OpenSim.Region.Framework.Scenes | |||
98 | private bool m_hasGroupChanged = false; | 98 | private bool m_hasGroupChanged = false; |
99 | private long timeFirstChanged; | 99 | private long timeFirstChanged; |
100 | private long timeLastChanged; | 100 | private long timeLastChanged; |
101 | private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
102 | |||
103 | public void lockPartsForRead(bool locked) | ||
104 | { | ||
105 | if (locked) | ||
106 | { | ||
107 | if (m_partsLock.RecursiveReadCount > 0) | ||
108 | { | ||
109 | m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
110 | m_partsLock.ExitReadLock(); | ||
111 | } | ||
112 | if (m_partsLock.RecursiveWriteCount > 0) | ||
113 | { | ||
114 | m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed."); | ||
115 | m_partsLock.ExitWriteLock(); | ||
116 | } | ||
117 | |||
118 | while (!m_partsLock.TryEnterReadLock(60000)) | ||
119 | { | ||
120 | m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
121 | if (m_partsLock.IsWriteLockHeld) | ||
122 | { | ||
123 | m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | else | ||
128 | { | ||
129 | if (m_partsLock.RecursiveReadCount > 0) | ||
130 | { | ||
131 | m_partsLock.ExitReadLock(); | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | public void lockPartsForWrite(bool locked) | ||
136 | { | ||
137 | if (locked) | ||
138 | { | ||
139 | if (m_partsLock.RecursiveReadCount > 0) | ||
140 | { | ||
141 | m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
142 | m_partsLock.ExitReadLock(); | ||
143 | } | ||
144 | if (m_partsLock.RecursiveWriteCount > 0) | ||
145 | { | ||
146 | m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
147 | m_partsLock.ExitWriteLock(); | ||
148 | } | ||
149 | |||
150 | while (!m_partsLock.TryEnterWriteLock(60000)) | ||
151 | { | ||
152 | m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
153 | if (m_partsLock.IsWriteLockHeld) | ||
154 | { | ||
155 | m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | if (m_partsLock.RecursiveWriteCount > 0) | ||
162 | { | ||
163 | m_partsLock.ExitWriteLock(); | ||
164 | } | ||
165 | } | ||
166 | } | ||
101 | 167 | ||
102 | public bool HasGroupChanged | 168 | public bool HasGroupChanged |
103 | { | 169 | { |
@@ -243,13 +309,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
243 | set | 309 | set |
244 | { | 310 | { |
245 | m_regionHandle = value; | 311 | m_regionHandle = value; |
246 | lock (m_parts) | 312 | lockPartsForRead(true); |
247 | { | 313 | { |
248 | foreach (SceneObjectPart part in m_parts.Values) | 314 | foreach (SceneObjectPart part in m_parts.Values) |
249 | { | 315 | { |
316 | |||
250 | part.RegionHandle = m_regionHandle; | 317 | part.RegionHandle = m_regionHandle; |
318 | |||
251 | } | 319 | } |
252 | } | 320 | } |
321 | lockPartsForRead(false); | ||
253 | } | 322 | } |
254 | } | 323 | } |
255 | 324 | ||
@@ -275,13 +344,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
275 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 344 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
276 | } | 345 | } |
277 | 346 | ||
278 | lock (m_parts) | 347 | lockPartsForRead(true); |
279 | { | 348 | { |
280 | foreach (SceneObjectPart part in m_parts.Values) | 349 | foreach (SceneObjectPart part in m_parts.Values) |
281 | { | 350 | { |
351 | |||
282 | part.GroupPosition = val; | 352 | part.GroupPosition = val; |
353 | |||
283 | } | 354 | } |
284 | } | 355 | } |
356 | lockPartsForRead(false); | ||
285 | 357 | ||
286 | //if (m_rootPart.PhysActor != null) | 358 | //if (m_rootPart.PhysActor != null) |
287 | //{ | 359 | //{ |
@@ -443,13 +515,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
443 | 515 | ||
444 | public void SetFromItemID(UUID AssetId) | 516 | public void SetFromItemID(UUID AssetId) |
445 | { | 517 | { |
446 | lock (m_parts) | 518 | lockPartsForRead(true); |
447 | { | 519 | { |
448 | foreach (SceneObjectPart part in m_parts.Values) | 520 | foreach (SceneObjectPart part in m_parts.Values) |
449 | { | 521 | { |
522 | |||
450 | part.FromItemID = AssetId; | 523 | part.FromItemID = AssetId; |
524 | |||
451 | } | 525 | } |
452 | } | 526 | } |
527 | lockPartsForRead(false); | ||
453 | } | 528 | } |
454 | 529 | ||
455 | public UUID GetFromItemID() | 530 | public UUID GetFromItemID() |
@@ -516,10 +591,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
516 | Vector3 maxScale = Vector3.Zero; | 591 | Vector3 maxScale = Vector3.Zero; |
517 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | 592 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); |
518 | 593 | ||
519 | lock (m_parts) | 594 | lockPartsForRead(true); |
520 | { | 595 | { |
521 | foreach (SceneObjectPart part in m_parts.Values) | 596 | foreach (SceneObjectPart part in m_parts.Values) |
522 | { | 597 | { |
598 | |||
523 | Vector3 partscale = part.Scale; | 599 | Vector3 partscale = part.Scale; |
524 | Vector3 partoffset = part.OffsetPosition; | 600 | Vector3 partoffset = part.OffsetPosition; |
525 | 601 | ||
@@ -530,8 +606,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
530 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | 606 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; |
531 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | 607 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; |
532 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | 608 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; |
609 | |||
533 | } | 610 | } |
534 | } | 611 | } |
612 | lockPartsForRead(false); | ||
613 | |||
535 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | 614 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; |
536 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | 615 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; |
537 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | 616 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; |
@@ -547,10 +626,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
547 | 626 | ||
548 | EntityIntersection result = new EntityIntersection(); | 627 | EntityIntersection result = new EntityIntersection(); |
549 | 628 | ||
550 | lock (m_parts) | 629 | lockPartsForRead(true); |
551 | { | 630 | { |
552 | foreach (SceneObjectPart part in m_parts.Values) | 631 | foreach (SceneObjectPart part in m_parts.Values) |
553 | { | 632 | { |
633 | |||
554 | // Temporary commented to stop compiler warning | 634 | // Temporary commented to stop compiler warning |
555 | //Vector3 partPosition = | 635 | //Vector3 partPosition = |
556 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); | 636 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); |
@@ -578,8 +658,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
578 | result.distance = inter.distance; | 658 | result.distance = inter.distance; |
579 | } | 659 | } |
580 | } | 660 | } |
661 | |||
581 | } | 662 | } |
582 | } | 663 | } |
664 | lockPartsForRead(false); | ||
583 | return result; | 665 | return result; |
584 | } | 666 | } |
585 | 667 | ||
@@ -592,10 +674,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
592 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) | 674 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) |
593 | { | 675 | { |
594 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; | 676 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; |
595 | lock (m_parts) | 677 | lockPartsForRead(true); |
596 | { | 678 | { |
597 | foreach (SceneObjectPart part in m_parts.Values) | 679 | foreach (SceneObjectPart part in m_parts.Values) |
598 | { | 680 | { |
681 | |||
599 | Vector3 worldPos = part.GetWorldPosition(); | 682 | Vector3 worldPos = part.GetWorldPosition(); |
600 | Vector3 offset = worldPos - AbsolutePosition; | 683 | Vector3 offset = worldPos - AbsolutePosition; |
601 | Quaternion worldRot; | 684 | Quaternion worldRot; |
@@ -654,6 +737,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
654 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); | 737 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); |
655 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); | 738 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); |
656 | 739 | ||
740 | |||
741 | |||
657 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); | 742 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); |
658 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); | 743 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); |
659 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); | 744 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); |
@@ -825,6 +910,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
825 | minZ = backBottomLeft.Z; | 910 | minZ = backBottomLeft.Z; |
826 | } | 911 | } |
827 | } | 912 | } |
913 | lockPartsForRead(false); | ||
828 | 914 | ||
829 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); | 915 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); |
830 | 916 | ||
@@ -853,17 +939,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
853 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); | 939 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); |
854 | 940 | ||
855 | // Capture script state while holding the lock | 941 | // Capture script state while holding the lock |
856 | lock (m_parts) | 942 | lockPartsForRead(true); |
857 | { | 943 | { |
858 | foreach (SceneObjectPart part in m_parts.Values) | 944 | foreach (SceneObjectPart part in m_parts.Values) |
859 | { | 945 | { |
946 | |||
860 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); | 947 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); |
861 | foreach (UUID itemid in pstates.Keys) | 948 | foreach (UUID itemid in pstates.Keys) |
862 | { | 949 | { |
863 | states.Add(itemid, pstates[itemid]); | 950 | states.Add(itemid, pstates[itemid]); |
864 | } | 951 | } |
952 | |||
865 | } | 953 | } |
866 | } | 954 | } |
955 | lockPartsForRead(false); | ||
867 | 956 | ||
868 | if (states.Count > 0) | 957 | if (states.Count > 0) |
869 | { | 958 | { |
@@ -1025,13 +1114,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1025 | 1114 | ||
1026 | public override void UpdateMovement() | 1115 | public override void UpdateMovement() |
1027 | { | 1116 | { |
1028 | lock (m_parts) | 1117 | lockPartsForRead(true); |
1029 | { | 1118 | { |
1030 | foreach (SceneObjectPart part in m_parts.Values) | 1119 | foreach (SceneObjectPart part in m_parts.Values) |
1031 | { | 1120 | { |
1121 | |||
1032 | part.UpdateMovement(); | 1122 | part.UpdateMovement(); |
1123 | |||
1033 | } | 1124 | } |
1034 | } | 1125 | } |
1126 | lockPartsForRead(false); | ||
1035 | } | 1127 | } |
1036 | 1128 | ||
1037 | public ushort GetTimeDilation() | 1129 | public ushort GetTimeDilation() |
@@ -1075,7 +1167,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1075 | /// <param name="part"></param> | 1167 | /// <param name="part"></param> |
1076 | public void AddPart(SceneObjectPart part) | 1168 | public void AddPart(SceneObjectPart part) |
1077 | { | 1169 | { |
1078 | lock (m_parts) | 1170 | lockPartsForWrite(true); |
1079 | { | 1171 | { |
1080 | part.SetParent(this); | 1172 | part.SetParent(this); |
1081 | m_parts.Add(part.UUID, part); | 1173 | m_parts.Add(part.UUID, part); |
@@ -1085,6 +1177,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1085 | if (part.LinkNum == 2 && RootPart != null) | 1177 | if (part.LinkNum == 2 && RootPart != null) |
1086 | RootPart.LinkNum = 1; | 1178 | RootPart.LinkNum = 1; |
1087 | } | 1179 | } |
1180 | lockPartsForWrite(false); | ||
1088 | } | 1181 | } |
1089 | 1182 | ||
1090 | /// <summary> | 1183 | /// <summary> |
@@ -1092,28 +1185,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1092 | /// </summary> | 1185 | /// </summary> |
1093 | private void UpdateParentIDs() | 1186 | private void UpdateParentIDs() |
1094 | { | 1187 | { |
1095 | lock (m_parts) | 1188 | lockPartsForRead(true); |
1096 | { | 1189 | { |
1097 | foreach (SceneObjectPart part in m_parts.Values) | 1190 | foreach (SceneObjectPart part in m_parts.Values) |
1098 | { | 1191 | { |
1192 | |||
1099 | if (part.UUID != m_rootPart.UUID) | 1193 | if (part.UUID != m_rootPart.UUID) |
1100 | { | 1194 | { |
1101 | part.ParentID = m_rootPart.LocalId; | 1195 | part.ParentID = m_rootPart.LocalId; |
1102 | } | 1196 | } |
1197 | |||
1103 | } | 1198 | } |
1104 | } | 1199 | } |
1200 | lockPartsForRead(false); | ||
1105 | } | 1201 | } |
1106 | 1202 | ||
1107 | public void RegenerateFullIDs() | 1203 | public void RegenerateFullIDs() |
1108 | { | 1204 | { |
1109 | lock (m_parts) | 1205 | lockPartsForRead(true); |
1110 | { | 1206 | { |
1111 | foreach (SceneObjectPart part in m_parts.Values) | 1207 | foreach (SceneObjectPart part in m_parts.Values) |
1112 | { | 1208 | { |
1209 | |||
1113 | part.UUID = UUID.Random(); | 1210 | part.UUID = UUID.Random(); |
1114 | 1211 | ||
1115 | } | 1212 | } |
1116 | } | 1213 | } |
1214 | lockPartsForRead(false); | ||
1117 | } | 1215 | } |
1118 | 1216 | ||
1119 | // helper provided for parts. | 1217 | // helper provided for parts. |
@@ -1194,29 +1292,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1194 | 1292 | ||
1195 | DetachFromBackup(); | 1293 | DetachFromBackup(); |
1196 | 1294 | ||
1197 | lock (m_parts) | 1295 | lockPartsForRead(true); |
1296 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1297 | lockPartsForRead(false); | ||
1298 | |||
1299 | foreach (SceneObjectPart part in values) | ||
1198 | { | 1300 | { |
1199 | foreach (SceneObjectPart part in m_parts.Values) | ||
1200 | { | ||
1201 | // part.Inventory.RemoveScriptInstances(); | 1301 | // part.Inventory.RemoveScriptInstances(); |
1202 | 1302 | ||
1203 | ScenePresence[] avatars = Scene.GetScenePresences(); | 1303 | ScenePresence[] avatars = Scene.GetScenePresences(); |
1204 | for (int i = 0; i < avatars.Length; i++) | 1304 | for (int i = 0; i < avatars.Length; i++) |
1305 | { | ||
1306 | if (avatars[i].ParentID == LocalId) | ||
1205 | { | 1307 | { |
1206 | if (avatars[i].ParentID == LocalId) | 1308 | avatars[i].StandUp(); |
1207 | { | 1309 | } |
1208 | avatars[i].StandUp(); | ||
1209 | } | ||
1210 | 1310 | ||
1211 | if (!silent) | 1311 | if (!silent) |
1212 | { | 1312 | { |
1213 | part.UpdateFlag = 0; | 1313 | part.UpdateFlag = 0; |
1214 | if (part == m_rootPart) | 1314 | if (part == m_rootPart) |
1215 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); | 1315 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); |
1216 | } | ||
1217 | } | 1316 | } |
1218 | } | 1317 | } |
1318 | |||
1219 | } | 1319 | } |
1320 | |||
1321 | |||
1220 | } | 1322 | } |
1221 | 1323 | ||
1222 | public void AddScriptLPS(int count) | 1324 | public void AddScriptLPS(int count) |
@@ -1241,17 +1343,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1241 | 1343 | ||
1242 | scriptEvents aggregateScriptEvents=0; | 1344 | scriptEvents aggregateScriptEvents=0; |
1243 | 1345 | ||
1244 | lock (m_parts) | 1346 | lockPartsForRead(true); |
1245 | { | 1347 | { |
1246 | foreach (SceneObjectPart part in m_parts.Values) | 1348 | foreach (SceneObjectPart part in m_parts.Values) |
1247 | { | 1349 | { |
1350 | |||
1248 | if (part == null) | 1351 | if (part == null) |
1249 | continue; | 1352 | continue; |
1250 | if (part != RootPart) | 1353 | if (part != RootPart) |
1251 | part.ObjectFlags = objectflagupdate; | 1354 | part.ObjectFlags = objectflagupdate; |
1252 | aggregateScriptEvents |= part.AggregateScriptEvents; | 1355 | aggregateScriptEvents |= part.AggregateScriptEvents; |
1356 | |||
1253 | } | 1357 | } |
1254 | } | 1358 | } |
1359 | lockPartsForRead(false); | ||
1255 | 1360 | ||
1256 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); | 1361 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); |
1257 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); | 1362 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); |
@@ -1284,42 +1389,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
1284 | /// <param name="m_physicalPrim"></param> | 1389 | /// <param name="m_physicalPrim"></param> |
1285 | public void ApplyPhysics(bool m_physicalPrim) | 1390 | public void ApplyPhysics(bool m_physicalPrim) |
1286 | { | 1391 | { |
1287 | lock (m_parts) | 1392 | lockPartsForRead(true); |
1393 | |||
1394 | if (m_parts.Count > 1) | ||
1288 | { | 1395 | { |
1289 | if (m_parts.Count > 1) | 1396 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); |
1397 | lockPartsForRead(false); | ||
1398 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1399 | foreach (SceneObjectPart part in values) | ||
1290 | { | 1400 | { |
1291 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | 1401 | |
1292 | foreach (SceneObjectPart part in m_parts.Values) | 1402 | if (part.LocalId != m_rootPart.LocalId) |
1293 | { | 1403 | { |
1294 | if (part.LocalId != m_rootPart.LocalId) | 1404 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); |
1295 | { | ||
1296 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); | ||
1297 | } | ||
1298 | } | 1405 | } |
1299 | 1406 | ||
1300 | // Hack to get the physics scene geometries in the right spot | ||
1301 | ResetChildPrimPhysicsPositions(); | ||
1302 | } | ||
1303 | else | ||
1304 | { | ||
1305 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1306 | } | 1407 | } |
1408 | // Hack to get the physics scene geometries in the right spot | ||
1409 | ResetChildPrimPhysicsPositions(); | ||
1410 | } | ||
1411 | else | ||
1412 | { | ||
1413 | lockPartsForRead(false); | ||
1414 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1307 | } | 1415 | } |
1308 | } | 1416 | } |
1309 | 1417 | ||
1310 | public void SetOwnerId(UUID userId) | 1418 | public void SetOwnerId(UUID userId) |
1311 | { | 1419 | { |
1312 | ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); | 1420 | ForEachPart(delegate(SceneObjectPart part) |
1421 | { | ||
1422 | |||
1423 | part.OwnerID = userId; | ||
1424 | |||
1425 | }); | ||
1313 | } | 1426 | } |
1314 | 1427 | ||
1315 | public void ForEachPart(Action<SceneObjectPart> whatToDo) | 1428 | public void ForEachPart(Action<SceneObjectPart> whatToDo) |
1316 | { | 1429 | { |
1317 | lock (m_parts) | 1430 | lockPartsForRead(true); |
1431 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1432 | lockPartsForRead(false); | ||
1433 | foreach (SceneObjectPart part in values) | ||
1318 | { | 1434 | { |
1319 | foreach (SceneObjectPart part in m_parts.Values) | 1435 | |
1320 | { | 1436 | whatToDo(part); |
1321 | whatToDo(part); | 1437 | |
1322 | } | ||
1323 | } | 1438 | } |
1324 | } | 1439 | } |
1325 | 1440 | ||
@@ -1418,14 +1533,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1418 | { | 1533 | { |
1419 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); | 1534 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); |
1420 | 1535 | ||
1421 | lock (m_parts) | 1536 | lockPartsForRead(true); |
1422 | { | 1537 | { |
1423 | foreach (SceneObjectPart part in m_parts.Values) | 1538 | foreach (SceneObjectPart part in m_parts.Values) |
1424 | { | 1539 | { |
1540 | |||
1425 | if (part != RootPart) | 1541 | if (part != RootPart) |
1426 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | 1542 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); |
1543 | |||
1427 | } | 1544 | } |
1428 | } | 1545 | } |
1546 | lockPartsForRead(false); | ||
1429 | } | 1547 | } |
1430 | 1548 | ||
1431 | /// <summary> | 1549 | /// <summary> |
@@ -1520,10 +1638,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1520 | 1638 | ||
1521 | List<SceneObjectPart> partList; | 1639 | List<SceneObjectPart> partList; |
1522 | 1640 | ||
1523 | lock (m_parts) | 1641 | lockPartsForRead(true); |
1524 | { | 1642 | |
1525 | partList = new List<SceneObjectPart>(m_parts.Values); | 1643 | partList = new List<SceneObjectPart>(m_parts.Values); |
1526 | } | 1644 | |
1645 | lockPartsForRead(false); | ||
1527 | 1646 | ||
1528 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) | 1647 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) |
1529 | { | 1648 | { |
@@ -1772,6 +1891,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1772 | } | 1891 | } |
1773 | } | 1892 | } |
1774 | } | 1893 | } |
1894 | |||
1775 | public void stopLookAt() | 1895 | public void stopLookAt() |
1776 | { | 1896 | { |
1777 | SceneObjectPart rootpart = m_rootPart; | 1897 | SceneObjectPart rootpart = m_rootPart; |
@@ -1846,10 +1966,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1846 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 1966 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); |
1847 | newPart.SetParent(this); | 1967 | newPart.SetParent(this); |
1848 | 1968 | ||
1849 | lock (m_parts) | 1969 | lockPartsForWrite(true); |
1850 | { | 1970 | { |
1851 | m_parts.Add(newPart.UUID, newPart); | 1971 | m_parts.Add(newPart.UUID, newPart); |
1852 | } | 1972 | } |
1973 | lockPartsForWrite(false); | ||
1853 | 1974 | ||
1854 | SetPartAsNonRoot(newPart); | 1975 | SetPartAsNonRoot(newPart); |
1855 | 1976 | ||
@@ -1912,7 +2033,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1912 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 2033 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
1913 | // return; | 2034 | // return; |
1914 | 2035 | ||
1915 | lock (m_parts) | 2036 | lockPartsForRead(true); |
1916 | { | 2037 | { |
1917 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 2038 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); |
1918 | 2039 | ||
@@ -1930,34 +2051,43 @@ namespace OpenSim.Region.Framework.Scenes | |||
1930 | 2051 | ||
1931 | foreach (SceneObjectPart part in m_parts.Values) | 2052 | foreach (SceneObjectPart part in m_parts.Values) |
1932 | { | 2053 | { |
2054 | |||
1933 | part.SendScheduledUpdates(); | 2055 | part.SendScheduledUpdates(); |
2056 | |||
1934 | } | 2057 | } |
1935 | } | 2058 | } |
2059 | lockPartsForRead(false); | ||
1936 | } | 2060 | } |
1937 | 2061 | ||
1938 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) | 2062 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) |
1939 | { | 2063 | { |
1940 | RootPart.AddFullUpdateToAvatar(presence); | 2064 | RootPart.AddFullUpdateToAvatar(presence); |
1941 | 2065 | ||
1942 | lock (m_parts) | 2066 | lockPartsForRead(true); |
1943 | { | 2067 | { |
1944 | foreach (SceneObjectPart part in m_parts.Values) | 2068 | foreach (SceneObjectPart part in m_parts.Values) |
1945 | { | 2069 | { |
2070 | |||
1946 | if (part != RootPart) | 2071 | if (part != RootPart) |
1947 | part.AddFullUpdateToAvatar(presence); | 2072 | part.AddFullUpdateToAvatar(presence); |
2073 | |||
1948 | } | 2074 | } |
1949 | } | 2075 | } |
2076 | lockPartsForRead(false); | ||
1950 | } | 2077 | } |
1951 | 2078 | ||
1952 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) | 2079 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) |
1953 | { | 2080 | { |
1954 | lock (m_parts) | 2081 | lockPartsForRead(true); |
1955 | { | 2082 | { |
1956 | foreach (SceneObjectPart part in m_parts.Values) | 2083 | foreach (SceneObjectPart part in m_parts.Values) |
1957 | { | 2084 | { |
2085 | |||
1958 | part.AddTerseUpdateToAvatar(presence); | 2086 | part.AddTerseUpdateToAvatar(presence); |
2087 | |||
1959 | } | 2088 | } |
1960 | } | 2089 | } |
2090 | lockPartsForRead(false); | ||
1961 | } | 2091 | } |
1962 | 2092 | ||
1963 | /// <summary> | 2093 | /// <summary> |
@@ -1968,14 +2098,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1968 | checkAtTargets(); | 2098 | checkAtTargets(); |
1969 | RootPart.ScheduleFullUpdate(); | 2099 | RootPart.ScheduleFullUpdate(); |
1970 | 2100 | ||
1971 | lock (m_parts) | 2101 | lockPartsForRead(true); |
1972 | { | 2102 | { |
1973 | foreach (SceneObjectPart part in m_parts.Values) | 2103 | foreach (SceneObjectPart part in m_parts.Values) |
1974 | { | 2104 | { |
2105 | |||
1975 | if (part != RootPart) | 2106 | if (part != RootPart) |
1976 | part.ScheduleFullUpdate(); | 2107 | part.ScheduleFullUpdate(); |
2108 | |||
1977 | } | 2109 | } |
1978 | } | 2110 | } |
2111 | lockPartsForRead(false); | ||
1979 | } | 2112 | } |
1980 | 2113 | ||
1981 | /// <summary> | 2114 | /// <summary> |
@@ -1983,13 +2116,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1983 | /// </summary> | 2116 | /// </summary> |
1984 | public void ScheduleGroupForTerseUpdate() | 2117 | public void ScheduleGroupForTerseUpdate() |
1985 | { | 2118 | { |
1986 | lock (m_parts) | 2119 | lockPartsForRead(true); |
1987 | { | 2120 | { |
1988 | foreach (SceneObjectPart part in m_parts.Values) | 2121 | foreach (SceneObjectPart part in m_parts.Values) |
1989 | { | 2122 | { |
2123 | |||
1990 | part.ScheduleTerseUpdate(); | 2124 | part.ScheduleTerseUpdate(); |
2125 | |||
1991 | } | 2126 | } |
1992 | } | 2127 | } |
2128 | lockPartsForRead(false); | ||
1993 | } | 2129 | } |
1994 | 2130 | ||
1995 | /// <summary> | 2131 | /// <summary> |
@@ -2002,14 +2138,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2002 | 2138 | ||
2003 | RootPart.SendFullUpdateToAllClients(); | 2139 | RootPart.SendFullUpdateToAllClients(); |
2004 | 2140 | ||
2005 | lock (m_parts) | 2141 | lockPartsForRead(true); |
2006 | { | 2142 | { |
2007 | foreach (SceneObjectPart part in m_parts.Values) | 2143 | foreach (SceneObjectPart part in m_parts.Values) |
2008 | { | 2144 | { |
2145 | |||
2009 | if (part != RootPart) | 2146 | if (part != RootPart) |
2010 | part.SendFullUpdateToAllClients(); | 2147 | part.SendFullUpdateToAllClients(); |
2148 | |||
2011 | } | 2149 | } |
2012 | } | 2150 | } |
2151 | lockPartsForRead(false); | ||
2013 | } | 2152 | } |
2014 | 2153 | ||
2015 | /// <summary> | 2154 | /// <summary> |
@@ -2040,14 +2179,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2040 | { | 2179 | { |
2041 | if (IsDeleted) | 2180 | if (IsDeleted) |
2042 | return; | 2181 | return; |
2043 | 2182 | ||
2044 | lock (m_parts) | 2183 | lockPartsForRead(true); |
2045 | { | 2184 | { |
2046 | foreach (SceneObjectPart part in m_parts.Values) | 2185 | foreach (SceneObjectPart part in m_parts.Values) |
2047 | { | 2186 | { |
2048 | part.SendTerseUpdateToAllClients(); | 2187 | part.SendTerseUpdateToAllClients(); |
2049 | } | 2188 | } |
2050 | } | 2189 | } |
2190 | lockPartsForRead(false); | ||
2051 | } | 2191 | } |
2052 | 2192 | ||
2053 | #endregion | 2193 | #endregion |
@@ -2061,16 +2201,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2061 | /// <returns>null if no child part with that linknum or child part</returns> | 2201 | /// <returns>null if no child part with that linknum or child part</returns> |
2062 | public SceneObjectPart GetLinkNumPart(int linknum) | 2202 | public SceneObjectPart GetLinkNumPart(int linknum) |
2063 | { | 2203 | { |
2064 | lock (m_parts) | 2204 | lockPartsForRead(true); |
2065 | { | 2205 | { |
2066 | foreach (SceneObjectPart part in m_parts.Values) | 2206 | foreach (SceneObjectPart part in m_parts.Values) |
2067 | { | 2207 | { |
2068 | if (part.LinkNum == linknum) | 2208 | if (part.LinkNum == linknum) |
2069 | { | 2209 | { |
2210 | lockPartsForRead(false); | ||
2070 | return part; | 2211 | return part; |
2071 | } | 2212 | } |
2072 | } | 2213 | } |
2073 | } | 2214 | } |
2215 | lockPartsForRead(false); | ||
2074 | 2216 | ||
2075 | return null; | 2217 | return null; |
2076 | } | 2218 | } |
@@ -2098,17 +2240,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2098 | public SceneObjectPart GetChildPart(uint localID) | 2240 | public SceneObjectPart GetChildPart(uint localID) |
2099 | { | 2241 | { |
2100 | //m_log.DebugFormat("Entered looking for {0}", localID); | 2242 | //m_log.DebugFormat("Entered looking for {0}", localID); |
2101 | lock (m_parts) | 2243 | lockPartsForRead(true); |
2102 | { | 2244 | { |
2103 | foreach (SceneObjectPart part in m_parts.Values) | 2245 | foreach (SceneObjectPart part in m_parts.Values) |
2104 | { | 2246 | { |
2105 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2247 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2106 | if (part.LocalId == localID) | 2248 | if (part.LocalId == localID) |
2107 | { | 2249 | { |
2250 | lockPartsForRead(false); | ||
2108 | return part; | 2251 | return part; |
2109 | } | 2252 | } |
2110 | } | 2253 | } |
2111 | } | 2254 | } |
2255 | lockPartsForRead(false); | ||
2112 | 2256 | ||
2113 | return null; | 2257 | return null; |
2114 | } | 2258 | } |
@@ -2138,17 +2282,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2138 | public bool HasChildPrim(uint localID) | 2282 | public bool HasChildPrim(uint localID) |
2139 | { | 2283 | { |
2140 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); | 2284 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); |
2141 | lock (m_parts) | 2285 | lockPartsForRead(true); |
2142 | { | 2286 | { |
2143 | foreach (SceneObjectPart part in m_parts.Values) | 2287 | foreach (SceneObjectPart part in m_parts.Values) |
2144 | { | 2288 | { |
2145 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2289 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2146 | if (part.LocalId == localID) | 2290 | if (part.LocalId == localID) |
2147 | { | 2291 | { |
2292 | lockPartsForRead(false); | ||
2148 | return true; | 2293 | return true; |
2149 | } | 2294 | } |
2150 | } | 2295 | } |
2151 | } | 2296 | } |
2297 | lockPartsForRead(false); | ||
2152 | 2298 | ||
2153 | return false; | 2299 | return false; |
2154 | } | 2300 | } |
@@ -2198,53 +2344,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
2198 | if (m_rootPart.LinkNum == 0) | 2344 | if (m_rootPart.LinkNum == 0) |
2199 | m_rootPart.LinkNum = 1; | 2345 | m_rootPart.LinkNum = 1; |
2200 | 2346 | ||
2201 | lock (m_parts) | 2347 | lockPartsForWrite(true); |
2202 | { | 2348 | |
2203 | m_parts.Add(linkPart.UUID, linkPart); | 2349 | m_parts.Add(linkPart.UUID, linkPart); |
2204 | 2350 | ||
2205 | // Insert in terms of link numbers, the new links | 2351 | lockPartsForWrite(false); |
2206 | // before the current ones (with the exception of | 2352 | |
2207 | // the root prim. Shuffle the old ones up | 2353 | // Insert in terms of link numbers, the new links |
2208 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | 2354 | // before the current ones (with the exception of |
2355 | // the root prim. Shuffle the old ones up | ||
2356 | lockPartsForRead(true); | ||
2357 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | ||
2358 | { | ||
2359 | if (kvp.Value.LinkNum != 1) | ||
2209 | { | 2360 | { |
2210 | if (kvp.Value.LinkNum != 1) | 2361 | // Don't update root prim link number |
2211 | { | 2362 | kvp.Value.LinkNum += objectGroup.PrimCount; |
2212 | // Don't update root prim link number | ||
2213 | kvp.Value.LinkNum += objectGroup.PrimCount; | ||
2214 | } | ||
2215 | } | 2363 | } |
2364 | } | ||
2365 | lockPartsForRead(false); | ||
2216 | 2366 | ||
2217 | linkPart.LinkNum = 2; | 2367 | linkPart.LinkNum = 2; |
2218 | 2368 | ||
2219 | linkPart.SetParent(this); | 2369 | linkPart.SetParent(this); |
2220 | linkPart.AddFlag(PrimFlags.CreateSelected); | 2370 | linkPart.AddFlag(PrimFlags.CreateSelected); |
2221 | 2371 | ||
2222 | //if (linkPart.PhysActor != null) | 2372 | //if (linkPart.PhysActor != null) |
2223 | //{ | 2373 | //{ |
2224 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); | 2374 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); |
2225 | 2375 | ||
2226 | //linkPart.PhysActor = null; | 2376 | //linkPart.PhysActor = null; |
2227 | //} | 2377 | //} |
2228 | 2378 | ||
2229 | //TODO: rest of parts | 2379 | //TODO: rest of parts |
2230 | int linkNum = 3; | 2380 | int linkNum = 3; |
2231 | foreach (SceneObjectPart part in objectGroup.Children.Values) | 2381 | foreach (SceneObjectPart part in objectGroup.Children.Values) |
2382 | { | ||
2383 | if (part.UUID != objectGroup.m_rootPart.UUID) | ||
2232 | { | 2384 | { |
2233 | if (part.UUID != objectGroup.m_rootPart.UUID) | 2385 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); |
2234 | { | ||
2235 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); | ||
2236 | } | ||
2237 | part.ClearUndoState(); | ||
2238 | } | 2386 | } |
2387 | part.ClearUndoState(); | ||
2239 | } | 2388 | } |
2240 | 2389 | ||
2241 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); | 2390 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); |
2242 | objectGroup.m_isDeleted = true; | 2391 | objectGroup.m_isDeleted = true; |
2392 | |||
2393 | objectGroup.lockPartsForWrite(true); | ||
2243 | 2394 | ||
2244 | lock (objectGroup.m_parts) | 2395 | objectGroup.m_parts.Clear(); |
2245 | { | 2396 | |
2246 | objectGroup.m_parts.Clear(); | 2397 | objectGroup.lockPartsForWrite(false); |
2247 | } | ||
2248 | 2398 | ||
2249 | // Can't do this yet since backup still makes use of the root part without any synchronization | 2399 | // Can't do this yet since backup still makes use of the root part without any synchronization |
2250 | // objectGroup.m_rootPart = null; | 2400 | // objectGroup.m_rootPart = null; |
@@ -2303,11 +2453,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2303 | Quaternion worldRot = linkPart.GetWorldRotation(); | 2453 | Quaternion worldRot = linkPart.GetWorldRotation(); |
2304 | 2454 | ||
2305 | // Remove the part from this object | 2455 | // Remove the part from this object |
2306 | lock (m_parts) | 2456 | lockPartsForWrite(true); |
2307 | { | 2457 | { |
2308 | m_parts.Remove(linkPart.UUID); | 2458 | m_parts.Remove(linkPart.UUID); |
2309 | } | 2459 | } |
2310 | 2460 | lockPartsForWrite(false); | |
2461 | lockPartsForRead(true); | ||
2311 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | 2462 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left |
2312 | RootPart.LinkNum = 0; | 2463 | RootPart.LinkNum = 0; |
2313 | else | 2464 | else |
@@ -2318,6 +2469,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2318 | p.LinkNum--; | 2469 | p.LinkNum--; |
2319 | } | 2470 | } |
2320 | } | 2471 | } |
2472 | lockPartsForRead(false); | ||
2321 | 2473 | ||
2322 | linkPart.ParentID = 0; | 2474 | linkPart.ParentID = 0; |
2323 | linkPart.LinkNum = 0; | 2475 | linkPart.LinkNum = 0; |
@@ -2635,9 +2787,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2635 | 2787 | ||
2636 | if (selectionPart != null) | 2788 | if (selectionPart != null) |
2637 | { | 2789 | { |
2638 | lock (m_parts) | 2790 | lockPartsForRead(true); |
2791 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | ||
2792 | lockPartsForRead(false); | ||
2793 | foreach (SceneObjectPart part in parts) | ||
2639 | { | 2794 | { |
2640 | foreach (SceneObjectPart part in m_parts.Values) | 2795 | if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) |
2641 | { | 2796 | { |
2642 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | 2797 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || |
2643 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | 2798 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || |
@@ -2647,12 +2802,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2647 | break; | 2802 | break; |
2648 | } | 2803 | } |
2649 | } | 2804 | } |
2805 | } | ||
2650 | 2806 | ||
2651 | foreach (SceneObjectPart part in m_parts.Values) | 2807 | foreach (SceneObjectPart part in parts) |
2652 | { | 2808 | { |
2653 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2809 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
2654 | } | ||
2655 | } | 2810 | } |
2811 | |||
2656 | } | 2812 | } |
2657 | } | 2813 | } |
2658 | 2814 | ||
@@ -2738,11 +2894,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2738 | scale.Y = m_scene.m_maxNonphys; | 2894 | scale.Y = m_scene.m_maxNonphys; |
2739 | if (scale.Z > m_scene.m_maxNonphys) | 2895 | if (scale.Z > m_scene.m_maxNonphys) |
2740 | scale.Z = m_scene.m_maxNonphys; | 2896 | scale.Z = m_scene.m_maxNonphys; |
2741 | |||
2742 | SceneObjectPart part = GetChildPart(localID); | 2897 | SceneObjectPart part = GetChildPart(localID); |
2743 | if (part != null) | 2898 | if (part != null) |
2744 | { | 2899 | { |
2745 | part.Resize(scale); | ||
2746 | if (part.PhysActor != null) | 2900 | if (part.PhysActor != null) |
2747 | { | 2901 | { |
2748 | if (part.PhysActor.IsPhysical) | 2902 | if (part.PhysActor.IsPhysical) |
@@ -2757,7 +2911,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2757 | part.PhysActor.Size = scale; | 2911 | part.PhysActor.Size = scale; |
2758 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 2912 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); |
2759 | } | 2913 | } |
2760 | //if (part.UUID != m_rootPart.UUID) | 2914 | part.Resize(scale); |
2761 | 2915 | ||
2762 | HasGroupChanged = true; | 2916 | HasGroupChanged = true; |
2763 | ScheduleGroupForFullUpdate(); | 2917 | ScheduleGroupForFullUpdate(); |
@@ -2798,77 +2952,76 @@ namespace OpenSim.Region.Framework.Scenes | |||
2798 | float y = (scale.Y / part.Scale.Y); | 2952 | float y = (scale.Y / part.Scale.Y); |
2799 | float z = (scale.Z / part.Scale.Z); | 2953 | float z = (scale.Z / part.Scale.Z); |
2800 | 2954 | ||
2801 | lock (m_parts) | 2955 | lockPartsForRead(true); |
2956 | if (x > 1.0f || y > 1.0f || z > 1.0f) | ||
2802 | { | 2957 | { |
2803 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 2958 | foreach (SceneObjectPart obPart in m_parts.Values) |
2804 | { | 2959 | { |
2805 | foreach (SceneObjectPart obPart in m_parts.Values) | 2960 | if (obPart.UUID != m_rootPart.UUID) |
2806 | { | 2961 | { |
2807 | if (obPart.UUID != m_rootPart.UUID) | 2962 | Vector3 oldSize = new Vector3(obPart.Scale); |
2808 | { | ||
2809 | Vector3 oldSize = new Vector3(obPart.Scale); | ||
2810 | 2963 | ||
2811 | float f = 1.0f; | 2964 | float f = 1.0f; |
2812 | float a = 1.0f; | 2965 | float a = 1.0f; |
2813 | 2966 | ||
2814 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | 2967 | if (part.PhysActor != null && part.PhysActor.IsPhysical) |
2968 | { | ||
2969 | if (oldSize.X*x > m_scene.m_maxPhys) | ||
2815 | { | 2970 | { |
2816 | if (oldSize.X*x > m_scene.m_maxPhys) | 2971 | f = m_scene.m_maxPhys / oldSize.X; |
2817 | { | 2972 | a = f / x; |
2818 | f = m_scene.m_maxPhys / oldSize.X; | 2973 | x *= a; |
2819 | a = f / x; | 2974 | y *= a; |
2820 | x *= a; | 2975 | z *= a; |
2821 | y *= a; | ||
2822 | z *= a; | ||
2823 | } | ||
2824 | if (oldSize.Y*y > m_scene.m_maxPhys) | ||
2825 | { | ||
2826 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2827 | a = f / y; | ||
2828 | x *= a; | ||
2829 | y *= a; | ||
2830 | z *= a; | ||
2831 | } | ||
2832 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
2833 | { | ||
2834 | f = m_scene.m_maxPhys / oldSize.Z; | ||
2835 | a = f / z; | ||
2836 | x *= a; | ||
2837 | y *= a; | ||
2838 | z *= a; | ||
2839 | } | ||
2840 | } | 2976 | } |
2841 | else | 2977 | if (oldSize.Y*y > m_scene.m_maxPhys) |
2978 | { | ||
2979 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2980 | a = f / y; | ||
2981 | x *= a; | ||
2982 | y *= a; | ||
2983 | z *= a; | ||
2984 | } | ||
2985 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
2986 | { | ||
2987 | f = m_scene.m_maxPhys / oldSize.Z; | ||
2988 | a = f / z; | ||
2989 | x *= a; | ||
2990 | y *= a; | ||
2991 | z *= a; | ||
2992 | } | ||
2993 | } | ||
2994 | else | ||
2995 | { | ||
2996 | if (oldSize.X*x > m_scene.m_maxNonphys) | ||
2997 | { | ||
2998 | f = m_scene.m_maxNonphys / oldSize.X; | ||
2999 | a = f / x; | ||
3000 | x *= a; | ||
3001 | y *= a; | ||
3002 | z *= a; | ||
3003 | } | ||
3004 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
2842 | { | 3005 | { |
2843 | if (oldSize.X*x > m_scene.m_maxNonphys) | 3006 | f = m_scene.m_maxNonphys / oldSize.Y; |
2844 | { | 3007 | a = f / y; |
2845 | f = m_scene.m_maxNonphys / oldSize.X; | 3008 | x *= a; |
2846 | a = f / x; | 3009 | y *= a; |
2847 | x *= a; | 3010 | z *= a; |
2848 | y *= a; | 3011 | } |
2849 | z *= a; | 3012 | if (oldSize.Z*z > m_scene.m_maxNonphys) |
2850 | } | 3013 | { |
2851 | if (oldSize.Y*y > m_scene.m_maxNonphys) | 3014 | f = m_scene.m_maxNonphys / oldSize.Z; |
2852 | { | 3015 | a = f / z; |
2853 | f = m_scene.m_maxNonphys / oldSize.Y; | 3016 | x *= a; |
2854 | a = f / y; | 3017 | y *= a; |
2855 | x *= a; | 3018 | z *= a; |
2856 | y *= a; | ||
2857 | z *= a; | ||
2858 | } | ||
2859 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2860 | { | ||
2861 | f = m_scene.m_maxNonphys / oldSize.Z; | ||
2862 | a = f / z; | ||
2863 | x *= a; | ||
2864 | y *= a; | ||
2865 | z *= a; | ||
2866 | } | ||
2867 | } | 3019 | } |
2868 | } | 3020 | } |
2869 | } | 3021 | } |
2870 | } | 3022 | } |
2871 | } | 3023 | } |
3024 | lockPartsForRead(false); | ||
2872 | 3025 | ||
2873 | Vector3 prevScale = part.Scale; | 3026 | Vector3 prevScale = part.Scale; |
2874 | prevScale.X *= x; | 3027 | prevScale.X *= x; |
@@ -2876,7 +3029,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2876 | prevScale.Z *= z; | 3029 | prevScale.Z *= z; |
2877 | part.Resize(prevScale); | 3030 | part.Resize(prevScale); |
2878 | 3031 | ||
2879 | lock (m_parts) | 3032 | lockPartsForRead(true); |
2880 | { | 3033 | { |
2881 | foreach (SceneObjectPart obPart in m_parts.Values) | 3034 | foreach (SceneObjectPart obPart in m_parts.Values) |
2882 | { | 3035 | { |
@@ -2895,6 +3048,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2895 | } | 3048 | } |
2896 | } | 3049 | } |
2897 | } | 3050 | } |
3051 | lockPartsForRead(false); | ||
2898 | 3052 | ||
2899 | if (part.PhysActor != null) | 3053 | if (part.PhysActor != null) |
2900 | { | 3054 | { |
@@ -2975,7 +3129,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2975 | axDiff *= Quaternion.Inverse(partRotation); | 3129 | axDiff *= Quaternion.Inverse(partRotation); |
2976 | diff = axDiff; | 3130 | diff = axDiff; |
2977 | 3131 | ||
2978 | lock (m_parts) | 3132 | lockPartsForRead(true); |
2979 | { | 3133 | { |
2980 | foreach (SceneObjectPart obPart in m_parts.Values) | 3134 | foreach (SceneObjectPart obPart in m_parts.Values) |
2981 | { | 3135 | { |
@@ -2985,6 +3139,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2985 | } | 3139 | } |
2986 | } | 3140 | } |
2987 | } | 3141 | } |
3142 | lockPartsForRead(false); | ||
2988 | 3143 | ||
2989 | AbsolutePosition = newPos; | 3144 | AbsolutePosition = newPos; |
2990 | 3145 | ||
@@ -3102,7 +3257,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3102 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 3257 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); |
3103 | } | 3258 | } |
3104 | 3259 | ||
3105 | lock (m_parts) | 3260 | lockPartsForRead(true); |
3106 | { | 3261 | { |
3107 | foreach (SceneObjectPart prim in m_parts.Values) | 3262 | foreach (SceneObjectPart prim in m_parts.Values) |
3108 | { | 3263 | { |
@@ -3120,6 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3120 | } | 3275 | } |
3121 | } | 3276 | } |
3122 | } | 3277 | } |
3278 | lockPartsForRead(false); | ||
3123 | 3279 | ||
3124 | m_rootPart.ScheduleTerseUpdate(); | 3280 | m_rootPart.ScheduleTerseUpdate(); |
3125 | } | 3281 | } |
@@ -3218,7 +3374,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3218 | if (atTargets.Count > 0) | 3374 | if (atTargets.Count > 0) |
3219 | { | 3375 | { |
3220 | uint[] localids = new uint[0]; | 3376 | uint[] localids = new uint[0]; |
3221 | lock (m_parts) | 3377 | lockPartsForRead(true); |
3222 | { | 3378 | { |
3223 | localids = new uint[m_parts.Count]; | 3379 | localids = new uint[m_parts.Count]; |
3224 | int cntr = 0; | 3380 | int cntr = 0; |
@@ -3228,6 +3384,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3228 | cntr++; | 3384 | cntr++; |
3229 | } | 3385 | } |
3230 | } | 3386 | } |
3387 | lockPartsForRead(false); | ||
3231 | 3388 | ||
3232 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3389 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3233 | { | 3390 | { |
@@ -3246,7 +3403,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3246 | { | 3403 | { |
3247 | //trigger not_at_target | 3404 | //trigger not_at_target |
3248 | uint[] localids = new uint[0]; | 3405 | uint[] localids = new uint[0]; |
3249 | lock (m_parts) | 3406 | lockPartsForRead(true); |
3250 | { | 3407 | { |
3251 | localids = new uint[m_parts.Count]; | 3408 | localids = new uint[m_parts.Count]; |
3252 | int cntr = 0; | 3409 | int cntr = 0; |
@@ -3256,7 +3413,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3256 | cntr++; | 3413 | cntr++; |
3257 | } | 3414 | } |
3258 | } | 3415 | } |
3259 | 3416 | lockPartsForRead(false); | |
3417 | |||
3260 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3418 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3261 | { | 3419 | { |
3262 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); | 3420 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); |
@@ -3269,19 +3427,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3269 | public float GetMass() | 3427 | public float GetMass() |
3270 | { | 3428 | { |
3271 | float retmass = 0f; | 3429 | float retmass = 0f; |
3272 | lock (m_parts) | 3430 | lockPartsForRead(true); |
3273 | { | 3431 | { |
3274 | foreach (SceneObjectPart part in m_parts.Values) | 3432 | foreach (SceneObjectPart part in m_parts.Values) |
3275 | { | 3433 | { |
3276 | retmass += part.GetMass(); | 3434 | retmass += part.GetMass(); |
3277 | } | 3435 | } |
3278 | } | 3436 | } |
3437 | lockPartsForRead(false); | ||
3279 | return retmass; | 3438 | return retmass; |
3280 | } | 3439 | } |
3281 | 3440 | ||
3282 | public void CheckSculptAndLoad() | 3441 | public void CheckSculptAndLoad() |
3283 | { | 3442 | { |
3284 | lock (m_parts) | 3443 | lockPartsForRead(true); |
3285 | { | 3444 | { |
3286 | if (!IsDeleted) | 3445 | if (!IsDeleted) |
3287 | { | 3446 | { |
@@ -3306,6 +3465,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3306 | } | 3465 | } |
3307 | } | 3466 | } |
3308 | } | 3467 | } |
3468 | lockPartsForRead(false); | ||
3309 | } | 3469 | } |
3310 | 3470 | ||
3311 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 3471 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
@@ -3326,7 +3486,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3326 | /// <param name="client"></param> | 3486 | /// <param name="client"></param> |
3327 | public void SetGroup(UUID GroupID, IClientAPI client) | 3487 | public void SetGroup(UUID GroupID, IClientAPI client) |
3328 | { | 3488 | { |
3329 | lock (m_parts) | 3489 | lockPartsForRead(true); |
3330 | { | 3490 | { |
3331 | foreach (SceneObjectPart part in m_parts.Values) | 3491 | foreach (SceneObjectPart part in m_parts.Values) |
3332 | { | 3492 | { |
@@ -3336,7 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3336 | 3496 | ||
3337 | HasGroupChanged = true; | 3497 | HasGroupChanged = true; |
3338 | } | 3498 | } |
3339 | 3499 | lockPartsForRead(false); | |
3340 | ScheduleGroupForFullUpdate(); | 3500 | ScheduleGroupForFullUpdate(); |
3341 | } | 3501 | } |
3342 | 3502 | ||
@@ -3355,11 +3515,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3355 | 3515 | ||
3356 | public void SetAttachmentPoint(byte point) | 3516 | public void SetAttachmentPoint(byte point) |
3357 | { | 3517 | { |
3358 | lock (m_parts) | 3518 | lockPartsForRead(true); |
3359 | { | 3519 | { |
3360 | foreach (SceneObjectPart part in m_parts.Values) | 3520 | foreach (SceneObjectPart part in m_parts.Values) |
3361 | part.SetAttachmentPoint(point); | 3521 | part.SetAttachmentPoint(point); |
3362 | } | 3522 | } |
3523 | lockPartsForRead(false); | ||
3363 | } | 3524 | } |
3364 | 3525 | ||
3365 | #region ISceneObject | 3526 | #region ISceneObject |