diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 187 |
1 files changed, 92 insertions, 95 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e599e90..92ce411 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -271,38 +271,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
271 | { | 271 | { |
272 | if (!m_parentScene.CombineRegions) | 272 | if (!m_parentScene.CombineRegions) |
273 | { | 273 | { |
274 | // temporary checks to remove after varsize suport | ||
275 | float regionSizeX = m_parentScene.RegionInfo.RegionSizeX; | ||
276 | if (regionSizeX == 0) | ||
277 | regionSizeX = Constants.RegionSize; | ||
278 | float regionSizeY = m_parentScene.RegionInfo.RegionSizeY; | ||
279 | if (regionSizeY == 0) | ||
280 | regionSizeY = Constants.RegionSize; | ||
281 | |||
274 | // KF: Check for out-of-region, move inside and make static. | 282 | // KF: Check for out-of-region, move inside and make static. |
275 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | 283 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, |
276 | sceneObject.RootPart.GroupPosition.Y, | 284 | sceneObject.RootPart.GroupPosition.Y, |
277 | sceneObject.RootPart.GroupPosition.Z); | 285 | sceneObject.RootPart.GroupPosition.Z); |
278 | if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || | 286 | if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || |
279 | npos.X > Constants.RegionSize || | 287 | npos.X > regionSizeX || |
280 | npos.Y > Constants.RegionSize)) | 288 | npos.Y > regionSizeY)) |
281 | { | 289 | { |
282 | if (npos.X < 0.0) npos.X = 1.0f; | 290 | if (npos.X < 0.0) npos.X = 1.0f; |
283 | if (npos.Y < 0.0) npos.Y = 1.0f; | 291 | if (npos.Y < 0.0) npos.Y = 1.0f; |
284 | if (npos.Z < 0.0) npos.Z = 0.0f; | 292 | if (npos.Z < 0.0) npos.Z = 0.0f; |
285 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; | 293 | if (npos.X > regionSizeX) npos.X = regionSizeX - 1.0f; |
286 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; | 294 | if (npos.Y > regionSizeY) npos.Y = regionSizeY - 1.0f; |
287 | 295 | ||
296 | SceneObjectPart rootpart = sceneObject.RootPart; | ||
297 | rootpart.GroupPosition = npos; | ||
298 | |||
288 | foreach (SceneObjectPart part in sceneObject.Parts) | 299 | foreach (SceneObjectPart part in sceneObject.Parts) |
289 | { | 300 | { |
301 | if (part == rootpart) | ||
302 | continue; | ||
290 | part.GroupPosition = npos; | 303 | part.GroupPosition = npos; |
291 | } | 304 | } |
292 | sceneObject.RootPart.Velocity = Vector3.Zero; | 305 | rootpart.Velocity = Vector3.Zero; |
293 | sceneObject.RootPart.AngularVelocity = Vector3.Zero; | 306 | rootpart.AngularVelocity = Vector3.Zero; |
294 | sceneObject.RootPart.Acceleration = Vector3.Zero; | 307 | rootpart.Acceleration = Vector3.Zero; |
295 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
296 | } | 308 | } |
297 | } | 309 | } |
298 | 310 | ||
311 | bool ret = AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); | ||
312 | |||
299 | if (attachToBackup && (!alreadyPersisted)) | 313 | if (attachToBackup && (!alreadyPersisted)) |
300 | { | 314 | { |
301 | sceneObject.ForceInventoryPersistence(); | 315 | sceneObject.ForceInventoryPersistence(); |
302 | sceneObject.HasGroupChanged = true; | 316 | sceneObject.HasGroupChanged = true; |
303 | } | 317 | } |
304 | 318 | ||
305 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); | 319 | return ret; |
306 | } | 320 | } |
307 | 321 | ||
308 | /// <summary> | 322 | /// <summary> |
@@ -319,12 +333,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
319 | /// </returns> | 333 | /// </returns> |
320 | protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) | 334 | protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) |
321 | { | 335 | { |
322 | // Ensure that we persist this new scene object if it's not an | 336 | |
337 | bool ret = AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); | ||
338 | |||
339 | // Ensure that we persist this new scene object if it's not an | ||
323 | // attachment | 340 | // attachment |
341 | |||
324 | if (attachToBackup) | 342 | if (attachToBackup) |
325 | sceneObject.HasGroupChanged = true; | 343 | sceneObject.HasGroupChanged = true; |
326 | 344 | ||
327 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); | 345 | return ret; |
328 | } | 346 | } |
329 | 347 | ||
330 | /// <summary> | 348 | /// <summary> |
@@ -421,9 +439,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
421 | { | 439 | { |
422 | Vector3 scale = part.Shape.Scale; | 440 | Vector3 scale = part.Shape.Scale; |
423 | 441 | ||
424 | scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X)); | 442 | scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); |
425 | scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y)); | 443 | scale.Y = Util.Clamp(scale.Y, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); |
426 | scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z)); | 444 | scale.Z = Util.Clamp(scale.Z, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); |
427 | 445 | ||
428 | part.Shape.Scale = scale; | 446 | part.Shape.Scale = scale; |
429 | } | 447 | } |
@@ -432,36 +450,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
432 | 450 | ||
433 | sceneObject.AttachToScene(m_parentScene); | 451 | sceneObject.AttachToScene(m_parentScene); |
434 | 452 | ||
435 | if (sendClientUpdates) | ||
436 | sceneObject.ScheduleGroupForFullUpdate(); | ||
437 | |||
438 | Entities.Add(sceneObject); | 453 | Entities.Add(sceneObject); |
439 | 454 | ||
440 | if (attachToBackup) | ||
441 | sceneObject.AttachToBackup(); | ||
442 | |||
443 | lock (SceneObjectGroupsByFullID) | 455 | lock (SceneObjectGroupsByFullID) |
444 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; | 456 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; |
445 | 457 | ||
446 | lock (SceneObjectGroupsByFullPartID) | 458 | foreach (SceneObjectPart part in parts) |
447 | { | 459 | { |
448 | foreach (SceneObjectPart part in parts) | 460 | lock (SceneObjectGroupsByFullPartID) |
449 | SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; | 461 | SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; |
450 | } | ||
451 | 462 | ||
452 | lock (SceneObjectGroupsByLocalPartID) | 463 | lock (SceneObjectGroupsByLocalPartID) |
453 | { | ||
454 | // m_log.DebugFormat( | ||
455 | // "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}", | ||
456 | // sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName); | ||
457 | |||
458 | foreach (SceneObjectPart part in parts) | ||
459 | SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; | 464 | SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; |
460 | } | 465 | } |
461 | 466 | ||
467 | if (sendClientUpdates) | ||
468 | sceneObject.ScheduleGroupForFullUpdate(); | ||
469 | |||
470 | if (attachToBackup) | ||
471 | sceneObject.AttachToBackup(); | ||
472 | |||
462 | return true; | 473 | return true; |
463 | } | 474 | } |
464 | 475 | ||
476 | public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp) | ||
477 | { | ||
478 | // no tests, caller has responsability... | ||
479 | lock (SceneObjectGroupsByFullPartID) | ||
480 | SceneObjectGroupsByFullPartID[part.UUID] = grp; | ||
481 | |||
482 | lock (SceneObjectGroupsByLocalPartID) | ||
483 | SceneObjectGroupsByLocalPartID[part.LocalId] = grp; | ||
484 | } | ||
485 | |||
465 | /// <summary> | 486 | /// <summary> |
466 | /// Delete an object from the scene | 487 | /// Delete an object from the scene |
467 | /// </summary> | 488 | /// </summary> |
@@ -488,25 +509,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
488 | if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | 509 | if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) |
489 | RemovePhysicalPrim(grp.PrimCount); | 510 | RemovePhysicalPrim(grp.PrimCount); |
490 | } | 511 | } |
491 | 512 | ||
513 | bool ret = Entities.Remove(uuid); | ||
514 | |||
492 | lock (SceneObjectGroupsByFullID) | 515 | lock (SceneObjectGroupsByFullID) |
493 | SceneObjectGroupsByFullID.Remove(grp.UUID); | 516 | SceneObjectGroupsByFullID.Remove(grp.UUID); |
494 | 517 | ||
495 | lock (SceneObjectGroupsByFullPartID) | 518 | SceneObjectPart[] parts = grp.Parts; |
519 | for (int i = 0; i < parts.Length; i++) | ||
496 | { | 520 | { |
497 | SceneObjectPart[] parts = grp.Parts; | 521 | lock (SceneObjectGroupsByFullPartID) |
498 | for (int i = 0; i < parts.Length; i++) | ||
499 | SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); | 522 | SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); |
500 | } | ||
501 | 523 | ||
502 | lock (SceneObjectGroupsByLocalPartID) | 524 | lock (SceneObjectGroupsByLocalPartID) |
503 | { | ||
504 | SceneObjectPart[] parts = grp.Parts; | ||
505 | for (int i = 0; i < parts.Length; i++) | ||
506 | SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); | 525 | SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); |
507 | } | 526 | } |
508 | 527 | ||
509 | return Entities.Remove(uuid); | 528 | return ret; |
510 | } | 529 | } |
511 | 530 | ||
512 | /// <summary> | 531 | /// <summary> |
@@ -631,40 +650,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
631 | protected internal ScenePresence CreateAndAddChildScenePresence( | 650 | protected internal ScenePresence CreateAndAddChildScenePresence( |
632 | IClientAPI client, AvatarAppearance appearance, PresenceType type) | 651 | IClientAPI client, AvatarAppearance appearance, PresenceType type) |
633 | { | 652 | { |
634 | ScenePresence newAvatar = null; | ||
635 | |||
636 | // ScenePresence always defaults to child agent | 653 | // ScenePresence always defaults to child agent |
637 | newAvatar = new ScenePresence(client, m_parentScene, appearance, type); | 654 | ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type); |
638 | |||
639 | AddScenePresence(newAvatar); | ||
640 | |||
641 | return newAvatar; | ||
642 | } | ||
643 | |||
644 | /// <summary> | ||
645 | /// Add a presence to the scene | ||
646 | /// </summary> | ||
647 | /// <param name="presence"></param> | ||
648 | protected internal void AddScenePresence(ScenePresence presence) | ||
649 | { | ||
650 | // Always a child when added to the scene | ||
651 | bool child = presence.IsChildAgent; | ||
652 | |||
653 | if (child) | ||
654 | { | ||
655 | m_numChildAgents++; | ||
656 | } | ||
657 | else | ||
658 | { | ||
659 | m_numRootAgents++; | ||
660 | presence.AddToPhysicalScene(false); | ||
661 | } | ||
662 | 655 | ||
663 | Entities[presence.UUID] = presence; | 656 | Entities[presence.UUID] = presence; |
664 | 657 | ||
665 | m_scenePresencesLock.EnterWriteLock(); | 658 | m_scenePresencesLock.EnterWriteLock(); |
666 | try | 659 | try |
667 | { | 660 | { |
661 | m_numChildAgents++; | ||
662 | |||
668 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 663 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
669 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 664 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
670 | 665 | ||
@@ -675,7 +670,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
675 | } | 670 | } |
676 | else | 671 | else |
677 | { | 672 | { |
678 | // Remember the old presene reference from the dictionary | 673 | // Remember the old presence reference from the dictionary |
679 | ScenePresence oldref = newmap[presence.UUID]; | 674 | ScenePresence oldref = newmap[presence.UUID]; |
680 | // Replace the presence reference in the dictionary with the new value | 675 | // Replace the presence reference in the dictionary with the new value |
681 | newmap[presence.UUID] = presence; | 676 | newmap[presence.UUID] = presence; |
@@ -691,6 +686,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
691 | { | 686 | { |
692 | m_scenePresencesLock.ExitWriteLock(); | 687 | m_scenePresencesLock.ExitWriteLock(); |
693 | } | 688 | } |
689 | |||
690 | return presence; | ||
694 | } | 691 | } |
695 | 692 | ||
696 | /// <summary> | 693 | /// <summary> |
@@ -949,7 +946,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
949 | m_log.WarnFormat( | 946 | m_log.WarnFormat( |
950 | "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.", | 947 | "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.", |
951 | sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); | 948 | sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); |
952 | 949 | m_log.WarnFormat("stack: {0}", Environment.StackTrace); | |
953 | SceneObjectGroupsByLocalPartID.Remove(localID); | 950 | SceneObjectGroupsByLocalPartID.Remove(localID); |
954 | } | 951 | } |
955 | } | 952 | } |
@@ -1569,6 +1566,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1569 | // VolumeDetect can't be set via UI and will always be off when a change is made there | 1566 | // VolumeDetect can't be set via UI and will always be off when a change is made there |
1570 | // now only change volume dtc if phantom off | 1567 | // now only change volume dtc if phantom off |
1571 | 1568 | ||
1569 | bool wantedPhys = UsePhysics; | ||
1572 | if (PhysData.PhysShapeType == PhysShapeType.invalid) // check for extraPhysics data | 1570 | if (PhysData.PhysShapeType == PhysShapeType.invalid) // check for extraPhysics data |
1573 | { | 1571 | { |
1574 | bool vdtc; | 1572 | bool vdtc; |
@@ -1585,10 +1583,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1585 | if (part != null) | 1583 | if (part != null) |
1586 | { | 1584 | { |
1587 | part.UpdateExtraPhysics(PhysData); | 1585 | part.UpdateExtraPhysics(PhysData); |
1588 | if (part.UpdatePhysRequired) | 1586 | if (part.UpdatePhysRequired && remoteClient != null) |
1589 | remoteClient.SendPartPhysicsProprieties(part); | 1587 | remoteClient.SendPartPhysicsProprieties(part); |
1590 | } | 1588 | } |
1591 | } | 1589 | } |
1590 | |||
1591 | if (wantedPhys != group.UsesPhysics && remoteClient != null) | ||
1592 | { | ||
1593 | remoteClient.SendAlertMessage("Object physics canceled because exceeds the limit of " + | ||
1594 | m_parentScene.m_linksetPhysCapacity + " physical prims with shape type not set to None"); | ||
1595 | group.RootPart.ScheduleFullUpdate(); | ||
1596 | } | ||
1592 | } | 1597 | } |
1593 | } | 1598 | } |
1594 | } | 1599 | } |
@@ -1818,7 +1823,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1818 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); | 1823 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); |
1819 | 1824 | ||
1820 | // We do this in reverse to get the link order of the prims correct | 1825 | // We do this in reverse to get the link order of the prims correct |
1821 | for (int i = 0 ; i < children.Count ; i++) | 1826 | for (int i = 0; i < children.Count; i++) |
1822 | { | 1827 | { |
1823 | SceneObjectGroup child = children[i].ParentGroup; | 1828 | SceneObjectGroup child = children[i].ParentGroup; |
1824 | 1829 | ||
@@ -1829,7 +1834,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1829 | // Make sure no child prim is set for sale | 1834 | // Make sure no child prim is set for sale |
1830 | // So that, on delink, no prims are unwittingly | 1835 | // So that, on delink, no prims are unwittingly |
1831 | // left for sale and sold off | 1836 | // left for sale and sold off |
1832 | 1837 | ||
1833 | if (child != null) | 1838 | if (child != null) |
1834 | { | 1839 | { |
1835 | child.RootPart.ObjectSaleType = 0; | 1840 | child.RootPart.ObjectSaleType = 0; |
@@ -1864,12 +1869,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1864 | } | 1869 | } |
1865 | finally | 1870 | finally |
1866 | { | 1871 | { |
1872 | /* | ||
1867 | lock (SceneObjectGroupsByLocalPartID) | 1873 | lock (SceneObjectGroupsByLocalPartID) |
1868 | { | 1874 | { |
1869 | foreach (SceneObjectPart part in parentGroup.Parts) | 1875 | foreach (SceneObjectPart part in parentGroup.Parts) |
1870 | SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup; | 1876 | SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup; |
1871 | } | 1877 | } |
1872 | 1878 | */ | |
1873 | parentGroup.AdjustChildPrimPermissions(); | 1879 | parentGroup.AdjustChildPrimPermissions(); |
1874 | parentGroup.HasGroupChanged = true; | 1880 | parentGroup.HasGroupChanged = true; |
1875 | parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true); | 1881 | parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true); |
@@ -1952,20 +1958,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1952 | // slated for unlink, we need to do this | 1958 | // slated for unlink, we need to do this |
1953 | // Unlink the remaining set | 1959 | // Unlink the remaining set |
1954 | // | 1960 | // |
1955 | bool sendEventsToRemainder = true; | 1961 | bool sendEventsToRemainder = false; |
1956 | if (numChildren > 1) | 1962 | if (numChildren == 2) // only one child prim no re-link needed |
1957 | sendEventsToRemainder = false; | 1963 | sendEventsToRemainder = true; |
1958 | 1964 | ||
1959 | foreach (SceneObjectPart p in newSet) | 1965 | foreach (SceneObjectPart p in newSet) |
1960 | { | 1966 | { |
1961 | if (p != group.RootPart) | 1967 | if (p != group.RootPart) |
1962 | { | 1968 | { |
1963 | group.DelinkFromGroup(p, sendEventsToRemainder); | 1969 | group.DelinkFromGroup(p, sendEventsToRemainder); |
1964 | if (numChildren > 2) | 1970 | if (sendEventsToRemainder) // finish single child prim now |
1965 | { | 1971 | { |
1966 | } | ||
1967 | else | ||
1968 | { | ||
1969 | p.ParentGroup.HasGroupChanged = true; | 1972 | p.ParentGroup.HasGroupChanged = true; |
1970 | p.ParentGroup.ScheduleGroupForFullUpdate(); | 1973 | p.ParentGroup.ScheduleGroupForFullUpdate(); |
1971 | } | 1974 | } |
@@ -1998,8 +2001,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1998 | newChild.ClearUpdateSchedule(); | 2001 | newChild.ClearUpdateSchedule(); |
1999 | 2002 | ||
2000 | LinkObjects(newRoot, newSet); | 2003 | LinkObjects(newRoot, newSet); |
2001 | if (!affectedGroups.Contains(newRoot.ParentGroup)) | 2004 | // if (!affectedGroups.Contains(newRoot.ParentGroup)) |
2002 | affectedGroups.Add(newRoot.ParentGroup); | 2005 | // affectedGroups.Add(newRoot.ParentGroup); |
2003 | } | 2006 | } |
2004 | } | 2007 | } |
2005 | 2008 | ||
@@ -2126,21 +2129,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2126 | lock (SceneObjectGroupsByFullID) | 2129 | lock (SceneObjectGroupsByFullID) |
2127 | SceneObjectGroupsByFullID[copy.UUID] = copy; | 2130 | SceneObjectGroupsByFullID[copy.UUID] = copy; |
2128 | 2131 | ||
2129 | SceneObjectPart[] children = copy.Parts; | 2132 | SceneObjectPart[] parts = copy.Parts; |
2130 | 2133 | foreach (SceneObjectPart part in parts) | |
2131 | lock (SceneObjectGroupsByFullPartID) | ||
2132 | { | 2134 | { |
2133 | SceneObjectGroupsByFullPartID[copy.UUID] = copy; | 2135 | lock (SceneObjectGroupsByFullPartID) |
2134 | foreach (SceneObjectPart part in children) | ||
2135 | SceneObjectGroupsByFullPartID[part.UUID] = copy; | 2136 | SceneObjectGroupsByFullPartID[part.UUID] = copy; |
2136 | } | 2137 | lock (SceneObjectGroupsByLocalPartID) |
2137 | |||
2138 | lock (SceneObjectGroupsByLocalPartID) | ||
2139 | { | ||
2140 | SceneObjectGroupsByLocalPartID[copy.LocalId] = copy; | ||
2141 | foreach (SceneObjectPart part in children) | ||
2142 | SceneObjectGroupsByLocalPartID[part.LocalId] = copy; | 2138 | SceneObjectGroupsByLocalPartID[part.LocalId] = copy; |
2143 | } | 2139 | } |
2140 | |||
2144 | // PROBABLE END OF FIXME | 2141 | // PROBABLE END OF FIXME |
2145 | 2142 | ||
2146 | // Since we copy from a source group that is in selected | 2143 | // Since we copy from a source group that is in selected |