diff options
author | Justin Clark-Casey (justincc) | 2010-08-26 00:08:53 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2010-08-26 00:08:53 +0100 |
commit | 8031f8ec09df4f654c86a9c7bc498664f7b9d9dc (patch) | |
tree | d6a6da4d448b9bc11ff8d1078b9be089b9872151 /OpenSim/Region | |
parent | minor: remove mono compiler warning (diff) | |
download | opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.zip opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.gz opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.bz2 opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.xz |
Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking
Diffstat (limited to '')
19 files changed, 739 insertions, 586 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 365cdbb..847a999 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -406,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
406 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 406 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) |
407 | { | 407 | { |
408 | if (!m_scene.Permissions.CanRezObject( | 408 | if (!m_scene.Permissions.CanRezObject( |
409 | part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition)) | 409 | part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) |
410 | return; | 410 | return; |
411 | 411 | ||
412 | presence.Appearance.DetachAttachment(itemID); | 412 | presence.Appearance.DetachAttachment(itemID); |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index eef0c73..6decf54 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -526,7 +526,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
526 | group.RootPart.CreateSelected = true; | 526 | group.RootPart.CreateSelected = true; |
527 | 527 | ||
528 | if (!m_Scene.Permissions.CanRezObject( | 528 | if (!m_Scene.Permissions.CanRezObject( |
529 | group.Children.Count, remoteClient.AgentId, pos) | 529 | group.PrimCount, remoteClient.AgentId, pos) |
530 | && !attachment) | 530 | && !attachment) |
531 | { | 531 | { |
532 | // The client operates in no fail mode. It will | 532 | // The client operates in no fail mode. It will |
@@ -594,7 +594,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
594 | rootPart.Name = item.Name; | 594 | rootPart.Name = item.Name; |
595 | rootPart.Description = item.Description; | 595 | rootPart.Description = item.Description; |
596 | 596 | ||
597 | List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); | 597 | List<SceneObjectPart> partList = null; |
598 | lock (group.Children) | ||
599 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
598 | 600 | ||
599 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | 601 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); |
600 | if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) | 602 | if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index bc653ce..1623e6e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -243,36 +243,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
243 | // to the same scene (when this is possible). | 243 | // to the same scene (when this is possible). |
244 | sceneObject.ResetIDs(); | 244 | sceneObject.ResetIDs(); |
245 | 245 | ||
246 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 246 | lock (sceneObject.Children) |
247 | { | 247 | { |
248 | if (!ResolveUserUuid(part.CreatorID)) | 248 | foreach (SceneObjectPart part in sceneObject.Children.Values) |
249 | part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
250 | |||
251 | if (!ResolveUserUuid(part.OwnerID)) | ||
252 | part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
253 | |||
254 | if (!ResolveUserUuid(part.LastOwnerID)) | ||
255 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
256 | |||
257 | // And zap any troublesome sit target information | ||
258 | part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | ||
259 | part.SitTargetPosition = new Vector3(0, 0, 0); | ||
260 | |||
261 | // Fix ownership/creator of inventory items | ||
262 | // Not doing so results in inventory items | ||
263 | // being no copy/no mod for everyone | ||
264 | lock (part.TaskInventory) | ||
265 | { | 249 | { |
266 | TaskInventoryDictionary inv = part.TaskInventory; | 250 | if (!ResolveUserUuid(part.CreatorID)) |
267 | foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) | 251 | part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
252 | |||
253 | if (!ResolveUserUuid(part.OwnerID)) | ||
254 | part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
255 | |||
256 | if (!ResolveUserUuid(part.LastOwnerID)) | ||
257 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
258 | |||
259 | // And zap any troublesome sit target information | ||
260 | part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | ||
261 | part.SitTargetPosition = new Vector3(0, 0, 0); | ||
262 | |||
263 | // Fix ownership/creator of inventory items | ||
264 | // Not doing so results in inventory items | ||
265 | // being no copy/no mod for everyone | ||
266 | lock (part.TaskInventory) | ||
268 | { | 267 | { |
269 | if (!ResolveUserUuid(kvp.Value.OwnerID)) | 268 | TaskInventoryDictionary inv = part.TaskInventory; |
270 | { | 269 | foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) |
271 | kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
272 | } | ||
273 | if (!ResolveUserUuid(kvp.Value.CreatorID)) | ||
274 | { | 270 | { |
275 | kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 271 | if (!ResolveUserUuid(kvp.Value.OwnerID)) |
272 | { | ||
273 | kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
274 | } | ||
275 | if (!ResolveUserUuid(kvp.Value.CreatorID)) | ||
276 | { | ||
277 | kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
278 | } | ||
276 | } | 279 | } |
277 | } | 280 | } |
278 | } | 281 | } |
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 62abd4c..8ce6daf 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | |||
@@ -128,7 +128,10 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell | |||
128 | group.SetOwnerId(remoteClient.AgentId); | 128 | group.SetOwnerId(remoteClient.AgentId); |
129 | group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); | 129 | group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); |
130 | 130 | ||
131 | List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); | 131 | List<SceneObjectPart> partList = null; |
132 | |||
133 | lock (group.Children) | ||
134 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
132 | 135 | ||
133 | if (m_scene.Permissions.PropagatePermissions()) | 136 | if (m_scene.Permissions.PropagatePermissions()) |
134 | { | 137 | { |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs index b96d95a..2f70c0a 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs | |||
@@ -227,277 +227,281 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
227 | { | 227 | { |
228 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; | 228 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; |
229 | Color mapdotspot = Color.Gray; // Default color when prim color is white | 229 | Color mapdotspot = Color.Gray; // Default color when prim color is white |
230 | |||
230 | // Loop over prim in group | 231 | // Loop over prim in group |
231 | foreach (SceneObjectPart part in mapdot.Children.Values) | 232 | lock (mapdot.Children) |
232 | { | 233 | { |
233 | if (part == null) | 234 | foreach (SceneObjectPart part in mapdot.Children.Values) |
234 | continue; | ||
235 | |||
236 | // Draw if the object is at least 1 meter wide in any direction | ||
237 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) | ||
238 | { | 235 | { |
239 | // Try to get the RGBA of the default texture entry.. | 236 | if (part == null) |
240 | // | 237 | continue; |
241 | try | 238 | |
239 | // Draw if the object is at least 1 meter wide in any direction | ||
240 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) | ||
242 | { | 241 | { |
243 | // get the null checks out of the way | 242 | // Try to get the RGBA of the default texture entry.. |
244 | // skip the ones that break | 243 | // |
245 | if (part == null) | 244 | try |
246 | continue; | ||
247 | |||
248 | if (part.Shape == null) | ||
249 | continue; | ||
250 | |||
251 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) | ||
252 | continue; // eliminates trees from this since we don't really have a good tree representation | ||
253 | // if you want tree blocks on the map comment the above line and uncomment the below line | ||
254 | //mapdotspot = Color.PaleGreen; | ||
255 | |||
256 | Primitive.TextureEntry textureEntry = part.Shape.Textures; | ||
257 | |||
258 | if (textureEntry == null || textureEntry.DefaultTexture == null) | ||
259 | continue; | ||
260 | |||
261 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; | ||
262 | |||
263 | // Not sure why some of these are null, oh well. | ||
264 | |||
265 | int colorr = 255 - (int)(texcolor.R * 255f); | ||
266 | int colorg = 255 - (int)(texcolor.G * 255f); | ||
267 | int colorb = 255 - (int)(texcolor.B * 255f); | ||
268 | |||
269 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) | ||
270 | { | 245 | { |
271 | //Try to set the map spot color | 246 | // get the null checks out of the way |
272 | try | 247 | // skip the ones that break |
273 | { | 248 | if (part == null) |
274 | // If the color gets goofy somehow, skip it *shakes fist at Color4 | 249 | continue; |
275 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); | 250 | |
276 | } | 251 | if (part.Shape == null) |
277 | catch (ArgumentException) | 252 | continue; |
253 | |||
254 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) | ||
255 | continue; // eliminates trees from this since we don't really have a good tree representation | ||
256 | // if you want tree blocks on the map comment the above line and uncomment the below line | ||
257 | //mapdotspot = Color.PaleGreen; | ||
258 | |||
259 | Primitive.TextureEntry textureEntry = part.Shape.Textures; | ||
260 | |||
261 | if (textureEntry == null || textureEntry.DefaultTexture == null) | ||
262 | continue; | ||
263 | |||
264 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; | ||
265 | |||
266 | // Not sure why some of these are null, oh well. | ||
267 | |||
268 | int colorr = 255 - (int)(texcolor.R * 255f); | ||
269 | int colorg = 255 - (int)(texcolor.G * 255f); | ||
270 | int colorb = 255 - (int)(texcolor.B * 255f); | ||
271 | |||
272 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) | ||
278 | { | 273 | { |
274 | //Try to set the map spot color | ||
275 | try | ||
276 | { | ||
277 | // If the color gets goofy somehow, skip it *shakes fist at Color4 | ||
278 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); | ||
279 | } | ||
280 | catch (ArgumentException) | ||
281 | { | ||
282 | } | ||
279 | } | 283 | } |
280 | } | 284 | } |
281 | } | 285 | catch (IndexOutOfRangeException) |
282 | catch (IndexOutOfRangeException) | 286 | { |
283 | { | 287 | // Windows Array |
284 | // Windows Array | 288 | } |
285 | } | 289 | catch (ArgumentOutOfRangeException) |
286 | catch (ArgumentOutOfRangeException) | 290 | { |
287 | { | 291 | // Mono Array |
288 | // Mono Array | 292 | } |
289 | } | 293 | |
290 | 294 | Vector3 pos = part.GetWorldPosition(); | |
291 | Vector3 pos = part.GetWorldPosition(); | 295 | |
292 | 296 | // skip prim outside of retion | |
293 | // skip prim outside of retion | 297 | if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) |
294 | if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) | ||
295 | continue; | ||
296 | |||
297 | // skip prim in non-finite position | ||
298 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || | ||
299 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) | ||
300 | continue; | ||
301 | |||
302 | // Figure out if object is under 256m above the height of the terrain | ||
303 | bool isBelow256AboveTerrain = false; | ||
304 | |||
305 | try | ||
306 | { | ||
307 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); | ||
308 | } | ||
309 | catch (Exception) | ||
310 | { | ||
311 | } | ||
312 | |||
313 | if (isBelow256AboveTerrain) | ||
314 | { | ||
315 | // Translate scale by rotation so scale is represented properly when object is rotated | ||
316 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); | ||
317 | Vector3 scale = new Vector3(); | ||
318 | Vector3 tScale = new Vector3(); | ||
319 | Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | ||
320 | |||
321 | Quaternion llrot = part.GetWorldRotation(); | ||
322 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | ||
323 | scale = lscale * rot; | ||
324 | |||
325 | // negative scales don't work in this situation | ||
326 | scale.X = Math.Abs(scale.X); | ||
327 | scale.Y = Math.Abs(scale.Y); | ||
328 | scale.Z = Math.Abs(scale.Z); | ||
329 | |||
330 | // This scaling isn't very accurate and doesn't take into account the face rotation :P | ||
331 | int mapdrawstartX = (int)(pos.X - scale.X); | ||
332 | int mapdrawstartY = (int)(pos.Y - scale.Y); | ||
333 | int mapdrawendX = (int)(pos.X + scale.X); | ||
334 | int mapdrawendY = (int)(pos.Y + scale.Y); | ||
335 | |||
336 | // If object is beyond the edge of the map, don't draw it to avoid errors | ||
337 | if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | ||
338 | || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | ||
339 | || mapdrawendY > ((int)Constants.RegionSize - 1)) | ||
340 | continue; | 298 | continue; |
341 | 299 | ||
342 | #region obb face reconstruction part duex | 300 | // skip prim in non-finite position |
343 | Vector3[] vertexes = new Vector3[8]; | 301 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || |
344 | 302 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) | |
345 | // float[] distance = new float[6]; | 303 | continue; |
346 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei | 304 | |
347 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei | 305 | // Figure out if object is under 256m above the height of the terrain |
348 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei | 306 | bool isBelow256AboveTerrain = false; |
349 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei | 307 | |
350 | 308 | try | |
351 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); | ||
352 | scale = ((tScale * rot)); | ||
353 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
354 | // vertexes[0].x = pos.X + vertexes[0].x; | ||
355 | //vertexes[0].y = pos.Y + vertexes[0].y; | ||
356 | //vertexes[0].z = pos.Z + vertexes[0].z; | ||
357 | |||
358 | FaceA[0] = vertexes[0]; | ||
359 | FaceB[3] = vertexes[0]; | ||
360 | FaceA[4] = vertexes[0]; | ||
361 | |||
362 | tScale = lscale; | ||
363 | scale = ((tScale * rot)); | ||
364 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
365 | |||
366 | // vertexes[1].x = pos.X + vertexes[1].x; | ||
367 | // vertexes[1].y = pos.Y + vertexes[1].y; | ||
368 | //vertexes[1].z = pos.Z + vertexes[1].z; | ||
369 | |||
370 | FaceB[0] = vertexes[1]; | ||
371 | FaceA[1] = vertexes[1]; | ||
372 | FaceC[4] = vertexes[1]; | ||
373 | |||
374 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); | ||
375 | scale = ((tScale * rot)); | ||
376 | |||
377 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
378 | |||
379 | //vertexes[2].x = pos.X + vertexes[2].x; | ||
380 | //vertexes[2].y = pos.Y + vertexes[2].y; | ||
381 | //vertexes[2].z = pos.Z + vertexes[2].z; | ||
382 | |||
383 | FaceC[0] = vertexes[2]; | ||
384 | FaceD[3] = vertexes[2]; | ||
385 | FaceC[5] = vertexes[2]; | ||
386 | |||
387 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); | ||
388 | scale = ((tScale * rot)); | ||
389 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
390 | |||
391 | //vertexes[3].x = pos.X + vertexes[3].x; | ||
392 | // vertexes[3].y = pos.Y + vertexes[3].y; | ||
393 | // vertexes[3].z = pos.Z + vertexes[3].z; | ||
394 | |||
395 | FaceD[0] = vertexes[3]; | ||
396 | FaceC[1] = vertexes[3]; | ||
397 | FaceA[5] = vertexes[3]; | ||
398 | |||
399 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); | ||
400 | scale = ((tScale * rot)); | ||
401 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
402 | |||
403 | // vertexes[4].x = pos.X + vertexes[4].x; | ||
404 | // vertexes[4].y = pos.Y + vertexes[4].y; | ||
405 | // vertexes[4].z = pos.Z + vertexes[4].z; | ||
406 | |||
407 | FaceB[1] = vertexes[4]; | ||
408 | FaceA[2] = vertexes[4]; | ||
409 | FaceD[4] = vertexes[4]; | ||
410 | |||
411 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); | ||
412 | scale = ((tScale * rot)); | ||
413 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
414 | |||
415 | // vertexes[5].x = pos.X + vertexes[5].x; | ||
416 | // vertexes[5].y = pos.Y + vertexes[5].y; | ||
417 | // vertexes[5].z = pos.Z + vertexes[5].z; | ||
418 | |||
419 | FaceD[1] = vertexes[5]; | ||
420 | FaceC[2] = vertexes[5]; | ||
421 | FaceB[5] = vertexes[5]; | ||
422 | |||
423 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); | ||
424 | scale = ((tScale * rot)); | ||
425 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
426 | |||
427 | // vertexes[6].x = pos.X + vertexes[6].x; | ||
428 | // vertexes[6].y = pos.Y + vertexes[6].y; | ||
429 | // vertexes[6].z = pos.Z + vertexes[6].z; | ||
430 | |||
431 | FaceB[2] = vertexes[6]; | ||
432 | FaceA[3] = vertexes[6]; | ||
433 | FaceB[4] = vertexes[6]; | ||
434 | |||
435 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); | ||
436 | scale = ((tScale * rot)); | ||
437 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
438 | |||
439 | // vertexes[7].x = pos.X + vertexes[7].x; | ||
440 | // vertexes[7].y = pos.Y + vertexes[7].y; | ||
441 | // vertexes[7].z = pos.Z + vertexes[7].z; | ||
442 | |||
443 | FaceD[2] = vertexes[7]; | ||
444 | FaceC[3] = vertexes[7]; | ||
445 | FaceD[5] = vertexes[7]; | ||
446 | #endregion | ||
447 | |||
448 | //int wy = 0; | ||
449 | |||
450 | //bool breakYN = false; // If we run into an error drawing, break out of the | ||
451 | // loop so we don't lag to death on error handling | ||
452 | DrawStruct ds = new DrawStruct(); | ||
453 | ds.brush = new SolidBrush(mapdotspot); | ||
454 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); | ||
455 | |||
456 | ds.trns = new face[FaceA.Length]; | ||
457 | |||
458 | for (int i = 0; i < FaceA.Length; i++) | ||
459 | { | 309 | { |
460 | Point[] working = new Point[5]; | 310 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); |
461 | working[0] = project(FaceA[i], axPos); | ||
462 | working[1] = project(FaceB[i], axPos); | ||
463 | working[2] = project(FaceD[i], axPos); | ||
464 | working[3] = project(FaceC[i], axPos); | ||
465 | working[4] = project(FaceA[i], axPos); | ||
466 | |||
467 | face workingface = new face(); | ||
468 | workingface.pts = working; | ||
469 | |||
470 | ds.trns[i] = workingface; | ||
471 | } | 311 | } |
472 | 312 | catch (Exception) | |
473 | z_sort.Add(part.LocalId, ds); | 313 | { |
474 | z_localIDs.Add(part.LocalId); | 314 | } |
475 | z_sortheights.Add(pos.Z); | 315 | |
476 | 316 | if (isBelow256AboveTerrain) | |
477 | //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) | 317 | { |
478 | //{ | 318 | // Translate scale by rotation so scale is represented properly when object is rotated |
479 | //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) | 319 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); |
320 | Vector3 scale = new Vector3(); | ||
321 | Vector3 tScale = new Vector3(); | ||
322 | Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | ||
323 | |||
324 | Quaternion llrot = part.GetWorldRotation(); | ||
325 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | ||
326 | scale = lscale * rot; | ||
327 | |||
328 | // negative scales don't work in this situation | ||
329 | scale.X = Math.Abs(scale.X); | ||
330 | scale.Y = Math.Abs(scale.Y); | ||
331 | scale.Z = Math.Abs(scale.Z); | ||
332 | |||
333 | // This scaling isn't very accurate and doesn't take into account the face rotation :P | ||
334 | int mapdrawstartX = (int)(pos.X - scale.X); | ||
335 | int mapdrawstartY = (int)(pos.Y - scale.Y); | ||
336 | int mapdrawendX = (int)(pos.X + scale.X); | ||
337 | int mapdrawendY = (int)(pos.Y + scale.Y); | ||
338 | |||
339 | // If object is beyond the edge of the map, don't draw it to avoid errors | ||
340 | if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | ||
341 | || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | ||
342 | || mapdrawendY > ((int)Constants.RegionSize - 1)) | ||
343 | continue; | ||
344 | |||
345 | #region obb face reconstruction part duex | ||
346 | Vector3[] vertexes = new Vector3[8]; | ||
347 | |||
348 | // float[] distance = new float[6]; | ||
349 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei | ||
350 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei | ||
351 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei | ||
352 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei | ||
353 | |||
354 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); | ||
355 | scale = ((tScale * rot)); | ||
356 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
357 | // vertexes[0].x = pos.X + vertexes[0].x; | ||
358 | //vertexes[0].y = pos.Y + vertexes[0].y; | ||
359 | //vertexes[0].z = pos.Z + vertexes[0].z; | ||
360 | |||
361 | FaceA[0] = vertexes[0]; | ||
362 | FaceB[3] = vertexes[0]; | ||
363 | FaceA[4] = vertexes[0]; | ||
364 | |||
365 | tScale = lscale; | ||
366 | scale = ((tScale * rot)); | ||
367 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
368 | |||
369 | // vertexes[1].x = pos.X + vertexes[1].x; | ||
370 | // vertexes[1].y = pos.Y + vertexes[1].y; | ||
371 | //vertexes[1].z = pos.Z + vertexes[1].z; | ||
372 | |||
373 | FaceB[0] = vertexes[1]; | ||
374 | FaceA[1] = vertexes[1]; | ||
375 | FaceC[4] = vertexes[1]; | ||
376 | |||
377 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); | ||
378 | scale = ((tScale * rot)); | ||
379 | |||
380 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
381 | |||
382 | //vertexes[2].x = pos.X + vertexes[2].x; | ||
383 | //vertexes[2].y = pos.Y + vertexes[2].y; | ||
384 | //vertexes[2].z = pos.Z + vertexes[2].z; | ||
385 | |||
386 | FaceC[0] = vertexes[2]; | ||
387 | FaceD[3] = vertexes[2]; | ||
388 | FaceC[5] = vertexes[2]; | ||
389 | |||
390 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); | ||
391 | scale = ((tScale * rot)); | ||
392 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
393 | |||
394 | //vertexes[3].x = pos.X + vertexes[3].x; | ||
395 | // vertexes[3].y = pos.Y + vertexes[3].y; | ||
396 | // vertexes[3].z = pos.Z + vertexes[3].z; | ||
397 | |||
398 | FaceD[0] = vertexes[3]; | ||
399 | FaceC[1] = vertexes[3]; | ||
400 | FaceA[5] = vertexes[3]; | ||
401 | |||
402 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); | ||
403 | scale = ((tScale * rot)); | ||
404 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
405 | |||
406 | // vertexes[4].x = pos.X + vertexes[4].x; | ||
407 | // vertexes[4].y = pos.Y + vertexes[4].y; | ||
408 | // vertexes[4].z = pos.Z + vertexes[4].z; | ||
409 | |||
410 | FaceB[1] = vertexes[4]; | ||
411 | FaceA[2] = vertexes[4]; | ||
412 | FaceD[4] = vertexes[4]; | ||
413 | |||
414 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); | ||
415 | scale = ((tScale * rot)); | ||
416 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
417 | |||
418 | // vertexes[5].x = pos.X + vertexes[5].x; | ||
419 | // vertexes[5].y = pos.Y + vertexes[5].y; | ||
420 | // vertexes[5].z = pos.Z + vertexes[5].z; | ||
421 | |||
422 | FaceD[1] = vertexes[5]; | ||
423 | FaceC[2] = vertexes[5]; | ||
424 | FaceB[5] = vertexes[5]; | ||
425 | |||
426 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); | ||
427 | scale = ((tScale * rot)); | ||
428 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
429 | |||
430 | // vertexes[6].x = pos.X + vertexes[6].x; | ||
431 | // vertexes[6].y = pos.Y + vertexes[6].y; | ||
432 | // vertexes[6].z = pos.Z + vertexes[6].z; | ||
433 | |||
434 | FaceB[2] = vertexes[6]; | ||
435 | FaceA[3] = vertexes[6]; | ||
436 | FaceB[4] = vertexes[6]; | ||
437 | |||
438 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); | ||
439 | scale = ((tScale * rot)); | ||
440 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
441 | |||
442 | // vertexes[7].x = pos.X + vertexes[7].x; | ||
443 | // vertexes[7].y = pos.Y + vertexes[7].y; | ||
444 | // vertexes[7].z = pos.Z + vertexes[7].z; | ||
445 | |||
446 | FaceD[2] = vertexes[7]; | ||
447 | FaceC[3] = vertexes[7]; | ||
448 | FaceD[5] = vertexes[7]; | ||
449 | #endregion | ||
450 | |||
451 | //int wy = 0; | ||
452 | |||
453 | //bool breakYN = false; // If we run into an error drawing, break out of the | ||
454 | // loop so we don't lag to death on error handling | ||
455 | DrawStruct ds = new DrawStruct(); | ||
456 | ds.brush = new SolidBrush(mapdotspot); | ||
457 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); | ||
458 | |||
459 | ds.trns = new face[FaceA.Length]; | ||
460 | |||
461 | for (int i = 0; i < FaceA.Length; i++) | ||
462 | { | ||
463 | Point[] working = new Point[5]; | ||
464 | working[0] = project(FaceA[i], axPos); | ||
465 | working[1] = project(FaceB[i], axPos); | ||
466 | working[2] = project(FaceD[i], axPos); | ||
467 | working[3] = project(FaceC[i], axPos); | ||
468 | working[4] = project(FaceA[i], axPos); | ||
469 | |||
470 | face workingface = new face(); | ||
471 | workingface.pts = working; | ||
472 | |||
473 | ds.trns[i] = workingface; | ||
474 | } | ||
475 | |||
476 | z_sort.Add(part.LocalId, ds); | ||
477 | z_localIDs.Add(part.LocalId); | ||
478 | z_sortheights.Add(pos.Z); | ||
479 | |||
480 | //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) | ||
480 | //{ | 481 | //{ |
481 | //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); | 482 | //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) |
482 | //try | ||
483 | //{ | 483 | //{ |
484 | // Remember, flip the y! | 484 | //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); |
485 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); | 485 | //try |
486 | //{ | ||
487 | // Remember, flip the y! | ||
488 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); | ||
489 | //} | ||
490 | //catch (ArgumentException) | ||
491 | //{ | ||
492 | // breakYN = true; | ||
493 | //} | ||
494 | |||
495 | //if (breakYN) | ||
496 | // break; | ||
486 | //} | 497 | //} |
487 | //catch (ArgumentException) | 498 | |
488 | //{ | ||
489 | // breakYN = true; | ||
490 | //} | ||
491 | |||
492 | //if (breakYN) | 499 | //if (breakYN) |
493 | // break; | 500 | // break; |
494 | //} | 501 | //} |
495 | 502 | } // Object is within 256m Z of terrain | |
496 | //if (breakYN) | 503 | } // object is at least a meter wide |
497 | // break; | 504 | } // mapdot.Children lock |
498 | //} | ||
499 | } // Object is within 256m Z of terrain | ||
500 | } // object is at least a meter wide | ||
501 | } // loop over group children | 505 | } // loop over group children |
502 | } // entitybase is sceneobject group | 506 | } // entitybase is sceneobject group |
503 | } // foreach loop over entities | 507 | } // foreach loop over entities |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9fef8f4..379128a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -1974,7 +1974,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1974 | if (null == group) | 1974 | if (null == group) |
1975 | return null; | 1975 | return null; |
1976 | 1976 | ||
1977 | if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos)) | 1977 | if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos)) |
1978 | return null; | 1978 | return null; |
1979 | 1979 | ||
1980 | if (!Permissions.BypassPermissions()) | 1980 | if (!Permissions.BypassPermissions()) |
@@ -2051,8 +2051,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2051 | sog.SetGroup(groupID, remoteClient); | 2051 | sog.SetGroup(groupID, remoteClient); |
2052 | sog.ScheduleGroupForFullUpdate(); | 2052 | sog.ScheduleGroupForFullUpdate(); |
2053 | 2053 | ||
2054 | foreach (SceneObjectPart child in sog.Children.Values) | 2054 | lock (sog.Children) |
2055 | child.Inventory.ChangeInventoryOwner(ownerID); | 2055 | { |
2056 | foreach (SceneObjectPart child in sog.Children.Values) | ||
2057 | child.Inventory.ChangeInventoryOwner(ownerID); | ||
2058 | } | ||
2056 | } | 2059 | } |
2057 | else | 2060 | else |
2058 | { | 2061 | { |
@@ -2062,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2062 | if (sog.GroupID != groupID) | 2065 | if (sog.GroupID != groupID) |
2063 | continue; | 2066 | continue; |
2064 | 2067 | ||
2065 | foreach (SceneObjectPart child in sog.Children.Values) | 2068 | lock (sog.Children) |
2066 | { | 2069 | { |
2067 | child.LastOwnerID = child.OwnerID; | 2070 | foreach (SceneObjectPart child in sog.Children.Values) |
2068 | child.Inventory.ChangeInventoryOwner(groupID); | 2071 | { |
2072 | child.LastOwnerID = child.OwnerID; | ||
2073 | child.Inventory.ChangeInventoryOwner(groupID); | ||
2074 | } | ||
2069 | } | 2075 | } |
2070 | 2076 | ||
2071 | sog.SetOwnerId(groupID); | 2077 | sog.SetOwnerId(groupID); |
2072 | sog.ApplyNextOwnerPermissions(); | 2078 | sog.ApplyNextOwnerPermissions(); |
2073 | } | 2079 | } |
2074 | |||
2075 | } | 2080 | } |
2076 | 2081 | ||
2077 | foreach (uint localID in localIDs) | 2082 | foreach (uint localID in localIDs) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index e25b1f1..9f1575d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -156,21 +156,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
156 | } | 156 | } |
157 | break; | 157 | break; |
158 | } | 158 | } |
159 | else | 159 | else |
160 | { | 160 | { |
161 | // We also need to check the children of this prim as they | 161 | // We also need to check the children of this prim as they |
162 | // can be selected as well and send property information | 162 | // can be selected as well and send property information |
163 | bool foundPrim = false; | 163 | bool foundPrim = false; |
164 | foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children) | 164 | |
165 | { | 165 | SceneObjectGroup sog = ent as SceneObjectGroup; |
166 | if (child.Value.LocalId == primLocalID) | 166 | |
167 | { | 167 | lock (sog.Children) |
168 | child.Value.GetProperties(remoteClient); | 168 | { |
169 | foundPrim = true; | 169 | foreach (KeyValuePair<UUID, SceneObjectPart> child in (sog.Children)) |
170 | break; | 170 | { |
171 | } | 171 | if (child.Value.LocalId == primLocalID) |
172 | } | 172 | { |
173 | if (foundPrim) break; | 173 | child.Value.GetProperties(remoteClient); |
174 | foundPrim = true; | ||
175 | break; | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | |||
180 | if (foundPrim) | ||
181 | break; | ||
174 | } | 182 | } |
175 | } | 183 | } |
176 | } | 184 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b808c6d..8556105 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1756,8 +1756,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1756 | 1756 | ||
1757 | if (group.RootPart == null) | 1757 | if (group.RootPart == null) |
1758 | { | 1758 | { |
1759 | m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", | 1759 | m_log.ErrorFormat( |
1760 | group.Children == null ? 0 : group.Children.Count); | 1760 | "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", |
1761 | group.Children == null ? 0 : group.PrimCount); | ||
1761 | } | 1762 | } |
1762 | 1763 | ||
1763 | AddRestoredSceneObject(group, true, true); | 1764 | AddRestoredSceneObject(group, true, true); |
@@ -2064,18 +2065,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
2064 | group.RemoveScriptInstances(true); | 2065 | group.RemoveScriptInstances(true); |
2065 | } | 2066 | } |
2066 | 2067 | ||
2067 | foreach (SceneObjectPart part in group.Children.Values) | 2068 | lock (group.Children) |
2068 | { | 2069 | { |
2069 | if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) | 2070 | foreach (SceneObjectPart part in group.Children.Values) |
2070 | { | 2071 | { |
2071 | PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? | 2072 | if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) |
2072 | } | 2073 | { |
2073 | else if (part.PhysActor != null) | 2074 | PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? |
2074 | { | 2075 | } |
2075 | PhysicsScene.RemovePrim(part.PhysActor); | 2076 | else if (part.PhysActor != null) |
2076 | part.PhysActor = null; | 2077 | { |
2078 | PhysicsScene.RemovePrim(part.PhysActor); | ||
2079 | part.PhysActor = null; | ||
2080 | } | ||
2077 | } | 2081 | } |
2078 | } | 2082 | } |
2083 | |||
2079 | // if (rootPart.PhysActor != null) | 2084 | // if (rootPart.PhysActor != null) |
2080 | // { | 2085 | // { |
2081 | // PhysicsScene.RemovePrim(rootPart.PhysActor); | 2086 | // PhysicsScene.RemovePrim(rootPart.PhysActor); |
@@ -2426,14 +2431,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2426 | 2431 | ||
2427 | // Force allocation of new LocalId | 2432 | // Force allocation of new LocalId |
2428 | // | 2433 | // |
2429 | foreach (SceneObjectPart p in sceneObject.Children.Values) | 2434 | lock (sceneObject.Children) |
2430 | p.LocalId = 0; | 2435 | { |
2436 | foreach (SceneObjectPart p in sceneObject.Children.Values) | ||
2437 | p.LocalId = 0; | ||
2438 | } | ||
2431 | 2439 | ||
2432 | if (sceneObject.IsAttachmentCheckFull()) // Attachment | 2440 | if (sceneObject.IsAttachmentCheckFull()) // Attachment |
2433 | { | 2441 | { |
2434 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); | 2442 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); |
2435 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); | 2443 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); |
2436 | |||
2437 | 2444 | ||
2438 | // Don't sent a full update here because this will cause full updates to be sent twice for | 2445 | // Don't sent a full update here because this will cause full updates to be sent twice for |
2439 | // attachments on region crossings, resulting in viewer glitches. | 2446 | // attachments on region crossings, resulting in viewer glitches. |
@@ -2447,7 +2454,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2447 | 2454 | ||
2448 | if (sp != null) | 2455 | if (sp != null) |
2449 | { | 2456 | { |
2450 | |||
2451 | SceneObjectGroup grp = sceneObject; | 2457 | SceneObjectGroup grp = sceneObject; |
2452 | 2458 | ||
2453 | m_log.DebugFormat( | 2459 | m_log.DebugFormat( |
@@ -2459,7 +2465,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2459 | 2465 | ||
2460 | if (AttachmentsModule != null) | 2466 | if (AttachmentsModule != null) |
2461 | AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); | 2467 | AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); |
2462 | |||
2463 | } | 2468 | } |
2464 | else | 2469 | else |
2465 | { | 2470 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 31faeec..2b24706 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -364,45 +364,48 @@ namespace OpenSim.Region.Framework.Scenes | |||
364 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", | 364 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", |
365 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); | 365 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); |
366 | 366 | ||
367 | if (m_parentScene.m_clampPrimSize) | 367 | lock (sceneObject.Children) |
368 | { | 368 | { |
369 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 369 | if (m_parentScene.m_clampPrimSize) |
370 | { | 370 | { |
371 | Vector3 scale = part.Shape.Scale; | 371 | foreach (SceneObjectPart part in sceneObject.Children.Values) |
372 | 372 | { | |
373 | if (scale.X > m_parentScene.m_maxNonphys) | 373 | Vector3 scale = part.Shape.Scale; |
374 | scale.X = m_parentScene.m_maxNonphys; | 374 | |
375 | if (scale.Y > m_parentScene.m_maxNonphys) | 375 | if (scale.X > m_parentScene.m_maxNonphys) |
376 | scale.Y = m_parentScene.m_maxNonphys; | 376 | scale.X = m_parentScene.m_maxNonphys; |
377 | if (scale.Z > m_parentScene.m_maxNonphys) | 377 | if (scale.Y > m_parentScene.m_maxNonphys) |
378 | scale.Z = m_parentScene.m_maxNonphys; | 378 | scale.Y = m_parentScene.m_maxNonphys; |
379 | 379 | if (scale.Z > m_parentScene.m_maxNonphys) | |
380 | part.Shape.Scale = scale; | 380 | scale.Z = m_parentScene.m_maxNonphys; |
381 | |||
382 | part.Shape.Scale = scale; | ||
383 | } | ||
381 | } | 384 | } |
382 | } | 385 | |
386 | sceneObject.AttachToScene(m_parentScene); | ||
387 | |||
388 | if (sendClientUpdates) | ||
389 | sceneObject.ScheduleGroupForFullUpdate(); | ||
390 | |||
391 | Entities.Add(sceneObject); | ||
392 | m_numPrim += sceneObject.Children.Count; | ||
383 | 393 | ||
384 | sceneObject.AttachToScene(m_parentScene); | 394 | if (attachToBackup) |
395 | sceneObject.AttachToBackup(); | ||
385 | 396 | ||
386 | if (sendClientUpdates) | 397 | if (OnObjectCreate != null) |
387 | sceneObject.ScheduleGroupForFullUpdate(); | 398 | OnObjectCreate(sceneObject); |
388 | 399 | ||
389 | Entities.Add(sceneObject); | 400 | lock (m_dictionary_lock) |
390 | m_numPrim += sceneObject.Children.Count; | ||
391 | |||
392 | if (attachToBackup) | ||
393 | sceneObject.AttachToBackup(); | ||
394 | |||
395 | if (OnObjectCreate != null) | ||
396 | OnObjectCreate(sceneObject); | ||
397 | |||
398 | lock (m_dictionary_lock) | ||
399 | { | ||
400 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; | ||
401 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; | ||
402 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
403 | { | 401 | { |
404 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; | 402 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; |
405 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | 403 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; |
404 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
405 | { | ||
406 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; | ||
407 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | ||
408 | } | ||
406 | } | 409 | } |
407 | } | 410 | } |
408 | } | 411 | } |
@@ -420,11 +423,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
420 | { | 423 | { |
421 | if (!resultOfObjectLinked) | 424 | if (!resultOfObjectLinked) |
422 | { | 425 | { |
423 | m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; | 426 | SceneObjectGroup sog = Entities[uuid] as SceneObjectGroup; |
424 | 427 | ||
425 | if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | 428 | lock (sog.Children) |
426 | { | 429 | { |
427 | RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); | 430 | m_numPrim -= sog.PrimCount; |
431 | |||
432 | if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | ||
433 | { | ||
434 | RemovePhysicalPrim(sog.PrimCount); | ||
435 | } | ||
428 | } | 436 | } |
429 | } | 437 | } |
430 | 438 | ||
@@ -1603,7 +1611,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1603 | { | 1611 | { |
1604 | if (part != null) | 1612 | if (part != null) |
1605 | { | 1613 | { |
1606 | if (part.ParentGroup.Children.Count != 1) // Skip single | 1614 | if (part.ParentGroup.PrimCount != 1) // Skip single |
1607 | { | 1615 | { |
1608 | if (part.LinkNum < 2) // Root | 1616 | if (part.LinkNum < 2) // Root |
1609 | rootParts.Add(part); | 1617 | rootParts.Add(part); |
@@ -1631,8 +1639,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1631 | // However, editing linked parts and unlinking may be different | 1639 | // However, editing linked parts and unlinking may be different |
1632 | // | 1640 | // |
1633 | SceneObjectGroup group = root.ParentGroup; | 1641 | SceneObjectGroup group = root.ParentGroup; |
1634 | List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values); | 1642 | |
1635 | int numChildren = group.Children.Count; | 1643 | List<SceneObjectPart> newSet = null; |
1644 | int numChildren = -1; | ||
1645 | |||
1646 | lock (group.Children) | ||
1647 | { | ||
1648 | newSet = new List<SceneObjectPart>(group.Children.Values); | ||
1649 | numChildren = group.PrimCount; | ||
1650 | } | ||
1636 | 1651 | ||
1637 | // If there are prims left in a link set, but the root is | 1652 | // If there are prims left in a link set, but the root is |
1638 | // slated for unlink, we need to do this | 1653 | // slated for unlink, we need to do this |
@@ -1711,12 +1726,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1711 | { | 1726 | { |
1712 | if (ent is SceneObjectGroup) | 1727 | if (ent is SceneObjectGroup) |
1713 | { | 1728 | { |
1714 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children) | 1729 | SceneObjectGroup sog = ent as SceneObjectGroup; |
1730 | |||
1731 | lock (sog.Children) | ||
1715 | { | 1732 | { |
1716 | if (subent.Value.LocalId == localID) | 1733 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children) |
1717 | { | 1734 | { |
1718 | objid = subent.Key; | 1735 | if (subent.Value.LocalId == localID) |
1719 | obj = subent.Value; | 1736 | { |
1737 | objid = subent.Key; | ||
1738 | obj = subent.Value; | ||
1739 | } | ||
1720 | } | 1740 | } |
1721 | } | 1741 | } |
1722 | } | 1742 | } |
@@ -1781,7 +1801,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1781 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); | 1801 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); |
1782 | if (original != null) | 1802 | if (original != null) |
1783 | { | 1803 | { |
1784 | if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) | 1804 | if (m_parentScene.Permissions.CanDuplicateObject( |
1805 | original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) | ||
1785 | { | 1806 | { |
1786 | SceneObjectGroup copy = original.Copy(true); | 1807 | SceneObjectGroup copy = original.Copy(true); |
1787 | copy.AbsolutePosition = copy.AbsolutePosition + offset; | 1808 | copy.AbsolutePosition = copy.AbsolutePosition + offset; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 952d280..5ee8d73 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
213 | /// </summary> | 213 | /// </summary> |
214 | public int PrimCount | 214 | public int PrimCount |
215 | { | 215 | { |
216 | get { return m_parts.Count; } | 216 | get { lock (m_parts) { return m_parts.Count; } } |
217 | } | 217 | } |
218 | 218 | ||
219 | protected Quaternion m_rotation = Quaternion.Identity; | 219 | protected Quaternion m_rotation = Quaternion.Identity; |
@@ -237,6 +237,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
237 | 237 | ||
238 | /// <value> | 238 | /// <value> |
239 | /// The parts of this scene object group. You must lock this property before using it. | 239 | /// The parts of this scene object group. You must lock this property before using it. |
240 | /// If you want to know the number of children, consider using the PrimCount property instead | ||
240 | /// </value> | 241 | /// </value> |
241 | public Dictionary<UUID, SceneObjectPart> Children | 242 | public Dictionary<UUID, SceneObjectPart> Children |
242 | { | 243 | { |
@@ -298,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
298 | { | 299 | { |
299 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 300 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
300 | } | 301 | } |
302 | |||
301 | if (RootPart.GetStatusSandbox()) | 303 | if (RootPart.GetStatusSandbox()) |
302 | { | 304 | { |
303 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) | 305 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
@@ -308,6 +310,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
308 | return; | 310 | return; |
309 | } | 311 | } |
310 | } | 312 | } |
313 | |||
311 | lock (m_parts) | 314 | lock (m_parts) |
312 | { | 315 | { |
313 | foreach (SceneObjectPart part in m_parts.Values) | 316 | foreach (SceneObjectPart part in m_parts.Values) |
@@ -558,21 +561,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
558 | if (m_rootPart.LocalId == 0) | 561 | if (m_rootPart.LocalId == 0) |
559 | m_rootPart.LocalId = m_scene.AllocateLocalId(); | 562 | m_rootPart.LocalId = m_scene.AllocateLocalId(); |
560 | 563 | ||
561 | // No need to lock here since the object isn't yet in a scene | 564 | lock (m_parts) |
562 | foreach (SceneObjectPart part in m_parts.Values) | ||
563 | { | 565 | { |
564 | if (Object.ReferenceEquals(part, m_rootPart)) | 566 | foreach (SceneObjectPart part in m_parts.Values) |
565 | { | ||
566 | continue; | ||
567 | } | ||
568 | |||
569 | if (part.LocalId == 0) | ||
570 | { | 567 | { |
571 | part.LocalId = m_scene.AllocateLocalId(); | 568 | if (Object.ReferenceEquals(part, m_rootPart)) |
569 | { | ||
570 | continue; | ||
571 | } | ||
572 | |||
573 | if (part.LocalId == 0) | ||
574 | { | ||
575 | part.LocalId = m_scene.AllocateLocalId(); | ||
576 | } | ||
577 | |||
578 | part.ParentID = m_rootPart.LocalId; | ||
579 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | ||
572 | } | 580 | } |
573 | |||
574 | part.ParentID = m_rootPart.LocalId; | ||
575 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | ||
576 | } | 581 | } |
577 | 582 | ||
578 | ApplyPhysics(m_scene.m_physicalPrim); | 583 | ApplyPhysics(m_scene.m_physicalPrim); |
@@ -670,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
670 | minY = 256f; | 675 | minY = 256f; |
671 | minZ = 8192f; | 676 | minZ = 8192f; |
672 | 677 | ||
673 | lock(m_parts); | 678 | lock(m_parts) |
674 | { | 679 | { |
675 | foreach (SceneObjectPart part in m_parts.Values) | 680 | foreach (SceneObjectPart part in m_parts.Values) |
676 | { | 681 | { |
@@ -995,9 +1000,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
995 | m_rootPart.AttachedAvatar = agentID; | 1000 | m_rootPart.AttachedAvatar = agentID; |
996 | 1001 | ||
997 | //Anakin Lohner bug #3839 | 1002 | //Anakin Lohner bug #3839 |
998 | foreach (SceneObjectPart p in m_parts.Values) | 1003 | lock (m_parts) |
999 | { | 1004 | { |
1000 | p.AttachedAvatar = agentID; | 1005 | foreach (SceneObjectPart p in m_parts.Values) |
1006 | { | ||
1007 | p.AttachedAvatar = agentID; | ||
1008 | } | ||
1001 | } | 1009 | } |
1002 | 1010 | ||
1003 | if (m_rootPart.PhysActor != null) | 1011 | if (m_rootPart.PhysActor != null) |
@@ -1065,10 +1073,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1065 | 1073 | ||
1066 | AbsolutePosition = detachedpos; | 1074 | AbsolutePosition = detachedpos; |
1067 | m_rootPart.AttachedAvatar = UUID.Zero; | 1075 | m_rootPart.AttachedAvatar = UUID.Zero; |
1068 | //Anakin Lohner bug #3839 | 1076 | |
1069 | foreach (SceneObjectPart p in m_parts.Values) | 1077 | //Anakin Lohner bug #3839 |
1078 | lock (m_parts) | ||
1070 | { | 1079 | { |
1071 | p.AttachedAvatar = UUID.Zero; | 1080 | foreach (SceneObjectPart p in m_parts.Values) |
1081 | { | ||
1082 | p.AttachedAvatar = UUID.Zero; | ||
1083 | } | ||
1072 | } | 1084 | } |
1073 | 1085 | ||
1074 | m_rootPart.SetParentLocalId(0); | 1086 | m_rootPart.SetParentLocalId(0); |
@@ -1094,10 +1106,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1094 | } | 1106 | } |
1095 | 1107 | ||
1096 | m_rootPart.AttachedAvatar = UUID.Zero; | 1108 | m_rootPart.AttachedAvatar = UUID.Zero; |
1109 | |||
1097 | //Anakin Lohner bug #3839 | 1110 | //Anakin Lohner bug #3839 |
1098 | foreach (SceneObjectPart p in m_parts.Values) | 1111 | lock (m_parts) |
1099 | { | 1112 | { |
1100 | p.AttachedAvatar = UUID.Zero; | 1113 | foreach (SceneObjectPart p in m_parts.Values) |
1114 | { | ||
1115 | p.AttachedAvatar = UUID.Zero; | ||
1116 | } | ||
1101 | } | 1117 | } |
1102 | 1118 | ||
1103 | m_rootPart.SetParentLocalId(0); | 1119 | m_rootPart.SetParentLocalId(0); |
@@ -1160,9 +1176,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1160 | part.ParentID = 0; | 1176 | part.ParentID = 0; |
1161 | part.LinkNum = 0; | 1177 | part.LinkNum = 0; |
1162 | 1178 | ||
1163 | // No locking required since the SOG should not be in the scene yet - one can't change root parts after | 1179 | lock (m_parts) |
1164 | // the scene object has been attached to the scene | 1180 | m_parts.Add(m_rootPart.UUID, m_rootPart); |
1165 | m_parts.Add(m_rootPart.UUID, m_rootPart); | ||
1166 | } | 1181 | } |
1167 | 1182 | ||
1168 | /// <summary> | 1183 | /// <summary> |
@@ -1625,7 +1640,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1625 | } | 1640 | } |
1626 | 1641 | ||
1627 | /// <summary> | 1642 | /// <summary> |
1628 | /// | 1643 | /// Copy the given part as the root part of this scene object. |
1629 | /// </summary> | 1644 | /// </summary> |
1630 | /// <param name="part"></param> | 1645 | /// <param name="part"></param> |
1631 | /// <param name="cAgentID"></param> | 1646 | /// <param name="cAgentID"></param> |
@@ -1882,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1882 | /// <param name="cGroupID"></param> | 1897 | /// <param name="cGroupID"></param> |
1883 | public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) | 1898 | public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) |
1884 | { | 1899 | { |
1885 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 1900 | SceneObjectPart newPart = null; |
1886 | newPart.SetParent(this); | 1901 | |
1887 | |||
1888 | lock (m_parts) | 1902 | lock (m_parts) |
1889 | { | 1903 | { |
1904 | newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | ||
1905 | newPart.SetParent(this); | ||
1890 | m_parts.Add(newPart.UUID, newPart); | 1906 | m_parts.Add(newPart.UUID, newPart); |
1891 | } | 1907 | } |
1892 | 1908 | ||
@@ -1903,14 +1919,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1903 | /// </summary> | 1919 | /// </summary> |
1904 | public void ResetIDs() | 1920 | public void ResetIDs() |
1905 | { | 1921 | { |
1906 | // As this is only ever called for prims which are not currently part of the scene (and hence | 1922 | lock (m_parts) |
1907 | // not accessible by clients), there should be no need to lock | ||
1908 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); | ||
1909 | m_parts.Clear(); | ||
1910 | foreach (SceneObjectPart part in partsList) | ||
1911 | { | 1923 | { |
1912 | part.ResetIDs(part.LinkNum); // Don't change link nums | 1924 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); |
1913 | m_parts.Add(part.UUID, part); | 1925 | m_parts.Clear(); |
1926 | foreach (SceneObjectPart part in partsList) | ||
1927 | { | ||
1928 | part.ResetIDs(part.LinkNum); // Don't change link nums | ||
1929 | m_parts.Add(part.UUID, part); | ||
1930 | } | ||
1914 | } | 1931 | } |
1915 | } | 1932 | } |
1916 | 1933 | ||
@@ -2136,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2136 | public SceneObjectPart GetChildPart(UUID primID) | 2153 | public SceneObjectPart GetChildPart(UUID primID) |
2137 | { | 2154 | { |
2138 | SceneObjectPart childPart = null; | 2155 | SceneObjectPart childPart = null; |
2139 | if (m_parts.ContainsKey(primID)) | 2156 | |
2157 | lock (m_parts) | ||
2140 | { | 2158 | { |
2141 | childPart = m_parts[primID]; | 2159 | if (m_parts.ContainsKey(primID)) |
2160 | { | ||
2161 | childPart = m_parts[primID]; | ||
2162 | } | ||
2142 | } | 2163 | } |
2164 | |||
2143 | return childPart; | 2165 | return childPart; |
2144 | } | 2166 | } |
2145 | 2167 | ||
@@ -2174,9 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2174 | /// <returns></returns> | 2196 | /// <returns></returns> |
2175 | public bool HasChildPrim(UUID primID) | 2197 | public bool HasChildPrim(UUID primID) |
2176 | { | 2198 | { |
2177 | if (m_parts.ContainsKey(primID)) | 2199 | lock (m_parts) |
2178 | { | 2200 | { |
2179 | return true; | 2201 | if (m_parts.ContainsKey(primID)) |
2202 | return true; | ||
2180 | } | 2203 | } |
2181 | 2204 | ||
2182 | return false; | 2205 | return false; |
@@ -2370,17 +2393,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2370 | lock (m_parts) | 2393 | lock (m_parts) |
2371 | { | 2394 | { |
2372 | m_parts.Remove(linkPart.UUID); | 2395 | m_parts.Remove(linkPart.UUID); |
2373 | } | 2396 | |
2374 | 2397 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | |
2375 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | ||
2376 | RootPart.LinkNum = 0; | ||
2377 | else | ||
2378 | { | ||
2379 | foreach (SceneObjectPart p in m_parts.Values) | ||
2380 | { | 2398 | { |
2381 | if (p.LinkNum > linkPart.LinkNum) | 2399 | RootPart.LinkNum = 0; |
2382 | p.LinkNum--; | ||
2383 | } | 2400 | } |
2401 | else | ||
2402 | { | ||
2403 | foreach (SceneObjectPart p in m_parts.Values) | ||
2404 | { | ||
2405 | if (p.LinkNum > linkPart.LinkNum) | ||
2406 | p.LinkNum--; | ||
2407 | } | ||
2408 | } | ||
2384 | } | 2409 | } |
2385 | 2410 | ||
2386 | linkPart.ParentID = 0; | 2411 | linkPart.ParentID = 0; |
@@ -2762,9 +2787,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2762 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, | 2787 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, |
2763 | uint mask, byte addRemTF) | 2788 | uint mask, byte addRemTF) |
2764 | { | 2789 | { |
2765 | foreach (SceneObjectPart part in m_parts.Values) | 2790 | lock (m_parts) |
2766 | part.UpdatePermissions(AgentID, field, localID, mask, | 2791 | { |
2767 | addRemTF); | 2792 | foreach (SceneObjectPart part in m_parts.Values) |
2793 | part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); | ||
2794 | } | ||
2768 | 2795 | ||
2769 | HasGroupChanged = true; | 2796 | HasGroupChanged = true; |
2770 | } | 2797 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 84b7365..e08fa77 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -601,7 +601,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
601 | rootPart.Name = item.Name; | 601 | rootPart.Name = item.Name; |
602 | rootPart.Description = item.Description; | 602 | rootPart.Description = item.Description; |
603 | 603 | ||
604 | List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); | 604 | List<SceneObjectPart> partList = null; |
605 | |||
606 | lock (group.Children) | ||
607 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
605 | 608 | ||
606 | group.SetGroup(m_part.GroupID, null); | 609 | group.SetGroup(m_part.GroupID, null); |
607 | 610 | ||
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs index 56656fc..de1e01c 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs | |||
@@ -121,16 +121,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
121 | continue; | 121 | continue; |
122 | temp = (SceneObjectGroup) currObj; | 122 | temp = (SceneObjectGroup) currObj; |
123 | 123 | ||
124 | if (m_CMEntityHash.ContainsKey(temp.UUID)) | 124 | lock (temp.Children) |
125 | { | 125 | { |
126 | foreach (SceneObjectPart part in temp.Children.Values) | 126 | if (m_CMEntityHash.ContainsKey(temp.UUID)) |
127 | if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) | 127 | { |
128 | foreach (SceneObjectPart part in temp.Children.Values) | ||
129 | if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) | ||
130 | missingList.Add(part); | ||
131 | } | ||
132 | else //Entire group is missing from revision. (and is a new part in region) | ||
133 | { | ||
134 | foreach (SceneObjectPart part in temp.Children.Values) | ||
128 | missingList.Add(part); | 135 | missingList.Add(part); |
129 | } | 136 | } |
130 | else //Entire group is missing from revision. (and is a new part in region) | ||
131 | { | ||
132 | foreach (SceneObjectPart part in temp.Children.Values) | ||
133 | missingList.Add(part); | ||
134 | } | 137 | } |
135 | } | 138 | } |
136 | return missingList; | 139 | return missingList; |
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs index 0dc78c0..e5fcb54 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -167,9 +167,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
167 | public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) | 167 | public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) |
168 | { | 168 | { |
169 | // Deal with new parts not revisioned that have been deleted. | 169 | // Deal with new parts not revisioned that have been deleted. |
170 | foreach (SceneObjectPart part in group.Children.Values) | 170 | lock (group.Children) |
171 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | 171 | { |
172 | m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); | 172 | foreach (SceneObjectPart part in group.Children.Values) |
173 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
174 | m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); | ||
175 | } | ||
173 | } | 176 | } |
174 | 177 | ||
175 | /// <summary> | 178 | /// <summary> |
@@ -207,8 +210,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
207 | { | 210 | { |
208 | temp = SceneObjectSerializer.FromXml2Format(xml); | 211 | temp = SceneObjectSerializer.FromXml2Format(xml); |
209 | temp.SetScene(scene); | 212 | temp.SetScene(scene); |
210 | foreach (SceneObjectPart part in temp.Children.Values) | 213 | |
211 | part.RegionHandle = scene.RegionInfo.RegionHandle; | 214 | lock (temp.Children) |
215 | { | ||
216 | foreach (SceneObjectPart part in temp.Children.Values) | ||
217 | part.RegionHandle = scene.RegionInfo.RegionHandle; | ||
218 | } | ||
219 | |||
212 | ReplacementList.Add(temp.UUID, (EntityBase)temp); | 220 | ReplacementList.Add(temp.UUID, (EntityBase)temp); |
213 | } | 221 | } |
214 | catch (Exception e) | 222 | catch (Exception e) |
@@ -338,15 +346,20 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
338 | System.Collections.ArrayList auraList = new System.Collections.ArrayList(); | 346 | System.Collections.ArrayList auraList = new System.Collections.ArrayList(); |
339 | if (group == null) | 347 | if (group == null) |
340 | return null; | 348 | return null; |
341 | foreach (SceneObjectPart part in group.Children.Values) | 349 | |
350 | lock (group.Children) | ||
342 | { | 351 | { |
343 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | 352 | foreach (SceneObjectPart part in group.Children.Values) |
344 | { | 353 | { |
345 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); | 354 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) |
346 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); | 355 | { |
347 | auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); | 356 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); |
357 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); | ||
358 | auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); | ||
359 | } | ||
348 | } | 360 | } |
349 | } | 361 | } |
362 | |||
350 | return auraList; | 363 | return auraList; |
351 | } | 364 | } |
352 | 365 | ||
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs index 46fbd39..f75f40a 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs | |||
@@ -186,9 +186,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
186 | ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); | 186 | ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); |
187 | 187 | ||
188 | // Deal with new parts not revisioned that have been deleted. | 188 | // Deal with new parts not revisioned that have been deleted. |
189 | foreach (SceneObjectPart part in group.Children.Values) | 189 | lock (group.Children) |
190 | if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) | 190 | { |
191 | ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); | 191 | foreach (SceneObjectPart part in group.Children.Values) |
192 | if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
193 | ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); | ||
194 | } | ||
192 | } | 195 | } |
193 | 196 | ||
194 | public void SendMetaEntitiesToNewClient(IClientAPI client) | 197 | public void SendMetaEntitiesToNewClient(IClientAPI client) |
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs index ada6701..2730eee 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -132,30 +132,33 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
132 | // if group is not contained in scene's list | 132 | // if group is not contained in scene's list |
133 | if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) | 133 | if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) |
134 | { | 134 | { |
135 | foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) | 135 | lock (m_UnchangedEntity.Children) |
136 | { | 136 | { |
137 | // if scene list no longer contains this part, display translucent part and mark with red aura | 137 | foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) |
138 | if (!ContainsKey(sceneEntityList, part.UUID)) | ||
139 | { | 138 | { |
140 | // if already displaying a red aura over part, make sure its red | 139 | // if scene list no longer contains this part, display translucent part and mark with red aura |
141 | if (m_AuraEntities.ContainsKey(part.UUID)) | 140 | if (!ContainsKey(sceneEntityList, part.UUID)) |
142 | { | ||
143 | m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale); | ||
144 | } | ||
145 | else | ||
146 | { | 141 | { |
147 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | 142 | // if already displaying a red aura over part, make sure its red |
148 | part.GetWorldPosition(), | 143 | if (m_AuraEntities.ContainsKey(part.UUID)) |
149 | MetaEntity.TRANSLUCENT, | 144 | { |
150 | new Vector3(254,0,0), | 145 | m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale); |
151 | part.Scale | 146 | } |
152 | ); | 147 | else |
153 | m_AuraEntities.Add(part.UUID, auraGroup); | 148 | { |
149 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
150 | part.GetWorldPosition(), | ||
151 | MetaEntity.TRANSLUCENT, | ||
152 | new Vector3(254,0,0), | ||
153 | part.Scale | ||
154 | ); | ||
155 | m_AuraEntities.Add(part.UUID, auraGroup); | ||
156 | } | ||
157 | SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); | ||
158 | SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); | ||
154 | } | 159 | } |
155 | SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); | 160 | // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id |
156 | SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); | ||
157 | } | 161 | } |
158 | // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id | ||
159 | } | 162 | } |
160 | 163 | ||
161 | // a deleted part has no where to point a beam particle system, | 164 | // a deleted part has no where to point a beam particle system, |
@@ -180,8 +183,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
180 | /// </summary> | 183 | /// </summary> |
181 | public bool HasChildPrim(UUID uuid) | 184 | public bool HasChildPrim(UUID uuid) |
182 | { | 185 | { |
183 | if (m_UnchangedEntity.Children.ContainsKey(uuid)) | 186 | lock (m_UnchangedEntity.Children) |
184 | return true; | 187 | if (m_UnchangedEntity.Children.ContainsKey(uuid)) |
188 | return true; | ||
189 | |||
185 | return false; | 190 | return false; |
186 | } | 191 | } |
187 | 192 | ||
@@ -190,9 +195,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
190 | /// </summary> | 195 | /// </summary> |
191 | public bool HasChildPrim(uint localID) | 196 | public bool HasChildPrim(uint localID) |
192 | { | 197 | { |
193 | foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) | 198 | lock (m_UnchangedEntity.Children) |
194 | if (part.LocalId == localID) | 199 | { |
195 | return true; | 200 | foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) |
201 | if (part.LocalId == localID) | ||
202 | return true; | ||
203 | } | ||
204 | |||
196 | return false; | 205 | return false; |
197 | } | 206 | } |
198 | 207 | ||
@@ -228,37 +237,72 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
228 | // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user | 237 | // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user |
229 | // had originally saved. | 238 | // had originally saved. |
230 | // m_Entity will NOT necessarily be the same entity as the user had saved. | 239 | // m_Entity will NOT necessarily be the same entity as the user had saved. |
231 | foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) | 240 | lock (m_UnchangedEntity.Children) |
232 | { | 241 | { |
233 | //This is the part that we use to show changes. | 242 | foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) |
234 | metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); | ||
235 | if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) | ||
236 | { | 243 | { |
237 | sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; | 244 | //This is the part that we use to show changes. |
238 | differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); | 245 | metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); |
239 | if (differences != Diff.NONE) | 246 | if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) |
240 | metaEntityPart.Text = "CHANGE: " + differences.ToString(); | ||
241 | if (differences != 0) | ||
242 | { | 247 | { |
243 | // Root Part that has been modified | 248 | sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; |
244 | if ((differences&Diff.POSITION) > 0) | 249 | differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); |
250 | if (differences != Diff.NONE) | ||
251 | metaEntityPart.Text = "CHANGE: " + differences.ToString(); | ||
252 | if (differences != 0) | ||
253 | { | ||
254 | // Root Part that has been modified | ||
255 | if ((differences&Diff.POSITION) > 0) | ||
256 | { | ||
257 | // If the position of any part has changed, make sure the RootPart of the | ||
258 | // meta entity is pointing with a beam particle system | ||
259 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
260 | { | ||
261 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
262 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
263 | } | ||
264 | BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, | ||
265 | m_UnchangedEntity.RootPart.GetWorldPosition(), | ||
266 | MetaEntity.TRANSLUCENT, | ||
267 | sceneEntityPart, | ||
268 | new Vector3(0,0,254) | ||
269 | ); | ||
270 | m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); | ||
271 | } | ||
272 | |||
273 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
274 | { | ||
275 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
276 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
277 | } | ||
278 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
279 | UnchangedPart.GetWorldPosition(), | ||
280 | MetaEntity.TRANSLUCENT, | ||
281 | new Vector3(0,0,254), | ||
282 | UnchangedPart.Scale | ||
283 | ); | ||
284 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
285 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
286 | |||
287 | DiffersFromSceneGroup = true; | ||
288 | } | ||
289 | else // no differences between scene part and meta part | ||
245 | { | 290 | { |
246 | // If the position of any part has changed, make sure the RootPart of the | ||
247 | // meta entity is pointing with a beam particle system | ||
248 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | 291 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) |
249 | { | 292 | { |
250 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | 293 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); |
251 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | 294 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); |
252 | } | 295 | } |
253 | BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, | 296 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) |
254 | m_UnchangedEntity.RootPart.GetWorldPosition(), | 297 | { |
255 | MetaEntity.TRANSLUCENT, | 298 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); |
256 | sceneEntityPart, | 299 | m_AuraEntities.Remove(UnchangedPart.UUID); |
257 | new Vector3(0,0,254) | 300 | } |
258 | ); | 301 | SetPartTransparency(metaEntityPart, MetaEntity.NONE); |
259 | m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); | ||
260 | } | 302 | } |
261 | 303 | } | |
304 | else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. | ||
305 | { | ||
262 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | 306 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) |
263 | { | 307 | { |
264 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | 308 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); |
@@ -267,48 +311,17 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
267 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | 311 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, |
268 | UnchangedPart.GetWorldPosition(), | 312 | UnchangedPart.GetWorldPosition(), |
269 | MetaEntity.TRANSLUCENT, | 313 | MetaEntity.TRANSLUCENT, |
270 | new Vector3(0,0,254), | 314 | new Vector3(254,0,0), |
271 | UnchangedPart.Scale | 315 | UnchangedPart.Scale |
272 | ); | 316 | ); |
273 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | 317 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); |
274 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | 318 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); |
275 | 319 | ||
276 | DiffersFromSceneGroup = true; | 320 | DiffersFromSceneGroup = true; |
277 | } | 321 | } |
278 | else // no differences between scene part and meta part | ||
279 | { | ||
280 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
281 | { | ||
282 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
283 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
284 | } | ||
285 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
286 | { | ||
287 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
288 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
289 | } | ||
290 | SetPartTransparency(metaEntityPart, MetaEntity.NONE); | ||
291 | } | ||
292 | } | ||
293 | else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. | ||
294 | { | ||
295 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
296 | { | ||
297 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
298 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
299 | } | ||
300 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
301 | UnchangedPart.GetWorldPosition(), | ||
302 | MetaEntity.TRANSLUCENT, | ||
303 | new Vector3(254,0,0), | ||
304 | UnchangedPart.Scale | ||
305 | ); | ||
306 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
307 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
308 | |||
309 | DiffersFromSceneGroup = true; | ||
310 | } | 322 | } |
311 | } | 323 | } |
324 | |||
312 | return changed; | 325 | return changed; |
313 | } | 326 | } |
314 | 327 | ||
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs index 841ee00..796f437 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs | |||
@@ -150,15 +150,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
150 | { | 150 | { |
151 | //make new uuids | 151 | //make new uuids |
152 | Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>(); | 152 | Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>(); |
153 | foreach (SceneObjectPart part in m_Entity.Children.Values) | 153 | |
154 | lock (m_Entity.Children) | ||
154 | { | 155 | { |
155 | part.ResetIDs(part.LinkNum); | 156 | foreach (SceneObjectPart part in m_Entity.Children.Values) |
156 | parts.Add(part.UUID, part); | 157 | { |
158 | part.ResetIDs(part.LinkNum); | ||
159 | parts.Add(part.UUID, part); | ||
160 | } | ||
161 | |||
162 | //finalize | ||
163 | m_Entity.RootPart.PhysActor = null; | ||
164 | m_Entity.Children = parts; | ||
157 | } | 165 | } |
158 | |||
159 | //finalize | ||
160 | m_Entity.RootPart.PhysActor = null; | ||
161 | m_Entity.Children = parts; | ||
162 | } | 166 | } |
163 | 167 | ||
164 | #endregion Protected Methods | 168 | #endregion Protected Methods |
@@ -173,8 +177,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
173 | //This deletes the group without removing from any databases. | 177 | //This deletes the group without removing from any databases. |
174 | //This is important because we are not IN any database. | 178 | //This is important because we are not IN any database. |
175 | //m_Entity.FakeDeleteGroup(); | 179 | //m_Entity.FakeDeleteGroup(); |
176 | foreach (SceneObjectPart part in m_Entity.Children.Values) | 180 | lock (m_Entity.Children) |
177 | client.SendKillObject(m_Entity.RegionHandle, part.LocalId); | 181 | { |
182 | foreach (SceneObjectPart part in m_Entity.Children.Values) | ||
183 | client.SendKillObject(m_Entity.RegionHandle, part.LocalId); | ||
184 | } | ||
178 | } | 185 | } |
179 | 186 | ||
180 | /// <summary> | 187 | /// <summary> |
@@ -182,12 +189,15 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
182 | /// </summary> | 189 | /// </summary> |
183 | public virtual void HideFromAll() | 190 | public virtual void HideFromAll() |
184 | { | 191 | { |
185 | foreach (SceneObjectPart part in m_Entity.Children.Values) | 192 | lock (m_Entity.Children) |
186 | { | 193 | { |
187 | m_Entity.Scene.ForEachClient( | 194 | foreach (SceneObjectPart part in m_Entity.Children.Values) |
188 | delegate(IClientAPI controller) | 195 | { |
189 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } | 196 | m_Entity.Scene.ForEachClient( |
190 | ); | 197 | delegate(IClientAPI controller) |
198 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } | ||
199 | ); | ||
200 | } | ||
191 | } | 201 | } |
192 | } | 202 | } |
193 | 203 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 96cccb7..34171b0 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs | |||
@@ -185,14 +185,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
185 | get | 185 | get |
186 | { | 186 | { |
187 | SceneObjectPart my = GetSOP(); | 187 | SceneObjectPart my = GetSOP(); |
188 | int total = my.ParentGroup.Children.Count; | 188 | IObject[] rets = null; |
189 | 189 | ||
190 | IObject[] rets = new IObject[total]; | 190 | lock (my.ParentGroup.Children) |
191 | |||
192 | int i = 0; | ||
193 | foreach (KeyValuePair<UUID, SceneObjectPart> pair in my.ParentGroup.Children) | ||
194 | { | 191 | { |
195 | rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security); | 192 | int total = my.ParentGroup.Children.Count; |
193 | |||
194 | rets = new IObject[total]; | ||
195 | |||
196 | int i = 0; | ||
197 | foreach (KeyValuePair<UUID, SceneObjectPart> pair in my.ParentGroup.Children) | ||
198 | { | ||
199 | rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security); | ||
200 | } | ||
196 | } | 201 | } |
197 | 202 | ||
198 | return rets; | 203 | return rets; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 21604d0..af42dae 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -235,7 +235,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
235 | { | 235 | { |
236 | case ScriptBaseClass.LINK_SET: | 236 | case ScriptBaseClass.LINK_SET: |
237 | if (m_host.ParentGroup != null) | 237 | if (m_host.ParentGroup != null) |
238 | return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | 238 | { |
239 | lock (m_host.ParentGroup.Children) | ||
240 | return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
241 | } | ||
239 | return ret; | 242 | return ret; |
240 | 243 | ||
241 | case ScriptBaseClass.LINK_ROOT: | 244 | case ScriptBaseClass.LINK_ROOT: |
@@ -250,7 +253,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
250 | case ScriptBaseClass.LINK_ALL_OTHERS: | 253 | case ScriptBaseClass.LINK_ALL_OTHERS: |
251 | if (m_host.ParentGroup == null) | 254 | if (m_host.ParentGroup == null) |
252 | return new List<SceneObjectPart>(); | 255 | return new List<SceneObjectPart>(); |
253 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | 256 | |
257 | lock (m_host.ParentGroup.Children) | ||
258 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
259 | |||
254 | if (ret.Contains(m_host)) | 260 | if (ret.Contains(m_host)) |
255 | ret.Remove(m_host); | 261 | ret.Remove(m_host); |
256 | return ret; | 262 | return ret; |
@@ -258,7 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
258 | case ScriptBaseClass.LINK_ALL_CHILDREN: | 264 | case ScriptBaseClass.LINK_ALL_CHILDREN: |
259 | if (m_host.ParentGroup == null) | 265 | if (m_host.ParentGroup == null) |
260 | return new List<SceneObjectPart>(); | 266 | return new List<SceneObjectPart>(); |
261 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | 267 | |
268 | lock (m_host.ParentGroup.Children) | ||
269 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
270 | |||
262 | if (ret.Contains(m_host.ParentGroup.RootPart)) | 271 | if (ret.Contains(m_host.ParentGroup.RootPart)) |
263 | ret.Remove(m_host.ParentGroup.RootPart); | 272 | ret.Remove(m_host.ParentGroup.RootPart); |
264 | return ret; | 273 | return ret; |
@@ -1178,12 +1187,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1178 | if (group == null) | 1187 | if (group == null) |
1179 | return; | 1188 | return; |
1180 | bool allow = true; | 1189 | bool allow = true; |
1181 | foreach (SceneObjectPart part in group.Children.Values) | 1190 | |
1191 | lock (group.Children) | ||
1182 | { | 1192 | { |
1183 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) | 1193 | foreach (SceneObjectPart part in group.Children.Values) |
1184 | { | 1194 | { |
1185 | allow = false; | 1195 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) |
1186 | break; | 1196 | { |
1197 | allow = false; | ||
1198 | break; | ||
1199 | } | ||
1187 | } | 1200 | } |
1188 | } | 1201 | } |
1189 | 1202 | ||
@@ -3492,7 +3505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3492 | { | 3505 | { |
3493 | m_host.AddScriptLPS(1); | 3506 | m_host.AddScriptLPS(1); |
3494 | 3507 | ||
3495 | if (m_host.ParentGroup.Children.Count > 1) | 3508 | if (m_host.ParentGroup.PrimCount > 1) |
3496 | { | 3509 | { |
3497 | return m_host.LinkNum; | 3510 | return m_host.LinkNum; |
3498 | } | 3511 | } |
@@ -3604,15 +3617,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3604 | case ScriptBaseClass.LINK_ALL_OTHERS: | 3617 | case ScriptBaseClass.LINK_ALL_OTHERS: |
3605 | case ScriptBaseClass.LINK_ALL_CHILDREN: | 3618 | case ScriptBaseClass.LINK_ALL_CHILDREN: |
3606 | case ScriptBaseClass.LINK_THIS: | 3619 | case ScriptBaseClass.LINK_THIS: |
3607 | foreach (SceneObjectPart part in parentPrim.Children.Values) | 3620 | lock (parentPrim.Children) |
3608 | { | 3621 | { |
3609 | if (part.UUID != m_host.UUID) | 3622 | foreach (SceneObjectPart part in parentPrim.Children.Values) |
3610 | { | 3623 | { |
3611 | childPrim = part; | 3624 | if (part.UUID != m_host.UUID) |
3612 | break; | 3625 | { |
3626 | childPrim = part; | ||
3627 | break; | ||
3628 | } | ||
3613 | } | 3629 | } |
3630 | break; | ||
3614 | } | 3631 | } |
3615 | break; | ||
3616 | default: | 3632 | default: |
3617 | childPrim = parentPrim.GetLinkNumPart(linknum); | 3633 | childPrim = parentPrim.GetLinkNumPart(linknum); |
3618 | if (childPrim.UUID == m_host.UUID) | 3634 | if (childPrim.UUID == m_host.UUID) |
@@ -3623,27 +3639,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3623 | if (linknum == ScriptBaseClass.LINK_ROOT) | 3639 | if (linknum == ScriptBaseClass.LINK_ROOT) |
3624 | { | 3640 | { |
3625 | // Restructuring Multiple Prims. | 3641 | // Restructuring Multiple Prims. |
3626 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); | 3642 | lock (parentPrim.Children) |
3627 | parts.Remove(parentPrim.RootPart); | ||
3628 | foreach (SceneObjectPart part in parts) | ||
3629 | { | ||
3630 | parentPrim.DelinkFromGroup(part.LocalId, true); | ||
3631 | } | ||
3632 | parentPrim.HasGroupChanged = true; | ||
3633 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3634 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||
3635 | |||
3636 | if (parts.Count > 0) | ||
3637 | { | 3643 | { |
3638 | SceneObjectPart newRoot = parts[0]; | 3644 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); |
3639 | parts.Remove(newRoot); | 3645 | parts.Remove(parentPrim.RootPart); |
3640 | foreach (SceneObjectPart part in parts) | 3646 | foreach (SceneObjectPart part in parts) |
3641 | { | 3647 | { |
3642 | part.UpdateFlag = 0; | 3648 | parentPrim.DelinkFromGroup(part.LocalId, true); |
3643 | newRoot.ParentGroup.LinkToGroup(part.ParentGroup); | 3649 | } |
3650 | parentPrim.HasGroupChanged = true; | ||
3651 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3652 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||
3653 | |||
3654 | if (parts.Count > 0) | ||
3655 | { | ||
3656 | SceneObjectPart newRoot = parts[0]; | ||
3657 | parts.Remove(newRoot); | ||
3658 | foreach (SceneObjectPart part in parts) | ||
3659 | { | ||
3660 | part.UpdateFlag = 0; | ||
3661 | newRoot.ParentGroup.LinkToGroup(part.ParentGroup); | ||
3662 | } | ||
3663 | newRoot.ParentGroup.HasGroupChanged = true; | ||
3664 | newRoot.ParentGroup.ScheduleGroupForFullUpdate(); | ||
3644 | } | 3665 | } |
3645 | newRoot.ParentGroup.HasGroupChanged = true; | ||
3646 | newRoot.ParentGroup.ScheduleGroupForFullUpdate(); | ||
3647 | } | 3666 | } |
3648 | } | 3667 | } |
3649 | else | 3668 | else |
@@ -3665,16 +3684,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3665 | if (parentPrim.RootPart.AttachmentPoint != 0) | 3684 | if (parentPrim.RootPart.AttachmentPoint != 0) |
3666 | return; // Fail silently if attached | 3685 | return; // Fail silently if attached |
3667 | 3686 | ||
3668 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); | 3687 | lock (parentPrim.Children) |
3669 | parts.Remove(parentPrim.RootPart); | ||
3670 | |||
3671 | foreach (SceneObjectPart part in parts) | ||
3672 | { | 3688 | { |
3673 | parentPrim.DelinkFromGroup(part.LocalId, true); | 3689 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); |
3674 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | 3690 | parts.Remove(parentPrim.RootPart); |
3691 | |||
3692 | foreach (SceneObjectPart part in parts) | ||
3693 | { | ||
3694 | parentPrim.DelinkFromGroup(part.LocalId, true); | ||
3695 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||
3696 | } | ||
3697 | parentPrim.HasGroupChanged = true; | ||
3698 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3675 | } | 3699 | } |
3676 | parentPrim.HasGroupChanged = true; | ||
3677 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3678 | } | 3700 | } |
3679 | 3701 | ||
3680 | public LSL_String llGetLinkKey(int linknum) | 3702 | public LSL_String llGetLinkKey(int linknum) |
@@ -4200,7 +4222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4200 | { | 4222 | { |
4201 | partItemID = item.ItemID; | 4223 | partItemID = item.ItemID; |
4202 | int linkNumber = m_host.LinkNum; | 4224 | int linkNumber = m_host.LinkNum; |
4203 | if (m_host.ParentGroup.Children.Count == 1) | 4225 | if (m_host.ParentGroup.PrimCount == 1) |
4204 | linkNumber = 0; | 4226 | linkNumber = 0; |
4205 | 4227 | ||
4206 | object[] resobj = new object[] | 4228 | object[] resobj = new object[] |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 4855d64..41501f2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs | |||
@@ -209,12 +209,15 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
209 | else | 209 | else |
210 | Type = 0x02; // Passive | 210 | Type = 0x02; // Passive |
211 | 211 | ||
212 | foreach (SceneObjectPart p in part.ParentGroup.Children.Values) | 212 | lock (part.ParentGroup.Children) |
213 | { | 213 | { |
214 | if (p.Inventory.ContainsScripts()) | 214 | foreach (SceneObjectPart p in part.ParentGroup.Children.Values) |
215 | { | 215 | { |
216 | Type |= 0x08; // Scripted | 216 | if (p.Inventory.ContainsScripts()) |
217 | break; | 217 | { |
218 | Type |= 0x08; // Scripted | ||
219 | break; | ||
220 | } | ||
218 | } | 221 | } |
219 | } | 222 | } |
220 | 223 | ||