diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 534 |
1 files changed, 348 insertions, 186 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c5a6171..2a4e5a2 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 | ||
@@ -298,6 +367,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
298 | { | 367 | { |
299 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 368 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
300 | } | 369 | } |
370 | |||
371 | lockPartsForRead(true); | ||
372 | |||
301 | if (RootPart.GetStatusSandbox()) | 373 | if (RootPart.GetStatusSandbox()) |
302 | { | 374 | { |
303 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) | 375 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
@@ -305,16 +377,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
305 | RootPart.ScriptSetPhysicsStatus(false); | 377 | RootPart.ScriptSetPhysicsStatus(false); |
306 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), | 378 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), |
307 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); | 379 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); |
380 | lockPartsForRead(false); | ||
308 | return; | 381 | return; |
309 | } | 382 | } |
310 | } | 383 | } |
311 | lock (m_parts) | 384 | |
312 | { | 385 | foreach (SceneObjectPart part in m_parts.Values) |
313 | foreach (SceneObjectPart part in m_parts.Values) | 386 | part.GroupPosition = val; |
314 | { | 387 | |
315 | part.GroupPosition = val; | 388 | lockPartsForRead(false); |
316 | } | ||
317 | } | ||
318 | 389 | ||
319 | //if (m_rootPart.PhysActor != null) | 390 | //if (m_rootPart.PhysActor != null) |
320 | //{ | 391 | //{ |
@@ -504,13 +575,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
504 | 575 | ||
505 | public void SetFromItemID(UUID AssetId) | 576 | public void SetFromItemID(UUID AssetId) |
506 | { | 577 | { |
507 | lock (m_parts) | 578 | lockPartsForRead(true); |
508 | { | 579 | { |
509 | foreach (SceneObjectPart part in m_parts.Values) | 580 | foreach (SceneObjectPart part in m_parts.Values) |
510 | { | 581 | { |
582 | |||
511 | part.FromItemID = AssetId; | 583 | part.FromItemID = AssetId; |
584 | |||
512 | } | 585 | } |
513 | } | 586 | } |
587 | lockPartsForRead(false); | ||
514 | } | 588 | } |
515 | 589 | ||
516 | public UUID GetFromItemID() | 590 | public UUID GetFromItemID() |
@@ -577,10 +651,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
577 | Vector3 maxScale = Vector3.Zero; | 651 | Vector3 maxScale = Vector3.Zero; |
578 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | 652 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); |
579 | 653 | ||
580 | lock (m_parts) | 654 | lockPartsForRead(true); |
581 | { | 655 | { |
582 | foreach (SceneObjectPart part in m_parts.Values) | 656 | foreach (SceneObjectPart part in m_parts.Values) |
583 | { | 657 | { |
658 | |||
584 | Vector3 partscale = part.Scale; | 659 | Vector3 partscale = part.Scale; |
585 | Vector3 partoffset = part.OffsetPosition; | 660 | Vector3 partoffset = part.OffsetPosition; |
586 | 661 | ||
@@ -591,8 +666,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
591 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | 666 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; |
592 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | 667 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; |
593 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | 668 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; |
669 | |||
594 | } | 670 | } |
595 | } | 671 | } |
672 | lockPartsForRead(false); | ||
673 | |||
596 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | 674 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; |
597 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | 675 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; |
598 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | 676 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; |
@@ -608,10 +686,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
608 | 686 | ||
609 | EntityIntersection result = new EntityIntersection(); | 687 | EntityIntersection result = new EntityIntersection(); |
610 | 688 | ||
611 | lock (m_parts) | 689 | lockPartsForRead(true); |
612 | { | 690 | { |
613 | foreach (SceneObjectPart part in m_parts.Values) | 691 | foreach (SceneObjectPart part in m_parts.Values) |
614 | { | 692 | { |
693 | |||
615 | // Temporary commented to stop compiler warning | 694 | // Temporary commented to stop compiler warning |
616 | //Vector3 partPosition = | 695 | //Vector3 partPosition = |
617 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); | 696 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); |
@@ -639,8 +718,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
639 | result.distance = inter.distance; | 718 | result.distance = inter.distance; |
640 | } | 719 | } |
641 | } | 720 | } |
721 | |||
642 | } | 722 | } |
643 | } | 723 | } |
724 | lockPartsForRead(false); | ||
644 | return result; | 725 | return result; |
645 | } | 726 | } |
646 | 727 | ||
@@ -653,10 +734,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
653 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) | 734 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) |
654 | { | 735 | { |
655 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; | 736 | float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; |
656 | lock (m_parts) | 737 | lockPartsForRead(true); |
657 | { | 738 | { |
658 | foreach (SceneObjectPart part in m_parts.Values) | 739 | foreach (SceneObjectPart part in m_parts.Values) |
659 | { | 740 | { |
741 | |||
660 | Vector3 worldPos = part.GetWorldPosition(); | 742 | Vector3 worldPos = part.GetWorldPosition(); |
661 | Vector3 offset = worldPos - AbsolutePosition; | 743 | Vector3 offset = worldPos - AbsolutePosition; |
662 | Quaternion worldRot; | 744 | Quaternion worldRot; |
@@ -715,6 +797,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
715 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); | 797 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); |
716 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); | 798 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); |
717 | 799 | ||
800 | |||
801 | |||
718 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); | 802 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); |
719 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); | 803 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); |
720 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); | 804 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); |
@@ -886,6 +970,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
886 | minZ = backBottomLeft.Z; | 970 | minZ = backBottomLeft.Z; |
887 | } | 971 | } |
888 | } | 972 | } |
973 | lockPartsForRead(false); | ||
889 | 974 | ||
890 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); | 975 | Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); |
891 | 976 | ||
@@ -914,17 +999,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
914 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); | 999 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); |
915 | 1000 | ||
916 | // Capture script state while holding the lock | 1001 | // Capture script state while holding the lock |
917 | lock (m_parts) | 1002 | lockPartsForRead(true); |
918 | { | 1003 | { |
919 | foreach (SceneObjectPart part in m_parts.Values) | 1004 | foreach (SceneObjectPart part in m_parts.Values) |
920 | { | 1005 | { |
1006 | |||
921 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); | 1007 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); |
922 | foreach (UUID itemid in pstates.Keys) | 1008 | foreach (UUID itemid in pstates.Keys) |
923 | { | 1009 | { |
924 | states.Add(itemid, pstates[itemid]); | 1010 | states.Add(itemid, pstates[itemid]); |
925 | } | 1011 | } |
1012 | |||
926 | } | 1013 | } |
927 | } | 1014 | } |
1015 | lockPartsForRead(false); | ||
928 | 1016 | ||
929 | if (states.Count > 0) | 1017 | if (states.Count > 0) |
930 | { | 1018 | { |
@@ -1086,13 +1174,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1086 | 1174 | ||
1087 | public override void UpdateMovement() | 1175 | public override void UpdateMovement() |
1088 | { | 1176 | { |
1089 | lock (m_parts) | 1177 | lockPartsForRead(true); |
1090 | { | 1178 | { |
1091 | foreach (SceneObjectPart part in m_parts.Values) | 1179 | foreach (SceneObjectPart part in m_parts.Values) |
1092 | { | 1180 | { |
1181 | |||
1093 | part.UpdateMovement(); | 1182 | part.UpdateMovement(); |
1183 | |||
1094 | } | 1184 | } |
1095 | } | 1185 | } |
1186 | lockPartsForRead(false); | ||
1096 | } | 1187 | } |
1097 | 1188 | ||
1098 | public ushort GetTimeDilation() | 1189 | public ushort GetTimeDilation() |
@@ -1136,7 +1227,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1136 | /// <param name="part"></param> | 1227 | /// <param name="part"></param> |
1137 | public void AddPart(SceneObjectPart part) | 1228 | public void AddPart(SceneObjectPart part) |
1138 | { | 1229 | { |
1139 | lock (m_parts) | 1230 | lockPartsForWrite(true); |
1140 | { | 1231 | { |
1141 | part.SetParent(this); | 1232 | part.SetParent(this); |
1142 | m_parts.Add(part.UUID, part); | 1233 | m_parts.Add(part.UUID, part); |
@@ -1146,6 +1237,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1146 | if (part.LinkNum == 2 && RootPart != null) | 1237 | if (part.LinkNum == 2 && RootPart != null) |
1147 | RootPart.LinkNum = 1; | 1238 | RootPart.LinkNum = 1; |
1148 | } | 1239 | } |
1240 | lockPartsForWrite(false); | ||
1149 | } | 1241 | } |
1150 | 1242 | ||
1151 | /// <summary> | 1243 | /// <summary> |
@@ -1153,28 +1245,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1153 | /// </summary> | 1245 | /// </summary> |
1154 | private void UpdateParentIDs() | 1246 | private void UpdateParentIDs() |
1155 | { | 1247 | { |
1156 | lock (m_parts) | 1248 | lockPartsForRead(true); |
1157 | { | 1249 | { |
1158 | foreach (SceneObjectPart part in m_parts.Values) | 1250 | foreach (SceneObjectPart part in m_parts.Values) |
1159 | { | 1251 | { |
1252 | |||
1160 | if (part.UUID != m_rootPart.UUID) | 1253 | if (part.UUID != m_rootPart.UUID) |
1161 | { | 1254 | { |
1162 | part.ParentID = m_rootPart.LocalId; | 1255 | part.ParentID = m_rootPart.LocalId; |
1163 | } | 1256 | } |
1257 | |||
1164 | } | 1258 | } |
1165 | } | 1259 | } |
1260 | lockPartsForRead(false); | ||
1166 | } | 1261 | } |
1167 | 1262 | ||
1168 | public void RegenerateFullIDs() | 1263 | public void RegenerateFullIDs() |
1169 | { | 1264 | { |
1170 | lock (m_parts) | 1265 | lockPartsForRead(true); |
1171 | { | 1266 | { |
1172 | foreach (SceneObjectPart part in m_parts.Values) | 1267 | foreach (SceneObjectPart part in m_parts.Values) |
1173 | { | 1268 | { |
1269 | |||
1174 | part.UUID = UUID.Random(); | 1270 | part.UUID = UUID.Random(); |
1175 | 1271 | ||
1176 | } | 1272 | } |
1177 | } | 1273 | } |
1274 | lockPartsForRead(false); | ||
1178 | } | 1275 | } |
1179 | 1276 | ||
1180 | // helper provided for parts. | 1277 | // helper provided for parts. |
@@ -1255,29 +1352,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1255 | 1352 | ||
1256 | DetachFromBackup(); | 1353 | DetachFromBackup(); |
1257 | 1354 | ||
1258 | lock (m_parts) | 1355 | lockPartsForRead(true); |
1356 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1357 | lockPartsForRead(false); | ||
1358 | |||
1359 | foreach (SceneObjectPart part in values) | ||
1259 | { | 1360 | { |
1260 | foreach (SceneObjectPart part in m_parts.Values) | ||
1261 | { | ||
1262 | // part.Inventory.RemoveScriptInstances(); | 1361 | // part.Inventory.RemoveScriptInstances(); |
1263 | 1362 | ||
1264 | ScenePresence[] avatars = Scene.GetScenePresences(); | 1363 | ScenePresence[] avatars = Scene.GetScenePresences(); |
1265 | for (int i = 0; i < avatars.Length; i++) | 1364 | for (int i = 0; i < avatars.Length; i++) |
1365 | { | ||
1366 | if (avatars[i].ParentID == LocalId) | ||
1266 | { | 1367 | { |
1267 | if (avatars[i].ParentID == LocalId) | 1368 | avatars[i].StandUp(); |
1268 | { | 1369 | } |
1269 | avatars[i].StandUp(); | ||
1270 | } | ||
1271 | 1370 | ||
1272 | if (!silent) | 1371 | if (!silent) |
1273 | { | 1372 | { |
1274 | part.UpdateFlag = 0; | 1373 | part.UpdateFlag = 0; |
1275 | if (part == m_rootPart) | 1374 | if (part == m_rootPart) |
1276 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); | 1375 | avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); |
1277 | } | ||
1278 | } | 1376 | } |
1279 | } | 1377 | } |
1378 | |||
1280 | } | 1379 | } |
1380 | |||
1381 | |||
1281 | } | 1382 | } |
1282 | 1383 | ||
1283 | public void AddScriptLPS(int count) | 1384 | public void AddScriptLPS(int count) |
@@ -1302,17 +1403,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1302 | 1403 | ||
1303 | scriptEvents aggregateScriptEvents=0; | 1404 | scriptEvents aggregateScriptEvents=0; |
1304 | 1405 | ||
1305 | lock (m_parts) | 1406 | lockPartsForRead(true); |
1306 | { | 1407 | { |
1307 | foreach (SceneObjectPart part in m_parts.Values) | 1408 | foreach (SceneObjectPart part in m_parts.Values) |
1308 | { | 1409 | { |
1410 | |||
1309 | if (part == null) | 1411 | if (part == null) |
1310 | continue; | 1412 | continue; |
1311 | if (part != RootPart) | 1413 | if (part != RootPart) |
1312 | part.ObjectFlags = objectflagupdate; | 1414 | part.ObjectFlags = objectflagupdate; |
1313 | aggregateScriptEvents |= part.AggregateScriptEvents; | 1415 | aggregateScriptEvents |= part.AggregateScriptEvents; |
1416 | |||
1314 | } | 1417 | } |
1315 | } | 1418 | } |
1419 | lockPartsForRead(false); | ||
1316 | 1420 | ||
1317 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); | 1421 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); |
1318 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); | 1422 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); |
@@ -1354,42 +1458,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
1354 | /// <param name="m_physicalPrim"></param> | 1458 | /// <param name="m_physicalPrim"></param> |
1355 | public void ApplyPhysics(bool m_physicalPrim) | 1459 | public void ApplyPhysics(bool m_physicalPrim) |
1356 | { | 1460 | { |
1357 | lock (m_parts) | 1461 | lockPartsForRead(true); |
1462 | |||
1463 | if (m_parts.Count > 1) | ||
1358 | { | 1464 | { |
1359 | if (m_parts.Count > 1) | 1465 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); |
1466 | lockPartsForRead(false); | ||
1467 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1468 | foreach (SceneObjectPart part in values) | ||
1360 | { | 1469 | { |
1361 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | 1470 | |
1362 | foreach (SceneObjectPart part in m_parts.Values) | 1471 | if (part.LocalId != m_rootPart.LocalId) |
1363 | { | 1472 | { |
1364 | if (part.LocalId != m_rootPart.LocalId) | 1473 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); |
1365 | { | ||
1366 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); | ||
1367 | } | ||
1368 | } | 1474 | } |
1369 | 1475 | ||
1370 | // Hack to get the physics scene geometries in the right spot | ||
1371 | ResetChildPrimPhysicsPositions(); | ||
1372 | } | ||
1373 | else | ||
1374 | { | ||
1375 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1376 | } | 1476 | } |
1477 | // Hack to get the physics scene geometries in the right spot | ||
1478 | ResetChildPrimPhysicsPositions(); | ||
1479 | } | ||
1480 | else | ||
1481 | { | ||
1482 | lockPartsForRead(false); | ||
1483 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1377 | } | 1484 | } |
1378 | } | 1485 | } |
1379 | 1486 | ||
1380 | public void SetOwnerId(UUID userId) | 1487 | public void SetOwnerId(UUID userId) |
1381 | { | 1488 | { |
1382 | ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); | 1489 | ForEachPart(delegate(SceneObjectPart part) |
1490 | { | ||
1491 | |||
1492 | part.OwnerID = userId; | ||
1493 | |||
1494 | }); | ||
1383 | } | 1495 | } |
1384 | 1496 | ||
1385 | public void ForEachPart(Action<SceneObjectPart> whatToDo) | 1497 | public void ForEachPart(Action<SceneObjectPart> whatToDo) |
1386 | { | 1498 | { |
1387 | lock (m_parts) | 1499 | lockPartsForRead(true); |
1500 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | ||
1501 | lockPartsForRead(false); | ||
1502 | foreach (SceneObjectPart part in values) | ||
1388 | { | 1503 | { |
1389 | foreach (SceneObjectPart part in m_parts.Values) | 1504 | |
1390 | { | 1505 | whatToDo(part); |
1391 | whatToDo(part); | 1506 | |
1392 | } | ||
1393 | } | 1507 | } |
1394 | } | 1508 | } |
1395 | 1509 | ||
@@ -1488,14 +1602,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1488 | { | 1602 | { |
1489 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); | 1603 | SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); |
1490 | 1604 | ||
1491 | lock (m_parts) | 1605 | lockPartsForRead(true); |
1492 | { | 1606 | { |
1493 | foreach (SceneObjectPart part in m_parts.Values) | 1607 | foreach (SceneObjectPart part in m_parts.Values) |
1494 | { | 1608 | { |
1609 | |||
1495 | if (part != RootPart) | 1610 | if (part != RootPart) |
1496 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | 1611 | SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); |
1612 | |||
1497 | } | 1613 | } |
1498 | } | 1614 | } |
1615 | lockPartsForRead(false); | ||
1499 | } | 1616 | } |
1500 | 1617 | ||
1501 | /// <summary> | 1618 | /// <summary> |
@@ -1593,10 +1710,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1593 | 1710 | ||
1594 | List<SceneObjectPart> partList; | 1711 | List<SceneObjectPart> partList; |
1595 | 1712 | ||
1596 | lock (m_parts) | 1713 | lockPartsForRead(true); |
1597 | { | 1714 | |
1598 | partList = new List<SceneObjectPart>(m_parts.Values); | 1715 | partList = new List<SceneObjectPart>(m_parts.Values); |
1599 | } | 1716 | |
1717 | lockPartsForRead(false); | ||
1600 | 1718 | ||
1601 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) | 1719 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) |
1602 | { | 1720 | { |
@@ -1893,10 +2011,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1893 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 2011 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); |
1894 | newPart.SetParent(this); | 2012 | newPart.SetParent(this); |
1895 | 2013 | ||
1896 | lock (m_parts) | 2014 | lockPartsForWrite(true); |
1897 | { | 2015 | { |
1898 | m_parts.Add(newPart.UUID, newPart); | 2016 | m_parts.Add(newPart.UUID, newPart); |
1899 | } | 2017 | } |
2018 | lockPartsForWrite(false); | ||
1900 | 2019 | ||
1901 | SetPartAsNonRoot(newPart); | 2020 | SetPartAsNonRoot(newPart); |
1902 | 2021 | ||
@@ -1959,7 +2078,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1959 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 2078 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
1960 | // return; | 2079 | // return; |
1961 | 2080 | ||
1962 | lock (m_parts) | 2081 | lockPartsForRead(true); |
1963 | { | 2082 | { |
1964 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 2083 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); |
1965 | 2084 | ||
@@ -1979,34 +2098,43 @@ namespace OpenSim.Region.Framework.Scenes | |||
1979 | { | 2098 | { |
1980 | if (!IsSelected) | 2099 | if (!IsSelected) |
1981 | part.UpdateLookAt(); | 2100 | part.UpdateLookAt(); |
2101 | |||
1982 | part.SendScheduledUpdates(); | 2102 | part.SendScheduledUpdates(); |
2103 | |||
1983 | } | 2104 | } |
1984 | } | 2105 | } |
2106 | lockPartsForRead(false); | ||
1985 | } | 2107 | } |
1986 | 2108 | ||
1987 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) | 2109 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) |
1988 | { | 2110 | { |
1989 | RootPart.AddFullUpdateToAvatar(presence); | 2111 | RootPart.AddFullUpdateToAvatar(presence); |
1990 | 2112 | ||
1991 | lock (m_parts) | 2113 | lockPartsForRead(true); |
1992 | { | 2114 | { |
1993 | foreach (SceneObjectPart part in m_parts.Values) | 2115 | foreach (SceneObjectPart part in m_parts.Values) |
1994 | { | 2116 | { |
2117 | |||
1995 | if (part != RootPart) | 2118 | if (part != RootPart) |
1996 | part.AddFullUpdateToAvatar(presence); | 2119 | part.AddFullUpdateToAvatar(presence); |
2120 | |||
1997 | } | 2121 | } |
1998 | } | 2122 | } |
2123 | lockPartsForRead(false); | ||
1999 | } | 2124 | } |
2000 | 2125 | ||
2001 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) | 2126 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) |
2002 | { | 2127 | { |
2003 | lock (m_parts) | 2128 | lockPartsForRead(true); |
2004 | { | 2129 | { |
2005 | foreach (SceneObjectPart part in m_parts.Values) | 2130 | foreach (SceneObjectPart part in m_parts.Values) |
2006 | { | 2131 | { |
2132 | |||
2007 | part.AddTerseUpdateToAvatar(presence); | 2133 | part.AddTerseUpdateToAvatar(presence); |
2134 | |||
2008 | } | 2135 | } |
2009 | } | 2136 | } |
2137 | lockPartsForRead(false); | ||
2010 | } | 2138 | } |
2011 | 2139 | ||
2012 | /// <summary> | 2140 | /// <summary> |
@@ -2017,14 +2145,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2017 | checkAtTargets(); | 2145 | checkAtTargets(); |
2018 | RootPart.ScheduleFullUpdate(); | 2146 | RootPart.ScheduleFullUpdate(); |
2019 | 2147 | ||
2020 | lock (m_parts) | 2148 | lockPartsForRead(true); |
2021 | { | 2149 | { |
2022 | foreach (SceneObjectPart part in m_parts.Values) | 2150 | foreach (SceneObjectPart part in m_parts.Values) |
2023 | { | 2151 | { |
2152 | |||
2024 | if (part != RootPart) | 2153 | if (part != RootPart) |
2025 | part.ScheduleFullUpdate(); | 2154 | part.ScheduleFullUpdate(); |
2155 | |||
2026 | } | 2156 | } |
2027 | } | 2157 | } |
2158 | lockPartsForRead(false); | ||
2028 | } | 2159 | } |
2029 | 2160 | ||
2030 | /// <summary> | 2161 | /// <summary> |
@@ -2032,13 +2163,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2032 | /// </summary> | 2163 | /// </summary> |
2033 | public void ScheduleGroupForTerseUpdate() | 2164 | public void ScheduleGroupForTerseUpdate() |
2034 | { | 2165 | { |
2035 | lock (m_parts) | 2166 | lockPartsForRead(true); |
2036 | { | 2167 | { |
2037 | foreach (SceneObjectPart part in m_parts.Values) | 2168 | foreach (SceneObjectPart part in m_parts.Values) |
2038 | { | 2169 | { |
2170 | |||
2039 | part.ScheduleTerseUpdate(); | 2171 | part.ScheduleTerseUpdate(); |
2172 | |||
2040 | } | 2173 | } |
2041 | } | 2174 | } |
2175 | lockPartsForRead(false); | ||
2042 | } | 2176 | } |
2043 | 2177 | ||
2044 | /// <summary> | 2178 | /// <summary> |
@@ -2051,14 +2185,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2051 | 2185 | ||
2052 | RootPart.SendFullUpdateToAllClients(); | 2186 | RootPart.SendFullUpdateToAllClients(); |
2053 | 2187 | ||
2054 | lock (m_parts) | 2188 | lockPartsForRead(true); |
2055 | { | 2189 | { |
2056 | foreach (SceneObjectPart part in m_parts.Values) | 2190 | foreach (SceneObjectPart part in m_parts.Values) |
2057 | { | 2191 | { |
2192 | |||
2058 | if (part != RootPart) | 2193 | if (part != RootPart) |
2059 | part.SendFullUpdateToAllClients(); | 2194 | part.SendFullUpdateToAllClients(); |
2195 | |||
2060 | } | 2196 | } |
2061 | } | 2197 | } |
2198 | lockPartsForRead(false); | ||
2062 | } | 2199 | } |
2063 | 2200 | ||
2064 | /// <summary> | 2201 | /// <summary> |
@@ -2089,14 +2226,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2089 | { | 2226 | { |
2090 | if (IsDeleted) | 2227 | if (IsDeleted) |
2091 | return; | 2228 | return; |
2092 | 2229 | ||
2093 | lock (m_parts) | 2230 | lockPartsForRead(true); |
2094 | { | 2231 | { |
2095 | foreach (SceneObjectPart part in m_parts.Values) | 2232 | foreach (SceneObjectPart part in m_parts.Values) |
2096 | { | 2233 | { |
2097 | part.SendTerseUpdateToAllClients(); | 2234 | part.SendTerseUpdateToAllClients(); |
2098 | } | 2235 | } |
2099 | } | 2236 | } |
2237 | lockPartsForRead(false); | ||
2100 | } | 2238 | } |
2101 | 2239 | ||
2102 | #endregion | 2240 | #endregion |
@@ -2110,16 +2248,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2110 | /// <returns>null if no child part with that linknum or child part</returns> | 2248 | /// <returns>null if no child part with that linknum or child part</returns> |
2111 | public SceneObjectPart GetLinkNumPart(int linknum) | 2249 | public SceneObjectPart GetLinkNumPart(int linknum) |
2112 | { | 2250 | { |
2113 | lock (m_parts) | 2251 | lockPartsForRead(true); |
2114 | { | 2252 | { |
2115 | foreach (SceneObjectPart part in m_parts.Values) | 2253 | foreach (SceneObjectPart part in m_parts.Values) |
2116 | { | 2254 | { |
2117 | if (part.LinkNum == linknum) | 2255 | if (part.LinkNum == linknum) |
2118 | { | 2256 | { |
2257 | lockPartsForRead(false); | ||
2119 | return part; | 2258 | return part; |
2120 | } | 2259 | } |
2121 | } | 2260 | } |
2122 | } | 2261 | } |
2262 | lockPartsForRead(false); | ||
2123 | 2263 | ||
2124 | return null; | 2264 | return null; |
2125 | } | 2265 | } |
@@ -2147,17 +2287,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2147 | public SceneObjectPart GetChildPart(uint localID) | 2287 | public SceneObjectPart GetChildPart(uint localID) |
2148 | { | 2288 | { |
2149 | //m_log.DebugFormat("Entered looking for {0}", localID); | 2289 | //m_log.DebugFormat("Entered looking for {0}", localID); |
2150 | lock (m_parts) | 2290 | lockPartsForRead(true); |
2151 | { | 2291 | { |
2152 | foreach (SceneObjectPart part in m_parts.Values) | 2292 | foreach (SceneObjectPart part in m_parts.Values) |
2153 | { | 2293 | { |
2154 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2294 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2155 | if (part.LocalId == localID) | 2295 | if (part.LocalId == localID) |
2156 | { | 2296 | { |
2297 | lockPartsForRead(false); | ||
2157 | return part; | 2298 | return part; |
2158 | } | 2299 | } |
2159 | } | 2300 | } |
2160 | } | 2301 | } |
2302 | lockPartsForRead(false); | ||
2161 | 2303 | ||
2162 | return null; | 2304 | return null; |
2163 | } | 2305 | } |
@@ -2187,17 +2329,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2187 | public bool HasChildPrim(uint localID) | 2329 | public bool HasChildPrim(uint localID) |
2188 | { | 2330 | { |
2189 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); | 2331 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); |
2190 | lock (m_parts) | 2332 | lockPartsForRead(true); |
2191 | { | 2333 | { |
2192 | foreach (SceneObjectPart part in m_parts.Values) | 2334 | foreach (SceneObjectPart part in m_parts.Values) |
2193 | { | 2335 | { |
2194 | //m_log.DebugFormat("Found {0}", part.LocalId); | 2336 | //m_log.DebugFormat("Found {0}", part.LocalId); |
2195 | if (part.LocalId == localID) | 2337 | if (part.LocalId == localID) |
2196 | { | 2338 | { |
2339 | lockPartsForRead(false); | ||
2197 | return true; | 2340 | return true; |
2198 | } | 2341 | } |
2199 | } | 2342 | } |
2200 | } | 2343 | } |
2344 | lockPartsForRead(false); | ||
2201 | 2345 | ||
2202 | return false; | 2346 | return false; |
2203 | } | 2347 | } |
@@ -2247,53 +2391,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
2247 | if (m_rootPart.LinkNum == 0) | 2391 | if (m_rootPart.LinkNum == 0) |
2248 | m_rootPart.LinkNum = 1; | 2392 | m_rootPart.LinkNum = 1; |
2249 | 2393 | ||
2250 | lock (m_parts) | 2394 | lockPartsForWrite(true); |
2251 | { | 2395 | |
2252 | m_parts.Add(linkPart.UUID, linkPart); | 2396 | m_parts.Add(linkPart.UUID, linkPart); |
2397 | |||
2398 | lockPartsForWrite(false); | ||
2253 | 2399 | ||
2254 | // Insert in terms of link numbers, the new links | 2400 | // Insert in terms of link numbers, the new links |
2255 | // before the current ones (with the exception of | 2401 | // before the current ones (with the exception of |
2256 | // the root prim. Shuffle the old ones up | 2402 | // the root prim. Shuffle the old ones up |
2257 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | 2403 | lockPartsForRead(true); |
2404 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | ||
2405 | { | ||
2406 | if (kvp.Value.LinkNum != 1) | ||
2258 | { | 2407 | { |
2259 | if (kvp.Value.LinkNum != 1) | 2408 | // Don't update root prim link number |
2260 | { | 2409 | kvp.Value.LinkNum += objectGroup.PrimCount; |
2261 | // Don't update root prim link number | ||
2262 | kvp.Value.LinkNum += objectGroup.PrimCount; | ||
2263 | } | ||
2264 | } | 2410 | } |
2411 | } | ||
2412 | lockPartsForRead(false); | ||
2265 | 2413 | ||
2266 | linkPart.LinkNum = 2; | 2414 | linkPart.LinkNum = 2; |
2267 | 2415 | ||
2268 | linkPart.SetParent(this); | 2416 | linkPart.SetParent(this); |
2269 | linkPart.AddFlag(PrimFlags.CreateSelected); | 2417 | linkPart.AddFlag(PrimFlags.CreateSelected); |
2270 | 2418 | ||
2271 | //if (linkPart.PhysActor != null) | 2419 | //if (linkPart.PhysActor != null) |
2272 | //{ | 2420 | //{ |
2273 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); | 2421 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); |
2274 | 2422 | ||
2275 | //linkPart.PhysActor = null; | 2423 | //linkPart.PhysActor = null; |
2276 | //} | 2424 | //} |
2277 | 2425 | ||
2278 | //TODO: rest of parts | 2426 | //TODO: rest of parts |
2279 | int linkNum = 3; | 2427 | int linkNum = 3; |
2280 | foreach (SceneObjectPart part in objectGroup.Children.Values) | 2428 | foreach (SceneObjectPart part in objectGroup.Children.Values) |
2429 | { | ||
2430 | if (part.UUID != objectGroup.m_rootPart.UUID) | ||
2281 | { | 2431 | { |
2282 | if (part.UUID != objectGroup.m_rootPart.UUID) | 2432 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); |
2283 | { | ||
2284 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); | ||
2285 | } | ||
2286 | part.ClearUndoState(); | ||
2287 | } | 2433 | } |
2434 | part.ClearUndoState(); | ||
2288 | } | 2435 | } |
2289 | 2436 | ||
2290 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); | 2437 | m_scene.UnlinkSceneObject(objectGroup.UUID, true); |
2291 | objectGroup.m_isDeleted = true; | 2438 | objectGroup.m_isDeleted = true; |
2439 | |||
2440 | objectGroup.lockPartsForWrite(true); | ||
2292 | 2441 | ||
2293 | lock (objectGroup.m_parts) | 2442 | objectGroup.m_parts.Clear(); |
2294 | { | 2443 | |
2295 | objectGroup.m_parts.Clear(); | 2444 | objectGroup.lockPartsForWrite(false); |
2296 | } | ||
2297 | 2445 | ||
2298 | // Can't do this yet since backup still makes use of the root part without any synchronization | 2446 | // Can't do this yet since backup still makes use of the root part without any synchronization |
2299 | // objectGroup.m_rootPart = null; | 2447 | // objectGroup.m_rootPart = null; |
@@ -2363,11 +2511,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2363 | Quaternion worldRot = linkPart.GetWorldRotation(); | 2511 | Quaternion worldRot = linkPart.GetWorldRotation(); |
2364 | 2512 | ||
2365 | // Remove the part from this object | 2513 | // Remove the part from this object |
2366 | lock (m_parts) | 2514 | lockPartsForWrite(true); |
2367 | { | 2515 | { |
2368 | m_parts.Remove(linkPart.UUID); | 2516 | m_parts.Remove(linkPart.UUID); |
2369 | } | 2517 | } |
2370 | 2518 | lockPartsForWrite(false); | |
2519 | lockPartsForRead(true); | ||
2371 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | 2520 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left |
2372 | RootPart.LinkNum = 0; | 2521 | RootPart.LinkNum = 0; |
2373 | else | 2522 | else |
@@ -2378,6 +2527,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2378 | p.LinkNum--; | 2527 | p.LinkNum--; |
2379 | } | 2528 | } |
2380 | } | 2529 | } |
2530 | lockPartsForRead(false); | ||
2381 | 2531 | ||
2382 | linkPart.ParentID = 0; | 2532 | linkPart.ParentID = 0; |
2383 | linkPart.LinkNum = 0; | 2533 | linkPart.LinkNum = 0; |
@@ -2699,9 +2849,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2699 | 2849 | ||
2700 | if (selectionPart != null) | 2850 | if (selectionPart != null) |
2701 | { | 2851 | { |
2702 | lock (m_parts) | 2852 | lockPartsForRead(true); |
2853 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | ||
2854 | lockPartsForRead(false); | ||
2855 | foreach (SceneObjectPart part in parts) | ||
2703 | { | 2856 | { |
2704 | foreach (SceneObjectPart part in m_parts.Values) | 2857 | if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) |
2705 | { | 2858 | { |
2706 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | 2859 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || |
2707 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | 2860 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || |
@@ -2711,12 +2864,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2711 | break; | 2864 | break; |
2712 | } | 2865 | } |
2713 | } | 2866 | } |
2867 | } | ||
2714 | 2868 | ||
2715 | foreach (SceneObjectPart part in m_parts.Values) | 2869 | foreach (SceneObjectPart part in parts) |
2716 | { | 2870 | { |
2717 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2871 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
2718 | } | ||
2719 | } | 2872 | } |
2873 | |||
2720 | } | 2874 | } |
2721 | } | 2875 | } |
2722 | 2876 | ||
@@ -2802,11 +2956,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2802 | scale.Y = m_scene.m_maxNonphys; | 2956 | scale.Y = m_scene.m_maxNonphys; |
2803 | if (scale.Z > m_scene.m_maxNonphys) | 2957 | if (scale.Z > m_scene.m_maxNonphys) |
2804 | scale.Z = m_scene.m_maxNonphys; | 2958 | scale.Z = m_scene.m_maxNonphys; |
2805 | |||
2806 | SceneObjectPart part = GetChildPart(localID); | 2959 | SceneObjectPart part = GetChildPart(localID); |
2807 | if (part != null) | 2960 | if (part != null) |
2808 | { | 2961 | { |
2809 | part.Resize(scale); | ||
2810 | if (part.PhysActor != null) | 2962 | if (part.PhysActor != null) |
2811 | { | 2963 | { |
2812 | if (part.PhysActor.IsPhysical) | 2964 | if (part.PhysActor.IsPhysical) |
@@ -2821,7 +2973,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2821 | part.PhysActor.Size = scale; | 2973 | part.PhysActor.Size = scale; |
2822 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 2974 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); |
2823 | } | 2975 | } |
2824 | //if (part.UUID != m_rootPart.UUID) | 2976 | part.Resize(scale); |
2825 | 2977 | ||
2826 | HasGroupChanged = true; | 2978 | HasGroupChanged = true; |
2827 | ScheduleGroupForFullUpdate(); | 2979 | ScheduleGroupForFullUpdate(); |
@@ -2863,73 +3015,71 @@ namespace OpenSim.Region.Framework.Scenes | |||
2863 | float y = (scale.Y / part.Scale.Y); | 3015 | float y = (scale.Y / part.Scale.Y); |
2864 | float z = (scale.Z / part.Scale.Z); | 3016 | float z = (scale.Z / part.Scale.Z); |
2865 | 3017 | ||
2866 | lock (m_parts) | 3018 | lockPartsForRead(true); |
3019 | if (x > 1.0f || y > 1.0f || z > 1.0f) | ||
2867 | { | 3020 | { |
2868 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 3021 | foreach (SceneObjectPart obPart in m_parts.Values) |
2869 | { | 3022 | { |
2870 | foreach (SceneObjectPart obPart in m_parts.Values) | 3023 | if (obPart.UUID != m_rootPart.UUID) |
2871 | { | 3024 | { |
2872 | if (obPart.UUID != m_rootPart.UUID) | 3025 | Vector3 oldSize = new Vector3(obPart.Scale); |
2873 | { | 3026 | obPart.IgnoreUndoUpdate = true; |
2874 | obPart.IgnoreUndoUpdate = true; | ||
2875 | Vector3 oldSize = new Vector3(obPart.Scale); | ||
2876 | 3027 | ||
2877 | float f = 1.0f; | 3028 | float f = 1.0f; |
2878 | float a = 1.0f; | 3029 | float a = 1.0f; |
2879 | 3030 | ||
2880 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | 3031 | if (part.PhysActor != null && part.PhysActor.IsPhysical) |
3032 | { | ||
3033 | if (oldSize.X*x > m_scene.m_maxPhys) | ||
2881 | { | 3034 | { |
2882 | if (oldSize.X*x > m_scene.m_maxPhys) | 3035 | f = m_scene.m_maxPhys / oldSize.X; |
2883 | { | 3036 | a = f / x; |
2884 | f = m_scene.m_maxPhys / oldSize.X; | 3037 | x *= a; |
2885 | a = f / x; | 3038 | y *= a; |
2886 | x *= a; | 3039 | z *= a; |
2887 | y *= a; | ||
2888 | z *= a; | ||
2889 | } | ||
2890 | if (oldSize.Y*y > m_scene.m_maxPhys) | ||
2891 | { | ||
2892 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2893 | a = f / y; | ||
2894 | x *= a; | ||
2895 | y *= a; | ||
2896 | z *= a; | ||
2897 | } | ||
2898 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
2899 | { | ||
2900 | f = m_scene.m_maxPhys / oldSize.Z; | ||
2901 | a = f / z; | ||
2902 | x *= a; | ||
2903 | y *= a; | ||
2904 | z *= a; | ||
2905 | } | ||
2906 | } | 3040 | } |
2907 | else | 3041 | if (oldSize.Y*y > m_scene.m_maxPhys) |
3042 | { | ||
3043 | f = m_scene.m_maxPhys / oldSize.Y; | ||
3044 | a = f / y; | ||
3045 | x *= a; | ||
3046 | y *= a; | ||
3047 | z *= a; | ||
3048 | } | ||
3049 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
3050 | { | ||
3051 | f = m_scene.m_maxPhys / oldSize.Z; | ||
3052 | a = f / z; | ||
3053 | x *= a; | ||
3054 | y *= a; | ||
3055 | z *= a; | ||
3056 | } | ||
3057 | } | ||
3058 | else | ||
3059 | { | ||
3060 | if (oldSize.X*x > m_scene.m_maxNonphys) | ||
3061 | { | ||
3062 | f = m_scene.m_maxNonphys / oldSize.X; | ||
3063 | a = f / x; | ||
3064 | x *= a; | ||
3065 | y *= a; | ||
3066 | z *= a; | ||
3067 | } | ||
3068 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
3069 | { | ||
3070 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
3071 | a = f / y; | ||
3072 | x *= a; | ||
3073 | y *= a; | ||
3074 | z *= a; | ||
3075 | } | ||
3076 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2908 | { | 3077 | { |
2909 | if (oldSize.X*x > m_scene.m_maxNonphys) | 3078 | f = m_scene.m_maxNonphys / oldSize.Z; |
2910 | { | 3079 | a = f / z; |
2911 | f = m_scene.m_maxNonphys / oldSize.X; | 3080 | x *= a; |
2912 | a = f / x; | 3081 | y *= a; |
2913 | x *= a; | 3082 | z *= a; |
2914 | y *= a; | ||
2915 | z *= a; | ||
2916 | } | ||
2917 | if (oldSize.Y*y > m_scene.m_maxNonphys) | ||
2918 | { | ||
2919 | f = m_scene.m_maxNonphys / oldSize.Y; | ||
2920 | a = f / y; | ||
2921 | x *= a; | ||
2922 | y *= a; | ||
2923 | z *= a; | ||
2924 | } | ||
2925 | if (oldSize.Z*z > m_scene.m_maxNonphys) | ||
2926 | { | ||
2927 | f = m_scene.m_maxNonphys / oldSize.Z; | ||
2928 | a = f / z; | ||
2929 | x *= a; | ||
2930 | y *= a; | ||
2931 | z *= a; | ||
2932 | } | ||
2933 | } | 3083 | } |
2934 | obPart.IgnoreUndoUpdate = false; | 3084 | obPart.IgnoreUndoUpdate = false; |
2935 | obPart.StoreUndoState(); | 3085 | obPart.StoreUndoState(); |
@@ -2937,6 +3087,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2937 | } | 3087 | } |
2938 | } | 3088 | } |
2939 | } | 3089 | } |
3090 | lockPartsForRead(false); | ||
2940 | 3091 | ||
2941 | Vector3 prevScale = part.Scale; | 3092 | Vector3 prevScale = part.Scale; |
2942 | prevScale.X *= x; | 3093 | prevScale.X *= x; |
@@ -2944,7 +3095,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2944 | prevScale.Z *= z; | 3095 | prevScale.Z *= z; |
2945 | part.Resize(prevScale); | 3096 | part.Resize(prevScale); |
2946 | 3097 | ||
2947 | lock (m_parts) | 3098 | lockPartsForRead(true); |
2948 | { | 3099 | { |
2949 | foreach (SceneObjectPart obPart in m_parts.Values) | 3100 | foreach (SceneObjectPart obPart in m_parts.Values) |
2950 | { | 3101 | { |
@@ -2966,6 +3117,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2966 | obPart.StoreUndoState(); | 3117 | obPart.StoreUndoState(); |
2967 | } | 3118 | } |
2968 | } | 3119 | } |
3120 | lockPartsForRead(false); | ||
2969 | 3121 | ||
2970 | if (part.PhysActor != null) | 3122 | if (part.PhysActor != null) |
2971 | { | 3123 | { |
@@ -3068,7 +3220,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3068 | axDiff *= Quaternion.Inverse(partRotation); | 3220 | axDiff *= Quaternion.Inverse(partRotation); |
3069 | diff = axDiff; | 3221 | diff = axDiff; |
3070 | 3222 | ||
3071 | lock (m_parts) | 3223 | lockPartsForRead(true); |
3072 | { | 3224 | { |
3073 | foreach (SceneObjectPart obPart in m_parts.Values) | 3225 | foreach (SceneObjectPart obPart in m_parts.Values) |
3074 | { | 3226 | { |
@@ -3078,6 +3230,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3078 | } | 3230 | } |
3079 | } | 3231 | } |
3080 | } | 3232 | } |
3233 | lockPartsForRead(false); | ||
3081 | 3234 | ||
3082 | AbsolutePosition = newPos; | 3235 | AbsolutePosition = newPos; |
3083 | 3236 | ||
@@ -3211,7 +3364,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3211 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 3364 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); |
3212 | } | 3365 | } |
3213 | 3366 | ||
3214 | lock (m_parts) | 3367 | lockPartsForRead(true); |
3215 | { | 3368 | { |
3216 | foreach (SceneObjectPart prim in m_parts.Values) | 3369 | foreach (SceneObjectPart prim in m_parts.Values) |
3217 | { | 3370 | { |
@@ -3230,6 +3383,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3230 | } | 3383 | } |
3231 | } | 3384 | } |
3232 | } | 3385 | } |
3386 | |||
3233 | foreach (SceneObjectPart childpart in Children.Values) | 3387 | foreach (SceneObjectPart childpart in Children.Values) |
3234 | { | 3388 | { |
3235 | if (childpart != m_rootPart) | 3389 | if (childpart != m_rootPart) |
@@ -3238,6 +3392,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3238 | childpart.StoreUndoState(); | 3392 | childpart.StoreUndoState(); |
3239 | } | 3393 | } |
3240 | } | 3394 | } |
3395 | |||
3396 | lockPartsForRead(false); | ||
3397 | |||
3241 | m_rootPart.ScheduleTerseUpdate(); | 3398 | m_rootPart.ScheduleTerseUpdate(); |
3242 | } | 3399 | } |
3243 | 3400 | ||
@@ -3359,7 +3516,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3359 | if (atTargets.Count > 0) | 3516 | if (atTargets.Count > 0) |
3360 | { | 3517 | { |
3361 | uint[] localids = new uint[0]; | 3518 | uint[] localids = new uint[0]; |
3362 | lock (m_parts) | 3519 | lockPartsForRead(true); |
3363 | { | 3520 | { |
3364 | localids = new uint[m_parts.Count]; | 3521 | localids = new uint[m_parts.Count]; |
3365 | int cntr = 0; | 3522 | int cntr = 0; |
@@ -3369,6 +3526,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3369 | cntr++; | 3526 | cntr++; |
3370 | } | 3527 | } |
3371 | } | 3528 | } |
3529 | lockPartsForRead(false); | ||
3372 | 3530 | ||
3373 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3531 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3374 | { | 3532 | { |
@@ -3387,7 +3545,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3387 | { | 3545 | { |
3388 | //trigger not_at_target | 3546 | //trigger not_at_target |
3389 | uint[] localids = new uint[0]; | 3547 | uint[] localids = new uint[0]; |
3390 | lock (m_parts) | 3548 | lockPartsForRead(true); |
3391 | { | 3549 | { |
3392 | localids = new uint[m_parts.Count]; | 3550 | localids = new uint[m_parts.Count]; |
3393 | int cntr = 0; | 3551 | int cntr = 0; |
@@ -3397,7 +3555,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3397 | cntr++; | 3555 | cntr++; |
3398 | } | 3556 | } |
3399 | } | 3557 | } |
3400 | 3558 | lockPartsForRead(false); | |
3559 | |||
3401 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3560 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3402 | { | 3561 | { |
3403 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); | 3562 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); |
@@ -3489,19 +3648,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3489 | public float GetMass() | 3648 | public float GetMass() |
3490 | { | 3649 | { |
3491 | float retmass = 0f; | 3650 | float retmass = 0f; |
3492 | lock (m_parts) | 3651 | lockPartsForRead(true); |
3493 | { | 3652 | { |
3494 | foreach (SceneObjectPart part in m_parts.Values) | 3653 | foreach (SceneObjectPart part in m_parts.Values) |
3495 | { | 3654 | { |
3496 | retmass += part.GetMass(); | 3655 | retmass += part.GetMass(); |
3497 | } | 3656 | } |
3498 | } | 3657 | } |
3658 | lockPartsForRead(false); | ||
3499 | return retmass; | 3659 | return retmass; |
3500 | } | 3660 | } |
3501 | 3661 | ||
3502 | public void CheckSculptAndLoad() | 3662 | public void CheckSculptAndLoad() |
3503 | { | 3663 | { |
3504 | lock (m_parts) | 3664 | lockPartsForRead(true); |
3505 | { | 3665 | { |
3506 | if (!IsDeleted) | 3666 | if (!IsDeleted) |
3507 | { | 3667 | { |
@@ -3526,6 +3686,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3526 | } | 3686 | } |
3527 | } | 3687 | } |
3528 | } | 3688 | } |
3689 | lockPartsForRead(false); | ||
3529 | } | 3690 | } |
3530 | 3691 | ||
3531 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 3692 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
@@ -3546,7 +3707,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3546 | /// <param name="client"></param> | 3707 | /// <param name="client"></param> |
3547 | public void SetGroup(UUID GroupID, IClientAPI client) | 3708 | public void SetGroup(UUID GroupID, IClientAPI client) |
3548 | { | 3709 | { |
3549 | lock (m_parts) | 3710 | lockPartsForRead(true); |
3550 | { | 3711 | { |
3551 | foreach (SceneObjectPart part in m_parts.Values) | 3712 | foreach (SceneObjectPart part in m_parts.Values) |
3552 | { | 3713 | { |
@@ -3556,7 +3717,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3556 | 3717 | ||
3557 | HasGroupChanged = true; | 3718 | HasGroupChanged = true; |
3558 | } | 3719 | } |
3559 | 3720 | lockPartsForRead(false); | |
3560 | ScheduleGroupForFullUpdate(); | 3721 | ScheduleGroupForFullUpdate(); |
3561 | } | 3722 | } |
3562 | 3723 | ||
@@ -3575,11 +3736,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3575 | 3736 | ||
3576 | public void SetAttachmentPoint(byte point) | 3737 | public void SetAttachmentPoint(byte point) |
3577 | { | 3738 | { |
3578 | lock (m_parts) | 3739 | lockPartsForRead(true); |
3579 | { | 3740 | { |
3580 | foreach (SceneObjectPart part in m_parts.Values) | 3741 | foreach (SceneObjectPart part in m_parts.Values) |
3581 | part.SetAttachmentPoint(point); | 3742 | part.SetAttachmentPoint(point); |
3582 | } | 3743 | } |
3744 | lockPartsForRead(false); | ||
3583 | } | 3745 | } |
3584 | 3746 | ||
3585 | #region ISceneObject | 3747 | #region ISceneObject |