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.cs134
1 files changed, 119 insertions, 15 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index f47450f..c0ec5df 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 {
@@ -264,6 +278,33 @@ namespace OpenSim.Region.Framework.Scenes
264 protected internal bool AddRestoredSceneObject( 278 protected internal bool AddRestoredSceneObject(
265 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 279 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
266 { 280 {
281 if (!m_parentScene.CombineRegions)
282 {
283 // KF: Check for out-of-region, move inside and make static.
284 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
285 sceneObject.RootPart.GroupPosition.Y,
286 sceneObject.RootPart.GroupPosition.Z);
287 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 ||
288 npos.X > Constants.RegionSize ||
289 npos.Y > Constants.RegionSize))
290 {
291 if (npos.X < 0.0) npos.X = 1.0f;
292 if (npos.Y < 0.0) npos.Y = 1.0f;
293 if (npos.Z < 0.0) npos.Z = 0.0f;
294 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
295 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
296
297 foreach (SceneObjectPart part in sceneObject.Children.Values)
298 {
299 part.GroupPosition = npos;
300 }
301 sceneObject.RootPart.Velocity = Vector3.Zero;
302 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
303 sceneObject.RootPart.Acceleration = Vector3.Zero;
304 sceneObject.RootPart.Velocity = Vector3.Zero;
305 }
306 }
307
267 if (!alreadyPersisted) 308 if (!alreadyPersisted)
268 { 309 {
269 sceneObject.ForceInventoryPersistence(); 310 sceneObject.ForceInventoryPersistence();
@@ -354,10 +395,14 @@ namespace OpenSim.Region.Framework.Scenes
354 m_numPrim += sceneObject.Children.Count; 395 m_numPrim += sceneObject.Children.Count;
355 396
356 if (attachToBackup) 397 if (attachToBackup)
398 {
357 sceneObject.AttachToBackup(); 399 sceneObject.AttachToBackup();
400 }
358 401
359 if (OnObjectCreate != null) 402 if (OnObjectCreate != null)
403 {
360 OnObjectCreate(sceneObject); 404 OnObjectCreate(sceneObject);
405 }
361 406
362 lock (m_dictionary_lock) 407 lock (m_dictionary_lock)
363 { 408 {
@@ -424,6 +469,30 @@ namespace OpenSim.Region.Framework.Scenes
424 } 469 }
425 } 470 }
426 471
472 public void FireAttachToBackup(SceneObjectGroup obj)
473 {
474 if (OnAttachToBackup != null)
475 {
476 OnAttachToBackup(obj);
477 }
478 }
479
480 public void FireDetachFromBackup(SceneObjectGroup obj)
481 {
482 if (OnDetachFromBackup != null)
483 {
484 OnDetachFromBackup(obj);
485 }
486 }
487
488 public void FireChangeBackup(SceneObjectGroup obj)
489 {
490 if (OnChangeBackup != null)
491 {
492 OnChangeBackup(obj);
493 }
494 }
495
427 /// <summary> 496 /// <summary>
428 /// Process all pending updates 497 /// Process all pending updates
429 /// </summary> 498 /// </summary>
@@ -560,7 +629,8 @@ namespace OpenSim.Region.Framework.Scenes
560 629
561 Entities[presence.UUID] = presence; 630 Entities[presence.UUID] = presence;
562 631
563 lock (m_presenceLock) 632 m_scenePresencesLock.EnterWriteLock();
633 try
564 { 634 {
565 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 635 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
566 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 636 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -584,6 +654,10 @@ namespace OpenSim.Region.Framework.Scenes
584 m_scenePresenceMap = newmap; 654 m_scenePresenceMap = newmap;
585 m_scenePresenceArray = newlist; 655 m_scenePresenceArray = newlist;
586 } 656 }
657 finally
658 {
659 m_scenePresencesLock.ExitWriteLock();
660 }
587 } 661 }
588 662
589 /// <summary> 663 /// <summary>
@@ -598,7 +672,8 @@ namespace OpenSim.Region.Framework.Scenes
598 agentID); 672 agentID);
599 } 673 }
600 674
601 lock (m_presenceLock) 675 m_scenePresencesLock.EnterWriteLock();
676 try
602 { 677 {
603 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 678 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
604 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 679 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -620,6 +695,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); 695 m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
621 } 696 }
622 } 697 }
698 finally
699 {
700 m_scenePresencesLock.ExitWriteLock();
701 }
623 } 702 }
624 703
625 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 704 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1497,10 +1576,13 @@ namespace OpenSim.Region.Framework.Scenes
1497 /// <param name="childPrims"></param> 1576 /// <param name="childPrims"></param>
1498 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1577 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1499 { 1578 {
1579 SceneObjectGroup parentGroup = root.ParentGroup;
1580 if (parentGroup == null) return;
1500 Monitor.Enter(m_updateLock); 1581 Monitor.Enter(m_updateLock);
1582
1501 try 1583 try
1502 { 1584 {
1503 SceneObjectGroup parentGroup = root.ParentGroup; 1585 parentGroup.areUpdatesSuspended = true;
1504 1586
1505 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1587 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1506 if (parentGroup != null) 1588 if (parentGroup != null)
@@ -1539,12 +1621,12 @@ namespace OpenSim.Region.Framework.Scenes
1539 // occur on link to invoke this elsewhere (such as object selection) 1621 // occur on link to invoke this elsewhere (such as object selection)
1540 parentGroup.RootPart.CreateSelected = true; 1622 parentGroup.RootPart.CreateSelected = true;
1541 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1623 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1542 parentGroup.HasGroupChanged = true;
1543 parentGroup.ScheduleGroupForFullUpdate();
1544
1545 } 1624 }
1546 finally 1625 finally
1547 { 1626 {
1627 parentGroup.areUpdatesSuspended = false;
1628 parentGroup.HasGroupChanged = true;
1629 parentGroup.ScheduleGroupForFullUpdate();
1548 Monitor.Exit(m_updateLock); 1630 Monitor.Exit(m_updateLock);
1549 } 1631 }
1550 } 1632 }
@@ -1581,11 +1663,22 @@ namespace OpenSim.Region.Framework.Scenes
1581 } 1663 }
1582 } 1664 }
1583 1665
1584 foreach (SceneObjectPart child in childParts) 1666 if (childParts.Count > 0)
1585 { 1667 {
1586 // Unlink all child parts from their groups 1668 try
1587 // 1669 {
1588 child.ParentGroup.DelinkFromGroup(child, true); 1670 childParts[0].ParentGroup.areUpdatesSuspended = true;
1671 foreach (SceneObjectPart child in childParts)
1672 {
1673 // Unlink all child parts from their groups
1674 //
1675 child.ParentGroup.DelinkFromGroup(child, true);
1676 }
1677 }
1678 finally
1679 {
1680 childParts[0].ParentGroup.areUpdatesSuspended = false;
1681 }
1589 } 1682 }
1590 1683
1591 foreach (SceneObjectPart root in rootParts) 1684 foreach (SceneObjectPart root in rootParts)
@@ -1609,10 +1702,21 @@ namespace OpenSim.Region.Framework.Scenes
1609 if (numChildren > 1) 1702 if (numChildren > 1)
1610 sendEventsToRemainder = false; 1703 sendEventsToRemainder = false;
1611 1704
1612 foreach (SceneObjectPart p in newSet) 1705 if (newSet.Count > 0)
1613 { 1706 {
1614 if (p != group.RootPart) 1707 try
1615 group.DelinkFromGroup(p, sendEventsToRemainder); 1708 {
1709 newSet[0].ParentGroup.areUpdatesSuspended = true;
1710 foreach (SceneObjectPart p in newSet)
1711 {
1712 if (p != group.RootPart)
1713 group.DelinkFromGroup(p, sendEventsToRemainder);
1714 }
1715 }
1716 finally
1717 {
1718 newSet[0].ParentGroup.areUpdatesSuspended = false;
1719 }
1616 } 1720 }
1617 1721
1618 // If there is more than one prim remaining, we 1722 // If there is more than one prim remaining, we