diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 157 |
1 files changed, 121 insertions, 36 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9f38a99..94ec534 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -43,6 +43,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
43 | 43 | ||
44 | public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone); | 44 | public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone); |
45 | 45 | ||
46 | public delegate void AttachToBackupDelegate(SceneObjectGroup sog); | ||
47 | |||
48 | public delegate void DetachFromBackupDelegate(SceneObjectGroup sog); | ||
49 | |||
50 | public delegate void ChangedBackupDelegate(SceneObjectGroup sog); | ||
51 | |||
46 | public delegate void ObjectCreateDelegate(EntityBase obj); | 52 | public delegate void ObjectCreateDelegate(EntityBase obj); |
47 | 53 | ||
48 | public delegate void ObjectDeleteDelegate(EntityBase obj); | 54 | public delegate void ObjectDeleteDelegate(EntityBase obj); |
@@ -61,6 +67,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
61 | private PhysicsCrash handlerPhysicsCrash = null; | 67 | private PhysicsCrash handlerPhysicsCrash = null; |
62 | 68 | ||
63 | public event ObjectDuplicateDelegate OnObjectDuplicate; | 69 | public event ObjectDuplicateDelegate OnObjectDuplicate; |
70 | public event AttachToBackupDelegate OnAttachToBackup; | ||
71 | public event DetachFromBackupDelegate OnDetachFromBackup; | ||
72 | public event ChangedBackupDelegate OnChangeBackup; | ||
64 | public event ObjectCreateDelegate OnObjectCreate; | 73 | public event ObjectCreateDelegate OnObjectCreate; |
65 | public event ObjectDeleteDelegate OnObjectRemove; | 74 | public event ObjectDeleteDelegate OnObjectRemove; |
66 | 75 | ||
@@ -68,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
68 | 77 | ||
69 | #region Fields | 78 | #region Fields |
70 | 79 | ||
71 | protected object m_presenceLock = new object(); | 80 | protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); |
72 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); | 81 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); |
73 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); | 82 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); |
74 | 83 | ||
@@ -128,13 +137,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
128 | 137 | ||
129 | protected internal void Close() | 138 | protected internal void Close() |
130 | { | 139 | { |
131 | lock (m_presenceLock) | 140 | m_scenePresencesLock.EnterWriteLock(); |
141 | try | ||
132 | { | 142 | { |
133 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); | 143 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); |
134 | List<ScenePresence> newlist = new List<ScenePresence>(); | 144 | List<ScenePresence> newlist = new List<ScenePresence>(); |
135 | m_scenePresenceMap = newmap; | 145 | m_scenePresenceMap = newmap; |
136 | m_scenePresenceArray = newlist; | 146 | m_scenePresenceArray = newlist; |
137 | } | 147 | } |
148 | finally | ||
149 | { | ||
150 | m_scenePresencesLock.ExitWriteLock(); | ||
151 | } | ||
138 | 152 | ||
139 | lock (m_dictionary_lock) | 153 | lock (m_dictionary_lock) |
140 | { | 154 | { |
@@ -214,27 +228,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
214 | if (sp.IsChildAgent) | 228 | if (sp.IsChildAgent) |
215 | return; | 229 | return; |
216 | 230 | ||
217 | if (sp.ParentID != 0) | 231 | coarseLocations.Add(sp.AbsolutePosition); |
218 | { | 232 | avatarUUIDs.Add(sp.UUID); |
219 | // sitting avatar | ||
220 | SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID); | ||
221 | if (sop != null) | ||
222 | { | ||
223 | coarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition); | ||
224 | avatarUUIDs.Add(sp.UUID); | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | // we can't find the parent.. ! arg! | ||
229 | coarseLocations.Add(sp.AbsolutePosition); | ||
230 | avatarUUIDs.Add(sp.UUID); | ||
231 | } | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | coarseLocations.Add(sp.AbsolutePosition); | ||
236 | avatarUUIDs.Add(sp.UUID); | ||
237 | } | ||
238 | } | 233 | } |
239 | } | 234 | } |
240 | 235 | ||
@@ -264,6 +259,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
264 | protected internal bool AddRestoredSceneObject( | 259 | protected internal bool AddRestoredSceneObject( |
265 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) | 260 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) |
266 | { | 261 | { |
262 | if (!m_parentScene.CombineRegions) | ||
263 | { | ||
264 | // KF: Check for out-of-region, move inside and make static. | ||
265 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | ||
266 | sceneObject.RootPart.GroupPosition.Y, | ||
267 | sceneObject.RootPart.GroupPosition.Z); | ||
268 | 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 || | ||
269 | npos.X > Constants.RegionSize || | ||
270 | npos.Y > Constants.RegionSize)) | ||
271 | { | ||
272 | if (npos.X < 0.0) npos.X = 1.0f; | ||
273 | if (npos.Y < 0.0) npos.Y = 1.0f; | ||
274 | if (npos.Z < 0.0) npos.Z = 0.0f; | ||
275 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; | ||
276 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; | ||
277 | |||
278 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
279 | { | ||
280 | part.GroupPosition = npos; | ||
281 | } | ||
282 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
283 | sceneObject.RootPart.AngularVelocity = Vector3.Zero; | ||
284 | sceneObject.RootPart.Acceleration = Vector3.Zero; | ||
285 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
286 | } | ||
287 | } | ||
288 | |||
267 | if (!alreadyPersisted) | 289 | if (!alreadyPersisted) |
268 | { | 290 | { |
269 | sceneObject.ForceInventoryPersistence(); | 291 | sceneObject.ForceInventoryPersistence(); |
@@ -354,10 +376,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
354 | m_numPrim += sceneObject.Children.Count; | 376 | m_numPrim += sceneObject.Children.Count; |
355 | 377 | ||
356 | if (attachToBackup) | 378 | if (attachToBackup) |
379 | { | ||
357 | sceneObject.AttachToBackup(); | 380 | sceneObject.AttachToBackup(); |
381 | } | ||
358 | 382 | ||
359 | if (OnObjectCreate != null) | 383 | if (OnObjectCreate != null) |
384 | { | ||
360 | OnObjectCreate(sceneObject); | 385 | OnObjectCreate(sceneObject); |
386 | } | ||
361 | 387 | ||
362 | lock (m_dictionary_lock) | 388 | lock (m_dictionary_lock) |
363 | { | 389 | { |
@@ -424,6 +450,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
424 | } | 450 | } |
425 | } | 451 | } |
426 | 452 | ||
453 | public void FireAttachToBackup(SceneObjectGroup obj) | ||
454 | { | ||
455 | if (OnAttachToBackup != null) | ||
456 | { | ||
457 | OnAttachToBackup(obj); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | public void FireDetachFromBackup(SceneObjectGroup obj) | ||
462 | { | ||
463 | if (OnDetachFromBackup != null) | ||
464 | { | ||
465 | OnDetachFromBackup(obj); | ||
466 | } | ||
467 | } | ||
468 | |||
469 | public void FireChangeBackup(SceneObjectGroup obj) | ||
470 | { | ||
471 | if (OnChangeBackup != null) | ||
472 | { | ||
473 | OnChangeBackup(obj); | ||
474 | } | ||
475 | } | ||
476 | |||
427 | /// <summary> | 477 | /// <summary> |
428 | /// Process all pending updates | 478 | /// Process all pending updates |
429 | /// </summary> | 479 | /// </summary> |
@@ -560,7 +610,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
560 | 610 | ||
561 | Entities[presence.UUID] = presence; | 611 | Entities[presence.UUID] = presence; |
562 | 612 | ||
563 | lock (m_presenceLock) | 613 | m_scenePresencesLock.EnterWriteLock(); |
614 | try | ||
564 | { | 615 | { |
565 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 616 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
566 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 617 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -584,6 +635,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
584 | m_scenePresenceMap = newmap; | 635 | m_scenePresenceMap = newmap; |
585 | m_scenePresenceArray = newlist; | 636 | m_scenePresenceArray = newlist; |
586 | } | 637 | } |
638 | finally | ||
639 | { | ||
640 | m_scenePresencesLock.ExitWriteLock(); | ||
641 | } | ||
587 | } | 642 | } |
588 | 643 | ||
589 | /// <summary> | 644 | /// <summary> |
@@ -598,7 +653,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
598 | agentID); | 653 | agentID); |
599 | } | 654 | } |
600 | 655 | ||
601 | lock (m_presenceLock) | 656 | m_scenePresencesLock.EnterWriteLock(); |
657 | try | ||
602 | { | 658 | { |
603 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 659 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
604 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 660 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
@@ -620,6 +676,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
620 | m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 676 | m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); |
621 | } | 677 | } |
622 | } | 678 | } |
679 | finally | ||
680 | { | ||
681 | m_scenePresencesLock.ExitWriteLock(); | ||
682 | } | ||
623 | } | 683 | } |
624 | 684 | ||
625 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) | 685 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) |
@@ -1497,10 +1557,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1497 | /// <param name="childPrims"></param> | 1557 | /// <param name="childPrims"></param> |
1498 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) | 1558 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) |
1499 | { | 1559 | { |
1560 | SceneObjectGroup parentGroup = root.ParentGroup; | ||
1561 | if (parentGroup == null) return; | ||
1500 | Monitor.Enter(m_updateLock); | 1562 | Monitor.Enter(m_updateLock); |
1563 | |||
1501 | try | 1564 | try |
1502 | { | 1565 | { |
1503 | SceneObjectGroup parentGroup = root.ParentGroup; | 1566 | parentGroup.areUpdatesSuspended = true; |
1504 | 1567 | ||
1505 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); | 1568 | List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); |
1506 | if (parentGroup != null) | 1569 | if (parentGroup != null) |
@@ -1539,12 +1602,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1539 | // occur on link to invoke this elsewhere (such as object selection) | 1602 | // occur on link to invoke this elsewhere (such as object selection) |
1540 | parentGroup.RootPart.CreateSelected = true; | 1603 | parentGroup.RootPart.CreateSelected = true; |
1541 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); | 1604 | parentGroup.TriggerScriptChangedEvent(Changed.LINK); |
1542 | parentGroup.HasGroupChanged = true; | ||
1543 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1544 | |||
1545 | } | 1605 | } |
1546 | finally | 1606 | finally |
1547 | { | 1607 | { |
1608 | parentGroup.areUpdatesSuspended = false; | ||
1609 | parentGroup.HasGroupChanged = true; | ||
1610 | parentGroup.ScheduleGroupForFullUpdate(); | ||
1548 | Monitor.Exit(m_updateLock); | 1611 | Monitor.Exit(m_updateLock); |
1549 | } | 1612 | } |
1550 | } | 1613 | } |
@@ -1581,11 +1644,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
1581 | } | 1644 | } |
1582 | } | 1645 | } |
1583 | 1646 | ||
1584 | foreach (SceneObjectPart child in childParts) | 1647 | if (childParts.Count > 0) |
1585 | { | 1648 | { |
1586 | // Unlink all child parts from their groups | 1649 | try |
1587 | // | 1650 | { |
1588 | child.ParentGroup.DelinkFromGroup(child, true); | 1651 | childParts[0].ParentGroup.areUpdatesSuspended = true; |
1652 | foreach (SceneObjectPart child in childParts) | ||
1653 | { | ||
1654 | // Unlink all child parts from their groups | ||
1655 | // | ||
1656 | child.ParentGroup.DelinkFromGroup(child, true); | ||
1657 | } | ||
1658 | } | ||
1659 | finally | ||
1660 | { | ||
1661 | childParts[0].ParentGroup.areUpdatesSuspended = false; | ||
1662 | } | ||
1589 | } | 1663 | } |
1590 | 1664 | ||
1591 | foreach (SceneObjectPart root in rootParts) | 1665 | foreach (SceneObjectPart root in rootParts) |
@@ -1609,10 +1683,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1609 | if (numChildren > 1) | 1683 | if (numChildren > 1) |
1610 | sendEventsToRemainder = false; | 1684 | sendEventsToRemainder = false; |
1611 | 1685 | ||
1612 | foreach (SceneObjectPart p in newSet) | 1686 | if (newSet.Count > 0) |
1613 | { | 1687 | { |
1614 | if (p != group.RootPart) | 1688 | try |
1615 | group.DelinkFromGroup(p, sendEventsToRemainder); | 1689 | { |
1690 | newSet[0].ParentGroup.areUpdatesSuspended = true; | ||
1691 | foreach (SceneObjectPart p in newSet) | ||
1692 | { | ||
1693 | if (p != group.RootPart) | ||
1694 | group.DelinkFromGroup(p, sendEventsToRemainder); | ||
1695 | } | ||
1696 | } | ||
1697 | finally | ||
1698 | { | ||
1699 | newSet[0].ParentGroup.areUpdatesSuspended = false; | ||
1700 | } | ||
1616 | } | 1701 | } |
1617 | 1702 | ||
1618 | // If there is more than one prim remaining, we | 1703 | // If there is more than one prim remaining, we |