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 af46659..4676a30 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 | ||
@@ -299,13 +368,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
299 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 368 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
300 | } | 369 | } |
301 | 370 | ||
302 | lock (m_parts) | 371 | lockPartsForRead(true); |
303 | { | 372 | { |
304 | foreach (SceneObjectPart part in m_parts.Values) | 373 | foreach (SceneObjectPart part in m_parts.Values) |
305 | { | 374 | { |
375 | |||
306 | part.GroupPosition = val; | 376 | part.GroupPosition = val; |
377 | |||
307 | } | 378 | } |
308 | } | 379 | } |
380 | lockPartsForRead(false); | ||
309 | 381 | ||
310 | //if (m_rootPart.PhysActor != null) | 382 | //if (m_rootPart.PhysActor != null) |
311 | //{ | 383 | //{ |
@@ -467,13 +539,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
467 | 539 | ||
468 | public void SetFromItemID(UUID AssetId) | 540 | public void SetFromItemID(UUID AssetId) |
469 | { | 541 | { |
470 | lock (m_parts) | 542 | lockPartsForRead(true); |
471 | { | 543 | { |
472 | foreach (SceneObjectPart part in m_parts.Values) | 544 | foreach (SceneObjectPart part in m_parts.Values) |
473 | { | 545 | { |
546 | |||
474 | part.FromItemID = AssetId; | 547 | part.FromItemID = AssetId; |
548 | |||
475 | } | 549 | } |
476 | } | 550 | } |
551 | lockPartsForRead(false); | ||
477 | } | 552 | } |
478 | 553 | ||
479 | public UUID GetFromItemID() | 554 | public UUID GetFromItemID() |
@@ -540,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
540 | Vector3 maxScale = Vector3.Zero; | 615 | Vector3 maxScale = Vector3.Zero; |
541 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | 616 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); |
542 | 617 | ||
543 | lock (m_parts) | 618 | lockPartsForRead(true); |
544 | { | 619 | { |
545 | foreach (SceneObjectPart part in m_parts.Values) | 620 | foreach (SceneObjectPart part in m_parts.Values) |
546 | { | 621 | { |
622 | |||
547 | Vector3 partscale = part.Scale; | 623 | Vector3 partscale = part.Scale; |
548 | Vector3 partoffset = part.OffsetPosition; | 624 | Vector3 partoffset = part.OffsetPosition; |
549 | 625 | ||
@@ -554,8 +630,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
554 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | 630 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; |
555 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | 631 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; |
556 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | 632 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; |
633 | |||
557 | } | 634 | } |
558 | } | 635 | } |
636 | lockPartsForRead(false); | ||
637 | |||
559 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | 638 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; |
560 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | 639 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; |
561 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | 640 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; |
@@ -571,10 +650,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
571 | 650 | ||
572 | EntityIntersection result = new EntityIntersection(); | 651 | EntityIntersection result = new EntityIntersection(); |
573 | 652 | ||
574 | lock (m_parts) | 653 | lockPartsForRead(true); |
575 | { | 654 | { |
576 | foreach (SceneObjectPart part in m_parts.Values) | 655 | foreach (SceneObjectPart part in m_parts.Values) |
577 | { | 656 | { |
657 | |||
578 | // Temporary commented to stop compiler warning | 658 | // Temporary commented to stop compiler warning |
579 | //Vector3 partPosition = | 659 | //Vector3 partPosition = |
580 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); | 660 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); |
@@ -602,8 +682,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
602 | result.distance = inter.distance; | 682 | result.distance = inter.distance; |
603 | } | 683 | } |
604 | } | 684 | } |
685 | |||
605 | } | 686 | } |
606 | } | 687 | } |
688 | lockPartsForRead(false); | ||
607 | return result; | 689 | return result; |
608 | } | 690 | } |
609 | 691 | ||
@@ -616,10 +698,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
616 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) | 698 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) |
617 | { | 699 | { |
618 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; | 700 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; |
619 | lock (m_parts) | 701 | lockPartsForRead(true); |
620 | { | 702 | { |
621 | foreach (SceneObjectPart part in m_parts.Values) | 703 | foreach (SceneObjectPart part in m_parts.Values) |
622 | { | 704 | { |
705 | |||
623 | Vector3 worldPos = part.GetWorldPosition(); | 706 | Vector3 worldPos = part.GetWorldPosition(); |
624 | Vector3 offset = worldPos - AbsolutePosition; | 707 | Vector3 offset = worldPos - AbsolutePosition; |
625 | Quaternion worldRot; | 708 | Quaternion worldRot; |
@@ -678,6 +761,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
678 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); | 761 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); |
679 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); | 762 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); |
680 | 763 | ||
764 | |||
765 | |||
681 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); | 766 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); |
682 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); | 767 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); |
683 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); | 768 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); |
@@ -849,6 +934,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
849 | minZ = backBottomLeft.Z; | 934 | minZ = backBottomLeft.Z; |
850 | } | 935 | } |
851 | } | 936 | } |
937 | lockPartsForRead(false); | ||
852 | 938 | ||
853 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); | 939 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); |
854 | 940 | ||
@@ -877,17 +963,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
877 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); | 963 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); |
878 | 964 | ||
879 | // Capture script state while holding the lock | 965 | // Capture script state while holding the lock |
880 | lock (m_parts) | 966 | lockPartsForRead(true); |
881 | { | 967 | { |
882 | foreach (SceneObjectPart part in m_parts.Values) | 968 | foreach (SceneObjectPart part in m_parts.Values) |
883 | { | 969 | { |
970 | |||
884 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); | 971 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); |
885 | foreach (UUID itemid in pstates.Keys) | 972 | foreach (UUID itemid in pstates.Keys) |
886 | { | 973 | { |
887 | states.Add(itemid, pstates[itemid]); | 974 | states.Add(itemid, pstates[itemid]); |
888 | } | 975 | } |
976 | |||
889 | } | 977 | } |
890 | } | 978 | } |
979 | lockPartsForRead(false); | ||
891 | 980 | ||
892 | if (states.Count > 0) | 981 | if (states.Count > 0) |
893 | { | 982 | { |
@@ -1049,13 +1138,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1049 | 1138 | ||
1050 | public override void UpdateMovement() | 1139 | public override void UpdateMovement() |
1051 | { | 1140 | { |
1052 | lock (m_parts) | 1141 | lockPartsForRead(true); |
1053 | { | 1142 | { |
1054 | foreach (SceneObjectPart part in m_parts.Values) | 1143 | foreach (SceneObjectPart part in m_parts.Values) |
1055 | { | 1144 | { |
1145 | |||
1056 | part.UpdateMovement(); | 1146 | part.UpdateMovement(); |
1147 | |||
1057 | } | 1148 | } |
1058 | } | 1149 | } |
1150 | lockPartsForRead(false); | ||
1059 | } | 1151 | } |
1060 | 1152 | ||
1061 | public ushort GetTimeDilation() | 1153 | public ushort GetTimeDilation() |
@@ -1099,7 +1191,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1099 | /// <param name="part"></param> | 1191 | /// <param name="part"></param> |
1100 | public void AddPart(SceneObjectPart part) | 1192 | public void AddPart(SceneObjectPart part) |
1101 | { | 1193 | { |
1102 | lock (m_parts) | 1194 | lockPartsForWrite(true); |
1103 | { | 1195 | { |
1104 | part.SetParent(this); | 1196 | part.SetParent(this); |
1105 | m_parts.Add(part.UUID, part); | 1197 | m_parts.Add(part.UUID, part); |
@@ -1109,6 +1201,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1109 | if (part.LinkNum == 2 && RootPart != null) | 1201 | if (part.LinkNum == 2 && RootPart != null) |
1110 | RootPart.LinkNum = 1; | 1202 | RootPart.LinkNum = 1; |
1111 | } | 1203 | } |
1204 | lockPartsForWrite(false); | ||
1112 | } | 1205 | } |
1113 | 1206 | ||
1114 | /// <summary> | 1207 | /// <summary> |
@@ -1116,28 +1209,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1116 | /// </summary> | 1209 | /// </summary> |
1117 | private void UpdateParentIDs() | 1210 | private void UpdateParentIDs() |
1118 | { | 1211 | { |
1119 | lock (m_parts) | 1212 | lockPartsForRead(true); |
1120 | { | 1213 | { |
1121 | foreach (SceneObjectPart part in m_parts.Values) | 1214 | foreach (SceneObjectPart part in m_parts.Values) |
1122 | { | 1215 | { |
1216 | |||
1123 | if (part.UUID != m_rootPart.UUID) | 1217 | if (part.UUID != m_rootPart.UUID) |
1124 | { | 1218 | { |
1125 | part.ParentID = m_rootPart.LocalId; | 1219 | part.ParentID = m_rootPart.LocalId; |
1126 | } | 1220 | } |
1221 | |||
1127 | } | 1222 | } |
1128 | } | 1223 | } |
1224 | lockPartsForRead(false); | ||
1129 | } | 1225 | } |
1130 | 1226 | ||
1131 | public void RegenerateFullIDs() | 1227 | public void RegenerateFullIDs() |
1132 | { | 1228 | { |
1133 | lock (m_parts) | 1229 | lockPartsForRead(true); |
1134 | { | 1230 | { |
1135 | foreach (SceneObjectPart part in m_parts.Values) | 1231 | foreach (SceneObjectPart part in m_parts.Values) |
1136 | { | 1232 | { |
1233 | |||
1137 | part.UUID = UUID.Random(); | 1234 | part.UUID = UUID.Random(); |
1138 | 1235 | ||
1139 | } | 1236 | } |
1140 | } | 1237 | } |
1238 | lockPartsForRead(false); | ||
1141 | } | 1239 | } |
1142 | 1240 | ||
1143 | // helper provided for parts. | 1241 | // helper provided for parts. |
@@ -1218,29 +1316,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1218 | 1316 | ||
1219 | DetachFromBackup(); | 1317 | DetachFromBackup(); |
1220 | 1318 | ||
1221 | lock (m_parts) | 1319 | lockPartsForRead(true); |
1320 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1321 | lockPartsForRead(false); | ||
1322 | |||
1323 | foreach (SceneObjectPart part in values) | ||
1222 | { | 1324 | { |
1223 | foreach (SceneObjectPart part in m_parts.Values) | ||
1224 | { | ||
1225 | // part.Inventory.RemoveScriptInstances(); | 1325 | // part.Inventory.RemoveScriptInstances(); |
1226 | 1326 | ||
1227 | ScenePresence[] avatars = Scene.GetScenePresences(); | 1327 | ScenePresence[] avatars = Scene.GetScenePresences(); |
1228 | for (int i = 0; i < avatars.Length; i++) | 1328 | for (int i = 0; i < avatars.Length; i++) |
1329 | { | ||
1330 | if (avatars[i].ParentID == LocalId) | ||
1229 | { | 1331 | { |
1230 | if (avatars[i].ParentID == LocalId) | 1332 | avatars[i].StandUp(); |
1231 | { | 1333 | } |
1232 | avatars[i].StandUp(); | ||
1233 | } | ||
1234 | 1334 | ||
1235 | if (!silent) | 1335 | if (!silent) |
1236 | { | 1336 | { |
1237 | part.UpdateFlag = 0; | 1337 | part.UpdateFlag = 0; |
1238 | if (part == m_rootPart) | 1338 | if (part == m_rootPart) |
1239 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); | 1339 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); |
1240 | } | ||
1241 | } | 1340 | } |
1242 | } | 1341 | } |
1342 | |||
1243 | } | 1343 | } |
1344 | |||
1345 | |||
1244 | } | 1346 | } |
1245 | 1347 | ||
1246 | public void AddScriptLPS(int count) | 1348 | public void AddScriptLPS(int count) |
@@ -1265,17 +1367,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1265 | 1367 | ||
1266 | scriptEvents aggregateScriptEvents=0; | 1368 | scriptEvents aggregateScriptEvents=0; |
1267 | 1369 | ||
1268 | lock (m_parts) | 1370 | lockPartsForRead(true); |
1269 | { | 1371 | { |
1270 | foreach (SceneObjectPart part in m_parts.Values) | 1372 | foreach (SceneObjectPart part in m_parts.Values) |
1271 | { | 1373 | { |
1374 | |||
1272 | if (part == null) | 1375 | if (part == null) |
1273 | continue; | 1376 | continue; |
1274 | if (part != RootPart) | 1377 | if (part != RootPart) |
1275 | part.ObjectFlags = objectflagupdate; | 1378 | part.ObjectFlags = objectflagupdate; |
1276 | aggregateScriptEvents |= part.AggregateScriptEvents; | 1379 | aggregateScriptEvents |= part.AggregateScriptEvents; |
1380 | |||
1277 | } | 1381 | } |
1278 | } | 1382 | } |
1383 | lockPartsForRead(false); | ||
1279 | 1384 | ||
1280 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); | 1385 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); |
1281 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); | 1386 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); |
@@ -1317,42 +1422,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
1317 | /// <param name="m_physicalPrim"></param> | 1422 | /// <param name="m_physicalPrim"></param> |
1318 | public void ApplyPhysics(bool m_physicalPrim) | 1423 | public void ApplyPhysics(bool m_physicalPrim) |
1319 | { | 1424 | { |
1320 | lock (m_parts) | 1425 | lockPartsForRead(true); |
1426 | |||
1427 | if (m_parts.Count > 1) | ||
1321 | { | 1428 | { |
1322 | if (m_parts.Count > 1) | 1429 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); |
1430 | lockPartsForRead(false); | ||
1431 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1432 | foreach (SceneObjectPart part in values) | ||
1323 | { | 1433 | { |
1324 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | 1434 | |
1325 | foreach (SceneObjectPart part in m_parts.Values) | 1435 | if (part.LocalId != m_rootPart.LocalId) |
1326 | { | 1436 | { |
1327 | if (part.LocalId != m_rootPart.LocalId) | 1437 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); |
1328 | { | ||
1329 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); | ||
1330 | } | ||
1331 | } | 1438 | } |
1332 | 1439 | ||
1333 | // Hack to get the physics scene geometries in the right spot | ||
1334 | ResetChildPrimPhysicsPositions(); | ||
1335 | } | ||
1336 | else | ||
1337 | { | ||
1338 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1339 | } | 1440 | } |
1441 | // Hack to get the physics scene geometries in the right spot | ||
1442 | ResetChildPrimPhysicsPositions(); | ||
1443 | } | ||
1444 | else | ||
1445 | { | ||
1446 | lockPartsForRead(false); | ||
1447 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1340 | } | 1448 | } |
1341 | } | 1449 | } |
1342 | 1450 | ||
1343 | public void SetOwnerId(UUID userId) | 1451 | public void SetOwnerId(UUID userId) |
1344 | { | 1452 | { |
1345 | ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); | 1453 | ForEachPart(delegate(SceneObjectPart part) |
1454 | { | ||
1455 | |||
1456 | part.OwnerID = userId; | ||
1457 | |||
1458 | }); | ||
1346 | } | 1459 | } |
1347 | 1460 | ||
1348 | public void ForEachPart(Action<SceneObjectPart> whatToDo) | 1461 | public void ForEachPart(Action<SceneObjectPart> whatToDo) |
1349 | { | 1462 | { |
1350 | lock (m_parts) | 1463 | lockPartsForRead(true); |
1464 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1465 | lockPartsForRead(false); | ||
1466 | foreach (SceneObjectPart part in values) | ||
1351 | { | 1467 | { |
1352 | foreach (SceneObjectPart part in m_parts.Values) | 1468 | |
1353 | { | 1469 | whatToDo(part); |
1354 | whatToDo(part); | 1470 | |
1355 | } | ||
1356 | } | 1471 | } |
1357 | } | 1472 | } |
1358 | 1473 | ||
@@ -1451,14 +1566,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1451 | { | 1566 | { |
1452 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); | 1567 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); |
1453 | 1568 | ||
1454 | lock (m_parts) | 1569 | lockPartsForRead(true); |
1455 | { | 1570 | { |
1456 | foreach (SceneObjectPart part in m_parts.Values) | 1571 | foreach (SceneObjectPart part in m_parts.Values) |
1457 | { | 1572 | { |
1573 | |||
1458 | if (part != RootPart) | 1574 | if (part != RootPart) |
1459 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | 1575 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); |
1576 | |||
1460 | } | 1577 | } |
1461 | } | 1578 | } |
1579 | lockPartsForRead(false); | ||
1462 | } | 1580 | } |
1463 | 1581 | ||
1464 | /// <summary> | 1582 | /// <summary> |
@@ -1553,10 +1671,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1553 | 1671 | ||
1554 | List<SceneObjectPart> partList; | 1672 | List<SceneObjectPart> partList; |
1555 | 1673 | ||
1556 | lock (m_parts) | 1674 | lockPartsForRead(true); |
1557 | { | 1675 | |
1558 | partList = new List<SceneObjectPart>(m_parts.Values); | 1676 | partList = new List<SceneObjectPart>(m_parts.Values); |
1559 | } | 1677 | |
1678 | lockPartsForRead(false); | ||
1560 | 1679 | ||
1561 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) | 1680 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) |
1562 | { | 1681 | { |
@@ -1805,6 +1924,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1805 | } | 1924 | } |
1806 | } | 1925 | } |
1807 | } | 1926 | } |
1927 | |||
1808 | public void stopLookAt() | 1928 | public void stopLookAt() |
1809 | { | 1929 | { |
1810 | SceneObjectPart rootpart = m_rootPart; | 1930 | SceneObjectPart rootpart = m_rootPart; |
@@ -1879,10 +1999,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1879 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 1999 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); |
1880 | newPart.SetParent(this); | 2000 | newPart.SetParent(this); |
1881 | 2001 | ||
1882 | lock (m_parts) | 2002 | lockPartsForWrite(true); |
1883 | { | 2003 | { |
1884 | m_parts.Add(newPart.UUID, newPart); | 2004 | m_parts.Add(newPart.UUID, newPart); |
1885 | } | 2005 | } |
2006 | lockPartsForWrite(false); | ||
1886 | 2007 | ||
1887 | SetPartAsNonRoot(newPart); | 2008 | SetPartAsNonRoot(newPart); |
1888 | 2009 | ||
@@ -1945,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1945 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 2066 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
1946 | // return; | 2067 | // return; |
1947 | 2068 | ||
1948 | lock (m_parts) | 2069 | lockPartsForRead(true); |
1949 | { | 2070 | { |
1950 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 2071 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); |
1951 | 2072 | ||
@@ -1963,34 +2084,43 @@ namespace OpenSim.Region.Framework.Scenes | |||
1963 | 2084 | ||
1964 | foreach (SceneObjectPart part in m_parts.Values) | 2085 | foreach (SceneObjectPart part in m_parts.Values) |
1965 | { | 2086 | { |
2087 | |||
1966 | part.SendScheduledUpdates(); | 2088 | part.SendScheduledUpdates(); |
2089 | |||
1967 | } | 2090 | } |
1968 | } | 2091 | } |
2092 | lockPartsForRead(false); | ||
1969 | } | 2093 | } |
1970 | 2094 | ||
1971 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) | 2095 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) |
1972 | { | 2096 | { |
1973 | RootPart.AddFullUpdateToAvatar(presence); | 2097 | RootPart.AddFullUpdateToAvatar(presence); |
1974 | 2098 | ||
1975 | lock (m_parts) | 2099 | lockPartsForRead(true); |
1976 | { | 2100 | { |
1977 | foreach (SceneObjectPart part in m_parts.Values) | 2101 | foreach (SceneObjectPart part in m_parts.Values) |
1978 | { | 2102 | { |
2103 | |||
1979 | if (part != RootPart) | 2104 | if (part != RootPart) |
1980 | part.AddFullUpdateToAvatar(presence); | 2105 | part.AddFullUpdateToAvatar(presence); |
2106 | |||
1981 | } | 2107 | } |
1982 | } | 2108 | } |
2109 | lockPartsForRead(false); | ||
1983 | } | 2110 | } |
1984 | 2111 | ||
1985 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) | 2112 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) |
1986 | { | 2113 | { |
1987 | lock (m_parts) | 2114 | lockPartsForRead(true); |
1988 | { | 2115 | { |
1989 | foreach (SceneObjectPart part in m_parts.Values) | 2116 | foreach (SceneObjectPart part in m_parts.Values) |
1990 | { | 2117 | { |
2118 | |||
1991 | part.AddTerseUpdateToAvatar(presence); | 2119 | part.AddTerseUpdateToAvatar(presence); |
2120 | |||
1992 | } | 2121 | } |
1993 | } | 2122 | } |
2123 | lockPartsForRead(false); | ||
1994 | } | 2124 | } |
1995 | 2125 | ||
1996 | /// <summary> | 2126 | /// <summary> |
@@ -2001,14 +2131,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2001 | checkAtTargets(); | 2131 | checkAtTargets(); |
2002 | RootPart.ScheduleFullUpdate(); | 2132 | RootPart.ScheduleFullUpdate(); |
2003 | 2133 | ||
2004 | lock (m_parts) | 2134 | lockPartsForRead(true); |
2005 | { | 2135 | { |
2006 | foreach (SceneObjectPart part in m_parts.Values) | 2136 | foreach (SceneObjectPart part in m_parts.Values) |
2007 | { | 2137 | { |
2138 | |||
2008 | if (part != RootPart) | 2139 | if (part != RootPart) |
2009 | part.ScheduleFullUpdate(); | 2140 | part.ScheduleFullUpdate(); |
2141 | |||
2010 | } | 2142 | } |
2011 | } | 2143 | } |
2144 | lockPartsForRead(false); | ||
2012 | } | 2145 | } |
2013 | 2146 | ||
2014 | /// <summary> | 2147 | /// <summary> |
@@ -2016,13 +2149,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2016 | /// </summary> | 2149 | /// </summary> |
2017 | public void ScheduleGroupForTerseUpdate() | 2150 | public void ScheduleGroupForTerseUpdate() |
2018 | { | 2151 | { |
2019 | lock (m_parts) | 2152 | lockPartsForRead(true); |
2020 | { | 2153 | { |
2021 | foreach (SceneObjectPart part in m_parts.Values) | 2154 | foreach (SceneObjectPart part in m_parts.Values) |
2022 | { | 2155 | { |
2156 | |||
2023 | part.ScheduleTerseUpdate(); | 2157 | part.ScheduleTerseUpdate(); |
2158 | |||
2024 | } | 2159 | } |
2025 | } | 2160 | } |
2161 | lockPartsForRead(false); | ||
2026 | } | 2162 | } |
2027 | 2163 | ||
2028 | /// <summary> | 2164 | /// <summary> |
@@ -2035,14 +2171,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2035 | 2171 | ||
2036 | RootPart.SendFullUpdateToAllClients(); | 2172 | RootPart.SendFullUpdateToAllClients(); |
2037 | 2173 | ||
2038 | lock (m_parts) | 2174 | lockPartsForRead(true); |
2039 | { | 2175 | { |
2040 | foreach (SceneObjectPart part in m_parts.Values) | 2176 | foreach (SceneObjectPart part in m_parts.Values) |
2041 | { | 2177 | { |
2178 | |||
2042 | if (part != RootPart) | 2179 | if (part != RootPart) |
2043 | part.SendFullUpdateToAllClients(); | 2180 | part.SendFullUpdateToAllClients(); |
2181 | |||
2044 | } | 2182 | } |
2045 | } | 2183 | } |
2184 | lockPartsForRead(false); | ||
2046 | } | 2185 | } |
2047 | 2186 | ||
2048 | /// <summary> | 2187 | /// <summary> |
@@ -2073,14 +2212,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2073 | { | 2212 | { |
2074 | if (IsDeleted) | 2213 | if (IsDeleted) |
2075 | return; | 2214 | return; |
2076 | 2215 | ||
2077 | lock (m_parts) | 2216 | lockPartsForRead(true); |
2078 | { | 2217 | { |
2079 | foreach (SceneObjectPart part in m_parts.Values) | 2218 | foreach (SceneObjectPart part in m_parts.Values) |
2080 | { | 2219 | { |
2081 | part.SendTerseUpdateToAllClients(); | 2220 | part.SendTerseUpdateToAllClients(); |
2082 | } | 2221 | } |
2083 | } | 2222 | } |
2223 | lockPartsForRead(false); | ||
2084 | } | 2224 | } |
2085 | 2225 | ||
2086 | #endregion | 2226 | #endregion |
@@ -2094,16 +2234,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2094 | /// <returns>null if no child part with that linknum or child part</returns> | 2234 | /// <returns>null if no child part with that linknum or child part</returns> |
2095 | public SceneObjectPart GetLinkNumPart(int linknum) | 2235 | public SceneObjectPart GetLinkNumPart(int linknum) |
2096 | { | 2236 | { |
2097 | lock (m_parts) | 2237 | lockPartsForRead(true); |
2098 | { | 2238 | { |
2099 | foreach (SceneObjectPart part in m_parts.Values) | 2239 | foreach (SceneObjectPart part in m_parts.Values) |
2100 | { | 2240 | { |
2101 | if (part.LinkNum == linknum) | 2241 | if (part.LinkNum == linknum) |
2102 | { | 2242 | { |
2243 | lockPartsForRead(false); | ||
2103 | return part; | 2244 | return part; |
2104 | } | 2245 | } |
2105 | } | 2246 | } |
2106 | } | 2247 | } |
2248 | lockPartsForRead(false); | ||
2107 | 2249 | ||
2108 | return null; | 2250 | return null; |
2109 | } | 2251 | } |
@@ -2131,17 +2273,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2131 | public SceneObjectPart GetChildPart(uint localID) | 2273 | public SceneObjectPart GetChildPart(uint localID) |
2132 | { | 2274 | { |
2133 | //m_log.DebugFormat("Entered looking for {0}", localID); | 2275 | //m_log.DebugFormat("Entered looking for {0}", localID); |
2134 | lock (m_parts) | 2276 | lockPartsForRead(true); |
2135 | { | 2277 | { |
2136 | foreach (SceneObjectPart part in m_parts.Values) | 2278 | foreach (SceneObjectPart part in m_parts.Values) |
2137 | { | 2279 | { |
2138 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2280 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2139 | if (part.LocalId == localID) | 2281 | if (part.LocalId == localID) |
2140 | { | 2282 | { |
2283 | lockPartsForRead(false); | ||
2141 | return part; | 2284 | return part; |
2142 | } | 2285 | } |
2143 | } | 2286 | } |
2144 | } | 2287 | } |
2288 | lockPartsForRead(false); | ||
2145 | 2289 | ||
2146 | return null; | 2290 | return null; |
2147 | } | 2291 | } |
@@ -2171,17 +2315,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2171 | public bool HasChildPrim(uint localID) | 2315 | public bool HasChildPrim(uint localID) |
2172 | { | 2316 | { |
2173 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); | 2317 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); |
2174 | lock (m_parts) | 2318 | lockPartsForRead(true); |
2175 | { | 2319 | { |
2176 | foreach (SceneObjectPart part in m_parts.Values) | 2320 | foreach (SceneObjectPart part in m_parts.Values) |
2177 | { | 2321 | { |
2178 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2322 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2179 | if (part.LocalId == localID) | 2323 | if (part.LocalId == localID) |
2180 | { | 2324 | { |
2325 | lockPartsForRead(false); | ||
2181 | return true; | 2326 | return true; |
2182 | } | 2327 | } |
2183 | } | 2328 | } |
2184 | } | 2329 | } |
2330 | lockPartsForRead(false); | ||
2185 | 2331 | ||
2186 | return false; | 2332 | return false; |
2187 | } | 2333 | } |
@@ -2231,53 +2377,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
2231 | if (m_rootPart.LinkNum == 0) | 2377 | if (m_rootPart.LinkNum == 0) |
2232 | m_rootPart.LinkNum = 1; | 2378 | m_rootPart.LinkNum = 1; |
2233 | 2379 | ||
2234 | lock (m_parts) | 2380 | lockPartsForWrite(true); |
2235 | { | 2381 | |
2236 | m_parts.Add(linkPart.UUID, linkPart); | 2382 | m_parts.Add(linkPart.UUID, linkPart); |
2237 | 2383 | ||
2238 | // Insert in terms of link numbers, the new links | 2384 | lockPartsForWrite(false); |
2239 | // before the current ones (with the exception of | 2385 | |
2240 | // the root prim. Shuffle the old ones up | 2386 | // Insert in terms of link numbers, the new links |
2241 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | 2387 | // before the current ones (with the exception of |
2388 | // the root prim. Shuffle the old ones up | ||
2389 | lockPartsForRead(true); | ||
2390 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | ||
2391 | { | ||
2392 | if (kvp.Value.LinkNum != 1) | ||
2242 | { | 2393 | { |
2243 | if (kvp.Value.LinkNum != 1) | 2394 | // Don't update root prim link number |
2244 | { | 2395 | kvp.Value.LinkNum += objectGroup.PrimCount; |
2245 | // Don't update root prim link number | ||
2246 | kvp.Value.LinkNum += objectGroup.PrimCount; | ||
2247 | } | ||
2248 | } | 2396 | } |
2397 | } | ||
2398 | lockPartsForRead(false); | ||
2249 | 2399 | ||
2250 | linkPart.LinkNum = 2; | 2400 | linkPart.LinkNum = 2; |
2251 | 2401 | ||
2252 | linkPart.SetParent(this); | 2402 | linkPart.SetParent(this); |
2253 | linkPart.AddFlag(PrimFlags.CreateSelected); | 2403 | linkPart.AddFlag(PrimFlags.CreateSelected); |
2254 | 2404 | ||
2255 | //if (linkPart.PhysActor != null) | 2405 | //if (linkPart.PhysActor != null) |
2256 | //{ | 2406 | //{ |
2257 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); | 2407 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); |
2258 | 2408 | ||
2259 | //linkPart.PhysActor = null; | 2409 | //linkPart.PhysActor = null; |
2260 | //} | 2410 | //} |
2261 | 2411 | ||
2262 | //TODO: rest of parts | 2412 | //TODO: rest of parts |
2263 | int linkNum = 3; | 2413 | int linkNum = 3; |
2264 | foreach (SceneObjectPart part in objectGroup.Children.Values) | 2414 | foreach (SceneObjectPart part in objectGroup.Children.Values) |
2415 | { | ||
2416 | if (part.UUID != objectGroup.m_rootPart.UUID) | ||
2265 | { | 2417 | { |
2266 | if (part.UUID != objectGroup.m_rootPart.UUID) | 2418 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); |
2267 | { | ||
2268 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); | ||
2269 | } | ||
2270 | part.ClearUndoState(); | ||
2271 | } | 2419 | } |
2420 | part.ClearUndoState(); | ||
2272 | } | 2421 | } |
2273 | 2422 | ||
2274 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); | 2423 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); |
2275 | objectGroup.m_isDeleted = true; | 2424 | objectGroup.m_isDeleted = true; |
2425 | |||
2426 | objectGroup.lockPartsForWrite(true); | ||
2276 | 2427 | ||
2277 | lock (objectGroup.m_parts) | 2428 | objectGroup.m_parts.Clear(); |
2278 | { | 2429 | |
2279 | objectGroup.m_parts.Clear(); | 2430 | objectGroup.lockPartsForWrite(false); |
2280 | } | ||
2281 | 2431 | ||
2282 | // Can't do this yet since backup still makes use of the root part without any synchronization | 2432 | // Can't do this yet since backup still makes use of the root part without any synchronization |
2283 | // objectGroup.m_rootPart = null; | 2433 | // objectGroup.m_rootPart = null; |
@@ -2336,11 +2486,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2336 | Quaternion worldRot = linkPart.GetWorldRotation(); | 2486 | Quaternion worldRot = linkPart.GetWorldRotation(); |
2337 | 2487 | ||
2338 | // Remove the part from this object | 2488 | // Remove the part from this object |
2339 | lock (m_parts) | 2489 | lockPartsForWrite(true); |
2340 | { | 2490 | { |
2341 | m_parts.Remove(linkPart.UUID); | 2491 | m_parts.Remove(linkPart.UUID); |
2342 | } | 2492 | } |
2343 | 2493 | lockPartsForWrite(false); | |
2494 | lockPartsForRead(true); | ||
2344 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | 2495 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left |
2345 | RootPart.LinkNum = 0; | 2496 | RootPart.LinkNum = 0; |
2346 | else | 2497 | else |
@@ -2351,6 +2502,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2351 | p.LinkNum--; | 2502 | p.LinkNum--; |
2352 | } | 2503 | } |
2353 | } | 2504 | } |
2505 | lockPartsForRead(false); | ||
2354 | 2506 | ||
2355 | linkPart.ParentID = 0; | 2507 | linkPart.ParentID = 0; |
2356 | linkPart.LinkNum = 0; | 2508 | linkPart.LinkNum = 0; |
@@ -2668,9 +2820,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2668 | 2820 | ||
2669 | if (selectionPart != null) | 2821 | if (selectionPart != null) |
2670 | { | 2822 | { |
2671 | lock (m_parts) | 2823 | lockPartsForRead(true); |
2824 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | ||
2825 | lockPartsForRead(false); | ||
2826 | foreach (SceneObjectPart part in parts) | ||
2672 | { | 2827 | { |
2673 | foreach (SceneObjectPart part in m_parts.Values) | 2828 | if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) |
2674 | { | 2829 | { |
2675 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | 2830 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || |
2676 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | 2831 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || |
@@ -2680,12 +2835,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2680 | break; | 2835 | break; |
2681 | } | 2836 | } |
2682 | } | 2837 | } |
2838 | } | ||
2683 | 2839 | ||
2684 | foreach (SceneObjectPart part in m_parts.Values) | 2840 | foreach (SceneObjectPart part in parts) |
2685 | { | 2841 | { |
2686 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2842 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
2687 | } | ||
2688 | } | 2843 | } |
2844 | |||
2689 | } | 2845 | } |
2690 | } | 2846 | } |
2691 | 2847 | ||
@@ -2771,11 +2927,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2771 | scale.Y = m_scene.m_maxNonphys; | 2927 | scale.Y = m_scene.m_maxNonphys; |
2772 | if (scale.Z > m_scene.m_maxNonphys) | 2928 | if (scale.Z > m_scene.m_maxNonphys) |
2773 | scale.Z = m_scene.m_maxNonphys; | 2929 | scale.Z = m_scene.m_maxNonphys; |
2774 | |||
2775 | SceneObjectPart part = GetChildPart(localID); | 2930 | SceneObjectPart part = GetChildPart(localID); |
2776 | if (part != null) | 2931 | if (part != null) |
2777 | { | 2932 | { |
2778 | part.Resize(scale); | ||
2779 | if (part.PhysActor != null) | 2933 | if (part.PhysActor != null) |
2780 | { | 2934 | { |
2781 | if (part.PhysActor.IsPhysical) | 2935 | if (part.PhysActor.IsPhysical) |
@@ -2790,7 +2944,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2790 | part.PhysActor.Size = scale; | 2944 | part.PhysActor.Size = scale; |
2791 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 2945 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); |
2792 | } | 2946 | } |
2793 | //if (part.UUID != m_rootPart.UUID) | 2947 | part.Resize(scale); |
2794 | 2948 | ||
2795 | HasGroupChanged = true; | 2949 | HasGroupChanged = true; |
2796 | ScheduleGroupForFullUpdate(); | 2950 | ScheduleGroupForFullUpdate(); |
@@ -2831,77 +2985,76 @@ namespace OpenSim.Region.Framework.Scenes | |||
2831 | float y = (scale.Y / part.Scale.Y); | 2985 | float y = (scale.Y / part.Scale.Y); |
2832 | float z = (scale.Z / part.Scale.Z); | 2986 | float z = (scale.Z / part.Scale.Z); |
2833 | 2987 | ||
2834 | lock (m_parts) | 2988 | lockPartsForRead(true); |
2989 | if (x > 1.0f || y > 1.0f || z > 1.0f) | ||
2835 | { | 2990 | { |
2836 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 2991 | foreach (SceneObjectPart obPart in m_parts.Values) |
2837 | { | 2992 | { |
2838 | foreach (SceneObjectPart obPart in m_parts.Values) | 2993 | if (obPart.UUID != m_rootPart.UUID) |
2839 | { | 2994 | { |
2840 | if (obPart.UUID != m_rootPart.UUID) | 2995 | Vector3 oldSize = new Vector3(obPart.Scale); |
2841 | { | ||
2842 | Vector3 oldSize = new Vector3(obPart.Scale); | ||
2843 | 2996 | ||
2844 | float f = 1.0f; | 2997 | float f = 1.0f; |
2845 | float a = 1.0f; | 2998 | float a = 1.0f; |
2846 | 2999 | ||
2847 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | 3000 | if (part.PhysActor != null && part.PhysActor.IsPhysical) |
3001 | { | ||
3002 | if (oldSize.X*x > m_scene.m_maxPhys) | ||
2848 | { | 3003 | { |
2849 | if (oldSize.X*x > m_scene.m_maxPhys) | 3004 | f = m_scene.m_maxPhys / oldSize.X; |
2850 | { | 3005 | a = f / x; |
2851 | f = m_scene.m_maxPhys / oldSize.X; | 3006 | x *= a; |
2852 | a = f / x; | 3007 | y *= a; |
2853 | x *= a; | 3008 | z *= a; |
2854 | y *= a; | ||
2855 | z *= a; | ||
2856 | } | ||
2857 | if (oldSize.Y*y > m_scene.m_maxPhys) | ||
2858 | { | ||
2859 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2860 | a = f / y; | ||
2861 | x *= a; | ||
2862 | y *= a; | ||
2863 | z *= a; | ||
2864 | } | ||
2865 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
2866 | { | ||
2867 | f = m_scene.m_maxPhys / oldSize.Z; | ||
2868 | a = f / z; | ||
2869 | x *= a; | ||
2870 | y *= a; | ||
2871 | z *= a; | ||
2872 | } | ||
2873 | } | 3009 | } |
2874 | else | 3010 | if (oldSize.Y*y > m_scene.m_maxPhys) |
3011 | { | ||
3012 | f = m_scene.m_maxPhys / oldSize.Y; | ||
3013 | a = f / y; | ||
3014 | x *= a; | ||
3015 | y *= a; | ||
3016 | z *= a; | ||
3017 | } | ||
3018 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
3019 | { | ||
3020 | f = m_scene.m_maxPhys / oldSize.Z; | ||
3021 | a = f / z; | ||
3022 | x *= a; | ||
3023 | y *= a; | ||
3024 | z *= a; | ||
3025 | } | ||
3026 | } | ||
3027 | else | ||
3028 | { | ||
3029 | if (oldSize.X*x > m_scene.m_maxNonphys) | ||
3030 | { | ||
3031 | f = m_scene.m_maxNonphys / oldSize.X; | ||
3032 | a = f / x; | ||
3033 | x *= a; | ||
3034 | y *= a; | ||
3035 | z *= a; | ||
3036 | } | ||
3037 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
3038 | { | ||
3039 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
3040 | a = f / y; | ||
3041 | x *= a; | ||
3042 | y *= a; | ||
3043 | z *= a; | ||
3044 | } | ||
3045 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2875 | { | 3046 | { |
2876 | if (oldSize.X*x > m_scene.m_maxNonphys) | 3047 | f = m_scene.m_maxNonphys / oldSize.Z; |
2877 | { | 3048 | a = f / z; |
2878 | f = m_scene.m_maxNonphys / oldSize.X; | 3049 | x *= a; |
2879 | a = f / x; | 3050 | y *= a; |
2880 | x *= a; | 3051 | z *= a; |
2881 | y *= a; | ||
2882 | z *= a; | ||
2883 | } | ||
2884 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
2885 | { | ||
2886 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
2887 | a = f / y; | ||
2888 | x *= a; | ||
2889 | y *= a; | ||
2890 | z *= a; | ||
2891 | } | ||
2892 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2893 | { | ||
2894 | f = m_scene.m_maxNonphys / oldSize.Z; | ||
2895 | a = f / z; | ||
2896 | x *= a; | ||
2897 | y *= a; | ||
2898 | z *= a; | ||
2899 | } | ||
2900 | } | 3052 | } |
2901 | } | 3053 | } |
2902 | } | 3054 | } |
2903 | } | 3055 | } |
2904 | } | 3056 | } |
3057 | lockPartsForRead(false); | ||
2905 | 3058 | ||
2906 | Vector3 prevScale = part.Scale; | 3059 | Vector3 prevScale = part.Scale; |
2907 | prevScale.X *= x; | 3060 | prevScale.X *= x; |
@@ -2909,7 +3062,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2909 | prevScale.Z *= z; | 3062 | prevScale.Z *= z; |
2910 | part.Resize(prevScale); | 3063 | part.Resize(prevScale); |
2911 | 3064 | ||
2912 | lock (m_parts) | 3065 | lockPartsForRead(true); |
2913 | { | 3066 | { |
2914 | foreach (SceneObjectPart obPart in m_parts.Values) | 3067 | foreach (SceneObjectPart obPart in m_parts.Values) |
2915 | { | 3068 | { |
@@ -2928,6 +3081,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2928 | } | 3081 | } |
2929 | } | 3082 | } |
2930 | } | 3083 | } |
3084 | lockPartsForRead(false); | ||
2931 | 3085 | ||
2932 | if (part.PhysActor != null) | 3086 | if (part.PhysActor != null) |
2933 | { | 3087 | { |
@@ -3008,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3008 | axDiff *= Quaternion.Inverse(partRotation); | 3162 | axDiff *= Quaternion.Inverse(partRotation); |
3009 | diff = axDiff; | 3163 | diff = axDiff; |
3010 | 3164 | ||
3011 | lock (m_parts) | 3165 | lockPartsForRead(true); |
3012 | { | 3166 | { |
3013 | foreach (SceneObjectPart obPart in m_parts.Values) | 3167 | foreach (SceneObjectPart obPart in m_parts.Values) |
3014 | { | 3168 | { |
@@ -3018,6 +3172,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3018 | } | 3172 | } |
3019 | } | 3173 | } |
3020 | } | 3174 | } |
3175 | lockPartsForRead(false); | ||
3021 | 3176 | ||
3022 | AbsolutePosition = newPos; | 3177 | AbsolutePosition = newPos; |
3023 | 3178 | ||
@@ -3135,7 +3290,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3135 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 3290 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); |
3136 | } | 3291 | } |
3137 | 3292 | ||
3138 | lock (m_parts) | 3293 | lockPartsForRead(true); |
3139 | { | 3294 | { |
3140 | foreach (SceneObjectPart prim in m_parts.Values) | 3295 | foreach (SceneObjectPart prim in m_parts.Values) |
3141 | { | 3296 | { |
@@ -3153,6 +3308,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3153 | } | 3308 | } |
3154 | } | 3309 | } |
3155 | } | 3310 | } |
3311 | lockPartsForRead(false); | ||
3156 | 3312 | ||
3157 | m_rootPart.ScheduleTerseUpdate(); | 3313 | m_rootPart.ScheduleTerseUpdate(); |
3158 | } | 3314 | } |
@@ -3275,7 +3431,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3275 | if (atTargets.Count > 0) | 3431 | if (atTargets.Count > 0) |
3276 | { | 3432 | { |
3277 | uint[] localids = new uint[0]; | 3433 | uint[] localids = new uint[0]; |
3278 | lock (m_parts) | 3434 | lockPartsForRead(true); |
3279 | { | 3435 | { |
3280 | localids = new uint[m_parts.Count]; | 3436 | localids = new uint[m_parts.Count]; |
3281 | int cntr = 0; | 3437 | int cntr = 0; |
@@ -3285,6 +3441,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3285 | cntr++; | 3441 | cntr++; |
3286 | } | 3442 | } |
3287 | } | 3443 | } |
3444 | lockPartsForRead(false); | ||
3288 | 3445 | ||
3289 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3446 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3290 | { | 3447 | { |
@@ -3303,7 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3303 | { | 3460 | { |
3304 | //trigger not_at_target | 3461 | //trigger not_at_target |
3305 | uint[] localids = new uint[0]; | 3462 | uint[] localids = new uint[0]; |
3306 | lock (m_parts) | 3463 | lockPartsForRead(true); |
3307 | { | 3464 | { |
3308 | localids = new uint[m_parts.Count]; | 3465 | localids = new uint[m_parts.Count]; |
3309 | int cntr = 0; | 3466 | int cntr = 0; |
@@ -3313,7 +3470,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3313 | cntr++; | 3470 | cntr++; |
3314 | } | 3471 | } |
3315 | } | 3472 | } |
3316 | 3473 | lockPartsForRead(false); | |
3474 | |||
3317 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3475 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3318 | { | 3476 | { |
3319 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); | 3477 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); |
@@ -3405,19 +3563,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3405 | public float GetMass() | 3563 | public float GetMass() |
3406 | { | 3564 | { |
3407 | float retmass = 0f; | 3565 | float retmass = 0f; |
3408 | lock (m_parts) | 3566 | lockPartsForRead(true); |
3409 | { | 3567 | { |
3410 | foreach (SceneObjectPart part in m_parts.Values) | 3568 | foreach (SceneObjectPart part in m_parts.Values) |
3411 | { | 3569 | { |
3412 | retmass += part.GetMass(); | 3570 | retmass += part.GetMass(); |
3413 | } | 3571 | } |
3414 | } | 3572 | } |
3573 | lockPartsForRead(false); | ||
3415 | return retmass; | 3574 | return retmass; |
3416 | } | 3575 | } |
3417 | 3576 | ||
3418 | public void CheckSculptAndLoad() | 3577 | public void CheckSculptAndLoad() |
3419 | { | 3578 | { |
3420 | lock (m_parts) | 3579 | lockPartsForRead(true); |
3421 | { | 3580 | { |
3422 | if (!IsDeleted) | 3581 | if (!IsDeleted) |
3423 | { | 3582 | { |
@@ -3442,6 +3601,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3442 | } | 3601 | } |
3443 | } | 3602 | } |
3444 | } | 3603 | } |
3604 | lockPartsForRead(false); | ||
3445 | } | 3605 | } |
3446 | 3606 | ||
3447 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 3607 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
@@ -3462,7 +3622,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3462 | /// <param name="client"></param> | 3622 | /// <param name="client"></param> |
3463 | public void SetGroup(UUID GroupID, IClientAPI client) | 3623 | public void SetGroup(UUID GroupID, IClientAPI client) |
3464 | { | 3624 | { |
3465 | lock (m_parts) | 3625 | lockPartsForRead(true); |
3466 | { | 3626 | { |
3467 | foreach (SceneObjectPart part in m_parts.Values) | 3627 | foreach (SceneObjectPart part in m_parts.Values) |
3468 | { | 3628 | { |
@@ -3472,7 +3632,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3472 | 3632 | ||
3473 | HasGroupChanged = true; | 3633 | HasGroupChanged = true; |
3474 | } | 3634 | } |
3475 | 3635 | lockPartsForRead(false); | |
3476 | ScheduleGroupForFullUpdate(); | 3636 | ScheduleGroupForFullUpdate(); |
3477 | } | 3637 | } |
3478 | 3638 | ||
@@ -3491,11 +3651,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3491 | 3651 | ||
3492 | public void SetAttachmentPoint(byte point) | 3652 | public void SetAttachmentPoint(byte point) |
3493 | { | 3653 | { |
3494 | lock (m_parts) | 3654 | lockPartsForRead(true); |
3495 | { | 3655 | { |
3496 | foreach (SceneObjectPart part in m_parts.Values) | 3656 | foreach (SceneObjectPart part in m_parts.Values) |
3497 | part.SetAttachmentPoint(point); | 3657 | part.SetAttachmentPoint(point); |
3498 | } | 3658 | } |
3659 | lockPartsForRead(false); | ||
3499 | } | 3660 | } |
3500 | 3661 | ||
3501 | #region ISceneObject | 3662 | #region ISceneObject |