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.cs131
1 files changed, 116 insertions, 15 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 40332a6..a36800b 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
@@ -133,13 +142,18 @@ namespace OpenSim.Region.Framework.Scenes
133 142
134 protected internal void Close() 143 protected internal void Close()
135 { 144 {
136 lock (m_presenceLock) 145 m_scenePresencesLock.EnterWriteLock();
146 try
137 { 147 {
138 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 148 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
139 List<ScenePresence> newlist = new List<ScenePresence>(); 149 List<ScenePresence> newlist = new List<ScenePresence>();
140 m_scenePresenceMap = newmap; 150 m_scenePresenceMap = newmap;
141 m_scenePresenceArray = newlist; 151 m_scenePresenceArray = newlist;
142 } 152 }
153 finally
154 {
155 m_scenePresencesLock.ExitWriteLock();
156 }
143 157
144 lock (m_dictionary_lock) 158 lock (m_dictionary_lock)
145 { 159 {
@@ -269,6 +283,30 @@ namespace OpenSim.Region.Framework.Scenes
269 protected internal bool AddRestoredSceneObject( 283 protected internal bool AddRestoredSceneObject(
270 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 284 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
271 { 285 {
286 // KF: Check for out-of-region, move inside and make static.
287 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
288 sceneObject.RootPart.GroupPosition.Y,
289 sceneObject.RootPart.GroupPosition.Z);
290 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 ||
291 npos.X > Constants.RegionSize ||
292 npos.Y > Constants.RegionSize))
293 {
294 if (npos.X < 0.0) npos.X = 1.0f;
295 if (npos.Y < 0.0) npos.Y = 1.0f;
296 if (npos.Z < 0.0) npos.Z = 0.0f;
297 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
298 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
299
300 foreach (SceneObjectPart part in sceneObject.Children.Values)
301 {
302 part.GroupPosition = npos;
303 }
304 sceneObject.RootPart.Velocity = Vector3.Zero;
305 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
306 sceneObject.RootPart.Acceleration = Vector3.Zero;
307 sceneObject.RootPart.Velocity = Vector3.Zero;
308 }
309
272 if (!alreadyPersisted) 310 if (!alreadyPersisted)
273 { 311 {
274 sceneObject.ForceInventoryPersistence(); 312 sceneObject.ForceInventoryPersistence();
@@ -359,10 +397,14 @@ namespace OpenSim.Region.Framework.Scenes
359 m_numPrim += sceneObject.Children.Count; 397 m_numPrim += sceneObject.Children.Count;
360 398
361 if (attachToBackup) 399 if (attachToBackup)
400 {
362 sceneObject.AttachToBackup(); 401 sceneObject.AttachToBackup();
402 }
363 403
364 if (OnObjectCreate != null) 404 if (OnObjectCreate != null)
405 {
365 OnObjectCreate(sceneObject); 406 OnObjectCreate(sceneObject);
407 }
366 408
367 lock (m_dictionary_lock) 409 lock (m_dictionary_lock)
368 { 410 {
@@ -429,6 +471,30 @@ namespace OpenSim.Region.Framework.Scenes
429 } 471 }
430 } 472 }
431 473
474 public void FireAttachToBackup(SceneObjectGroup obj)
475 {
476 if (OnAttachToBackup != null)
477 {
478 OnAttachToBackup(obj);
479 }
480 }
481
482 public void FireDetachFromBackup(SceneObjectGroup obj)
483 {
484 if (OnDetachFromBackup != null)
485 {
486 OnDetachFromBackup(obj);
487 }
488 }
489
490 public void FireChangeBackup(SceneObjectGroup obj)
491 {
492 if (OnChangeBackup != null)
493 {
494 OnChangeBackup(obj);
495 }
496 }
497
432 /// <summary> 498 /// <summary>
433 /// Process all pending updates 499 /// Process all pending updates
434 /// </summary> 500 /// </summary>
@@ -565,7 +631,8 @@ namespace OpenSim.Region.Framework.Scenes
565 631
566 Entities[presence.UUID] = presence; 632 Entities[presence.UUID] = presence;
567 633
568 lock (m_presenceLock) 634 m_scenePresencesLock.EnterWriteLock();
635 try
569 { 636 {
570 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 637 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
571 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 638 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -589,6 +656,10 @@ namespace OpenSim.Region.Framework.Scenes
589 m_scenePresenceMap = newmap; 656 m_scenePresenceMap = newmap;
590 m_scenePresenceArray = newlist; 657 m_scenePresenceArray = newlist;
591 } 658 }
659 finally
660 {
661 m_scenePresencesLock.ExitWriteLock();
662 }
592 } 663 }
593 664
594 /// <summary> 665 /// <summary>
@@ -603,7 +674,8 @@ namespace OpenSim.Region.Framework.Scenes
603 agentID); 674 agentID);
604 } 675 }
605 676
606 lock (m_presenceLock) 677 m_scenePresencesLock.EnterWriteLock();
678 try
607 { 679 {
608 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 680 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
609 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 681 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -625,6 +697,10 @@ namespace OpenSim.Region.Framework.Scenes
625 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 697 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
626 } 698 }
627 } 699 }
700 finally
701 {
702 m_scenePresencesLock.ExitWriteLock();
703 }
628 } 704 }
629 705
630 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 706 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1502,10 +1578,13 @@ namespace OpenSim.Region.Framework.Scenes
1502 /// <param name="childPrims"></param> 1578 /// <param name="childPrims"></param>
1503 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1579 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1504 { 1580 {
1581 SceneObjectGroup parentGroup = root.ParentGroup;
1582 if (parentGroup == null) return;
1505 Monitor.Enter(m_updateLock); 1583 Monitor.Enter(m_updateLock);
1584
1506 try 1585 try
1507 { 1586 {
1508 SceneObjectGroup parentGroup = root.ParentGroup; 1587 parentGroup.areUpdatesSuspended = true;
1509 1588
1510 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1589 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1511 if (parentGroup != null) 1590 if (parentGroup != null)
@@ -1544,12 +1623,12 @@ namespace OpenSim.Region.Framework.Scenes
1544 // occur on link to invoke this elsewhere (such as object selection) 1623 // occur on link to invoke this elsewhere (such as object selection)
1545 parentGroup.RootPart.CreateSelected = true; 1624 parentGroup.RootPart.CreateSelected = true;
1546 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1625 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1547 parentGroup.HasGroupChanged = true;
1548 parentGroup.ScheduleGroupForFullUpdate();
1549
1550 } 1626 }
1551 finally 1627 finally
1552 { 1628 {
1629 parentGroup.areUpdatesSuspended = false;
1630 parentGroup.HasGroupChanged = true;
1631 parentGroup.ScheduleGroupForFullUpdate();
1553 Monitor.Exit(m_updateLock); 1632 Monitor.Exit(m_updateLock);
1554 } 1633 }
1555 } 1634 }
@@ -1586,11 +1665,22 @@ namespace OpenSim.Region.Framework.Scenes
1586 } 1665 }
1587 } 1666 }
1588 1667
1589 foreach (SceneObjectPart child in childParts) 1668 if (childParts.Count > 0)
1590 { 1669 {
1591 // Unlink all child parts from their groups 1670 try
1592 // 1671 {
1593 child.ParentGroup.DelinkFromGroup(child, true); 1672 childParts[0].ParentGroup.areUpdatesSuspended = true;
1673 foreach (SceneObjectPart child in childParts)
1674 {
1675 // Unlink all child parts from their groups
1676 //
1677 child.ParentGroup.DelinkFromGroup(child, true);
1678 }
1679 }
1680 finally
1681 {
1682 childParts[0].ParentGroup.areUpdatesSuspended = false;
1683 }
1594 } 1684 }
1595 1685
1596 foreach (SceneObjectPart root in rootParts) 1686 foreach (SceneObjectPart root in rootParts)
@@ -1614,10 +1704,21 @@ namespace OpenSim.Region.Framework.Scenes
1614 if (numChildren > 1) 1704 if (numChildren > 1)
1615 sendEventsToRemainder = false; 1705 sendEventsToRemainder = false;
1616 1706
1617 foreach (SceneObjectPart p in newSet) 1707 if (newSet.Count > 0)
1618 { 1708 {
1619 if (p != group.RootPart) 1709 try
1620 group.DelinkFromGroup(p, sendEventsToRemainder); 1710 {
1711 newSet[0].ParentGroup.areUpdatesSuspended = true;
1712 foreach (SceneObjectPart p in newSet)
1713 {
1714 if (p != group.RootPart)
1715 group.DelinkFromGroup(p, sendEventsToRemainder);
1716 }
1717 }
1718 finally
1719 {
1720 newSet[0].ParentGroup.areUpdatesSuspended = false;
1721 }
1621 } 1722 }
1622 1723
1623 // If there is more than one prim remaining, we 1724 // If there is more than one prim remaining, we