aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs159
1 files changed, 121 insertions, 38 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index e7175c5..8823df1 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
@@ -127,13 +136,18 @@ namespace OpenSim.Region.Framework.Scenes
127 136
128 protected internal void Close() 137 protected internal void Close()
129 { 138 {
130 lock (m_presenceLock) 139 m_scenePresencesLock.EnterWriteLock();
140 try
131 { 141 {
132 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 142 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
133 List<ScenePresence> newlist = new List<ScenePresence>(); 143 List<ScenePresence> newlist = new List<ScenePresence>();
134 m_scenePresenceMap = newmap; 144 m_scenePresenceMap = newmap;
135 m_scenePresenceArray = newlist; 145 m_scenePresenceArray = newlist;
136 } 146 }
147 finally
148 {
149 m_scenePresencesLock.ExitWriteLock();
150 }
137 151
138 lock (SceneObjectGroupsByFullID) 152 lock (SceneObjectGroupsByFullID)
139 SceneObjectGroupsByFullID.Clear(); 153 SceneObjectGroupsByFullID.Clear();
@@ -212,27 +226,8 @@ namespace OpenSim.Region.Framework.Scenes
212 if (sp.IsChildAgent) 226 if (sp.IsChildAgent)
213 return; 227 return;
214 228
215 if (sp.ParentID != 0) 229 coarseLocations.Add(sp.AbsolutePosition);
216 { 230 avatarUUIDs.Add(sp.UUID);
217 // sitting avatar
218 SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID);
219 if (sop != null)
220 {
221 coarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition);
222 avatarUUIDs.Add(sp.UUID);
223 }
224 else
225 {
226 // we can't find the parent.. ! arg!
227 coarseLocations.Add(sp.AbsolutePosition);
228 avatarUUIDs.Add(sp.UUID);
229 }
230 }
231 else
232 {
233 coarseLocations.Add(sp.AbsolutePosition);
234 avatarUUIDs.Add(sp.UUID);
235 }
236 } 231 }
237 } 232 }
238 233
@@ -262,6 +257,33 @@ namespace OpenSim.Region.Framework.Scenes
262 protected internal bool AddRestoredSceneObject( 257 protected internal bool AddRestoredSceneObject(
263 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 258 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
264 { 259 {
260 if (!m_parentScene.CombineRegions)
261 {
262 // KF: Check for out-of-region, move inside and make static.
263 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
264 sceneObject.RootPart.GroupPosition.Y,
265 sceneObject.RootPart.GroupPosition.Z);
266 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 ||
267 npos.X > Constants.RegionSize ||
268 npos.Y > Constants.RegionSize))
269 {
270 if (npos.X < 0.0) npos.X = 1.0f;
271 if (npos.Y < 0.0) npos.Y = 1.0f;
272 if (npos.Z < 0.0) npos.Z = 0.0f;
273 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
274 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
275
276 foreach (SceneObjectPart part in sceneObject.Children.Values)
277 {
278 part.GroupPosition = npos;
279 }
280 sceneObject.RootPart.Velocity = Vector3.Zero;
281 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
282 sceneObject.RootPart.Acceleration = Vector3.Zero;
283 sceneObject.RootPart.Velocity = Vector3.Zero;
284 }
285 }
286
265 if (!alreadyPersisted) 287 if (!alreadyPersisted)
266 { 288 {
267 sceneObject.ForceInventoryPersistence(); 289 sceneObject.ForceInventoryPersistence();
@@ -473,6 +495,30 @@ namespace OpenSim.Region.Framework.Scenes
473 } 495 }
474 } 496 }
475 497
498 public void FireAttachToBackup(SceneObjectGroup obj)
499 {
500 if (OnAttachToBackup != null)
501 {
502 OnAttachToBackup(obj);
503 }
504 }
505
506 public void FireDetachFromBackup(SceneObjectGroup obj)
507 {
508 if (OnDetachFromBackup != null)
509 {
510 OnDetachFromBackup(obj);
511 }
512 }
513
514 public void FireChangeBackup(SceneObjectGroup obj)
515 {
516 if (OnChangeBackup != null)
517 {
518 OnChangeBackup(obj);
519 }
520 }
521
476 /// <summary> 522 /// <summary>
477 /// Process all pending updates 523 /// Process all pending updates
478 /// </summary> 524 /// </summary>
@@ -609,7 +655,8 @@ namespace OpenSim.Region.Framework.Scenes
609 655
610 Entities[presence.UUID] = presence; 656 Entities[presence.UUID] = presence;
611 657
612 lock (m_presenceLock) 658 m_scenePresencesLock.EnterWriteLock();
659 try
613 { 660 {
614 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 661 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
615 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 662 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -633,6 +680,10 @@ namespace OpenSim.Region.Framework.Scenes
633 m_scenePresenceMap = newmap; 680 m_scenePresenceMap = newmap;
634 m_scenePresenceArray = newlist; 681 m_scenePresenceArray = newlist;
635 } 682 }
683 finally
684 {
685 m_scenePresencesLock.ExitWriteLock();
686 }
636 } 687 }
637 688
638 /// <summary> 689 /// <summary>
@@ -647,7 +698,8 @@ namespace OpenSim.Region.Framework.Scenes
647 agentID); 698 agentID);
648 } 699 }
649 700
650 lock (m_presenceLock) 701 m_scenePresencesLock.EnterWriteLock();
702 try
651 { 703 {
652 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 704 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
653 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 705 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -669,6 +721,10 @@ namespace OpenSim.Region.Framework.Scenes
669 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 721 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
670 } 722 }
671 } 723 }
724 finally
725 {
726 m_scenePresencesLock.ExitWriteLock();
727 }
672 } 728 }
673 729
674 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 730 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1084,9 +1140,11 @@ namespace OpenSim.Region.Framework.Scenes
1084 /// <param name="action"></param> 1140 /// <param name="action"></param>
1085 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1141 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1086 { 1142 {
1087 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1143 List<EntityBase> objlist = Entities.GetAllByType<SceneObjectGroup>();
1088 foreach (SceneObjectGroup obj in objlist) 1144 foreach (EntityBase ent in objlist)
1089 { 1145 {
1146 SceneObjectGroup obj = (SceneObjectGroup)ent;
1147
1090 try 1148 try
1091 { 1149 {
1092 action(obj); 1150 action(obj);
@@ -1543,10 +1601,13 @@ namespace OpenSim.Region.Framework.Scenes
1543 /// <param name="childPrims"></param> 1601 /// <param name="childPrims"></param>
1544 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1602 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1545 { 1603 {
1604 SceneObjectGroup parentGroup = root.ParentGroup;
1605 if (parentGroup == null) return;
1546 Monitor.Enter(m_updateLock); 1606 Monitor.Enter(m_updateLock);
1607
1547 try 1608 try
1548 { 1609 {
1549 SceneObjectGroup parentGroup = root.ParentGroup; 1610 parentGroup.areUpdatesSuspended = true;
1550 1611
1551 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1612 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1552 if (parentGroup != null) 1613 if (parentGroup != null)
@@ -1585,12 +1646,12 @@ namespace OpenSim.Region.Framework.Scenes
1585 // occur on link to invoke this elsewhere (such as object selection) 1646 // occur on link to invoke this elsewhere (such as object selection)
1586 parentGroup.RootPart.CreateSelected = true; 1647 parentGroup.RootPart.CreateSelected = true;
1587 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1648 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1588 parentGroup.HasGroupChanged = true;
1589 parentGroup.ScheduleGroupForFullUpdate();
1590
1591 } 1649 }
1592 finally 1650 finally
1593 { 1651 {
1652 parentGroup.areUpdatesSuspended = false;
1653 parentGroup.HasGroupChanged = true;
1654 parentGroup.ScheduleGroupForFullUpdate();
1594 Monitor.Exit(m_updateLock); 1655 Monitor.Exit(m_updateLock);
1595 } 1656 }
1596 } 1657 }
@@ -1627,11 +1688,22 @@ namespace OpenSim.Region.Framework.Scenes
1627 } 1688 }
1628 } 1689 }
1629 1690
1630 foreach (SceneObjectPart child in childParts) 1691 if (childParts.Count > 0)
1631 { 1692 {
1632 // Unlink all child parts from their groups 1693 try
1633 // 1694 {
1634 child.ParentGroup.DelinkFromGroup(child, true); 1695 childParts[0].ParentGroup.areUpdatesSuspended = true;
1696 foreach (SceneObjectPart child in childParts)
1697 {
1698 // Unlink all child parts from their groups
1699 //
1700 child.ParentGroup.DelinkFromGroup(child, true);
1701 }
1702 }
1703 finally
1704 {
1705 childParts[0].ParentGroup.areUpdatesSuspended = false;
1706 }
1635 } 1707 }
1636 1708
1637 foreach (SceneObjectPart root in rootParts) 1709 foreach (SceneObjectPart root in rootParts)
@@ -1662,10 +1734,21 @@ namespace OpenSim.Region.Framework.Scenes
1662 if (numChildren > 1) 1734 if (numChildren > 1)
1663 sendEventsToRemainder = false; 1735 sendEventsToRemainder = false;
1664 1736
1665 foreach (SceneObjectPart p in newSet) 1737 if (newSet.Count > 0)
1666 { 1738 {
1667 if (p != group.RootPart) 1739 try
1668 group.DelinkFromGroup(p, sendEventsToRemainder); 1740 {
1741 newSet[0].ParentGroup.areUpdatesSuspended = true;
1742 foreach (SceneObjectPart p in newSet)
1743 {
1744 if (p != group.RootPart)
1745 group.DelinkFromGroup(p, sendEventsToRemainder);
1746 }
1747 }
1748 finally
1749 {
1750 newSet[0].ParentGroup.areUpdatesSuspended = false;
1751 }
1669 } 1752 }
1670 1753
1671 // If there is more than one prim remaining, we 1754 // If there is more than one prim remaining, we