aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs551
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs70
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs379
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs280
7 files changed, 862 insertions, 475 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index a459ffa..50624a1 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -53,8 +53,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
53 { 53 {
54 get { return m_movementAnimation; } 54 get { return m_movementAnimation; }
55 } 55 }
56 protected string m_movementAnimation = "DEFAULT"; 56 // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist!
57 57 protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init.
58 private int m_animTickFall; 58 private int m_animTickFall;
59 private int m_animTickJump; 59 private int m_animTickJump;
60 60
@@ -123,17 +123,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
123 /// </summary> 123 /// </summary>
124 public void TrySetMovementAnimation(string anim) 124 public void TrySetMovementAnimation(string anim)
125 { 125 {
126 //m_log.DebugFormat("Updating movement animation to {0}", anim); 126//Console.WriteLine("Updating movement animation to {0}", anim);
127 127
128 if (!m_scenePresence.IsChildAgent) 128 if (!m_scenePresence.IsChildAgent)
129 { 129 {
130 if (m_animations.TrySetDefaultAnimation( 130 if (m_animations.TrySetDefaultAnimation(
131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero)) 131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero))
132 { 132 {
133//Console.WriteLine("TSMA {0} success.", anim);
133 // 16384 is CHANGED_ANIMATION 134 // 16384 is CHANGED_ANIMATION
134 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); 135 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
135 SendAnimPack(); 136 SendAnimPack();
136 } 137 }
138 else
139 {
140//Console.WriteLine("TSMA {0} fail.", anim);
141 }
137 } 142 }
138 } 143 }
139 144
@@ -156,10 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 161 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157 162
158 // Check control flags 163 // Check control flags
159 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; 164 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
160 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 165 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
161 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 166 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
162 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; 167 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 168 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
164 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 169 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
165 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 170 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
@@ -312,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
312 public void UpdateMovementAnimations() 317 public void UpdateMovementAnimations()
313 { 318 {
314 m_movementAnimation = GetMovementAnimation(); 319 m_movementAnimation = GetMovementAnimation();
315 320//Console.WriteLine("UMA got {0}", m_movementAnimation);
316 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) 321 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
317 { 322 {
318 // This was the previous behavior before PREJUMP 323 // This was the previous behavior before PREJUMP
@@ -450,4 +455,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
450 m_scenePresence = null; 455 m_scenePresence = null;
451 } 456 }
452 } 457 }
453} \ No newline at end of file 458}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 0b0c205..7ca779a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -840,8 +840,12 @@ namespace OpenSim.Region.Framework.Scenes
840 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 840 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
841 { 841 {
842 SceneObjectPart part = GetSceneObjectPart(localID); 842 SceneObjectPart part = GetSceneObjectPart(localID);
843 SceneObjectGroup group = part.ParentGroup; 843 SceneObjectGroup group = null;
844 if (group != null) 844 if (part != null)
845 {
846 group = part.ParentGroup;
847 }
848 if (part != null && group != null)
845 { 849 {
846 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 850 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
847 if (item == null) 851 if (item == null)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a22fb5f..a8bab5a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -881,6 +881,15 @@ namespace OpenSim.Region.Framework.Scenes
881 /// <param name="seconds">float indicating duration before restart.</param> 881 /// <param name="seconds">float indicating duration before restart.</param>
882 public virtual void Restart(float seconds) 882 public virtual void Restart(float seconds)
883 { 883 {
884 Restart(seconds, true);
885 }
886
887 /// <summary>
888 /// Given float seconds, this will restart the region. showDialog will optionally alert the users.
889 /// </summary>
890 /// <param name="seconds">float indicating duration before restart.</param>
891 public virtual void Restart(float seconds, bool showDialog)
892 {
884 // notifications are done in 15 second increments 893 // notifications are done in 15 second increments
885 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request 894 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
886 // It's a 'Cancel restart' request. 895 // It's a 'Cancel restart' request.
@@ -901,8 +910,11 @@ namespace OpenSim.Region.Framework.Scenes
901 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); 910 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
902 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); 911 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
903 m_restartTimer.Start(); 912 m_restartTimer.Start();
904 m_dialogModule.SendNotificationToUsersInRegion( 913 if (showDialog)
905 UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in 2 Minutes"); 914 {
915 m_dialogModule.SendNotificationToUsersInRegion(
916 UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in " + (seconds / 60).ToString() + " Minutes");
917 }
906 } 918 }
907 } 919 }
908 920
@@ -1173,16 +1185,16 @@ namespace OpenSim.Region.Framework.Scenes
1173 // Check if any objects have reached their targets 1185 // Check if any objects have reached their targets
1174 CheckAtTargets(); 1186 CheckAtTargets();
1175 1187
1176 // Update SceneObjectGroups that have scheduled themselves for updates
1177 // Objects queue their updates onto all scene presences
1178 if (m_frame % m_update_objects == 0)
1179 m_sceneGraph.UpdateObjectGroups();
1180
1181 // Run through all ScenePresences looking for updates 1188 // Run through all ScenePresences looking for updates
1182 // Presence updates and queued object updates for each presence are sent to clients 1189 // Presence updates and queued object updates for each presence are sent to clients
1183 if (m_frame % m_update_presences == 0) 1190 if (m_frame % m_update_presences == 0)
1184 m_sceneGraph.UpdatePresences(); 1191 m_sceneGraph.UpdatePresences();
1185 1192
1193 // Update SceneObjectGroups that have scheduled themselves for updates
1194 // Objects queue their updates onto all scene presences
1195 if (m_frame % m_update_objects == 0)
1196 m_sceneGraph.UpdateObjectGroups();
1197
1186 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1198 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1187 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1199 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1188 m_sceneGraph.UpdatePreparePhysics(); 1200 m_sceneGraph.UpdatePreparePhysics();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index cb87212..93888f1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -98,6 +98,66 @@ namespace OpenSim.Region.Framework.Scenes
98 private bool m_hasGroupChanged = false; 98 private bool m_hasGroupChanged = false;
99 private long timeFirstChanged; 99 private long timeFirstChanged;
100 private long timeLastChanged; 100 private long timeLastChanged;
101 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
102
103 public void lockPartsForRead(bool locked)
104 {
105 if (locked)
106 {
107 if (m_partsLock.RecursiveReadCount > 0)
108 {
109 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
110 m_partsLock.ExitReadLock();
111 }
112 if (m_partsLock.RecursiveWriteCount > 0)
113 {
114 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
115 m_partsLock.ExitWriteLock();
116 }
117
118 while (!m_partsLock.TryEnterReadLock(60000))
119 {
120 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
121 if (m_partsLock.IsWriteLockHeld)
122 {
123 m_partsLock = new System.Threading.ReaderWriterLockSlim();
124 }
125 }
126 }
127 else
128 {
129 m_partsLock.ExitReadLock();
130 }
131 }
132 public void lockPartsForWrite(bool locked)
133 {
134 if (locked)
135 {
136 if (m_partsLock.RecursiveReadCount > 0)
137 {
138 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
139 m_partsLock.ExitReadLock();
140 }
141 if (m_partsLock.RecursiveWriteCount > 0)
142 {
143 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
144 m_partsLock.ExitWriteLock();
145 }
146
147 while (!m_partsLock.TryEnterWriteLock(60000))
148 {
149 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
150 if (m_partsLock.IsWriteLockHeld)
151 {
152 m_partsLock = new System.Threading.ReaderWriterLockSlim();
153 }
154 }
155 }
156 else
157 {
158 m_partsLock.ExitWriteLock();
159 }
160 }
101 161
102 public bool HasGroupChanged 162 public bool HasGroupChanged
103 { 163 {
@@ -243,13 +303,16 @@ namespace OpenSim.Region.Framework.Scenes
243 set 303 set
244 { 304 {
245 m_regionHandle = value; 305 m_regionHandle = value;
246 lock (m_parts) 306 lockPartsForRead(true);
247 { 307 {
248 foreach (SceneObjectPart part in m_parts.Values) 308 foreach (SceneObjectPart part in m_parts.Values)
249 { 309 {
310
250 part.RegionHandle = m_regionHandle; 311 part.RegionHandle = m_regionHandle;
312
251 } 313 }
252 } 314 }
315 lockPartsForRead(false);
253 } 316 }
254 } 317 }
255 318
@@ -275,13 +338,16 @@ namespace OpenSim.Region.Framework.Scenes
275 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 338 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
276 } 339 }
277 340
278 lock (m_parts) 341 lockPartsForRead(true);
279 { 342 {
280 foreach (SceneObjectPart part in m_parts.Values) 343 foreach (SceneObjectPart part in m_parts.Values)
281 { 344 {
345
282 part.GroupPosition = val; 346 part.GroupPosition = val;
347
283 } 348 }
284 } 349 }
350 lockPartsForRead(false);
285 351
286 //if (m_rootPart.PhysActor != null) 352 //if (m_rootPart.PhysActor != null)
287 //{ 353 //{
@@ -432,13 +498,16 @@ namespace OpenSim.Region.Framework.Scenes
432 498
433 public void SetFromItemID(UUID AssetId) 499 public void SetFromItemID(UUID AssetId)
434 { 500 {
435 lock (m_parts) 501 lockPartsForRead(true);
436 { 502 {
437 foreach (SceneObjectPart part in m_parts.Values) 503 foreach (SceneObjectPart part in m_parts.Values)
438 { 504 {
505
439 part.FromItemID = AssetId; 506 part.FromItemID = AssetId;
507
440 } 508 }
441 } 509 }
510 lockPartsForRead(false);
442 } 511 }
443 512
444 public UUID GetFromItemID() 513 public UUID GetFromItemID()
@@ -505,10 +574,11 @@ namespace OpenSim.Region.Framework.Scenes
505 Vector3 maxScale = Vector3.Zero; 574 Vector3 maxScale = Vector3.Zero;
506 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 575 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
507 576
508 lock (m_parts) 577 lockPartsForRead(true);
509 { 578 {
510 foreach (SceneObjectPart part in m_parts.Values) 579 foreach (SceneObjectPart part in m_parts.Values)
511 { 580 {
581
512 Vector3 partscale = part.Scale; 582 Vector3 partscale = part.Scale;
513 Vector3 partoffset = part.OffsetPosition; 583 Vector3 partoffset = part.OffsetPosition;
514 584
@@ -519,8 +589,11 @@ namespace OpenSim.Region.Framework.Scenes
519 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 589 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
520 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 590 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
521 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 591 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
592
522 } 593 }
523 } 594 }
595 lockPartsForRead(false);
596
524 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 597 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
525 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 598 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
526 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 599 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -536,10 +609,11 @@ namespace OpenSim.Region.Framework.Scenes
536 609
537 EntityIntersection result = new EntityIntersection(); 610 EntityIntersection result = new EntityIntersection();
538 611
539 lock (m_parts) 612 lockPartsForRead(true);
540 { 613 {
541 foreach (SceneObjectPart part in m_parts.Values) 614 foreach (SceneObjectPart part in m_parts.Values)
542 { 615 {
616
543 // Temporary commented to stop compiler warning 617 // Temporary commented to stop compiler warning
544 //Vector3 partPosition = 618 //Vector3 partPosition =
545 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 619 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -567,8 +641,10 @@ namespace OpenSim.Region.Framework.Scenes
567 result.distance = inter.distance; 641 result.distance = inter.distance;
568 } 642 }
569 } 643 }
644
570 } 645 }
571 } 646 }
647 lockPartsForRead(false);
572 return result; 648 return result;
573 } 649 }
574 650
@@ -581,10 +657,11 @@ namespace OpenSim.Region.Framework.Scenes
581 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 657 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
582 { 658 {
583 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 659 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
584 lock (m_parts) 660 lockPartsForRead(true);
585 { 661 {
586 foreach (SceneObjectPart part in m_parts.Values) 662 foreach (SceneObjectPart part in m_parts.Values)
587 { 663 {
664
588 Vector3 worldPos = part.GetWorldPosition(); 665 Vector3 worldPos = part.GetWorldPosition();
589 Vector3 offset = worldPos - AbsolutePosition; 666 Vector3 offset = worldPos - AbsolutePosition;
590 Quaternion worldRot; 667 Quaternion worldRot;
@@ -643,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes
643 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 720 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
644 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 721 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
645 722
723
724
646 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 725 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
647 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 726 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
648 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 727 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -814,6 +893,7 @@ namespace OpenSim.Region.Framework.Scenes
814 minZ = backBottomLeft.Z; 893 minZ = backBottomLeft.Z;
815 } 894 }
816 } 895 }
896 lockPartsForRead(false);
817 897
818 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 898 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
819 899
@@ -842,17 +922,20 @@ namespace OpenSim.Region.Framework.Scenes
842 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 922 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
843 923
844 // Capture script state while holding the lock 924 // Capture script state while holding the lock
845 lock (m_parts) 925 lockPartsForRead(true);
846 { 926 {
847 foreach (SceneObjectPart part in m_parts.Values) 927 foreach (SceneObjectPart part in m_parts.Values)
848 { 928 {
929
849 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 930 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
850 foreach (UUID itemid in pstates.Keys) 931 foreach (UUID itemid in pstates.Keys)
851 { 932 {
852 states.Add(itemid, pstates[itemid]); 933 states.Add(itemid, pstates[itemid]);
853 } 934 }
935
854 } 936 }
855 } 937 }
938 lockPartsForRead(false);
856 939
857 if (states.Count > 0) 940 if (states.Count > 0)
858 { 941 {
@@ -1014,13 +1097,16 @@ namespace OpenSim.Region.Framework.Scenes
1014 1097
1015 public override void UpdateMovement() 1098 public override void UpdateMovement()
1016 { 1099 {
1017 lock (m_parts) 1100 lockPartsForRead(true);
1018 { 1101 {
1019 foreach (SceneObjectPart part in m_parts.Values) 1102 foreach (SceneObjectPart part in m_parts.Values)
1020 { 1103 {
1104
1021 part.UpdateMovement(); 1105 part.UpdateMovement();
1106
1022 } 1107 }
1023 } 1108 }
1109 lockPartsForRead(false);
1024 } 1110 }
1025 1111
1026 public ushort GetTimeDilation() 1112 public ushort GetTimeDilation()
@@ -1064,7 +1150,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 /// <param name="part"></param> 1150 /// <param name="part"></param>
1065 public void AddPart(SceneObjectPart part) 1151 public void AddPart(SceneObjectPart part)
1066 { 1152 {
1067 lock (m_parts) 1153 lockPartsForWrite(true);
1068 { 1154 {
1069 part.SetParent(this); 1155 part.SetParent(this);
1070 m_parts.Add(part.UUID, part); 1156 m_parts.Add(part.UUID, part);
@@ -1074,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (part.LinkNum == 2 && RootPart != null) 1160 if (part.LinkNum == 2 && RootPart != null)
1075 RootPart.LinkNum = 1; 1161 RootPart.LinkNum = 1;
1076 } 1162 }
1163 lockPartsForWrite(false);
1077 } 1164 }
1078 1165
1079 /// <summary> 1166 /// <summary>
@@ -1081,28 +1168,33 @@ namespace OpenSim.Region.Framework.Scenes
1081 /// </summary> 1168 /// </summary>
1082 private void UpdateParentIDs() 1169 private void UpdateParentIDs()
1083 { 1170 {
1084 lock (m_parts) 1171 lockPartsForRead(true);
1085 { 1172 {
1086 foreach (SceneObjectPart part in m_parts.Values) 1173 foreach (SceneObjectPart part in m_parts.Values)
1087 { 1174 {
1175
1088 if (part.UUID != m_rootPart.UUID) 1176 if (part.UUID != m_rootPart.UUID)
1089 { 1177 {
1090 part.ParentID = m_rootPart.LocalId; 1178 part.ParentID = m_rootPart.LocalId;
1091 } 1179 }
1180
1092 } 1181 }
1093 } 1182 }
1183 lockPartsForRead(false);
1094 } 1184 }
1095 1185
1096 public void RegenerateFullIDs() 1186 public void RegenerateFullIDs()
1097 { 1187 {
1098 lock (m_parts) 1188 lockPartsForRead(true);
1099 { 1189 {
1100 foreach (SceneObjectPart part in m_parts.Values) 1190 foreach (SceneObjectPart part in m_parts.Values)
1101 { 1191 {
1192
1102 part.UUID = UUID.Random(); 1193 part.UUID = UUID.Random();
1103 1194
1104 } 1195 }
1105 } 1196 }
1197 lockPartsForRead(false);
1106 } 1198 }
1107 1199
1108 // helper provided for parts. 1200 // helper provided for parts.
@@ -1183,29 +1275,33 @@ namespace OpenSim.Region.Framework.Scenes
1183 1275
1184 DetachFromBackup(); 1276 DetachFromBackup();
1185 1277
1186 lock (m_parts) 1278 lockPartsForRead(true);
1279 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1280 lockPartsForRead(false);
1281
1282 foreach (SceneObjectPart part in values)
1187 { 1283 {
1188 foreach (SceneObjectPart part in m_parts.Values)
1189 {
1190// part.Inventory.RemoveScriptInstances(); 1284// part.Inventory.RemoveScriptInstances();
1191 1285
1192 ScenePresence[] avatars = Scene.GetScenePresences(); 1286 ScenePresence[] avatars = Scene.GetScenePresences();
1193 for (int i = 0; i < avatars.Length; i++) 1287 for (int i = 0; i < avatars.Length; i++)
1288 {
1289 if (avatars[i].ParentID == LocalId)
1194 { 1290 {
1195 if (avatars[i].ParentID == LocalId) 1291 avatars[i].StandUp();
1196 { 1292 }
1197 avatars[i].StandUp();
1198 }
1199 1293
1200 if (!silent) 1294 if (!silent)
1201 { 1295 {
1202 part.UpdateFlag = 0; 1296 part.UpdateFlag = 0;
1203 if (part == m_rootPart) 1297 if (part == m_rootPart)
1204 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1298 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1205 }
1206 } 1299 }
1207 } 1300 }
1301
1208 } 1302 }
1303
1304
1209 } 1305 }
1210 1306
1211 public void AddScriptLPS(int count) 1307 public void AddScriptLPS(int count)
@@ -1230,17 +1326,20 @@ namespace OpenSim.Region.Framework.Scenes
1230 1326
1231 scriptEvents aggregateScriptEvents=0; 1327 scriptEvents aggregateScriptEvents=0;
1232 1328
1233 lock (m_parts) 1329 lockPartsForRead(true);
1234 { 1330 {
1235 foreach (SceneObjectPart part in m_parts.Values) 1331 foreach (SceneObjectPart part in m_parts.Values)
1236 { 1332 {
1333
1237 if (part == null) 1334 if (part == null)
1238 continue; 1335 continue;
1239 if (part != RootPart) 1336 if (part != RootPart)
1240 part.ObjectFlags = objectflagupdate; 1337 part.ObjectFlags = objectflagupdate;
1241 aggregateScriptEvents |= part.AggregateScriptEvents; 1338 aggregateScriptEvents |= part.AggregateScriptEvents;
1339
1242 } 1340 }
1243 } 1341 }
1342 lockPartsForRead(false);
1244 1343
1245 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1344 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1246 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1345 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1273,42 +1372,52 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <param name="m_physicalPrim"></param> 1372 /// <param name="m_physicalPrim"></param>
1274 public void ApplyPhysics(bool m_physicalPrim) 1373 public void ApplyPhysics(bool m_physicalPrim)
1275 { 1374 {
1276 lock (m_parts) 1375 lockPartsForRead(true);
1376
1377 if (m_parts.Count > 1)
1277 { 1378 {
1278 if (m_parts.Count > 1) 1379 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1380 lockPartsForRead(false);
1381 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1382 foreach (SceneObjectPart part in values)
1279 { 1383 {
1280 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1384
1281 foreach (SceneObjectPart part in m_parts.Values) 1385 if (part.LocalId != m_rootPart.LocalId)
1282 { 1386 {
1283 if (part.LocalId != m_rootPart.LocalId) 1387 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1284 {
1285 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1286 }
1287 } 1388 }
1288 1389
1289 // Hack to get the physics scene geometries in the right spot
1290 ResetChildPrimPhysicsPositions();
1291 }
1292 else
1293 {
1294 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1295 } 1390 }
1391 // Hack to get the physics scene geometries in the right spot
1392 ResetChildPrimPhysicsPositions();
1393 }
1394 else
1395 {
1396 lockPartsForRead(false);
1397 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1296 } 1398 }
1297 } 1399 }
1298 1400
1299 public void SetOwnerId(UUID userId) 1401 public void SetOwnerId(UUID userId)
1300 { 1402 {
1301 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1403 ForEachPart(delegate(SceneObjectPart part)
1404 {
1405
1406 part.OwnerID = userId;
1407
1408 });
1302 } 1409 }
1303 1410
1304 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1411 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1305 { 1412 {
1306 lock (m_parts) 1413 lockPartsForRead(true);
1414 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1415 lockPartsForRead(false);
1416 foreach (SceneObjectPart part in values)
1307 { 1417 {
1308 foreach (SceneObjectPart part in m_parts.Values) 1418
1309 { 1419 whatToDo(part);
1310 whatToDo(part); 1420
1311 }
1312 } 1421 }
1313 } 1422 }
1314 1423
@@ -1407,14 +1516,17 @@ namespace OpenSim.Region.Framework.Scenes
1407 { 1516 {
1408 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1517 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1409 1518
1410 lock (m_parts) 1519 lockPartsForRead(true);
1411 { 1520 {
1412 foreach (SceneObjectPart part in m_parts.Values) 1521 foreach (SceneObjectPart part in m_parts.Values)
1413 { 1522 {
1523
1414 if (part != RootPart) 1524 if (part != RootPart)
1415 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1525 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1526
1416 } 1527 }
1417 } 1528 }
1529 lockPartsForRead(false);
1418 } 1530 }
1419 1531
1420 /// <summary> 1532 /// <summary>
@@ -1509,10 +1621,11 @@ namespace OpenSim.Region.Framework.Scenes
1509 1621
1510 List<SceneObjectPart> partList; 1622 List<SceneObjectPart> partList;
1511 1623
1512 lock (m_parts) 1624 lockPartsForRead(true);
1513 { 1625
1514 partList = new List<SceneObjectPart>(m_parts.Values); 1626 partList = new List<SceneObjectPart>(m_parts.Values);
1515 } 1627
1628 lockPartsForRead(false);
1516 1629
1517 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1630 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1518 { 1631 {
@@ -1735,6 +1848,45 @@ namespace OpenSim.Region.Framework.Scenes
1735 } 1848 }
1736 } 1849 }
1737 1850
1851 public void rotLookAt(Quaternion target, float strength, float damping)
1852 {
1853 SceneObjectPart rootpart = m_rootPart;
1854 if (rootpart != null)
1855 {
1856 if (IsAttachment)
1857 {
1858 /*
1859 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1860 if (avatar != null)
1861 {
1862 Rotate the Av?
1863 } */
1864 }
1865 else
1866 {
1867 if (rootpart.PhysActor != null)
1868 {
1869 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1870 rootpart.PhysActor.APIDStrength = strength;
1871 rootpart.PhysActor.APIDDamping = damping;
1872 rootpart.PhysActor.APIDActive = true;
1873 }
1874 }
1875 }
1876 }
1877 public void stopLookAt()
1878 {
1879 SceneObjectPart rootpart = m_rootPart;
1880 if (rootpart != null)
1881 {
1882 if (rootpart.PhysActor != null)
1883 {
1884 rootpart.PhysActor.APIDActive = false;
1885 }
1886 }
1887
1888 }
1889
1738 /// <summary> 1890 /// <summary>
1739 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1891 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1740 /// </summary> 1892 /// </summary>
@@ -1796,10 +1948,11 @@ namespace OpenSim.Region.Framework.Scenes
1796 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1948 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1797 newPart.SetParent(this); 1949 newPart.SetParent(this);
1798 1950
1799 lock (m_parts) 1951 lockPartsForWrite(true);
1800 { 1952 {
1801 m_parts.Add(newPart.UUID, newPart); 1953 m_parts.Add(newPart.UUID, newPart);
1802 } 1954 }
1955 lockPartsForWrite(false);
1803 1956
1804 SetPartAsNonRoot(newPart); 1957 SetPartAsNonRoot(newPart);
1805 1958
@@ -1862,7 +2015,7 @@ namespace OpenSim.Region.Framework.Scenes
1862 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2015 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1863 // return; 2016 // return;
1864 2017
1865 lock (m_parts) 2018 lockPartsForRead(true);
1866 { 2019 {
1867 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2020 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1868 2021
@@ -1880,34 +2033,43 @@ namespace OpenSim.Region.Framework.Scenes
1880 2033
1881 foreach (SceneObjectPart part in m_parts.Values) 2034 foreach (SceneObjectPart part in m_parts.Values)
1882 { 2035 {
2036
1883 part.SendScheduledUpdates(); 2037 part.SendScheduledUpdates();
2038
1884 } 2039 }
1885 } 2040 }
2041 lockPartsForRead(false);
1886 } 2042 }
1887 2043
1888 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2044 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1889 { 2045 {
1890 RootPart.AddFullUpdateToAvatar(presence); 2046 RootPart.AddFullUpdateToAvatar(presence);
1891 2047
1892 lock (m_parts) 2048 lockPartsForRead(true);
1893 { 2049 {
1894 foreach (SceneObjectPart part in m_parts.Values) 2050 foreach (SceneObjectPart part in m_parts.Values)
1895 { 2051 {
2052
1896 if (part != RootPart) 2053 if (part != RootPart)
1897 part.AddFullUpdateToAvatar(presence); 2054 part.AddFullUpdateToAvatar(presence);
2055
1898 } 2056 }
1899 } 2057 }
2058 lockPartsForRead(false);
1900 } 2059 }
1901 2060
1902 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2061 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1903 { 2062 {
1904 lock (m_parts) 2063 lockPartsForRead(true);
1905 { 2064 {
1906 foreach (SceneObjectPart part in m_parts.Values) 2065 foreach (SceneObjectPart part in m_parts.Values)
1907 { 2066 {
2067
1908 part.AddTerseUpdateToAvatar(presence); 2068 part.AddTerseUpdateToAvatar(presence);
2069
1909 } 2070 }
1910 } 2071 }
2072 lockPartsForRead(false);
1911 } 2073 }
1912 2074
1913 /// <summary> 2075 /// <summary>
@@ -1918,14 +2080,17 @@ namespace OpenSim.Region.Framework.Scenes
1918 checkAtTargets(); 2080 checkAtTargets();
1919 RootPart.ScheduleFullUpdate(); 2081 RootPart.ScheduleFullUpdate();
1920 2082
1921 lock (m_parts) 2083 lockPartsForRead(true);
1922 { 2084 {
1923 foreach (SceneObjectPart part in m_parts.Values) 2085 foreach (SceneObjectPart part in m_parts.Values)
1924 { 2086 {
2087
1925 if (part != RootPart) 2088 if (part != RootPart)
1926 part.ScheduleFullUpdate(); 2089 part.ScheduleFullUpdate();
2090
1927 } 2091 }
1928 } 2092 }
2093 lockPartsForRead(false);
1929 } 2094 }
1930 2095
1931 /// <summary> 2096 /// <summary>
@@ -1933,13 +2098,16 @@ namespace OpenSim.Region.Framework.Scenes
1933 /// </summary> 2098 /// </summary>
1934 public void ScheduleGroupForTerseUpdate() 2099 public void ScheduleGroupForTerseUpdate()
1935 { 2100 {
1936 lock (m_parts) 2101 lockPartsForRead(true);
1937 { 2102 {
1938 foreach (SceneObjectPart part in m_parts.Values) 2103 foreach (SceneObjectPart part in m_parts.Values)
1939 { 2104 {
2105
1940 part.ScheduleTerseUpdate(); 2106 part.ScheduleTerseUpdate();
2107
1941 } 2108 }
1942 } 2109 }
2110 lockPartsForRead(false);
1943 } 2111 }
1944 2112
1945 /// <summary> 2113 /// <summary>
@@ -1952,14 +2120,17 @@ namespace OpenSim.Region.Framework.Scenes
1952 2120
1953 RootPart.SendFullUpdateToAllClients(); 2121 RootPart.SendFullUpdateToAllClients();
1954 2122
1955 lock (m_parts) 2123 lockPartsForRead(true);
1956 { 2124 {
1957 foreach (SceneObjectPart part in m_parts.Values) 2125 foreach (SceneObjectPart part in m_parts.Values)
1958 { 2126 {
2127
1959 if (part != RootPart) 2128 if (part != RootPart)
1960 part.SendFullUpdateToAllClients(); 2129 part.SendFullUpdateToAllClients();
2130
1961 } 2131 }
1962 } 2132 }
2133 lockPartsForRead(false);
1963 } 2134 }
1964 2135
1965 /// <summary> 2136 /// <summary>
@@ -1990,14 +2161,15 @@ namespace OpenSim.Region.Framework.Scenes
1990 { 2161 {
1991 if (IsDeleted) 2162 if (IsDeleted)
1992 return; 2163 return;
1993 2164
1994 lock (m_parts) 2165 lockPartsForRead(true);
1995 { 2166 {
1996 foreach (SceneObjectPart part in m_parts.Values) 2167 foreach (SceneObjectPart part in m_parts.Values)
1997 { 2168 {
1998 part.SendTerseUpdateToAllClients(); 2169 part.SendTerseUpdateToAllClients();
1999 } 2170 }
2000 } 2171 }
2172 lockPartsForRead(false);
2001 } 2173 }
2002 2174
2003 #endregion 2175 #endregion
@@ -2011,16 +2183,18 @@ namespace OpenSim.Region.Framework.Scenes
2011 /// <returns>null if no child part with that linknum or child part</returns> 2183 /// <returns>null if no child part with that linknum or child part</returns>
2012 public SceneObjectPart GetLinkNumPart(int linknum) 2184 public SceneObjectPart GetLinkNumPart(int linknum)
2013 { 2185 {
2014 lock (m_parts) 2186 lockPartsForRead(true);
2015 { 2187 {
2016 foreach (SceneObjectPart part in m_parts.Values) 2188 foreach (SceneObjectPart part in m_parts.Values)
2017 { 2189 {
2018 if (part.LinkNum == linknum) 2190 if (part.LinkNum == linknum)
2019 { 2191 {
2192 lockPartsForRead(false);
2020 return part; 2193 return part;
2021 } 2194 }
2022 } 2195 }
2023 } 2196 }
2197 lockPartsForRead(false);
2024 2198
2025 return null; 2199 return null;
2026 } 2200 }
@@ -2048,17 +2222,19 @@ namespace OpenSim.Region.Framework.Scenes
2048 public SceneObjectPart GetChildPart(uint localID) 2222 public SceneObjectPart GetChildPart(uint localID)
2049 { 2223 {
2050 //m_log.DebugFormat("Entered looking for {0}", localID); 2224 //m_log.DebugFormat("Entered looking for {0}", localID);
2051 lock (m_parts) 2225 lockPartsForRead(true);
2052 { 2226 {
2053 foreach (SceneObjectPart part in m_parts.Values) 2227 foreach (SceneObjectPart part in m_parts.Values)
2054 { 2228 {
2055 //m_log.DebugFormat("Found {0}", part.LocalId); 2229 //m_log.DebugFormat("Found {0}", part.LocalId);
2056 if (part.LocalId == localID) 2230 if (part.LocalId == localID)
2057 { 2231 {
2232 lockPartsForRead(false);
2058 return part; 2233 return part;
2059 } 2234 }
2060 } 2235 }
2061 } 2236 }
2237 lockPartsForRead(false);
2062 2238
2063 return null; 2239 return null;
2064 } 2240 }
@@ -2088,17 +2264,19 @@ namespace OpenSim.Region.Framework.Scenes
2088 public bool HasChildPrim(uint localID) 2264 public bool HasChildPrim(uint localID)
2089 { 2265 {
2090 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2266 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2091 lock (m_parts) 2267 lockPartsForRead(true);
2092 { 2268 {
2093 foreach (SceneObjectPart part in m_parts.Values) 2269 foreach (SceneObjectPart part in m_parts.Values)
2094 { 2270 {
2095 //m_log.DebugFormat("Found {0}", part.LocalId); 2271 //m_log.DebugFormat("Found {0}", part.LocalId);
2096 if (part.LocalId == localID) 2272 if (part.LocalId == localID)
2097 { 2273 {
2274 lockPartsForRead(false);
2098 return true; 2275 return true;
2099 } 2276 }
2100 } 2277 }
2101 } 2278 }
2279 lockPartsForRead(false);
2102 2280
2103 return false; 2281 return false;
2104 } 2282 }
@@ -2148,53 +2326,57 @@ namespace OpenSim.Region.Framework.Scenes
2148 if (m_rootPart.LinkNum == 0) 2326 if (m_rootPart.LinkNum == 0)
2149 m_rootPart.LinkNum = 1; 2327 m_rootPart.LinkNum = 1;
2150 2328
2151 lock (m_parts) 2329 lockPartsForWrite(true);
2152 { 2330
2153 m_parts.Add(linkPart.UUID, linkPart); 2331 m_parts.Add(linkPart.UUID, linkPart);
2332
2333 lockPartsForWrite(false);
2154 2334
2155 // Insert in terms of link numbers, the new links 2335 // Insert in terms of link numbers, the new links
2156 // before the current ones (with the exception of 2336 // before the current ones (with the exception of
2157 // the root prim. Shuffle the old ones up 2337 // the root prim. Shuffle the old ones up
2158 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2338 lockPartsForRead(true);
2339 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2340 {
2341 if (kvp.Value.LinkNum != 1)
2159 { 2342 {
2160 if (kvp.Value.LinkNum != 1) 2343 // Don't update root prim link number
2161 { 2344 kvp.Value.LinkNum += objectGroup.PrimCount;
2162 // Don't update root prim link number
2163 kvp.Value.LinkNum += objectGroup.PrimCount;
2164 }
2165 } 2345 }
2346 }
2347 lockPartsForRead(false);
2166 2348
2167 linkPart.LinkNum = 2; 2349 linkPart.LinkNum = 2;
2168 2350
2169 linkPart.SetParent(this); 2351 linkPart.SetParent(this);
2170 linkPart.AddFlag(PrimFlags.CreateSelected); 2352 linkPart.AddFlag(PrimFlags.CreateSelected);
2171 2353
2172 //if (linkPart.PhysActor != null) 2354 //if (linkPart.PhysActor != null)
2173 //{ 2355 //{
2174 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2356 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2175 2357
2176 //linkPart.PhysActor = null; 2358 //linkPart.PhysActor = null;
2177 //} 2359 //}
2178 2360
2179 //TODO: rest of parts 2361 //TODO: rest of parts
2180 int linkNum = 3; 2362 int linkNum = 3;
2181 foreach (SceneObjectPart part in objectGroup.Children.Values) 2363 foreach (SceneObjectPart part in objectGroup.Children.Values)
2364 {
2365 if (part.UUID != objectGroup.m_rootPart.UUID)
2182 { 2366 {
2183 if (part.UUID != objectGroup.m_rootPart.UUID) 2367 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2184 {
2185 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2186 }
2187 part.ClearUndoState();
2188 } 2368 }
2369 part.ClearUndoState();
2189 } 2370 }
2190 2371
2191 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2372 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2192 objectGroup.m_isDeleted = true; 2373 objectGroup.m_isDeleted = true;
2374
2375 objectGroup.lockPartsForWrite(true);
2193 2376
2194 lock (objectGroup.m_parts) 2377 objectGroup.m_parts.Clear();
2195 { 2378
2196 objectGroup.m_parts.Clear(); 2379 objectGroup.lockPartsForWrite(false);
2197 }
2198 2380
2199 // Can't do this yet since backup still makes use of the root part without any synchronization 2381 // Can't do this yet since backup still makes use of the root part without any synchronization
2200// objectGroup.m_rootPart = null; 2382// objectGroup.m_rootPart = null;
@@ -2253,11 +2435,12 @@ namespace OpenSim.Region.Framework.Scenes
2253 Quaternion worldRot = linkPart.GetWorldRotation(); 2435 Quaternion worldRot = linkPart.GetWorldRotation();
2254 2436
2255 // Remove the part from this object 2437 // Remove the part from this object
2256 lock (m_parts) 2438 lockPartsForWrite(true);
2257 { 2439 {
2258 m_parts.Remove(linkPart.UUID); 2440 m_parts.Remove(linkPart.UUID);
2259 } 2441 }
2260 2442 lockPartsForWrite(false);
2443 lockPartsForRead(true);
2261 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2444 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2262 RootPart.LinkNum = 0; 2445 RootPart.LinkNum = 0;
2263 else 2446 else
@@ -2268,6 +2451,7 @@ namespace OpenSim.Region.Framework.Scenes
2268 p.LinkNum--; 2451 p.LinkNum--;
2269 } 2452 }
2270 } 2453 }
2454 lockPartsForRead(false);
2271 2455
2272 linkPart.ParentID = 0; 2456 linkPart.ParentID = 0;
2273 linkPart.LinkNum = 0; 2457 linkPart.LinkNum = 0;
@@ -2585,9 +2769,12 @@ namespace OpenSim.Region.Framework.Scenes
2585 2769
2586 if (selectionPart != null) 2770 if (selectionPart != null)
2587 { 2771 {
2588 lock (m_parts) 2772 lockPartsForRead(true);
2773 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2774 lockPartsForRead(false);
2775 foreach (SceneObjectPart part in parts)
2589 { 2776 {
2590 foreach (SceneObjectPart part in m_parts.Values) 2777 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2591 { 2778 {
2592 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2779 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2593 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2780 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2597,12 +2784,13 @@ namespace OpenSim.Region.Framework.Scenes
2597 break; 2784 break;
2598 } 2785 }
2599 } 2786 }
2787 }
2600 2788
2601 foreach (SceneObjectPart part in m_parts.Values) 2789 foreach (SceneObjectPart part in parts)
2602 { 2790 {
2603 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2791 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2604 }
2605 } 2792 }
2793
2606 } 2794 }
2607 } 2795 }
2608 2796
@@ -2688,11 +2876,9 @@ namespace OpenSim.Region.Framework.Scenes
2688 scale.Y = m_scene.m_maxNonphys; 2876 scale.Y = m_scene.m_maxNonphys;
2689 if (scale.Z > m_scene.m_maxNonphys) 2877 if (scale.Z > m_scene.m_maxNonphys)
2690 scale.Z = m_scene.m_maxNonphys; 2878 scale.Z = m_scene.m_maxNonphys;
2691
2692 SceneObjectPart part = GetChildPart(localID); 2879 SceneObjectPart part = GetChildPart(localID);
2693 if (part != null) 2880 if (part != null)
2694 { 2881 {
2695 part.Resize(scale);
2696 if (part.PhysActor != null) 2882 if (part.PhysActor != null)
2697 { 2883 {
2698 if (part.PhysActor.IsPhysical) 2884 if (part.PhysActor.IsPhysical)
@@ -2707,7 +2893,7 @@ namespace OpenSim.Region.Framework.Scenes
2707 part.PhysActor.Size = scale; 2893 part.PhysActor.Size = scale;
2708 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2894 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2709 } 2895 }
2710 //if (part.UUID != m_rootPart.UUID) 2896 part.Resize(scale);
2711 2897
2712 HasGroupChanged = true; 2898 HasGroupChanged = true;
2713 ScheduleGroupForFullUpdate(); 2899 ScheduleGroupForFullUpdate();
@@ -2748,77 +2934,76 @@ namespace OpenSim.Region.Framework.Scenes
2748 float y = (scale.Y / part.Scale.Y); 2934 float y = (scale.Y / part.Scale.Y);
2749 float z = (scale.Z / part.Scale.Z); 2935 float z = (scale.Z / part.Scale.Z);
2750 2936
2751 lock (m_parts) 2937 lockPartsForRead(true);
2938 if (x > 1.0f || y > 1.0f || z > 1.0f)
2752 { 2939 {
2753 if (x > 1.0f || y > 1.0f || z > 1.0f) 2940 foreach (SceneObjectPart obPart in m_parts.Values)
2754 { 2941 {
2755 foreach (SceneObjectPart obPart in m_parts.Values) 2942 if (obPart.UUID != m_rootPart.UUID)
2756 { 2943 {
2757 if (obPart.UUID != m_rootPart.UUID) 2944 Vector3 oldSize = new Vector3(obPart.Scale);
2758 {
2759 Vector3 oldSize = new Vector3(obPart.Scale);
2760 2945
2761 float f = 1.0f; 2946 float f = 1.0f;
2762 float a = 1.0f; 2947 float a = 1.0f;
2763 2948
2764 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2949 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2950 {
2951 if (oldSize.X*x > m_scene.m_maxPhys)
2765 { 2952 {
2766 if (oldSize.X*x > m_scene.m_maxPhys) 2953 f = m_scene.m_maxPhys / oldSize.X;
2767 { 2954 a = f / x;
2768 f = m_scene.m_maxPhys / oldSize.X; 2955 x *= a;
2769 a = f / x; 2956 y *= a;
2770 x *= a; 2957 z *= a;
2771 y *= a;
2772 z *= a;
2773 }
2774 if (oldSize.Y*y > m_scene.m_maxPhys)
2775 {
2776 f = m_scene.m_maxPhys / oldSize.Y;
2777 a = f / y;
2778 x *= a;
2779 y *= a;
2780 z *= a;
2781 }
2782 if (oldSize.Z*z > m_scene.m_maxPhys)
2783 {
2784 f = m_scene.m_maxPhys / oldSize.Z;
2785 a = f / z;
2786 x *= a;
2787 y *= a;
2788 z *= a;
2789 }
2790 } 2958 }
2791 else 2959 if (oldSize.Y*y > m_scene.m_maxPhys)
2960 {
2961 f = m_scene.m_maxPhys / oldSize.Y;
2962 a = f / y;
2963 x *= a;
2964 y *= a;
2965 z *= a;
2966 }
2967 if (oldSize.Z*z > m_scene.m_maxPhys)
2792 { 2968 {
2793 if (oldSize.X*x > m_scene.m_maxNonphys) 2969 f = m_scene.m_maxPhys / oldSize.Z;
2794 { 2970 a = f / z;
2795 f = m_scene.m_maxNonphys / oldSize.X; 2971 x *= a;
2796 a = f / x; 2972 y *= a;
2797 x *= a; 2973 z *= a;
2798 y *= a; 2974 }
2799 z *= a; 2975 }
2800 } 2976 else
2801 if (oldSize.Y*y > m_scene.m_maxNonphys) 2977 {
2802 { 2978 if (oldSize.X*x > m_scene.m_maxNonphys)
2803 f = m_scene.m_maxNonphys / oldSize.Y; 2979 {
2804 a = f / y; 2980 f = m_scene.m_maxNonphys / oldSize.X;
2805 x *= a; 2981 a = f / x;
2806 y *= a; 2982 x *= a;
2807 z *= a; 2983 y *= a;
2808 } 2984 z *= a;
2809 if (oldSize.Z*z > m_scene.m_maxNonphys) 2985 }
2810 { 2986 if (oldSize.Y*y > m_scene.m_maxNonphys)
2811 f = m_scene.m_maxNonphys / oldSize.Z; 2987 {
2812 a = f / z; 2988 f = m_scene.m_maxNonphys / oldSize.Y;
2813 x *= a; 2989 a = f / y;
2814 y *= a; 2990 x *= a;
2815 z *= a; 2991 y *= a;
2816 } 2992 z *= a;
2993 }
2994 if (oldSize.Z*z > m_scene.m_maxNonphys)
2995 {
2996 f = m_scene.m_maxNonphys / oldSize.Z;
2997 a = f / z;
2998 x *= a;
2999 y *= a;
3000 z *= a;
2817 } 3001 }
2818 } 3002 }
2819 } 3003 }
2820 } 3004 }
2821 } 3005 }
3006 lockPartsForRead(false);
2822 3007
2823 Vector3 prevScale = part.Scale; 3008 Vector3 prevScale = part.Scale;
2824 prevScale.X *= x; 3009 prevScale.X *= x;
@@ -2826,7 +3011,7 @@ namespace OpenSim.Region.Framework.Scenes
2826 prevScale.Z *= z; 3011 prevScale.Z *= z;
2827 part.Resize(prevScale); 3012 part.Resize(prevScale);
2828 3013
2829 lock (m_parts) 3014 lockPartsForRead(true);
2830 { 3015 {
2831 foreach (SceneObjectPart obPart in m_parts.Values) 3016 foreach (SceneObjectPart obPart in m_parts.Values)
2832 { 3017 {
@@ -2845,6 +3030,7 @@ namespace OpenSim.Region.Framework.Scenes
2845 } 3030 }
2846 } 3031 }
2847 } 3032 }
3033 lockPartsForRead(false);
2848 3034
2849 if (part.PhysActor != null) 3035 if (part.PhysActor != null)
2850 { 3036 {
@@ -2925,7 +3111,7 @@ namespace OpenSim.Region.Framework.Scenes
2925 axDiff *= Quaternion.Inverse(partRotation); 3111 axDiff *= Quaternion.Inverse(partRotation);
2926 diff = axDiff; 3112 diff = axDiff;
2927 3113
2928 lock (m_parts) 3114 lockPartsForRead(true);
2929 { 3115 {
2930 foreach (SceneObjectPart obPart in m_parts.Values) 3116 foreach (SceneObjectPart obPart in m_parts.Values)
2931 { 3117 {
@@ -2935,6 +3121,7 @@ namespace OpenSim.Region.Framework.Scenes
2935 } 3121 }
2936 } 3122 }
2937 } 3123 }
3124 lockPartsForRead(false);
2938 3125
2939 AbsolutePosition = newPos; 3126 AbsolutePosition = newPos;
2940 3127
@@ -3052,7 +3239,7 @@ namespace OpenSim.Region.Framework.Scenes
3052 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3239 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3053 } 3240 }
3054 3241
3055 lock (m_parts) 3242 lockPartsForRead(true);
3056 { 3243 {
3057 foreach (SceneObjectPart prim in m_parts.Values) 3244 foreach (SceneObjectPart prim in m_parts.Values)
3058 { 3245 {
@@ -3070,6 +3257,7 @@ namespace OpenSim.Region.Framework.Scenes
3070 } 3257 }
3071 } 3258 }
3072 } 3259 }
3260 lockPartsForRead(false);
3073 3261
3074 m_rootPart.ScheduleTerseUpdate(); 3262 m_rootPart.ScheduleTerseUpdate();
3075 } 3263 }
@@ -3168,7 +3356,7 @@ namespace OpenSim.Region.Framework.Scenes
3168 if (atTargets.Count > 0) 3356 if (atTargets.Count > 0)
3169 { 3357 {
3170 uint[] localids = new uint[0]; 3358 uint[] localids = new uint[0];
3171 lock (m_parts) 3359 lockPartsForRead(true);
3172 { 3360 {
3173 localids = new uint[m_parts.Count]; 3361 localids = new uint[m_parts.Count];
3174 int cntr = 0; 3362 int cntr = 0;
@@ -3178,6 +3366,7 @@ namespace OpenSim.Region.Framework.Scenes
3178 cntr++; 3366 cntr++;
3179 } 3367 }
3180 } 3368 }
3369 lockPartsForRead(false);
3181 3370
3182 for (int ctr = 0; ctr < localids.Length; ctr++) 3371 for (int ctr = 0; ctr < localids.Length; ctr++)
3183 { 3372 {
@@ -3196,7 +3385,7 @@ namespace OpenSim.Region.Framework.Scenes
3196 { 3385 {
3197 //trigger not_at_target 3386 //trigger not_at_target
3198 uint[] localids = new uint[0]; 3387 uint[] localids = new uint[0];
3199 lock (m_parts) 3388 lockPartsForRead(true);
3200 { 3389 {
3201 localids = new uint[m_parts.Count]; 3390 localids = new uint[m_parts.Count];
3202 int cntr = 0; 3391 int cntr = 0;
@@ -3206,7 +3395,8 @@ namespace OpenSim.Region.Framework.Scenes
3206 cntr++; 3395 cntr++;
3207 } 3396 }
3208 } 3397 }
3209 3398 lockPartsForRead(false);
3399
3210 for (int ctr = 0; ctr < localids.Length; ctr++) 3400 for (int ctr = 0; ctr < localids.Length; ctr++)
3211 { 3401 {
3212 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3402 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3219,19 +3409,20 @@ namespace OpenSim.Region.Framework.Scenes
3219 public float GetMass() 3409 public float GetMass()
3220 { 3410 {
3221 float retmass = 0f; 3411 float retmass = 0f;
3222 lock (m_parts) 3412 lockPartsForRead(true);
3223 { 3413 {
3224 foreach (SceneObjectPart part in m_parts.Values) 3414 foreach (SceneObjectPart part in m_parts.Values)
3225 { 3415 {
3226 retmass += part.GetMass(); 3416 retmass += part.GetMass();
3227 } 3417 }
3228 } 3418 }
3419 lockPartsForRead(false);
3229 return retmass; 3420 return retmass;
3230 } 3421 }
3231 3422
3232 public void CheckSculptAndLoad() 3423 public void CheckSculptAndLoad()
3233 { 3424 {
3234 lock (m_parts) 3425 lockPartsForRead(true);
3235 { 3426 {
3236 if (!IsDeleted) 3427 if (!IsDeleted)
3237 { 3428 {
@@ -3256,6 +3447,7 @@ namespace OpenSim.Region.Framework.Scenes
3256 } 3447 }
3257 } 3448 }
3258 } 3449 }
3450 lockPartsForRead(false);
3259 } 3451 }
3260 3452
3261 protected void AssetReceived(string id, Object sender, AssetBase asset) 3453 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3276,7 +3468,7 @@ namespace OpenSim.Region.Framework.Scenes
3276 /// <param name="client"></param> 3468 /// <param name="client"></param>
3277 public void SetGroup(UUID GroupID, IClientAPI client) 3469 public void SetGroup(UUID GroupID, IClientAPI client)
3278 { 3470 {
3279 lock (m_parts) 3471 lockPartsForRead(true);
3280 { 3472 {
3281 foreach (SceneObjectPart part in m_parts.Values) 3473 foreach (SceneObjectPart part in m_parts.Values)
3282 { 3474 {
@@ -3286,7 +3478,7 @@ namespace OpenSim.Region.Framework.Scenes
3286 3478
3287 HasGroupChanged = true; 3479 HasGroupChanged = true;
3288 } 3480 }
3289 3481 lockPartsForRead(false);
3290 ScheduleGroupForFullUpdate(); 3482 ScheduleGroupForFullUpdate();
3291 } 3483 }
3292 3484
@@ -3305,11 +3497,12 @@ namespace OpenSim.Region.Framework.Scenes
3305 3497
3306 public void SetAttachmentPoint(byte point) 3498 public void SetAttachmentPoint(byte point)
3307 { 3499 {
3308 lock (m_parts) 3500 lockPartsForRead(true);
3309 { 3501 {
3310 foreach (SceneObjectPart part in m_parts.Values) 3502 foreach (SceneObjectPart part in m_parts.Values)
3311 part.SetAttachmentPoint(point); 3503 part.SetAttachmentPoint(point);
3312 } 3504 }
3505 lockPartsForRead(false);
3313 } 3506 }
3314 3507
3315 #region ISceneObject 3508 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b6916f2..19e3023 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -389,12 +389,16 @@ namespace OpenSim.Region.Framework.Scenes
389 } 389 }
390 390
391 /// <value> 391 /// <value>
392 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 392 /// Get the inventory list
393 /// </value> 393 /// </value>
394 public TaskInventoryDictionary TaskInventory 394 public TaskInventoryDictionary TaskInventory
395 { 395 {
396 get { return m_inventory.Items; } 396 get {
397 set { m_inventory.Items = value; } 397 return m_inventory.Items;
398 }
399 set {
400 m_inventory.Items = value;
401 }
398 } 402 }
399 403
400 public uint ObjectFlags 404 public uint ObjectFlags
@@ -1064,14 +1068,6 @@ namespace OpenSim.Region.Framework.Scenes
1064 } 1068 }
1065 } 1069 }
1066 1070
1067 /// <summary>
1068 /// Clear all pending updates of parts to clients
1069 /// </summary>
1070 private void ClearUpdateSchedule()
1071 {
1072 m_updateFlag = 0;
1073 }
1074
1075 private void SendObjectPropertiesToClient(UUID AgentID) 1071 private void SendObjectPropertiesToClient(UUID AgentID)
1076 { 1072 {
1077 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1073 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -2109,17 +2105,18 @@ namespace OpenSim.Region.Framework.Scenes
2109 //Trys to fetch sound id from prim's inventory. 2105 //Trys to fetch sound id from prim's inventory.
2110 //Prim's inventory doesn't support non script items yet 2106 //Prim's inventory doesn't support non script items yet
2111 2107
2112 lock (TaskInventory) 2108 TaskInventory.LockItemsForRead(true);
2109
2110 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2113 { 2111 {
2114 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2112 if (item.Value.Name == sound)
2115 { 2113 {
2116 if (item.Value.Name == sound) 2114 soundID = item.Value.ItemID;
2117 { 2115 break;
2118 soundID = item.Value.ItemID;
2119 break;
2120 }
2121 } 2116 }
2122 } 2117 }
2118
2119 TaskInventory.LockItemsForRead(false);
2123 } 2120 }
2124 2121
2125 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2122 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2185,6 +2182,11 @@ namespace OpenSim.Region.Framework.Scenes
2185 ParentGroup.HasGroupChanged = true; 2182 ParentGroup.HasGroupChanged = true;
2186 ScheduleFullUpdate(); 2183 ScheduleFullUpdate();
2187 } 2184 }
2185
2186 public void RotLookAt(Quaternion target, float strength, float damping)
2187 {
2188 m_parentGroup.rotLookAt(target, strength, damping);
2189 }
2188 2190
2189 /// <summary> 2191 /// <summary>
2190 /// Schedules this prim for a full update 2192 /// Schedules this prim for a full update
@@ -2389,8 +2391,8 @@ namespace OpenSim.Region.Framework.Scenes
2389 { 2391 {
2390 const float ROTATION_TOLERANCE = 0.01f; 2392 const float ROTATION_TOLERANCE = 0.01f;
2391 const float VELOCITY_TOLERANCE = 0.001f; 2393 const float VELOCITY_TOLERANCE = 0.001f;
2392 const float POSITION_TOLERANCE = 0.05f; 2394 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2393 const int TIME_MS_TOLERANCE = 3000; 2395 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2394 2396
2395 if (m_updateFlag == 1) 2397 if (m_updateFlag == 1)
2396 { 2398 {
@@ -2404,7 +2406,7 @@ namespace OpenSim.Region.Framework.Scenes
2404 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2406 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2405 { 2407 {
2406 AddTerseUpdateToAllAvatars(); 2408 AddTerseUpdateToAllAvatars();
2407 ClearUpdateSchedule(); 2409
2408 2410
2409 // This causes the Scene to 'poll' physical objects every couple of frames 2411 // This causes the Scene to 'poll' physical objects every couple of frames
2410 // bad, so it's been replaced by an event driven method. 2412 // bad, so it's been replaced by an event driven method.
@@ -2422,16 +2424,18 @@ namespace OpenSim.Region.Framework.Scenes
2422 m_lastAngularVelocity = AngularVelocity; 2424 m_lastAngularVelocity = AngularVelocity;
2423 m_lastTerseSent = Environment.TickCount; 2425 m_lastTerseSent = Environment.TickCount;
2424 } 2426 }
2427 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2428 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2425 } 2429 }
2426 else 2430 else
2427 { 2431 {
2428 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2432 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2429 { 2433 {
2430 AddFullUpdateToAllAvatars(); 2434 AddFullUpdateToAllAvatars();
2431 ClearUpdateSchedule(); 2435 m_updateFlag = 0; //Same here
2432 } 2436 }
2433 } 2437 }
2434 ClearUpdateSchedule(); 2438 m_updateFlag = 0;
2435 } 2439 }
2436 2440
2437 /// <summary> 2441 /// <summary>
@@ -2458,17 +2462,16 @@ namespace OpenSim.Region.Framework.Scenes
2458 if (!UUID.TryParse(sound, out soundID)) 2462 if (!UUID.TryParse(sound, out soundID))
2459 { 2463 {
2460 // search sound file from inventory 2464 // search sound file from inventory
2461 lock (TaskInventory) 2465 TaskInventory.LockItemsForRead(true);
2466 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2462 { 2467 {
2463 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2468 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2464 { 2469 {
2465 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2470 soundID = item.Value.ItemID;
2466 { 2471 break;
2467 soundID = item.Value.ItemID;
2468 break;
2469 }
2470 } 2472 }
2471 } 2473 }
2474 TaskInventory.LockItemsForRead(false);
2472 } 2475 }
2473 2476
2474 if (soundID == UUID.Zero) 2477 if (soundID == UUID.Zero)
@@ -2684,6 +2687,13 @@ namespace OpenSim.Region.Framework.Scenes
2684 SetText(text); 2687 SetText(text);
2685 } 2688 }
2686 2689
2690 public void StopLookAt()
2691 {
2692 m_parentGroup.stopLookAt();
2693
2694 m_parentGroup.ScheduleGroupForTerseUpdate();
2695 }
2696
2687 public void StopMoveToTarget() 2697 public void StopMoveToTarget()
2688 { 2698 {
2689 m_parentGroup.stopMoveToTarget(); 2699 m_parentGroup.stopMoveToTarget();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 22eedba..4780ff2 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -80,7 +80,9 @@ namespace OpenSim.Region.Framework.Scenes
80 /// </value> 80 /// </value>
81 protected internal TaskInventoryDictionary Items 81 protected internal TaskInventoryDictionary Items
82 { 82 {
83 get { return m_items; } 83 get {
84 return m_items;
85 }
84 set 86 set
85 { 87 {
86 m_items = value; 88 m_items = value;
@@ -116,22 +118,25 @@ namespace OpenSim.Region.Framework.Scenes
116 /// <param name="linkNum">Link number for the part</param> 118 /// <param name="linkNum">Link number for the part</param>
117 public void ResetInventoryIDs() 119 public void ResetInventoryIDs()
118 { 120 {
119 lock (Items) 121 m_items.LockItemsForWrite(true);
122
123 if (0 == Items.Count)
120 { 124 {
121 if (0 == Items.Count) 125 m_items.LockItemsForWrite(false);
122 return; 126 return;
127 }
123 128
124 HasInventoryChanged = true; 129 HasInventoryChanged = true;
125 m_part.ParentGroup.HasGroupChanged = true; 130 m_part.ParentGroup.HasGroupChanged = true;
126 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 131 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
127 Items.Clear(); 132 Items.Clear();
128 133
129 foreach (TaskInventoryItem item in items) 134 foreach (TaskInventoryItem item in items)
130 { 135 {
131 item.ResetIDs(m_part.UUID); 136 item.ResetIDs(m_part.UUID);
132 Items.Add(item.ItemID, item); 137 Items.Add(item.ItemID, item);
133 }
134 } 138 }
139 m_items.LockItemsForWrite(false);
135 } 140 }
136 141
137 /// <summary> 142 /// <summary>
@@ -140,25 +145,25 @@ namespace OpenSim.Region.Framework.Scenes
140 /// <param name="ownerId"></param> 145 /// <param name="ownerId"></param>
141 public void ChangeInventoryOwner(UUID ownerId) 146 public void ChangeInventoryOwner(UUID ownerId)
142 { 147 {
143 lock (Items) 148 m_items.LockItemsForWrite(true);
149 if (0 == Items.Count)
144 { 150 {
145 if (0 == Items.Count) 151 m_items.LockItemsForWrite(false);
146 { 152 return;
147 return; 153 }
148 }
149 154
150 HasInventoryChanged = true; 155 HasInventoryChanged = true;
151 m_part.ParentGroup.HasGroupChanged = true; 156 m_part.ParentGroup.HasGroupChanged = true;
152 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 157 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
153 foreach (TaskInventoryItem item in items) 158 foreach (TaskInventoryItem item in items)
159 {
160 if (ownerId != item.OwnerID)
154 { 161 {
155 if (ownerId != item.OwnerID) 162 item.LastOwnerID = item.OwnerID;
156 { 163 item.OwnerID = ownerId;
157 item.LastOwnerID = item.OwnerID;
158 item.OwnerID = ownerId;
159 }
160 } 164 }
161 } 165 }
166 m_items.LockItemsForWrite(false);
162 } 167 }
163 168
164 /// <summary> 169 /// <summary>
@@ -167,24 +172,24 @@ namespace OpenSim.Region.Framework.Scenes
167 /// <param name="groupID"></param> 172 /// <param name="groupID"></param>
168 public void ChangeInventoryGroup(UUID groupID) 173 public void ChangeInventoryGroup(UUID groupID)
169 { 174 {
170 lock (Items) 175 m_items.LockItemsForWrite(true);
176 if (0 == Items.Count)
171 { 177 {
172 if (0 == Items.Count) 178 m_items.LockItemsForWrite(false);
173 { 179 return;
174 return; 180 }
175 }
176 181
177 HasInventoryChanged = true; 182 HasInventoryChanged = true;
178 m_part.ParentGroup.HasGroupChanged = true; 183 m_part.ParentGroup.HasGroupChanged = true;
179 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 184 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
180 foreach (TaskInventoryItem item in items) 185 foreach (TaskInventoryItem item in items)
186 {
187 if (groupID != item.GroupID)
181 { 188 {
182 if (groupID != item.GroupID) 189 item.GroupID = groupID;
183 {
184 item.GroupID = groupID;
185 }
186 } 190 }
187 } 191 }
192 m_items.LockItemsForWrite(false);
188 } 193 }
189 194
190 /// <summary> 195 /// <summary>
@@ -192,14 +197,14 @@ namespace OpenSim.Region.Framework.Scenes
192 /// </summary> 197 /// </summary>
193 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 198 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
194 { 199 {
195 lock (m_items) 200 Items.LockItemsForRead(true);
201 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
202 Items.LockItemsForRead(false);
203 foreach (TaskInventoryItem item in items)
196 { 204 {
197 foreach (TaskInventoryItem item in Items.Values) 205 if ((int)InventoryType.LSL == item.InvType)
198 { 206 {
199 if ((int)InventoryType.LSL == item.InvType) 207 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
200 {
201 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 }
203 } 208 }
204 } 209 }
205 } 210 }
@@ -209,17 +214,20 @@ namespace OpenSim.Region.Framework.Scenes
209 /// </summary> 214 /// </summary>
210 public void RemoveScriptInstances() 215 public void RemoveScriptInstances()
211 { 216 {
212 lock (Items) 217 Items.LockItemsForRead(true);
218 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
219 Items.LockItemsForRead(false);
220
221 foreach (TaskInventoryItem item in items)
213 { 222 {
214 foreach (TaskInventoryItem item in Items.Values) 223 if ((int)InventoryType.LSL == item.InvType)
215 { 224 {
216 if ((int)InventoryType.LSL == item.InvType) 225 RemoveScriptInstance(item.ItemID);
217 { 226 m_part.RemoveScriptEvents(item.ItemID);
218 RemoveScriptInstance(item.ItemID);
219 m_part.RemoveScriptEvents(item.ItemID);
220 }
221 } 227 }
222 } 228 }
229
230
223 } 231 }
224 232
225 /// <summary> 233 /// <summary>
@@ -244,8 +252,10 @@ namespace OpenSim.Region.Framework.Scenes
244 if (stateSource == 1 && // Prim crossing 252 if (stateSource == 1 && // Prim crossing
245 m_part.ParentGroup.Scene.m_trustBinaries) 253 m_part.ParentGroup.Scene.m_trustBinaries)
246 { 254 {
255 m_items.LockItemsForWrite(true);
247 m_items[item.ItemID].PermsMask = 0; 256 m_items[item.ItemID].PermsMask = 0;
248 m_items[item.ItemID].PermsGranter = UUID.Zero; 257 m_items[item.ItemID].PermsGranter = UUID.Zero;
258 m_items.LockItemsForWrite(false);
249 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 259 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
250 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 260 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
251 m_part.ParentGroup.AddActiveScriptCount(1); 261 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -267,8 +277,10 @@ namespace OpenSim.Region.Framework.Scenes
267 { 277 {
268 if (m_part.ParentGroup.m_savedScriptState != null) 278 if (m_part.ParentGroup.m_savedScriptState != null)
269 RestoreSavedScriptState(item.OldItemID, item.ItemID); 279 RestoreSavedScriptState(item.OldItemID, item.ItemID);
280 m_items.LockItemsForWrite(true);
270 m_items[item.ItemID].PermsMask = 0; 281 m_items[item.ItemID].PermsMask = 0;
271 m_items[item.ItemID].PermsGranter = UUID.Zero; 282 m_items[item.ItemID].PermsGranter = UUID.Zero;
283 m_items.LockItemsForWrite(false);
272 string script = Utils.BytesToString(asset.Data); 284 string script = Utils.BytesToString(asset.Data);
273 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 285 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
274 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 286 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
@@ -303,7 +315,8 @@ namespace OpenSim.Region.Framework.Scenes
303 /// </param> 315 /// </param>
304 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 316 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
305 { 317 {
306 lock (m_items) 318 m_items.LockItemsForRead(true);
319 if (m_items.ContainsKey(itemId))
307 { 320 {
308 if (m_items.ContainsKey(itemId)) 321 if (m_items.ContainsKey(itemId))
309 { 322 {
@@ -317,7 +330,17 @@ namespace OpenSim.Region.Framework.Scenes
317 itemId, m_part.Name, m_part.UUID, 330 itemId, m_part.Name, m_part.UUID,
318 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 331 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
319 } 332 }
333 m_items.LockItemsForRead(false);
334 }
335 else
336 {
337 m_items.LockItemsForRead(false);
338 m_log.ErrorFormat(
339 "[PRIM INVENTORY]: " +
340 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
341 itemId, m_part.Name, m_part.UUID);
320 } 342 }
343
321 } 344 }
322 345
323 /// <summary> 346 /// <summary>
@@ -349,11 +372,16 @@ namespace OpenSim.Region.Framework.Scenes
349 /// <returns></returns> 372 /// <returns></returns>
350 private bool InventoryContainsName(string name) 373 private bool InventoryContainsName(string name)
351 { 374 {
352 foreach (TaskInventoryItem item in Items.Values) 375 m_items.LockItemsForRead(true);
376 foreach (TaskInventoryItem item in m_items.Values)
353 { 377 {
354 if (item.Name == name) 378 if (item.Name == name)
379 {
380 m_items.LockItemsForRead(false);
355 return true; 381 return true;
382 }
356 } 383 }
384 m_items.LockItemsForRead(false);
357 return false; 385 return false;
358 } 386 }
359 387
@@ -395,7 +423,9 @@ namespace OpenSim.Region.Framework.Scenes
395 /// <param name="item"></param> 423 /// <param name="item"></param>
396 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 424 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
397 { 425 {
426 m_items.LockItemsForRead(true);
398 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); 427 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
428 m_items.LockItemsForRead(false);
399 foreach (TaskInventoryItem i in il) 429 foreach (TaskInventoryItem i in il)
400 { 430 {
401 if (i.Name == item.Name) 431 if (i.Name == item.Name)
@@ -432,15 +462,14 @@ namespace OpenSim.Region.Framework.Scenes
432 item.ParentPartID = m_part.UUID; 462 item.ParentPartID = m_part.UUID;
433 item.Name = name; 463 item.Name = name;
434 464
435 lock (m_items) 465 m_items.LockItemsForWrite(true);
436 { 466 m_items.Add(item.ItemID, item);
437 m_items.Add(item.ItemID, item); 467 m_items.LockItemsForWrite(false);
438
439 if (allowedDrop) 468 if (allowedDrop)
440 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 469 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
441 else 470 else
442 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 471 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
443 } 472
444 473
445 m_inventorySerial++; 474 m_inventorySerial++;
446 //m_inventorySerial += 2; 475 //m_inventorySerial += 2;
@@ -457,14 +486,13 @@ namespace OpenSim.Region.Framework.Scenes
457 /// <param name="items"></param> 486 /// <param name="items"></param>
458 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 487 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
459 { 488 {
460 lock (m_items) 489 m_items.LockItemsForWrite(true);
490 foreach (TaskInventoryItem item in items)
461 { 491 {
462 foreach (TaskInventoryItem item in items) 492 m_items.Add(item.ItemID, item);
463 { 493 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
464 m_items.Add(item.ItemID, item);
465 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
466 }
467 } 494 }
495 m_items.LockItemsForWrite(false);
468 496
469 m_inventorySerial++; 497 m_inventorySerial++;
470 } 498 }
@@ -477,8 +505,9 @@ namespace OpenSim.Region.Framework.Scenes
477 public TaskInventoryItem GetInventoryItem(UUID itemId) 505 public TaskInventoryItem GetInventoryItem(UUID itemId)
478 { 506 {
479 TaskInventoryItem item; 507 TaskInventoryItem item;
508 m_items.LockItemsForRead(true);
480 m_items.TryGetValue(itemId, out item); 509 m_items.TryGetValue(itemId, out item);
481 510 m_items.LockItemsForRead(false);
482 return item; 511 return item;
483 } 512 }
484 513
@@ -490,46 +519,46 @@ namespace OpenSim.Region.Framework.Scenes
490 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 519 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
491 public bool UpdateInventoryItem(TaskInventoryItem item) 520 public bool UpdateInventoryItem(TaskInventoryItem item)
492 { 521 {
493 lock (m_items) 522 m_items.LockItemsForWrite(true);
523
524 if (m_items.ContainsKey(item.ItemID))
494 { 525 {
495 if (m_items.ContainsKey(item.ItemID)) 526 item.ParentID = m_part.UUID;
527 item.ParentPartID = m_part.UUID;
528 item.Flags = m_items[item.ItemID].Flags;
529 if (item.AssetID == UUID.Zero)
496 { 530 {
497 item.ParentID = m_part.UUID; 531 item.AssetID = m_items[item.ItemID].AssetID;
498 item.ParentPartID = m_part.UUID; 532 }
499 item.Flags = m_items[item.ItemID].Flags; 533 else if ((InventoryType)item.Type == InventoryType.Notecard)
500 if (item.AssetID == UUID.Zero) 534 {
501 { 535 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
502 item.AssetID = m_items[item.ItemID].AssetID;
503 }
504 else if ((InventoryType)item.Type == InventoryType.Notecard)
505 {
506 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
507 536
508 if (presence != null) 537 if (presence != null)
509 { 538 {
510 presence.ControllingClient.SendAgentAlertMessage( 539 presence.ControllingClient.SendAgentAlertMessage(
511 "Notecard saved", false); 540 "Notecard saved", false);
512 }
513 } 541 }
542 }
514 543
515 m_items[item.ItemID] = item; 544 m_items[item.ItemID] = item;
516 m_inventorySerial++; 545 m_inventorySerial++;
517 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 546 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
518
519 HasInventoryChanged = true;
520 m_part.ParentGroup.HasGroupChanged = true;
521 547
522 return true; 548 HasInventoryChanged = true;
523 } 549 m_part.ParentGroup.HasGroupChanged = true;
524 else 550 m_items.LockItemsForWrite(false);
525 { 551 return true;
526 m_log.ErrorFormat( 552 }
527 "[PRIM INVENTORY]: " + 553 else
528 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 554 {
529 item.ItemID, m_part.Name, m_part.UUID, 555 m_log.ErrorFormat(
530 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 556 "[PRIM INVENTORY]: " +
531 } 557 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
558 item.ItemID, m_part.Name, m_part.UUID,
559 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
532 } 560 }
561 m_items.LockItemsForWrite(false);
533 562
534 return false; 563 return false;
535 } 564 }
@@ -542,52 +571,54 @@ namespace OpenSim.Region.Framework.Scenes
542 /// in this prim's inventory.</returns> 571 /// in this prim's inventory.</returns>
543 public int RemoveInventoryItem(UUID itemID) 572 public int RemoveInventoryItem(UUID itemID)
544 { 573 {
545 lock (m_items) 574 m_items.LockItemsForRead(true);
575
576 if (m_items.ContainsKey(itemID))
546 { 577 {
547 if (m_items.ContainsKey(itemID)) 578 int type = m_items[itemID].InvType;
579 m_items.LockItemsForRead(false);
580 if (type == 10) // Script
548 { 581 {
549 int type = m_items[itemID].InvType; 582 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
550 if (type == 10) // Script 583 }
551 { 584 m_items.LockItemsForWrite(true);
552 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 585 m_items.Remove(itemID);
553 } 586 m_items.LockItemsForWrite(false);
554 m_items.Remove(itemID); 587 m_inventorySerial++;
555 m_inventorySerial++; 588 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
556 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
557
558 HasInventoryChanged = true;
559 m_part.ParentGroup.HasGroupChanged = true;
560 589
561 int scriptcount = 0; 590 HasInventoryChanged = true;
562 lock (m_items) 591 m_part.ParentGroup.HasGroupChanged = true;
563 {
564 foreach (TaskInventoryItem item in m_items.Values)
565 {
566 if (item.Type == 10)
567 {
568 scriptcount++;
569 }
570 }
571 }
572 592
573 if (scriptcount <= 0) 593 int scriptcount = 0;
594 m_items.LockItemsForRead(true);
595 foreach (TaskInventoryItem item in m_items.Values)
596 {
597 if (item.Type == 10)
574 { 598 {
575 m_part.RemFlag(PrimFlags.Scripted); 599 scriptcount++;
576 } 600 }
577
578 m_part.ScheduleFullUpdate();
579
580 return type;
581 } 601 }
582 else 602 m_items.LockItemsForRead(false);
603
604
605 if (scriptcount <= 0)
583 { 606 {
584 m_log.ErrorFormat( 607 m_part.RemFlag(PrimFlags.Scripted);
585 "[PRIM INVENTORY]: " +
586 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
587 itemID, m_part.Name, m_part.UUID,
588 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
589 } 608 }
609
610 m_part.ScheduleFullUpdate();
611
612 return type;
613 }
614 else
615 {
616 m_log.ErrorFormat(
617 "[PRIM INVENTORY]: " +
618 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
619 itemID, m_part.Name, m_part.UUID);
590 } 620 }
621 m_items.LockItemsForWrite(false);
591 622
592 return -1; 623 return -1;
593 } 624 }
@@ -640,52 +671,53 @@ namespace OpenSim.Region.Framework.Scenes
640 // isn't available (such as drag from prim inventory to agent inventory) 671 // isn't available (such as drag from prim inventory to agent inventory)
641 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 672 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
642 673
643 lock (m_items) 674 m_items.LockItemsForRead(true);
675
676 foreach (TaskInventoryItem item in m_items.Values)
644 { 677 {
645 foreach (TaskInventoryItem item in m_items.Values) 678 UUID ownerID = item.OwnerID;
646 { 679 uint everyoneMask = 0;
647 UUID ownerID = item.OwnerID; 680 uint baseMask = item.BasePermissions;
648 uint everyoneMask = 0; 681 uint ownerMask = item.CurrentPermissions;
649 uint baseMask = item.BasePermissions;
650 uint ownerMask = item.CurrentPermissions;
651 682
652 invString.AddItemStart(); 683 invString.AddItemStart();
653 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 684 invString.AddNameValueLine("item_id", item.ItemID.ToString());
654 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 685 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
655 686
656 invString.AddPermissionsStart(); 687 invString.AddPermissionsStart();
657 688
658 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 689 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
659 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 690 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
660 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 691 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
661 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 692 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
662 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 693 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
663 694
664 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 695 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
665 invString.AddNameValueLine("owner_id", ownerID.ToString()); 696 invString.AddNameValueLine("owner_id", ownerID.ToString());
666 697
667 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 698 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
668 699
669 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 700 invString.AddNameValueLine("group_id", item.GroupID.ToString());
670 invString.AddSectionEnd(); 701 invString.AddSectionEnd();
671 702
672 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 703 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
673 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 704 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
674 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 705 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
675 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 706 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
676 707
677 invString.AddSaleStart(); 708 invString.AddSaleStart();
678 invString.AddNameValueLine("sale_type", "not"); 709 invString.AddNameValueLine("sale_type", "not");
679 invString.AddNameValueLine("sale_price", "0"); 710 invString.AddNameValueLine("sale_price", "0");
680 invString.AddSectionEnd(); 711 invString.AddSectionEnd();
681 712
682 invString.AddNameValueLine("name", item.Name + "|"); 713 invString.AddNameValueLine("name", item.Name + "|");
683 invString.AddNameValueLine("desc", item.Description + "|"); 714 invString.AddNameValueLine("desc", item.Description + "|");
684 715
685 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 716 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
686 invString.AddSectionEnd(); 717 invString.AddSectionEnd();
687 }
688 } 718 }
719 int count = m_items.Count;
720 m_items.LockItemsForRead(false);
689 721
690 fileData = Utils.StringToBytes(invString.BuildString); 722 fileData = Utils.StringToBytes(invString.BuildString);
691 723
@@ -706,10 +738,9 @@ namespace OpenSim.Region.Framework.Scenes
706 { 738 {
707 if (HasInventoryChanged) 739 if (HasInventoryChanged)
708 { 740 {
709 lock (Items) 741 Items.LockItemsForRead(true);
710 { 742 datastore.StorePrimInventory(m_part.UUID, Items.Values);
711 datastore.StorePrimInventory(m_part.UUID, Items.Values); 743 Items.LockItemsForRead(false);
712 }
713 744
714 HasInventoryChanged = false; 745 HasInventoryChanged = false;
715 } 746 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 24840d4..3d4490a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,7 +115,9 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
117 private Vector3 m_lastPosition; 121 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 122 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 123 private Vector3 m_lastVelocity;
@@ -144,7 +148,6 @@ namespace OpenSim.Region.Framework.Scenes
144 private int m_perfMonMS; 148 private int m_perfMonMS;
145 149
146 private bool m_setAlwaysRun; 150 private bool m_setAlwaysRun;
147
148 private bool m_forceFly; 151 private bool m_forceFly;
149 private bool m_flyDisabled; 152 private bool m_flyDisabled;
150 153
@@ -168,7 +171,8 @@ namespace OpenSim.Region.Framework.Scenes
168 protected RegionInfo m_regionInfo; 171 protected RegionInfo m_regionInfo;
169 protected ulong crossingFromRegion; 172 protected ulong crossingFromRegion;
170 173
171 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 174 private readonly Vector3[] Dir_Vectors = new Vector3[11];
175 private bool m_isNudging = false;
172 176
173 // Position of agent's camera in world (region cordinates) 177 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter; 178 protected Vector3 m_CameraCenter;
@@ -203,6 +207,9 @@ namespace OpenSim.Region.Framework.Scenes
203 private bool m_followCamAuto; 207 private bool m_followCamAuto;
204 208
205 private int m_movementUpdateCount; 209 private int m_movementUpdateCount;
210 private int m_lastColCount = -1; //KF: Look for Collision chnages
211 private int m_updateCount = 0; //KF: Update Anims for a while
212 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
206 213
207 private const int NumMovementsBetweenRayCast = 5; 214 private const int NumMovementsBetweenRayCast = 5;
208 215
@@ -232,6 +239,10 @@ namespace OpenSim.Region.Framework.Scenes
232 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 239 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
233 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 240 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
234 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 241 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
242 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
243 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
244 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
245 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
235 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 246 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
236 } 247 }
237 248
@@ -658,9 +669,7 @@ namespace OpenSim.Region.Framework.Scenes
658 669
659 AdjustKnownSeeds(); 670 AdjustKnownSeeds();
660 671
661 // TODO: I think, this won't send anything, as we are still a child here... 672 Animator.TrySetMovementAnimation("STAND");
662 Animator.TrySetMovementAnimation("STAND");
663
664 // we created a new ScenePresence (a new child agent) in a fresh region. 673 // we created a new ScenePresence (a new child agent) in a fresh region.
665 // Request info about all the (root) agents in this region 674 // Request info about all the (root) agents in this region
666 // Note: This won't send data *to* other clients in that region (children don't send) 675 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -716,21 +725,47 @@ namespace OpenSim.Region.Framework.Scenes
716 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 725 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
717 Dir_Vectors[4] = Vector3.UnitZ; //UP 726 Dir_Vectors[4] = Vector3.UnitZ; //UP
718 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 727 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
719 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 728 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
729 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
730 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
731 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
732 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
720 } 733 }
721 734
722 private Vector3[] GetWalkDirectionVectors() 735 private Vector3[] GetWalkDirectionVectors()
723 { 736 {
724 Vector3[] vector = new Vector3[6]; 737 Vector3[] vector = new Vector3[11];
725 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 738 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
726 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 739 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
727 vector[2] = Vector3.UnitY; //LEFT 740 vector[2] = Vector3.UnitY; //LEFT
728 vector[3] = -Vector3.UnitY; //RIGHT 741 vector[3] = -Vector3.UnitY; //RIGHT
729 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 742 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
730 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 743 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 744 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
745 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
746 vector[8] = Vector3.UnitY; //LEFT_NUDGE
747 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
748 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
732 return vector; 749 return vector;
733 } 750 }
751
752 private bool[] GetDirectionIsNudge()
753 {
754 bool[] isNudge = new bool[11];
755 isNudge[0] = false; //FORWARD
756 isNudge[1] = false; //BACK
757 isNudge[2] = false; //LEFT
758 isNudge[3] = false; //RIGHT
759 isNudge[4] = false; //UP
760 isNudge[5] = false; //DOWN
761 isNudge[6] = true; //FORWARD_NUDGE
762 isNudge[7] = true; //BACK_NUDGE
763 isNudge[8] = true; //LEFT_NUDGE
764 isNudge[9] = true; //RIGHT_NUDGE
765 isNudge[10] = true; //DOWN_Nudge
766 return isNudge;
767 }
768
734 769
735 #endregion 770 #endregion
736 771
@@ -994,7 +1029,9 @@ namespace OpenSim.Region.Framework.Scenes
994 { 1029 {
995 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1030 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
996 } 1031 }
997 1032
1033 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1034
998 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1035 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
999 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1036 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1000 } 1037 }
@@ -1229,7 +1266,6 @@ namespace OpenSim.Region.Framework.Scenes
1229 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1266 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1230 } 1267 }
1231 } 1268 }
1232
1233 lock (scriptedcontrols) 1269 lock (scriptedcontrols)
1234 { 1270 {
1235 if (scriptedcontrols.Count > 0) 1271 if (scriptedcontrols.Count > 0)
@@ -1244,9 +1280,7 @@ namespace OpenSim.Region.Framework.Scenes
1244 1280
1245 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1281 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1246 { 1282 {
1247 // TODO: This doesn't prevent the user from walking yet. 1283 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1248 // Setting parent ID would fix this, if we knew what value
1249 // to use. Or we could add a m_isSitting variable.
1250 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1284 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1251 } 1285 }
1252 1286
@@ -1261,7 +1295,6 @@ namespace OpenSim.Region.Framework.Scenes
1261 { 1295 {
1262 return; 1296 return;
1263 } 1297 }
1264
1265 if (m_allowMovement) 1298 if (m_allowMovement)
1266 { 1299 {
1267 int i = 0; 1300 int i = 0;
@@ -1289,6 +1322,11 @@ namespace OpenSim.Region.Framework.Scenes
1289 update_rotation = true; 1322 update_rotation = true;
1290 } 1323 }
1291 1324
1325 //guilty until proven innocent..
1326 bool Nudging = true;
1327 //Basically, if there is at least one non-nudge control then we don't need
1328 //to worry about stopping the avatar
1329
1292 if (m_parentID == 0) 1330 if (m_parentID == 0)
1293 { 1331 {
1294 bool bAllowUpdateMoveToPosition = false; 1332 bool bAllowUpdateMoveToPosition = false;
@@ -1303,6 +1341,12 @@ namespace OpenSim.Region.Framework.Scenes
1303 else 1341 else
1304 dirVectors = Dir_Vectors; 1342 dirVectors = Dir_Vectors;
1305 1343
1344 bool[] isNudge = GetDirectionIsNudge();
1345
1346
1347
1348
1349
1306 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1350 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1307 { 1351 {
1308 if (((uint)flags & (uint)DCF) != 0) 1352 if (((uint)flags & (uint)DCF) != 0)
@@ -1312,6 +1356,10 @@ namespace OpenSim.Region.Framework.Scenes
1312 try 1356 try
1313 { 1357 {
1314 agent_control_v3 += dirVectors[i]; 1358 agent_control_v3 += dirVectors[i];
1359 if (isNudge[i] == false)
1360 {
1361 Nudging = false;
1362 }
1315 } 1363 }
1316 catch (IndexOutOfRangeException) 1364 catch (IndexOutOfRangeException)
1317 { 1365 {
@@ -1373,6 +1421,9 @@ namespace OpenSim.Region.Framework.Scenes
1373 // Ignore z component of vector 1421 // Ignore z component of vector
1374 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1422 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1375 LocalVectorToTarget2D.Normalize(); 1423 LocalVectorToTarget2D.Normalize();
1424
1425 //We're not nudging
1426 Nudging = false;
1376 agent_control_v3 += LocalVectorToTarget2D; 1427 agent_control_v3 += LocalVectorToTarget2D;
1377 1428
1378 // update avatar movement flags. the avatar coordinate system is as follows: 1429 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1455,7 +1506,7 @@ namespace OpenSim.Region.Framework.Scenes
1455 // m_log.DebugFormat( 1506 // m_log.DebugFormat(
1456 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1507 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1457 1508
1458 AddNewMovement(agent_control_v3, q); 1509 AddNewMovement(agent_control_v3, q, Nudging);
1459 1510
1460 if (update_movementflag) 1511 if (update_movementflag)
1461 Animator.UpdateMovementAnimations(); 1512 Animator.UpdateMovementAnimations();
@@ -1538,7 +1589,7 @@ namespace OpenSim.Region.Framework.Scenes
1538 Velocity = Vector3.Zero; 1589 Velocity = Vector3.Zero;
1539 SendFullUpdateToAllClients(); 1590 SendFullUpdateToAllClients();
1540 1591
1541 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1592 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1542 } 1593 }
1543 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1594 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1544 m_requestedSitTargetUUID = UUID.Zero; 1595 m_requestedSitTargetUUID = UUID.Zero;
@@ -1576,21 +1627,19 @@ namespace OpenSim.Region.Framework.Scenes
1576 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1627 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1577 if (part != null) 1628 if (part != null)
1578 { 1629 {
1630 part.TaskInventory.LockItemsForRead(true);
1579 TaskInventoryDictionary taskIDict = part.TaskInventory; 1631 TaskInventoryDictionary taskIDict = part.TaskInventory;
1580 if (taskIDict != null) 1632 if (taskIDict != null)
1581 { 1633 {
1582 lock (taskIDict) 1634 foreach (UUID taskID in taskIDict.Keys)
1583 { 1635 {
1584 foreach (UUID taskID in taskIDict.Keys) 1636 UnRegisterControlEventsToScript(LocalId, taskID);
1585 { 1637 taskIDict[taskID].PermsMask &= ~(
1586 UnRegisterControlEventsToScript(LocalId, taskID); 1638 2048 | //PERMISSION_CONTROL_CAMERA
1587 taskIDict[taskID].PermsMask &= ~( 1639 4); // PERMISSION_TAKE_CONTROLS
1588 2048 | //PERMISSION_CONTROL_CAMERA
1589 4); // PERMISSION_TAKE_CONTROLS
1590 }
1591 } 1640 }
1592
1593 } 1641 }
1642 part.TaskInventory.LockItemsForRead(false);
1594 // Reset sit target. 1643 // Reset sit target.
1595 if (part.GetAvatarOnSitTarget() == UUID) 1644 if (part.GetAvatarOnSitTarget() == UUID)
1596 part.SetAvatarOnSitTarget(UUID.Zero); 1645 part.SetAvatarOnSitTarget(UUID.Zero);
@@ -1603,9 +1652,9 @@ namespace OpenSim.Region.Framework.Scenes
1603 { 1652 {
1604 AddToPhysicalScene(false); 1653 AddToPhysicalScene(false);
1605 } 1654 }
1606
1607 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1655 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
1608 m_parentPosition = Vector3.Zero; 1656 m_parentPosition = Vector3.Zero;
1657//Console.WriteLine("Stand Pos {0}", m_pos);
1609 1658
1610 m_parentID = 0; 1659 m_parentID = 0;
1611 SendFullUpdateToAllClients(); 1660 SendFullUpdateToAllClients();
@@ -1651,7 +1700,7 @@ namespace OpenSim.Region.Framework.Scenes
1651 bool SitTargetisSet = 1700 bool SitTargetisSet =
1652 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f && 1701 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1653 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f)); 1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1654 1703 // this test is probably failing
1655 if (SitTargetisSet && SitTargetUnOccupied) 1704 if (SitTargetisSet && SitTargetUnOccupied)
1656 { 1705 {
1657 //switch the target to this prim 1706 //switch the target to this prim
@@ -1678,7 +1727,13 @@ namespace OpenSim.Region.Framework.Scenes
1678 { 1727 {
1679 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1728 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1680 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1729 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1681 1730
1731 // part is the prim to sit on
1732 // offset is the vector distance from that prim center to the click-spot
1733 // UUID is the UUID of the Avatar doing the clicking
1734
1735 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1736
1682 // Is a sit target available? 1737 // Is a sit target available?
1683 Vector3 avSitOffSet = part.SitTargetPosition; 1738 Vector3 avSitOffSet = part.SitTargetPosition;
1684 Quaternion avSitOrientation = part.SitTargetOrientation; 1739 Quaternion avSitOrientation = part.SitTargetOrientation;
@@ -1693,21 +1748,40 @@ namespace OpenSim.Region.Framework.Scenes
1693 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1748 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1694 ) 1749 )
1695 )); 1750 ));
1751
1752//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied +
1753// " TargSet=" + SitTargetisSet);
1754 // Sit analysis rewritten by KF 091125
1755 if (SitTargetisSet) // scipted sit
1756 {
1757 if (SitTargetUnOccupied)
1758 {
1759 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1760 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1761 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1762 autopilot = false; // Jump direct to scripted llSitPos()
1763 }
1764 else return;
1765 }
1766 else // Not Scripted
1767 {
1768 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) // large prim
1769 {
1770 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1771 m_avUnscriptedSitPos = offset * partIRot; // sit where clicked
1772 pos = part.AbsolutePosition + (offset * partIRot);
1773 }
1774 else // small prim
1775 {
1776 if (SitTargetUnOccupied)
1777 {
1778 m_avUnscriptedSitPos = Vector3.Zero; // Sit on unoccupied small prim center
1779 pos = part.AbsolutePosition;
1780 }
1781 else return; // occupied small
1782 } // end large/small
1783 } // end Scripted/not
1696 1784
1697 if (SitTargetisSet && SitTargetUnOccupied)
1698 {
1699 part.SetAvatarOnSitTarget(UUID);
1700 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1701 sitOrientation = avSitOrientation;
1702 autopilot = false;
1703 }
1704
1705 pos = part.AbsolutePosition + offset;
1706 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1707 //{
1708 // offset = pos;
1709 //autopilot = false;
1710 //}
1711 if (m_physicsActor != null) 1785 if (m_physicsActor != null)
1712 { 1786 {
1713 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1787 // If we're not using the client autopilot, we're immediately warping the avatar to the location
@@ -1715,17 +1789,17 @@ namespace OpenSim.Region.Framework.Scenes
1715 m_sitAvatarHeight = m_physicsActor.Size.Z; 1789 m_sitAvatarHeight = m_physicsActor.Size.Z;
1716 1790
1717 if (autopilot) 1791 if (autopilot)
1718 { 1792 { // its not a scripted sit
1719 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1793 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5)
1720 { 1794 {
1721 autopilot = false; 1795 autopilot = false; // close enough
1722 1796
1723 RemoveFromPhysicalScene(); 1797 RemoveFromPhysicalScene();
1724 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1798 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to Prim
1725 } 1799 } // else the autopilot will get us close
1726 } 1800 }
1727 else 1801 else
1728 { 1802 { // its a scripted sit
1729 RemoveFromPhysicalScene(); 1803 RemoveFromPhysicalScene();
1730 } 1804 }
1731 } 1805 }
@@ -1839,29 +1913,52 @@ namespace OpenSim.Region.Framework.Scenes
1839 { 1913 {
1840 if (part.GetAvatarOnSitTarget() == UUID) 1914 if (part.GetAvatarOnSitTarget() == UUID)
1841 { 1915 {
1916 // Scripted sit
1842 Vector3 sitTargetPos = part.SitTargetPosition; 1917 Vector3 sitTargetPos = part.SitTargetPosition;
1843 Quaternion sitTargetOrient = part.SitTargetOrientation; 1918 Quaternion sitTargetOrient = part.SitTargetOrientation;
1844
1845 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
1846 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
1847
1848 //Quaternion result = (sitTargetOrient * vq) * nq;
1849
1850 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 1919 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1851 m_pos += SIT_TARGET_ADJUSTMENT; 1920 m_pos += SIT_TARGET_ADJUSTMENT;
1852 m_bodyRot = sitTargetOrient; 1921 m_bodyRot = sitTargetOrient;
1853 //Rotation = sitTargetOrient;
1854 m_parentPosition = part.AbsolutePosition; 1922 m_parentPosition = part.AbsolutePosition;
1855
1856 //SendTerseUpdateToAllClients();
1857 } 1923 }
1858 else 1924 else
1859 { 1925 {
1860 m_pos -= part.AbsolutePosition; 1926 // Non-scripted sit by Kitto Flora 21Nov09
1927 // Calculate angle of line from prim to Av
1928 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
1929 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
1930 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
1931 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
1932 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
1933 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
1934 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1935 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
1936 // Av sits at world euler <0,0, z>, translated by part rotation
1937 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
1861 m_parentPosition = part.AbsolutePosition; 1938 m_parentPosition = part.AbsolutePosition;
1862 } 1939 if(m_avUnscriptedSitPos != Vector3.Zero)
1863 } 1940 { // sit where clicked on big prim
1864 else 1941 m_pos = m_avUnscriptedSitPos + (new Vector3(0.0f, 0f, 0.625f) * partIRot);
1942 }
1943 else
1944 { // sit at center of small prim
1945 m_pos = new Vector3(0f, 0f, 0.05f) +
1946 (new Vector3(0.0f, 0f, 0.625f) * partIRot) +
1947 (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot);
1948 //Set up raytrace to find top surface of prim
1949 Vector3 size = part.Scale;
1950 float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
1951 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
1952 Vector3 down = new Vector3(0f, 0f, -1f);
1953 m_scene.PhysicsScene.RaycastWorld(
1954 start, // Vector3 position,
1955 down, // Vector3 direction,
1956 mag, // float length,
1957 SitAltitudeCallback); // retMethod
1958 } // end small/big
1959 } // end scripted/not
1960 }
1961 else // no Av
1865 { 1962 {
1866 return; 1963 return;
1867 } 1964 }
@@ -1873,11 +1970,21 @@ namespace OpenSim.Region.Framework.Scenes
1873 1970
1874 Animator.TrySetMovementAnimation(sitAnimation); 1971 Animator.TrySetMovementAnimation(sitAnimation);
1875 SendFullUpdateToAllClients(); 1972 SendFullUpdateToAllClients();
1876 // This may seem stupid, but Our Full updates don't send avatar rotation :P
1877 // So we're also sending a terse update (which has avatar rotation)
1878 // [Update] We do now.
1879 //SendTerseUpdateToAllClients();
1880 } 1973 }
1974
1975 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance)
1976 {
1977 if(hitYN)
1978 {
1979 // m_pos = Av offset from prim center to make look like on center
1980 // m_parentPosition = Actual center pos of prim
1981 // collisionPoint = spot on prim where we want to sit
1982 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
1983 Vector3 offset = (collisionPoint - m_parentPosition) * Quaternion.Inverse(part.RotationOffset);
1984 m_pos += offset;
1985// Console.WriteLine("m_pos={0}, offset={1} newsit={2}", m_pos, offset, newsit);
1986 }
1987 }
1881 1988
1882 /// <summary> 1989 /// <summary>
1883 /// Event handler for the 'Always run' setting on the client 1990 /// Event handler for the 'Always run' setting on the client
@@ -1907,7 +2014,7 @@ namespace OpenSim.Region.Framework.Scenes
1907 /// </summary> 2014 /// </summary>
1908 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2015 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
1909 /// <param name="rotation">The direction in which this avatar should now face. 2016 /// <param name="rotation">The direction in which this avatar should now face.
1910 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2017 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
1911 { 2018 {
1912 if (m_isChildAgent) 2019 if (m_isChildAgent)
1913 { 2020 {
@@ -1981,7 +2088,7 @@ namespace OpenSim.Region.Framework.Scenes
1981 2088
1982 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2089 // TODO: Add the force instead of only setting it to support multiple forces per frame?
1983 m_forceToApply = direc; 2090 m_forceToApply = direc;
1984 2091 m_isNudging = Nudging;
1985 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2092 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1986 } 2093 }
1987 2094
@@ -1996,7 +2103,7 @@ namespace OpenSim.Region.Framework.Scenes
1996 const float POSITION_TOLERANCE = 0.05f; 2103 const float POSITION_TOLERANCE = 0.05f;
1997 //const int TIME_MS_TOLERANCE = 3000; 2104 //const int TIME_MS_TOLERANCE = 3000;
1998 2105
1999 SendPrimUpdates(); 2106
2000 2107
2001 if (m_newCoarseLocations) 2108 if (m_newCoarseLocations)
2002 { 2109 {
@@ -2032,6 +2139,9 @@ namespace OpenSim.Region.Framework.Scenes
2032 CheckForBorderCrossing(); 2139 CheckForBorderCrossing();
2033 CheckForSignificantMovement(); // sends update to the modules. 2140 CheckForSignificantMovement(); // sends update to the modules.
2034 } 2141 }
2142
2143 //Sending prim updates AFTER the avatar terse updates are sent
2144 SendPrimUpdates();
2035 } 2145 }
2036 2146
2037 #endregion 2147 #endregion
@@ -2885,14 +2995,25 @@ namespace OpenSim.Region.Framework.Scenes
2885 { 2995 {
2886 if (m_forceToApply.HasValue) 2996 if (m_forceToApply.HasValue)
2887 { 2997 {
2888 Vector3 force = m_forceToApply.Value;
2889 2998
2999 Vector3 force = m_forceToApply.Value;
2890 m_updateflag = true; 3000 m_updateflag = true;
2891// movementvector = force;
2892 Velocity = force; 3001 Velocity = force;
2893 3002
2894 m_forceToApply = null; 3003 m_forceToApply = null;
2895 } 3004 }
3005 else
3006 {
3007 if (m_isNudging)
3008 {
3009 Vector3 force = Vector3.Zero;
3010
3011 m_updateflag = true;
3012 Velocity = force;
3013 m_isNudging = false;
3014 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3015 }
3016 }
2896 } 3017 }
2897 3018
2898 public override void SetText(string text, Vector3 color, double alpha) 3019 public override void SetText(string text, Vector3 color, double alpha)
@@ -2942,10 +3063,15 @@ namespace OpenSim.Region.Framework.Scenes
2942 // Event called by the physics plugin to tell the avatar about a collision. 3063 // Event called by the physics plugin to tell the avatar about a collision.
2943 private void PhysicsCollisionUpdate(EventArgs e) 3064 private void PhysicsCollisionUpdate(EventArgs e)
2944 { 3065 {
3066 if (m_updateCount > 0) //KF: Update Anims for a short period. Many Anim
3067 { // changes are very asynchronous.
3068 Animator.UpdateMovementAnimations();
3069 m_updateCount--;
3070 }
3071
2945 if (e == null) 3072 if (e == null)
2946 return; 3073 return;
2947 3074
2948 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
2949 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( 3075 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
2950 // as of this comment the interval is set in AddToPhysicalScene 3076 // as of this comment the interval is set in AddToPhysicalScene
2951 if (Animator!=null) 3077 if (Animator!=null)
@@ -2956,6 +3082,12 @@ namespace OpenSim.Region.Framework.Scenes
2956 3082
2957 CollisionPlane = Vector4.UnitW; 3083 CollisionPlane = Vector4.UnitW;
2958 3084
3085 if (m_lastColCount != coldata.Count)
3086 {
3087 m_updateCount = 10;
3088 m_lastColCount = coldata.Count;
3089 }
3090
2959 if (coldata.Count != 0 && Animator != null) 3091 if (coldata.Count != 0 && Animator != null)
2960 { 3092 {
2961 switch (Animator.CurrentMovementAnimation) 3093 switch (Animator.CurrentMovementAnimation)
@@ -3604,4 +3736,4 @@ namespace OpenSim.Region.Framework.Scenes
3604 } 3736 }
3605 } 3737 }
3606 } 3738 }
3607} \ No newline at end of file 3739}