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 8c56870..9cb1398 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 | { |
@@ -258,13 +324,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
258 | set | 324 | set |
259 | { | 325 | { |
260 | m_regionHandle = value; | 326 | m_regionHandle = value; |
261 | lock (m_parts) | 327 | lockPartsForRead(true); |
262 | { | 328 | { |
263 | foreach (SceneObjectPart part in m_parts.Values) | 329 | foreach (SceneObjectPart part in m_parts.Values) |
264 | { | 330 | { |
331 | |||
265 | part.RegionHandle = m_regionHandle; | 332 | part.RegionHandle = m_regionHandle; |
333 | |||
266 | } | 334 | } |
267 | } | 335 | } |
336 | lockPartsForRead(false); | ||
268 | } | 337 | } |
269 | } | 338 | } |
270 | 339 | ||
@@ -290,13 +359,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
290 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 359 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
291 | } | 360 | } |
292 | 361 | ||
293 | lock (m_parts) | 362 | lockPartsForRead(true); |
294 | { | 363 | { |
295 | foreach (SceneObjectPart part in m_parts.Values) | 364 | foreach (SceneObjectPart part in m_parts.Values) |
296 | { | 365 | { |
366 | |||
297 | part.GroupPosition = val; | 367 | part.GroupPosition = val; |
368 | |||
298 | } | 369 | } |
299 | } | 370 | } |
371 | lockPartsForRead(false); | ||
300 | 372 | ||
301 | //if (m_rootPart.PhysActor != null) | 373 | //if (m_rootPart.PhysActor != null) |
302 | //{ | 374 | //{ |
@@ -458,13 +530,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
458 | 530 | ||
459 | public void SetFromItemID(UUID AssetId) | 531 | public void SetFromItemID(UUID AssetId) |
460 | { | 532 | { |
461 | lock (m_parts) | 533 | lockPartsForRead(true); |
462 | { | 534 | { |
463 | foreach (SceneObjectPart part in m_parts.Values) | 535 | foreach (SceneObjectPart part in m_parts.Values) |
464 | { | 536 | { |
537 | |||
465 | part.FromItemID = AssetId; | 538 | part.FromItemID = AssetId; |
539 | |||
466 | } | 540 | } |
467 | } | 541 | } |
542 | lockPartsForRead(false); | ||
468 | } | 543 | } |
469 | 544 | ||
470 | public UUID GetFromItemID() | 545 | public UUID GetFromItemID() |
@@ -531,10 +606,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
531 | Vector3 maxScale = Vector3.Zero; | 606 | Vector3 maxScale = Vector3.Zero; |
532 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | 607 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); |
533 | 608 | ||
534 | lock (m_parts) | 609 | lockPartsForRead(true); |
535 | { | 610 | { |
536 | foreach (SceneObjectPart part in m_parts.Values) | 611 | foreach (SceneObjectPart part in m_parts.Values) |
537 | { | 612 | { |
613 | |||
538 | Vector3 partscale = part.Scale; | 614 | Vector3 partscale = part.Scale; |
539 | Vector3 partoffset = part.OffsetPosition; | 615 | Vector3 partoffset = part.OffsetPosition; |
540 | 616 | ||
@@ -545,8 +621,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
545 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | 621 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; |
546 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | 622 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; |
547 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | 623 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; |
624 | |||
548 | } | 625 | } |
549 | } | 626 | } |
627 | lockPartsForRead(false); | ||
628 | |||
550 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | 629 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; |
551 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | 630 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; |
552 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | 631 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; |
@@ -562,10 +641,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
562 | 641 | ||
563 | EntityIntersection result = new EntityIntersection(); | 642 | EntityIntersection result = new EntityIntersection(); |
564 | 643 | ||
565 | lock (m_parts) | 644 | lockPartsForRead(true); |
566 | { | 645 | { |
567 | foreach (SceneObjectPart part in m_parts.Values) | 646 | foreach (SceneObjectPart part in m_parts.Values) |
568 | { | 647 | { |
648 | |||
569 | // Temporary commented to stop compiler warning | 649 | // Temporary commented to stop compiler warning |
570 | //Vector3 partPosition = | 650 | //Vector3 partPosition = |
571 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); | 651 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); |
@@ -593,8 +673,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
593 | result.distance = inter.distance; | 673 | result.distance = inter.distance; |
594 | } | 674 | } |
595 | } | 675 | } |
676 | |||
596 | } | 677 | } |
597 | } | 678 | } |
679 | lockPartsForRead(false); | ||
598 | return result; | 680 | return result; |
599 | } | 681 | } |
600 | 682 | ||
@@ -607,10 +689,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
607 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) | 689 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) |
608 | { | 690 | { |
609 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; | 691 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; |
610 | lock (m_parts) | 692 | lockPartsForRead(true); |
611 | { | 693 | { |
612 | foreach (SceneObjectPart part in m_parts.Values) | 694 | foreach (SceneObjectPart part in m_parts.Values) |
613 | { | 695 | { |
696 | |||
614 | Vector3 worldPos = part.GetWorldPosition(); | 697 | Vector3 worldPos = part.GetWorldPosition(); |
615 | Vector3 offset = worldPos - AbsolutePosition; | 698 | Vector3 offset = worldPos - AbsolutePosition; |
616 | Quaternion worldRot; | 699 | Quaternion worldRot; |
@@ -669,6 +752,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
669 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); | 752 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); |
670 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); | 753 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); |
671 | 754 | ||
755 | |||
756 | |||
672 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); | 757 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); |
673 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); | 758 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); |
674 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); | 759 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); |
@@ -840,6 +925,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
840 | minZ = backBottomLeft.Z; | 925 | minZ = backBottomLeft.Z; |
841 | } | 926 | } |
842 | } | 927 | } |
928 | lockPartsForRead(false); | ||
843 | 929 | ||
844 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); | 930 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); |
845 | 931 | ||
@@ -868,17 +954,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
868 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); | 954 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); |
869 | 955 | ||
870 | // Capture script state while holding the lock | 956 | // Capture script state while holding the lock |
871 | lock (m_parts) | 957 | lockPartsForRead(true); |
872 | { | 958 | { |
873 | foreach (SceneObjectPart part in m_parts.Values) | 959 | foreach (SceneObjectPart part in m_parts.Values) |
874 | { | 960 | { |
961 | |||
875 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); | 962 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); |
876 | foreach (UUID itemid in pstates.Keys) | 963 | foreach (UUID itemid in pstates.Keys) |
877 | { | 964 | { |
878 | states.Add(itemid, pstates[itemid]); | 965 | states.Add(itemid, pstates[itemid]); |
879 | } | 966 | } |
967 | |||
880 | } | 968 | } |
881 | } | 969 | } |
970 | lockPartsForRead(false); | ||
882 | 971 | ||
883 | if (states.Count > 0) | 972 | if (states.Count > 0) |
884 | { | 973 | { |
@@ -1040,13 +1129,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1040 | 1129 | ||
1041 | public override void UpdateMovement() | 1130 | public override void UpdateMovement() |
1042 | { | 1131 | { |
1043 | lock (m_parts) | 1132 | lockPartsForRead(true); |
1044 | { | 1133 | { |
1045 | foreach (SceneObjectPart part in m_parts.Values) | 1134 | foreach (SceneObjectPart part in m_parts.Values) |
1046 | { | 1135 | { |
1136 | |||
1047 | part.UpdateMovement(); | 1137 | part.UpdateMovement(); |
1138 | |||
1048 | } | 1139 | } |
1049 | } | 1140 | } |
1141 | lockPartsForRead(false); | ||
1050 | } | 1142 | } |
1051 | 1143 | ||
1052 | public ushort GetTimeDilation() | 1144 | public ushort GetTimeDilation() |
@@ -1090,7 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1090 | /// <param name="part"></param> | 1182 | /// <param name="part"></param> |
1091 | public void AddPart(SceneObjectPart part) | 1183 | public void AddPart(SceneObjectPart part) |
1092 | { | 1184 | { |
1093 | lock (m_parts) | 1185 | lockPartsForWrite(true); |
1094 | { | 1186 | { |
1095 | part.SetParent(this); | 1187 | part.SetParent(this); |
1096 | m_parts.Add(part.UUID, part); | 1188 | m_parts.Add(part.UUID, part); |
@@ -1100,6 +1192,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1100 | if (part.LinkNum == 2 && RootPart != null) | 1192 | if (part.LinkNum == 2 && RootPart != null) |
1101 | RootPart.LinkNum = 1; | 1193 | RootPart.LinkNum = 1; |
1102 | } | 1194 | } |
1195 | lockPartsForWrite(false); | ||
1103 | } | 1196 | } |
1104 | 1197 | ||
1105 | /// <summary> | 1198 | /// <summary> |
@@ -1107,28 +1200,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1107 | /// </summary> | 1200 | /// </summary> |
1108 | private void UpdateParentIDs() | 1201 | private void UpdateParentIDs() |
1109 | { | 1202 | { |
1110 | lock (m_parts) | 1203 | lockPartsForRead(true); |
1111 | { | 1204 | { |
1112 | foreach (SceneObjectPart part in m_parts.Values) | 1205 | foreach (SceneObjectPart part in m_parts.Values) |
1113 | { | 1206 | { |
1207 | |||
1114 | if (part.UUID != m_rootPart.UUID) | 1208 | if (part.UUID != m_rootPart.UUID) |
1115 | { | 1209 | { |
1116 | part.ParentID = m_rootPart.LocalId; | 1210 | part.ParentID = m_rootPart.LocalId; |
1117 | } | 1211 | } |
1212 | |||
1118 | } | 1213 | } |
1119 | } | 1214 | } |
1215 | lockPartsForRead(false); | ||
1120 | } | 1216 | } |
1121 | 1217 | ||
1122 | public void RegenerateFullIDs() | 1218 | public void RegenerateFullIDs() |
1123 | { | 1219 | { |
1124 | lock (m_parts) | 1220 | lockPartsForRead(true); |
1125 | { | 1221 | { |
1126 | foreach (SceneObjectPart part in m_parts.Values) | 1222 | foreach (SceneObjectPart part in m_parts.Values) |
1127 | { | 1223 | { |
1224 | |||
1128 | part.UUID = UUID.Random(); | 1225 | part.UUID = UUID.Random(); |
1129 | 1226 | ||
1130 | } | 1227 | } |
1131 | } | 1228 | } |
1229 | lockPartsForRead(false); | ||
1132 | } | 1230 | } |
1133 | 1231 | ||
1134 | // helper provided for parts. | 1232 | // helper provided for parts. |
@@ -1209,29 +1307,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1209 | 1307 | ||
1210 | DetachFromBackup(); | 1308 | DetachFromBackup(); |
1211 | 1309 | ||
1212 | lock (m_parts) | 1310 | lockPartsForRead(true); |
1311 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1312 | lockPartsForRead(false); | ||
1313 | |||
1314 | foreach (SceneObjectPart part in values) | ||
1213 | { | 1315 | { |
1214 | foreach (SceneObjectPart part in m_parts.Values) | ||
1215 | { | ||
1216 | // part.Inventory.RemoveScriptInstances(); | 1316 | // part.Inventory.RemoveScriptInstances(); |
1217 | 1317 | ||
1218 | ScenePresence[] avatars = Scene.GetScenePresences(); | 1318 | ScenePresence[] avatars = Scene.GetScenePresences(); |
1219 | for (int i = 0; i < avatars.Length; i++) | 1319 | for (int i = 0; i < avatars.Length; i++) |
1320 | { | ||
1321 | if (avatars[i].ParentID == LocalId) | ||
1220 | { | 1322 | { |
1221 | if (avatars[i].ParentID == LocalId) | 1323 | avatars[i].StandUp(); |
1222 | { | 1324 | } |
1223 | avatars[i].StandUp(); | ||
1224 | } | ||
1225 | 1325 | ||
1226 | if (!silent) | 1326 | if (!silent) |
1227 | { | 1327 | { |
1228 | part.UpdateFlag = 0; | 1328 | part.UpdateFlag = 0; |
1229 | if (part == m_rootPart) | 1329 | if (part == m_rootPart) |
1230 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); | 1330 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); |
1231 | } | ||
1232 | } | 1331 | } |
1233 | } | 1332 | } |
1333 | |||
1234 | } | 1334 | } |
1335 | |||
1336 | |||
1235 | } | 1337 | } |
1236 | 1338 | ||
1237 | public void AddScriptLPS(int count) | 1339 | public void AddScriptLPS(int count) |
@@ -1256,17 +1358,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1256 | 1358 | ||
1257 | scriptEvents aggregateScriptEvents=0; | 1359 | scriptEvents aggregateScriptEvents=0; |
1258 | 1360 | ||
1259 | lock (m_parts) | 1361 | lockPartsForRead(true); |
1260 | { | 1362 | { |
1261 | foreach (SceneObjectPart part in m_parts.Values) | 1363 | foreach (SceneObjectPart part in m_parts.Values) |
1262 | { | 1364 | { |
1365 | |||
1263 | if (part == null) | 1366 | if (part == null) |
1264 | continue; | 1367 | continue; |
1265 | if (part != RootPart) | 1368 | if (part != RootPart) |
1266 | part.ObjectFlags = objectflagupdate; | 1369 | part.ObjectFlags = objectflagupdate; |
1267 | aggregateScriptEvents |= part.AggregateScriptEvents; | 1370 | aggregateScriptEvents |= part.AggregateScriptEvents; |
1371 | |||
1268 | } | 1372 | } |
1269 | } | 1373 | } |
1374 | lockPartsForRead(false); | ||
1270 | 1375 | ||
1271 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); | 1376 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); |
1272 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); | 1377 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); |
@@ -1308,42 +1413,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
1308 | /// <param name="m_physicalPrim"></param> | 1413 | /// <param name="m_physicalPrim"></param> |
1309 | public void ApplyPhysics(bool m_physicalPrim) | 1414 | public void ApplyPhysics(bool m_physicalPrim) |
1310 | { | 1415 | { |
1311 | lock (m_parts) | 1416 | lockPartsForRead(true); |
1417 | |||
1418 | if (m_parts.Count > 1) | ||
1312 | { | 1419 | { |
1313 | if (m_parts.Count > 1) | 1420 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); |
1421 | lockPartsForRead(false); | ||
1422 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1423 | foreach (SceneObjectPart part in values) | ||
1314 | { | 1424 | { |
1315 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | 1425 | |
1316 | foreach (SceneObjectPart part in m_parts.Values) | 1426 | if (part.LocalId != m_rootPart.LocalId) |
1317 | { | 1427 | { |
1318 | if (part.LocalId != m_rootPart.LocalId) | 1428 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); |
1319 | { | ||
1320 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); | ||
1321 | } | ||
1322 | } | 1429 | } |
1323 | 1430 | ||
1324 | // Hack to get the physics scene geometries in the right spot | ||
1325 | ResetChildPrimPhysicsPositions(); | ||
1326 | } | ||
1327 | else | ||
1328 | { | ||
1329 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1330 | } | 1431 | } |
1432 | // Hack to get the physics scene geometries in the right spot | ||
1433 | ResetChildPrimPhysicsPositions(); | ||
1434 | } | ||
1435 | else | ||
1436 | { | ||
1437 | lockPartsForRead(false); | ||
1438 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1331 | } | 1439 | } |
1332 | } | 1440 | } |
1333 | 1441 | ||
1334 | public void SetOwnerId(UUID userId) | 1442 | public void SetOwnerId(UUID userId) |
1335 | { | 1443 | { |
1336 | ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); | 1444 | ForEachPart(delegate(SceneObjectPart part) |
1445 | { | ||
1446 | |||
1447 | part.OwnerID = userId; | ||
1448 | |||
1449 | }); | ||
1337 | } | 1450 | } |
1338 | 1451 | ||
1339 | public void ForEachPart(Action<SceneObjectPart> whatToDo) | 1452 | public void ForEachPart(Action<SceneObjectPart> whatToDo) |
1340 | { | 1453 | { |
1341 | lock (m_parts) | 1454 | lockPartsForRead(true); |
1455 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1456 | lockPartsForRead(false); | ||
1457 | foreach (SceneObjectPart part in values) | ||
1342 | { | 1458 | { |
1343 | foreach (SceneObjectPart part in m_parts.Values) | 1459 | |
1344 | { | 1460 | whatToDo(part); |
1345 | whatToDo(part); | 1461 | |
1346 | } | ||
1347 | } | 1462 | } |
1348 | } | 1463 | } |
1349 | 1464 | ||
@@ -1442,14 +1557,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1442 | { | 1557 | { |
1443 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); | 1558 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); |
1444 | 1559 | ||
1445 | lock (m_parts) | 1560 | lockPartsForRead(true); |
1446 | { | 1561 | { |
1447 | foreach (SceneObjectPart part in m_parts.Values) | 1562 | foreach (SceneObjectPart part in m_parts.Values) |
1448 | { | 1563 | { |
1564 | |||
1449 | if (part != RootPart) | 1565 | if (part != RootPart) |
1450 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | 1566 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); |
1567 | |||
1451 | } | 1568 | } |
1452 | } | 1569 | } |
1570 | lockPartsForRead(false); | ||
1453 | } | 1571 | } |
1454 | 1572 | ||
1455 | /// <summary> | 1573 | /// <summary> |
@@ -1544,10 +1662,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1544 | 1662 | ||
1545 | List<SceneObjectPart> partList; | 1663 | List<SceneObjectPart> partList; |
1546 | 1664 | ||
1547 | lock (m_parts) | 1665 | lockPartsForRead(true); |
1548 | { | 1666 | |
1549 | partList = new List<SceneObjectPart>(m_parts.Values); | 1667 | partList = new List<SceneObjectPart>(m_parts.Values); |
1550 | } | 1668 | |
1669 | lockPartsForRead(false); | ||
1551 | 1670 | ||
1552 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) | 1671 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) |
1553 | { | 1672 | { |
@@ -1796,6 +1915,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1796 | } | 1915 | } |
1797 | } | 1916 | } |
1798 | } | 1917 | } |
1918 | |||
1799 | public void stopLookAt() | 1919 | public void stopLookAt() |
1800 | { | 1920 | { |
1801 | SceneObjectPart rootpart = m_rootPart; | 1921 | SceneObjectPart rootpart = m_rootPart; |
@@ -1870,10 +1990,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1870 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 1990 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); |
1871 | newPart.SetParent(this); | 1991 | newPart.SetParent(this); |
1872 | 1992 | ||
1873 | lock (m_parts) | 1993 | lockPartsForWrite(true); |
1874 | { | 1994 | { |
1875 | m_parts.Add(newPart.UUID, newPart); | 1995 | m_parts.Add(newPart.UUID, newPart); |
1876 | } | 1996 | } |
1997 | lockPartsForWrite(false); | ||
1877 | 1998 | ||
1878 | SetPartAsNonRoot(newPart); | 1999 | SetPartAsNonRoot(newPart); |
1879 | 2000 | ||
@@ -1936,7 +2057,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1936 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 2057 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
1937 | // return; | 2058 | // return; |
1938 | 2059 | ||
1939 | lock (m_parts) | 2060 | lockPartsForRead(true); |
1940 | { | 2061 | { |
1941 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 2062 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); |
1942 | 2063 | ||
@@ -1954,34 +2075,43 @@ namespace OpenSim.Region.Framework.Scenes | |||
1954 | 2075 | ||
1955 | foreach (SceneObjectPart part in m_parts.Values) | 2076 | foreach (SceneObjectPart part in m_parts.Values) |
1956 | { | 2077 | { |
2078 | |||
1957 | part.SendScheduledUpdates(); | 2079 | part.SendScheduledUpdates(); |
2080 | |||
1958 | } | 2081 | } |
1959 | } | 2082 | } |
2083 | lockPartsForRead(false); | ||
1960 | } | 2084 | } |
1961 | 2085 | ||
1962 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) | 2086 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) |
1963 | { | 2087 | { |
1964 | RootPart.AddFullUpdateToAvatar(presence); | 2088 | RootPart.AddFullUpdateToAvatar(presence); |
1965 | 2089 | ||
1966 | lock (m_parts) | 2090 | lockPartsForRead(true); |
1967 | { | 2091 | { |
1968 | foreach (SceneObjectPart part in m_parts.Values) | 2092 | foreach (SceneObjectPart part in m_parts.Values) |
1969 | { | 2093 | { |
2094 | |||
1970 | if (part != RootPart) | 2095 | if (part != RootPart) |
1971 | part.AddFullUpdateToAvatar(presence); | 2096 | part.AddFullUpdateToAvatar(presence); |
2097 | |||
1972 | } | 2098 | } |
1973 | } | 2099 | } |
2100 | lockPartsForRead(false); | ||
1974 | } | 2101 | } |
1975 | 2102 | ||
1976 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) | 2103 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) |
1977 | { | 2104 | { |
1978 | lock (m_parts) | 2105 | lockPartsForRead(true); |
1979 | { | 2106 | { |
1980 | foreach (SceneObjectPart part in m_parts.Values) | 2107 | foreach (SceneObjectPart part in m_parts.Values) |
1981 | { | 2108 | { |
2109 | |||
1982 | part.AddTerseUpdateToAvatar(presence); | 2110 | part.AddTerseUpdateToAvatar(presence); |
2111 | |||
1983 | } | 2112 | } |
1984 | } | 2113 | } |
2114 | lockPartsForRead(false); | ||
1985 | } | 2115 | } |
1986 | 2116 | ||
1987 | /// <summary> | 2117 | /// <summary> |
@@ -1992,14 +2122,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1992 | checkAtTargets(); | 2122 | checkAtTargets(); |
1993 | RootPart.ScheduleFullUpdate(); | 2123 | RootPart.ScheduleFullUpdate(); |
1994 | 2124 | ||
1995 | lock (m_parts) | 2125 | lockPartsForRead(true); |
1996 | { | 2126 | { |
1997 | foreach (SceneObjectPart part in m_parts.Values) | 2127 | foreach (SceneObjectPart part in m_parts.Values) |
1998 | { | 2128 | { |
2129 | |||
1999 | if (part != RootPart) | 2130 | if (part != RootPart) |
2000 | part.ScheduleFullUpdate(); | 2131 | part.ScheduleFullUpdate(); |
2132 | |||
2001 | } | 2133 | } |
2002 | } | 2134 | } |
2135 | lockPartsForRead(false); | ||
2003 | } | 2136 | } |
2004 | 2137 | ||
2005 | /// <summary> | 2138 | /// <summary> |
@@ -2007,13 +2140,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2007 | /// </summary> | 2140 | /// </summary> |
2008 | public void ScheduleGroupForTerseUpdate() | 2141 | public void ScheduleGroupForTerseUpdate() |
2009 | { | 2142 | { |
2010 | lock (m_parts) | 2143 | lockPartsForRead(true); |
2011 | { | 2144 | { |
2012 | foreach (SceneObjectPart part in m_parts.Values) | 2145 | foreach (SceneObjectPart part in m_parts.Values) |
2013 | { | 2146 | { |
2147 | |||
2014 | part.ScheduleTerseUpdate(); | 2148 | part.ScheduleTerseUpdate(); |
2149 | |||
2015 | } | 2150 | } |
2016 | } | 2151 | } |
2152 | lockPartsForRead(false); | ||
2017 | } | 2153 | } |
2018 | 2154 | ||
2019 | /// <summary> | 2155 | /// <summary> |
@@ -2026,14 +2162,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2026 | 2162 | ||
2027 | RootPart.SendFullUpdateToAllClients(); | 2163 | RootPart.SendFullUpdateToAllClients(); |
2028 | 2164 | ||
2029 | lock (m_parts) | 2165 | lockPartsForRead(true); |
2030 | { | 2166 | { |
2031 | foreach (SceneObjectPart part in m_parts.Values) | 2167 | foreach (SceneObjectPart part in m_parts.Values) |
2032 | { | 2168 | { |
2169 | |||
2033 | if (part != RootPart) | 2170 | if (part != RootPart) |
2034 | part.SendFullUpdateToAllClients(); | 2171 | part.SendFullUpdateToAllClients(); |
2172 | |||
2035 | } | 2173 | } |
2036 | } | 2174 | } |
2175 | lockPartsForRead(false); | ||
2037 | } | 2176 | } |
2038 | 2177 | ||
2039 | /// <summary> | 2178 | /// <summary> |
@@ -2064,14 +2203,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2064 | { | 2203 | { |
2065 | if (IsDeleted) | 2204 | if (IsDeleted) |
2066 | return; | 2205 | return; |
2067 | 2206 | ||
2068 | lock (m_parts) | 2207 | lockPartsForRead(true); |
2069 | { | 2208 | { |
2070 | foreach (SceneObjectPart part in m_parts.Values) | 2209 | foreach (SceneObjectPart part in m_parts.Values) |
2071 | { | 2210 | { |
2072 | part.SendTerseUpdateToAllClients(); | 2211 | part.SendTerseUpdateToAllClients(); |
2073 | } | 2212 | } |
2074 | } | 2213 | } |
2214 | lockPartsForRead(false); | ||
2075 | } | 2215 | } |
2076 | 2216 | ||
2077 | #endregion | 2217 | #endregion |
@@ -2085,16 +2225,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2085 | /// <returns>null if no child part with that linknum or child part</returns> | 2225 | /// <returns>null if no child part with that linknum or child part</returns> |
2086 | public SceneObjectPart GetLinkNumPart(int linknum) | 2226 | public SceneObjectPart GetLinkNumPart(int linknum) |
2087 | { | 2227 | { |
2088 | lock (m_parts) | 2228 | lockPartsForRead(true); |
2089 | { | 2229 | { |
2090 | foreach (SceneObjectPart part in m_parts.Values) | 2230 | foreach (SceneObjectPart part in m_parts.Values) |
2091 | { | 2231 | { |
2092 | if (part.LinkNum == linknum) | 2232 | if (part.LinkNum == linknum) |
2093 | { | 2233 | { |
2234 | lockPartsForRead(false); | ||
2094 | return part; | 2235 | return part; |
2095 | } | 2236 | } |
2096 | } | 2237 | } |
2097 | } | 2238 | } |
2239 | lockPartsForRead(false); | ||
2098 | 2240 | ||
2099 | return null; | 2241 | return null; |
2100 | } | 2242 | } |
@@ -2122,17 +2264,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2122 | public SceneObjectPart GetChildPart(uint localID) | 2264 | public SceneObjectPart GetChildPart(uint localID) |
2123 | { | 2265 | { |
2124 | //m_log.DebugFormat("Entered looking for {0}", localID); | 2266 | //m_log.DebugFormat("Entered looking for {0}", localID); |
2125 | lock (m_parts) | 2267 | lockPartsForRead(true); |
2126 | { | 2268 | { |
2127 | foreach (SceneObjectPart part in m_parts.Values) | 2269 | foreach (SceneObjectPart part in m_parts.Values) |
2128 | { | 2270 | { |
2129 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2271 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2130 | if (part.LocalId == localID) | 2272 | if (part.LocalId == localID) |
2131 | { | 2273 | { |
2274 | lockPartsForRead(false); | ||
2132 | return part; | 2275 | return part; |
2133 | } | 2276 | } |
2134 | } | 2277 | } |
2135 | } | 2278 | } |
2279 | lockPartsForRead(false); | ||
2136 | 2280 | ||
2137 | return null; | 2281 | return null; |
2138 | } | 2282 | } |
@@ -2162,17 +2306,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2162 | public bool HasChildPrim(uint localID) | 2306 | public bool HasChildPrim(uint localID) |
2163 | { | 2307 | { |
2164 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); | 2308 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); |
2165 | lock (m_parts) | 2309 | lockPartsForRead(true); |
2166 | { | 2310 | { |
2167 | foreach (SceneObjectPart part in m_parts.Values) | 2311 | foreach (SceneObjectPart part in m_parts.Values) |
2168 | { | 2312 | { |
2169 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2313 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2170 | if (part.LocalId == localID) | 2314 | if (part.LocalId == localID) |
2171 | { | 2315 | { |
2316 | lockPartsForRead(false); | ||
2172 | return true; | 2317 | return true; |
2173 | } | 2318 | } |
2174 | } | 2319 | } |
2175 | } | 2320 | } |
2321 | lockPartsForRead(false); | ||
2176 | 2322 | ||
2177 | return false; | 2323 | return false; |
2178 | } | 2324 | } |
@@ -2222,53 +2368,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
2222 | if (m_rootPart.LinkNum == 0) | 2368 | if (m_rootPart.LinkNum == 0) |
2223 | m_rootPart.LinkNum = 1; | 2369 | m_rootPart.LinkNum = 1; |
2224 | 2370 | ||
2225 | lock (m_parts) | 2371 | lockPartsForWrite(true); |
2226 | { | 2372 | |
2227 | m_parts.Add(linkPart.UUID, linkPart); | 2373 | m_parts.Add(linkPart.UUID, linkPart); |
2228 | 2374 | ||
2229 | // Insert in terms of link numbers, the new links | 2375 | lockPartsForWrite(false); |
2230 | // before the current ones (with the exception of | 2376 | |
2231 | // the root prim. Shuffle the old ones up | 2377 | // Insert in terms of link numbers, the new links |
2232 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | 2378 | // before the current ones (with the exception of |
2379 | // the root prim. Shuffle the old ones up | ||
2380 | lockPartsForRead(true); | ||
2381 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | ||
2382 | { | ||
2383 | if (kvp.Value.LinkNum != 1) | ||
2233 | { | 2384 | { |
2234 | if (kvp.Value.LinkNum != 1) | 2385 | // Don't update root prim link number |
2235 | { | 2386 | kvp.Value.LinkNum += objectGroup.PrimCount; |
2236 | // Don't update root prim link number | ||
2237 | kvp.Value.LinkNum += objectGroup.PrimCount; | ||
2238 | } | ||
2239 | } | 2387 | } |
2388 | } | ||
2389 | lockPartsForRead(false); | ||
2240 | 2390 | ||
2241 | linkPart.LinkNum = 2; | 2391 | linkPart.LinkNum = 2; |
2242 | 2392 | ||
2243 | linkPart.SetParent(this); | 2393 | linkPart.SetParent(this); |
2244 | linkPart.AddFlag(PrimFlags.CreateSelected); | 2394 | linkPart.AddFlag(PrimFlags.CreateSelected); |
2245 | 2395 | ||
2246 | //if (linkPart.PhysActor != null) | 2396 | //if (linkPart.PhysActor != null) |
2247 | //{ | 2397 | //{ |
2248 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); | 2398 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); |
2249 | 2399 | ||
2250 | //linkPart.PhysActor = null; | 2400 | //linkPart.PhysActor = null; |
2251 | //} | 2401 | //} |
2252 | 2402 | ||
2253 | //TODO: rest of parts | 2403 | //TODO: rest of parts |
2254 | int linkNum = 3; | 2404 | int linkNum = 3; |
2255 | foreach (SceneObjectPart part in objectGroup.Children.Values) | 2405 | foreach (SceneObjectPart part in objectGroup.Children.Values) |
2406 | { | ||
2407 | if (part.UUID != objectGroup.m_rootPart.UUID) | ||
2256 | { | 2408 | { |
2257 | if (part.UUID != objectGroup.m_rootPart.UUID) | 2409 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); |
2258 | { | ||
2259 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); | ||
2260 | } | ||
2261 | part.ClearUndoState(); | ||
2262 | } | 2410 | } |
2411 | part.ClearUndoState(); | ||
2263 | } | 2412 | } |
2264 | 2413 | ||
2265 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); | 2414 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); |
2266 | objectGroup.m_isDeleted = true; | 2415 | objectGroup.m_isDeleted = true; |
2416 | |||
2417 | objectGroup.lockPartsForWrite(true); | ||
2267 | 2418 | ||
2268 | lock (objectGroup.m_parts) | 2419 | objectGroup.m_parts.Clear(); |
2269 | { | 2420 | |
2270 | objectGroup.m_parts.Clear(); | 2421 | objectGroup.lockPartsForWrite(false); |
2271 | } | ||
2272 | 2422 | ||
2273 | // Can't do this yet since backup still makes use of the root part without any synchronization | 2423 | // Can't do this yet since backup still makes use of the root part without any synchronization |
2274 | // objectGroup.m_rootPart = null; | 2424 | // objectGroup.m_rootPart = null; |
@@ -2327,11 +2477,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2327 | Quaternion worldRot = linkPart.GetWorldRotation(); | 2477 | Quaternion worldRot = linkPart.GetWorldRotation(); |
2328 | 2478 | ||
2329 | // Remove the part from this object | 2479 | // Remove the part from this object |
2330 | lock (m_parts) | 2480 | lockPartsForWrite(true); |
2331 | { | 2481 | { |
2332 | m_parts.Remove(linkPart.UUID); | 2482 | m_parts.Remove(linkPart.UUID); |
2333 | } | 2483 | } |
2334 | 2484 | lockPartsForWrite(false); | |
2485 | lockPartsForRead(true); | ||
2335 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | 2486 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left |
2336 | RootPart.LinkNum = 0; | 2487 | RootPart.LinkNum = 0; |
2337 | else | 2488 | else |
@@ -2342,6 +2493,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2342 | p.LinkNum--; | 2493 | p.LinkNum--; |
2343 | } | 2494 | } |
2344 | } | 2495 | } |
2496 | lockPartsForRead(false); | ||
2345 | 2497 | ||
2346 | linkPart.ParentID = 0; | 2498 | linkPart.ParentID = 0; |
2347 | linkPart.LinkNum = 0; | 2499 | linkPart.LinkNum = 0; |
@@ -2659,9 +2811,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2659 | 2811 | ||
2660 | if (selectionPart != null) | 2812 | if (selectionPart != null) |
2661 | { | 2813 | { |
2662 | lock (m_parts) | 2814 | lockPartsForRead(true); |
2815 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | ||
2816 | lockPartsForRead(false); | ||
2817 | foreach (SceneObjectPart part in parts) | ||
2663 | { | 2818 | { |
2664 | foreach (SceneObjectPart part in m_parts.Values) | 2819 | if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) |
2665 | { | 2820 | { |
2666 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | 2821 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || |
2667 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | 2822 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || |
@@ -2671,12 +2826,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2671 | break; | 2826 | break; |
2672 | } | 2827 | } |
2673 | } | 2828 | } |
2829 | } | ||
2674 | 2830 | ||
2675 | foreach (SceneObjectPart part in m_parts.Values) | 2831 | foreach (SceneObjectPart part in parts) |
2676 | { | 2832 | { |
2677 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2833 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
2678 | } | ||
2679 | } | 2834 | } |
2835 | |||
2680 | } | 2836 | } |
2681 | } | 2837 | } |
2682 | 2838 | ||
@@ -2762,11 +2918,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2762 | scale.Y = m_scene.m_maxNonphys; | 2918 | scale.Y = m_scene.m_maxNonphys; |
2763 | if (scale.Z > m_scene.m_maxNonphys) | 2919 | if (scale.Z > m_scene.m_maxNonphys) |
2764 | scale.Z = m_scene.m_maxNonphys; | 2920 | scale.Z = m_scene.m_maxNonphys; |
2765 | |||
2766 | SceneObjectPart part = GetChildPart(localID); | 2921 | SceneObjectPart part = GetChildPart(localID); |
2767 | if (part != null) | 2922 | if (part != null) |
2768 | { | 2923 | { |
2769 | part.Resize(scale); | ||
2770 | if (part.PhysActor != null) | 2924 | if (part.PhysActor != null) |
2771 | { | 2925 | { |
2772 | if (part.PhysActor.IsPhysical) | 2926 | if (part.PhysActor.IsPhysical) |
@@ -2781,7 +2935,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2781 | part.PhysActor.Size = scale; | 2935 | part.PhysActor.Size = scale; |
2782 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 2936 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); |
2783 | } | 2937 | } |
2784 | //if (part.UUID != m_rootPart.UUID) | 2938 | part.Resize(scale); |
2785 | 2939 | ||
2786 | HasGroupChanged = true; | 2940 | HasGroupChanged = true; |
2787 | ScheduleGroupForFullUpdate(); | 2941 | ScheduleGroupForFullUpdate(); |
@@ -2822,77 +2976,76 @@ namespace OpenSim.Region.Framework.Scenes | |||
2822 | float y = (scale.Y / part.Scale.Y); | 2976 | float y = (scale.Y / part.Scale.Y); |
2823 | float z = (scale.Z / part.Scale.Z); | 2977 | float z = (scale.Z / part.Scale.Z); |
2824 | 2978 | ||
2825 | lock (m_parts) | 2979 | lockPartsForRead(true); |
2980 | if (x > 1.0f || y > 1.0f || z > 1.0f) | ||
2826 | { | 2981 | { |
2827 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 2982 | foreach (SceneObjectPart obPart in m_parts.Values) |
2828 | { | 2983 | { |
2829 | foreach (SceneObjectPart obPart in m_parts.Values) | 2984 | if (obPart.UUID != m_rootPart.UUID) |
2830 | { | 2985 | { |
2831 | if (obPart.UUID != m_rootPart.UUID) | 2986 | Vector3 oldSize = new Vector3(obPart.Scale); |
2832 | { | ||
2833 | Vector3 oldSize = new Vector3(obPart.Scale); | ||
2834 | 2987 | ||
2835 | float f = 1.0f; | 2988 | float f = 1.0f; |
2836 | float a = 1.0f; | 2989 | float a = 1.0f; |
2837 | 2990 | ||
2838 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | 2991 | if (part.PhysActor != null && part.PhysActor.IsPhysical) |
2992 | { | ||
2993 | if (oldSize.X*x > m_scene.m_maxPhys) | ||
2839 | { | 2994 | { |
2840 | if (oldSize.X*x > m_scene.m_maxPhys) | 2995 | f = m_scene.m_maxPhys / oldSize.X; |
2841 | { | 2996 | a = f / x; |
2842 | f = m_scene.m_maxPhys / oldSize.X; | 2997 | x *= a; |
2843 | a = f / x; | 2998 | y *= a; |
2844 | x *= a; | 2999 | z *= a; |
2845 | y *= a; | ||
2846 | z *= a; | ||
2847 | } | ||
2848 | if (oldSize.Y*y > m_scene.m_maxPhys) | ||
2849 | { | ||
2850 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2851 | a = f / y; | ||
2852 | x *= a; | ||
2853 | y *= a; | ||
2854 | z *= a; | ||
2855 | } | ||
2856 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
2857 | { | ||
2858 | f = m_scene.m_maxPhys / oldSize.Z; | ||
2859 | a = f / z; | ||
2860 | x *= a; | ||
2861 | y *= a; | ||
2862 | z *= a; | ||
2863 | } | ||
2864 | } | 3000 | } |
2865 | else | 3001 | if (oldSize.Y*y > m_scene.m_maxPhys) |
3002 | { | ||
3003 | f = m_scene.m_maxPhys / oldSize.Y; | ||
3004 | a = f / y; | ||
3005 | x *= a; | ||
3006 | y *= a; | ||
3007 | z *= a; | ||
3008 | } | ||
3009 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
3010 | { | ||
3011 | f = m_scene.m_maxPhys / oldSize.Z; | ||
3012 | a = f / z; | ||
3013 | x *= a; | ||
3014 | y *= a; | ||
3015 | z *= a; | ||
3016 | } | ||
3017 | } | ||
3018 | else | ||
3019 | { | ||
3020 | if (oldSize.X*x > m_scene.m_maxNonphys) | ||
3021 | { | ||
3022 | f = m_scene.m_maxNonphys / oldSize.X; | ||
3023 | a = f / x; | ||
3024 | x *= a; | ||
3025 | y *= a; | ||
3026 | z *= a; | ||
3027 | } | ||
3028 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
3029 | { | ||
3030 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
3031 | a = f / y; | ||
3032 | x *= a; | ||
3033 | y *= a; | ||
3034 | z *= a; | ||
3035 | } | ||
3036 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2866 | { | 3037 | { |
2867 | if (oldSize.X*x > m_scene.m_maxNonphys) | 3038 | f = m_scene.m_maxNonphys / oldSize.Z; |
2868 | { | 3039 | a = f / z; |
2869 | f = m_scene.m_maxNonphys / oldSize.X; | 3040 | x *= a; |
2870 | a = f / x; | 3041 | y *= a; |
2871 | x *= a; | 3042 | z *= a; |
2872 | y *= a; | ||
2873 | z *= a; | ||
2874 | } | ||
2875 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
2876 | { | ||
2877 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
2878 | a = f / y; | ||
2879 | x *= a; | ||
2880 | y *= a; | ||
2881 | z *= a; | ||
2882 | } | ||
2883 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2884 | { | ||
2885 | f = m_scene.m_maxNonphys / oldSize.Z; | ||
2886 | a = f / z; | ||
2887 | x *= a; | ||
2888 | y *= a; | ||
2889 | z *= a; | ||
2890 | } | ||
2891 | } | 3043 | } |
2892 | } | 3044 | } |
2893 | } | 3045 | } |
2894 | } | 3046 | } |
2895 | } | 3047 | } |
3048 | lockPartsForRead(false); | ||
2896 | 3049 | ||
2897 | Vector3 prevScale = part.Scale; | 3050 | Vector3 prevScale = part.Scale; |
2898 | prevScale.X *= x; | 3051 | prevScale.X *= x; |
@@ -2900,7 +3053,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2900 | prevScale.Z *= z; | 3053 | prevScale.Z *= z; |
2901 | part.Resize(prevScale); | 3054 | part.Resize(prevScale); |
2902 | 3055 | ||
2903 | lock (m_parts) | 3056 | lockPartsForRead(true); |
2904 | { | 3057 | { |
2905 | foreach (SceneObjectPart obPart in m_parts.Values) | 3058 | foreach (SceneObjectPart obPart in m_parts.Values) |
2906 | { | 3059 | { |
@@ -2919,6 +3072,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2919 | } | 3072 | } |
2920 | } | 3073 | } |
2921 | } | 3074 | } |
3075 | lockPartsForRead(false); | ||
2922 | 3076 | ||
2923 | if (part.PhysActor != null) | 3077 | if (part.PhysActor != null) |
2924 | { | 3078 | { |
@@ -2999,7 +3153,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2999 | axDiff *= Quaternion.Inverse(partRotation); | 3153 | axDiff *= Quaternion.Inverse(partRotation); |
3000 | diff = axDiff; | 3154 | diff = axDiff; |
3001 | 3155 | ||
3002 | lock (m_parts) | 3156 | lockPartsForRead(true); |
3003 | { | 3157 | { |
3004 | foreach (SceneObjectPart obPart in m_parts.Values) | 3158 | foreach (SceneObjectPart obPart in m_parts.Values) |
3005 | { | 3159 | { |
@@ -3009,6 +3163,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3009 | } | 3163 | } |
3010 | } | 3164 | } |
3011 | } | 3165 | } |
3166 | lockPartsForRead(false); | ||
3012 | 3167 | ||
3013 | AbsolutePosition = newPos; | 3168 | AbsolutePosition = newPos; |
3014 | 3169 | ||
@@ -3126,7 +3281,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3126 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 3281 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); |
3127 | } | 3282 | } |
3128 | 3283 | ||
3129 | lock (m_parts) | 3284 | lockPartsForRead(true); |
3130 | { | 3285 | { |
3131 | foreach (SceneObjectPart prim in m_parts.Values) | 3286 | foreach (SceneObjectPart prim in m_parts.Values) |
3132 | { | 3287 | { |
@@ -3144,6 +3299,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3144 | } | 3299 | } |
3145 | } | 3300 | } |
3146 | } | 3301 | } |
3302 | lockPartsForRead(false); | ||
3147 | 3303 | ||
3148 | m_rootPart.ScheduleTerseUpdate(); | 3304 | m_rootPart.ScheduleTerseUpdate(); |
3149 | } | 3305 | } |
@@ -3266,7 +3422,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3266 | if (atTargets.Count > 0) | 3422 | if (atTargets.Count > 0) |
3267 | { | 3423 | { |
3268 | uint[] localids = new uint[0]; | 3424 | uint[] localids = new uint[0]; |
3269 | lock (m_parts) | 3425 | lockPartsForRead(true); |
3270 | { | 3426 | { |
3271 | localids = new uint[m_parts.Count]; | 3427 | localids = new uint[m_parts.Count]; |
3272 | int cntr = 0; | 3428 | int cntr = 0; |
@@ -3276,6 +3432,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3276 | cntr++; | 3432 | cntr++; |
3277 | } | 3433 | } |
3278 | } | 3434 | } |
3435 | lockPartsForRead(false); | ||
3279 | 3436 | ||
3280 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3437 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3281 | { | 3438 | { |
@@ -3294,7 +3451,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3294 | { | 3451 | { |
3295 | //trigger not_at_target | 3452 | //trigger not_at_target |
3296 | uint[] localids = new uint[0]; | 3453 | uint[] localids = new uint[0]; |
3297 | lock (m_parts) | 3454 | lockPartsForRead(true); |
3298 | { | 3455 | { |
3299 | localids = new uint[m_parts.Count]; | 3456 | localids = new uint[m_parts.Count]; |
3300 | int cntr = 0; | 3457 | int cntr = 0; |
@@ -3304,7 +3461,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3304 | cntr++; | 3461 | cntr++; |
3305 | } | 3462 | } |
3306 | } | 3463 | } |
3307 | 3464 | lockPartsForRead(false); | |
3465 | |||
3308 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3466 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3309 | { | 3467 | { |
3310 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); | 3468 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); |
@@ -3396,19 +3554,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3396 | public float GetMass() | 3554 | public float GetMass() |
3397 | { | 3555 | { |
3398 | float retmass = 0f; | 3556 | float retmass = 0f; |
3399 | lock (m_parts) | 3557 | lockPartsForRead(true); |
3400 | { | 3558 | { |
3401 | foreach (SceneObjectPart part in m_parts.Values) | 3559 | foreach (SceneObjectPart part in m_parts.Values) |
3402 | { | 3560 | { |
3403 | retmass += part.GetMass(); | 3561 | retmass += part.GetMass(); |
3404 | } | 3562 | } |
3405 | } | 3563 | } |
3564 | lockPartsForRead(false); | ||
3406 | return retmass; | 3565 | return retmass; |
3407 | } | 3566 | } |
3408 | 3567 | ||
3409 | public void CheckSculptAndLoad() | 3568 | public void CheckSculptAndLoad() |
3410 | { | 3569 | { |
3411 | lock (m_parts) | 3570 | lockPartsForRead(true); |
3412 | { | 3571 | { |
3413 | if (!IsDeleted) | 3572 | if (!IsDeleted) |
3414 | { | 3573 | { |
@@ -3433,6 +3592,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3433 | } | 3592 | } |
3434 | } | 3593 | } |
3435 | } | 3594 | } |
3595 | lockPartsForRead(false); | ||
3436 | } | 3596 | } |
3437 | 3597 | ||
3438 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 3598 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
@@ -3453,7 +3613,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3453 | /// <param name="client"></param> | 3613 | /// <param name="client"></param> |
3454 | public void SetGroup(UUID GroupID, IClientAPI client) | 3614 | public void SetGroup(UUID GroupID, IClientAPI client) |
3455 | { | 3615 | { |
3456 | lock (m_parts) | 3616 | lockPartsForRead(true); |
3457 | { | 3617 | { |
3458 | foreach (SceneObjectPart part in m_parts.Values) | 3618 | foreach (SceneObjectPart part in m_parts.Values) |
3459 | { | 3619 | { |
@@ -3463,7 +3623,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3463 | 3623 | ||
3464 | HasGroupChanged = true; | 3624 | HasGroupChanged = true; |
3465 | } | 3625 | } |
3466 | 3626 | lockPartsForRead(false); | |
3467 | ScheduleGroupForFullUpdate(); | 3627 | ScheduleGroupForFullUpdate(); |
3468 | } | 3628 | } |
3469 | 3629 | ||
@@ -3482,11 +3642,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3482 | 3642 | ||
3483 | public void SetAttachmentPoint(byte point) | 3643 | public void SetAttachmentPoint(byte point) |
3484 | { | 3644 | { |
3485 | lock (m_parts) | 3645 | lockPartsForRead(true); |
3486 | { | 3646 | { |
3487 | foreach (SceneObjectPart part in m_parts.Values) | 3647 | foreach (SceneObjectPart part in m_parts.Values) |
3488 | part.SetAttachmentPoint(point); | 3648 | part.SetAttachmentPoint(point); |
3489 | } | 3649 | } |
3650 | lockPartsForRead(false); | ||
3490 | } | 3651 | } |
3491 | 3652 | ||
3492 | #region ISceneObject | 3653 | #region ISceneObject |