aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs29
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs44
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs47
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs519
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs101
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs598
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs577
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs11
14 files changed, 1350 insertions, 760 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index fd526eb..e98f0e7 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, m_scenePresence.UUID)) 131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
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
@@ -146,10 +151,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
146 const float PREJUMP_DELAY = 0.25f; 151 const float PREJUMP_DELAY = 0.25f;
147 152
148 #region Inputs 153 #region Inputs
149 if (m_scenePresence.SitGround) 154
150 {
151 return "SIT_GROUND_CONSTRAINED";
152 }
153 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; 155 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
154 PhysicsActor actor = m_scenePresence.PhysicsActor; 156 PhysicsActor actor = m_scenePresence.PhysicsActor;
155 157
@@ -159,11 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
159 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 161 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
160 162
161 // Check control flags 163 // Check control flags
162 bool heldForward = 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);
163 (((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)); 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);
164 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 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);
165 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 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);
166 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
167 //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;
168 //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;
169 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;
@@ -316,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
316 public void UpdateMovementAnimations() 317 public void UpdateMovementAnimations()
317 { 318 {
318 m_movementAnimation = GetMovementAnimation(); 319 m_movementAnimation = GetMovementAnimation();
319 320//Console.WriteLine("UMA got {0}", m_movementAnimation);
320 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) 321 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
321 { 322 {
322 // This was the previous behavior before PREJUMP 323 // This was the previous behavior before PREJUMP
@@ -454,4 +455,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
454 m_scenePresence = null; 455 m_scenePresence = null;
455 } 456 }
456 } 457 }
457} \ No newline at end of file 458}
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 099fcce..c246e32 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes
40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); 40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>();
41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>(); 41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>(); 42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
43 private readonly Object m_lock = new Object(); 43 private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim();
44 44
45 [Obsolete("Use Add() instead.")] 45 [Obsolete("Use Add() instead.")]
46 public void Add(UUID id, EntityBase eb) 46 public void Add(UUID id, EntityBase eb)
@@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
50 50
51 public void Add(EntityBase entity) 51 public void Add(EntityBase entity)
52 { 52 {
53 lock (m_lock) 53 m_lock.EnterWriteLock();
54 try
54 { 55 {
55 try 56 try
56 { 57 {
@@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes
62 m_log.ErrorFormat("Add Entity failed: {0}", e.Message); 63 m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
63 } 64 }
64 } 65 }
66 finally
67 {
68 m_lock.ExitWriteLock();
69 }
65 } 70 }
66 71
67 public void InsertOrReplace(EntityBase entity) 72 public void InsertOrReplace(EntityBase entity)
68 { 73 {
69 lock (m_lock) 74 m_lock.EnterWriteLock();
75 try
70 { 76 {
71 try 77 try
72 { 78 {
@@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes
78 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); 84 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
79 } 85 }
80 } 86 }
87 finally
88 {
89 m_lock.ExitWriteLock();
90 }
81 } 91 }
82 92
83 public void Clear() 93 public void Clear()
84 { 94 {
85 lock (m_lock) 95 m_lock.EnterWriteLock();
96 try
86 { 97 {
87 m_eb_uuid.Clear(); 98 m_eb_uuid.Clear();
88 m_eb_localID.Clear(); 99 m_eb_localID.Clear();
89 } 100 }
101 finally
102 {
103 m_lock.ExitWriteLock();
104 }
90 } 105 }
91 106
92 public int Count 107 public int Count
@@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes
123 138
124 public bool Remove(uint localID) 139 public bool Remove(uint localID)
125 { 140 {
126 lock (m_lock) 141 m_lock.EnterWriteLock();
142 try
127 { 143 {
128 try 144 try
129 { 145 {
@@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes
141 return false; 157 return false;
142 } 158 }
143 } 159 }
160 finally
161 {
162 m_lock.ExitWriteLock();
163 }
144 } 164 }
145 165
146 public bool Remove(UUID id) 166 public bool Remove(UUID id)
147 { 167 {
148 lock (m_lock) 168 m_lock.EnterWriteLock();
169 try
149 { 170 {
150 try 171 try
151 { 172 {
@@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes
163 return false; 184 return false;
164 } 185 }
165 } 186 }
187 finally
188 {
189 m_lock.ExitWriteLock();
190 }
166 } 191 }
167 192
168 public List<EntityBase> GetAllByType<T>() 193 public List<EntityBase> GetAllByType<T>()
169 { 194 {
170 List<EntityBase> tmp = new List<EntityBase>(); 195 List<EntityBase> tmp = new List<EntityBase>();
171 196
172 lock (m_lock) 197 m_lock.EnterReadLock();
198 try
173 { 199 {
174 try 200 try
175 { 201 {
@@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes
187 tmp = null; 213 tmp = null;
188 } 214 }
189 } 215 }
216 finally
217 {
218 m_lock.ExitReadLock();
219 }
190 220
191 return tmp; 221 return tmp;
192 } 222 }
193 223
194 public List<EntityBase> GetEntities() 224 public List<EntityBase> GetEntities()
195 { 225 {
196 lock (m_lock) 226 m_lock.EnterReadLock();
227 try
197 { 228 {
198 return new List<EntityBase>(m_eb_uuid.Values); 229 return new List<EntityBase>(m_eb_uuid.Values);
199 } 230 }
231 finally
232 {
233 m_lock.ExitReadLock();
234 }
200 } 235 }
201 236
202 public EntityBase this[UUID id] 237 public EntityBase this[UUID id]
203 { 238 {
204 get 239 get
205 { 240 {
206 lock (m_lock) 241 m_lock.EnterReadLock();
242 try
207 { 243 {
208 EntityBase entity; 244 EntityBase entity;
209 if (m_eb_uuid.TryGetValue(id, out entity)) 245 if (m_eb_uuid.TryGetValue(id, out entity))
@@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes
211 else 247 else
212 return null; 248 return null;
213 } 249 }
250 finally
251 {
252 m_lock.ExitReadLock();
253 }
214 } 254 }
215 set 255 set
216 { 256 {
@@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes
222 { 262 {
223 get 263 get
224 { 264 {
225 lock (m_lock) 265 m_lock.EnterReadLock();
266 try
226 { 267 {
227 EntityBase entity; 268 EntityBase entity;
228 if (m_eb_localID.TryGetValue(localID, out entity)) 269 if (m_eb_localID.TryGetValue(localID, out entity))
@@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes
230 else 271 else
231 return null; 272 return null;
232 } 273 }
274 finally
275 {
276 m_lock.ExitReadLock();
277 }
233 } 278 }
234 set 279 set
235 { 280 {
@@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes
239 284
240 public bool TryGetValue(UUID key, out EntityBase obj) 285 public bool TryGetValue(UUID key, out EntityBase obj)
241 { 286 {
242 lock (m_lock) 287 m_lock.EnterReadLock();
288 try
243 { 289 {
244 return m_eb_uuid.TryGetValue(key, out obj); 290 return m_eb_uuid.TryGetValue(key, out obj);
245 } 291 }
292 finally
293 {
294 m_lock.ExitReadLock();
295 }
246 } 296 }
247 297
248 public bool TryGetValue(uint key, out EntityBase obj) 298 public bool TryGetValue(uint key, out EntityBase obj)
249 { 299 {
250 lock (m_lock) 300 m_lock.EnterReadLock();
301 try
251 { 302 {
252 return m_eb_localID.TryGetValue(key, out obj); 303 return m_eb_localID.TryGetValue(key, out obj);
253 } 304 }
305 finally
306 {
307 m_lock.ExitReadLock();
308 }
254 } 309 }
255 310
256 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index a4a1abc..fe40f52 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -199,7 +199,11 @@ namespace OpenSim.Region.Framework.Scenes
199 public event OnMakeChildAgentDelegate OnMakeChildAgent; 199 public event OnMakeChildAgentDelegate OnMakeChildAgent;
200 200
201 public delegate void OnMakeRootAgentDelegate(ScenePresence presence); 201 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
202 public delegate void OnSaveNewWindlightProfileDelegate();
203 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user);
202 public event OnMakeRootAgentDelegate OnMakeRootAgent; 204 public event OnMakeRootAgentDelegate OnMakeRootAgent;
205 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
206 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
203 207
204 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); 208 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
205 209
@@ -421,6 +425,8 @@ namespace OpenSim.Region.Framework.Scenes
421 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage; 425 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
422 private ClientClosed handlerClientClosed = null; //OnClientClosed; 426 private ClientClosed handlerClientClosed = null; //OnClientClosed;
423 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; 427 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
428 private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile;
429 private OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = null; //OnSendNewWindlightProfileTargeted;
424 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; 430 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
425 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; 431 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
426 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; 432 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
@@ -794,6 +800,24 @@ namespace OpenSim.Region.Framework.Scenes
794 } 800 }
795 } 801 }
796 802
803 public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
804 {
805 handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
806 if (handlerSendNewWindlightProfileTargeted != null)
807 {
808 handlerSendNewWindlightProfileTargeted(wl, user);
809 }
810 }
811
812 public void TriggerOnSaveNewWindlightProfile()
813 {
814 handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
815 if (handlerSaveNewWindlightProfile != null)
816 {
817 handlerSaveNewWindlightProfile();
818 }
819 }
820
797 public void TriggerOnMakeRootAgent(ScenePresence presence) 821 public void TriggerOnMakeRootAgent(ScenePresence presence)
798 { 822 {
799 handlerMakeRootAgent = OnMakeRootAgent; 823 handlerMakeRootAgent = OnMakeRootAgent;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 7df3e50..7b852a2 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -846,8 +846,12 @@ namespace OpenSim.Region.Framework.Scenes
846 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 846 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
847 { 847 {
848 SceneObjectPart part = GetSceneObjectPart(localID); 848 SceneObjectPart part = GetSceneObjectPart(localID);
849 SceneObjectGroup group = part.ParentGroup; 849 SceneObjectGroup group = null;
850 if (group != null) 850 if (part != null)
851 {
852 group = part.ParentGroup;
853 }
854 if (part != null && group != null)
851 { 855 {
852 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 856 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
853 if (item == null) 857 if (item == null)
@@ -1801,8 +1805,13 @@ namespace OpenSim.Region.Framework.Scenes
1801 } 1805 }
1802 else 1806 else
1803 { 1807 {
1804 item.BasePermissions = objectGroup.GetEffectivePermissions(); 1808 uint ownerPerms = objectGroup.GetEffectivePermissions();
1805 item.CurrentPermissions = objectGroup.GetEffectivePermissions(); 1809 if ((objectGroup.RootPart.OwnerMask & (uint)PermissionMask.Modify) != 0)
1810 ownerPerms |= (uint)PermissionMask.Modify;
1811
1812 item.BasePermissions = ownerPerms;
1813 item.CurrentPermissions = ownerPerms;
1814
1806 item.NextPermissions = objectGroup.RootPart.NextOwnerMask; 1815 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1807 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; 1816 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1808 item.GroupPermissions = objectGroup.RootPart.GroupMask; 1817 item.GroupPermissions = objectGroup.RootPart.GroupMask;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 73b0b3e..d2f33b0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -539,6 +539,8 @@ namespace OpenSim.Region.Framework.Scenes
539 539
540 // Load region settings 540 // Load region settings
541 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); 541 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
542 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
543
542 if (m_storageManager.EstateDataStore != null) 544 if (m_storageManager.EstateDataStore != null)
543 { 545 {
544 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID); 546 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
@@ -886,6 +888,15 @@ namespace OpenSim.Region.Framework.Scenes
886 /// <param name="seconds">float indicating duration before restart.</param> 888 /// <param name="seconds">float indicating duration before restart.</param>
887 public virtual void Restart(float seconds) 889 public virtual void Restart(float seconds)
888 { 890 {
891 Restart(seconds, true);
892 }
893
894 /// <summary>
895 /// Given float seconds, this will restart the region. showDialog will optionally alert the users.
896 /// </summary>
897 /// <param name="seconds">float indicating duration before restart.</param>
898 public virtual void Restart(float seconds, bool showDialog)
899 {
889 // notifications are done in 15 second increments 900 // notifications are done in 15 second increments
890 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request 901 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
891 // It's a 'Cancel restart' request. 902 // It's a 'Cancel restart' request.
@@ -906,8 +917,11 @@ namespace OpenSim.Region.Framework.Scenes
906 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); 917 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
907 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); 918 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
908 m_restartTimer.Start(); 919 m_restartTimer.Start();
909 m_dialogModule.SendNotificationToUsersInRegion( 920 if (showDialog)
921 {
922 m_dialogModule.SendNotificationToUsersInRegion(
910 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0))); 923 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
924 }
911 } 925 }
912 } 926 }
913 927
@@ -1189,16 +1203,16 @@ namespace OpenSim.Region.Framework.Scenes
1189 // Check if any objects have reached their targets 1203 // Check if any objects have reached their targets
1190 CheckAtTargets(); 1204 CheckAtTargets();
1191 1205
1192 // Update SceneObjectGroups that have scheduled themselves for updates
1193 // Objects queue their updates onto all scene presences
1194 if (m_frame % m_update_objects == 0)
1195 m_sceneGraph.UpdateObjectGroups();
1196
1197 // Run through all ScenePresences looking for updates 1206 // Run through all ScenePresences looking for updates
1198 // Presence updates and queued object updates for each presence are sent to clients 1207 // Presence updates and queued object updates for each presence are sent to clients
1199 if (m_frame % m_update_presences == 0) 1208 if (m_frame % m_update_presences == 0)
1200 m_sceneGraph.UpdatePresences(); 1209 m_sceneGraph.UpdatePresences();
1201 1210
1211 // Update SceneObjectGroups that have scheduled themselves for updates
1212 // Objects queue their updates onto all scene presences
1213 if (m_frame % m_update_objects == 0)
1214 m_sceneGraph.UpdateObjectGroups();
1215
1202 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1216 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1203 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1217 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1204 m_sceneGraph.UpdatePreparePhysics(); 1218 m_sceneGraph.UpdatePreparePhysics();
@@ -1509,6 +1523,19 @@ namespace OpenSim.Region.Framework.Scenes
1509 public void SaveTerrain() 1523 public void SaveTerrain()
1510 { 1524 {
1511 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1525 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1526 }
1527
1528 public void StoreWindlightProfile(RegionMeta7WindlightData wl)
1529 {
1530 m_regInfo.WindlightSettings = wl;
1531 m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
1532 m_eventManager.TriggerOnSaveNewWindlightProfile();
1533 }
1534
1535 public void LoadWindlightProfile()
1536 {
1537 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID);
1538 m_eventManager.TriggerOnSaveNewWindlightProfile();
1512 } 1539 }
1513 1540
1514 /// <summary> 1541 /// <summary>
@@ -3396,6 +3423,9 @@ namespace OpenSim.Region.Framework.Scenes
3396 3423
3397 CapsModule.AddCapsHandler(agent.AgentID); 3424 CapsModule.AddCapsHandler(agent.AgentID);
3398 3425
3426 if ((teleportFlags & ((uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.Default)) != 0)
3427 System.Threading.Thread.Sleep(2000);
3428
3399 if (!agent.child) 3429 if (!agent.child)
3400 { 3430 {
3401 if (TestBorderCross(agent.startpos,Cardinals.E)) 3431 if (TestBorderCross(agent.startpos,Cardinals.E))
@@ -3454,6 +3484,7 @@ namespace OpenSim.Region.Framework.Scenes
3454 } 3484 }
3455 } 3485 }
3456 // Honor parcel landing type and position. 3486 // Honor parcel landing type and position.
3487 /*
3457 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 3488 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3458 if (land != null) 3489 if (land != null)
3459 { 3490 {
@@ -3462,6 +3493,7 @@ namespace OpenSim.Region.Framework.Scenes
3462 agent.startpos = land.LandData.UserLocation; 3493 agent.startpos = land.LandData.UserLocation;
3463 } 3494 }
3464 } 3495 }
3496 */// This is now handled properly in ScenePresence.MakeRootAgent
3465 } 3497 }
3466 3498
3467 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3499 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 6164368..6a3c386 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -699,17 +699,42 @@ namespace OpenSim.Region.Framework.Scenes
699 { 699 {
700 m_log.DebugFormat( 700 m_log.DebugFormat(
701 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", 701 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}",
702 position, m_regionInfo.RegionName); 702 position, m_regionInfo.RegionName);
703 703
704 // Teleport within the same region 704 // Teleport within the same region
705 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) 705 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0)
706 { 706 {
707 Vector3 emergencyPos = new Vector3(128, 128, 128); 707 Vector3 emergencyPos = new Vector3(128, 128, 128);
708 708
709 m_log.WarnFormat( 709 m_log.WarnFormat(
710 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 710 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
711 position, avatar.Name, avatar.UUID, emergencyPos); 711 position, avatar.Name, avatar.UUID, emergencyPos);
712 position = emergencyPos; 712 position = emergencyPos;
713 }
714
715 Vector3 currentPos = avatar.AbsolutePosition;
716 ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y);
717 ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y);
718 if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0)
719 {
720 if (srcLand.LandData.LocalID == destLand.LandData.LocalID)
721 {
722 //TPing within the same parcel. If the landing point is restricted, block the TP.
723 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
724 if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID)
725 {
726 avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false);
727 position = currentPos;
728 }
729 }
730 else
731 {
732 //Tping to a different parcel. Respect the landing point on the destination parcel.
733 if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID)
734 {
735 position = destLand.LandData.UserLocation;
736 }
737 }
713 } 738 }
714 739
715 // TODO: Get proper AVG Height 740 // TODO: Get proper AVG Height
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 1ac061a..2c66719 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -222,6 +222,30 @@ namespace OpenSim.Region.Framework.Scenes
222 protected internal bool AddRestoredSceneObject( 222 protected internal bool AddRestoredSceneObject(
223 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) 223 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
224 { 224 {
225 // KF: Check for out-of-region, move inside and make static.
226 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
227 sceneObject.RootPart.GroupPosition.Y,
228 sceneObject.RootPart.GroupPosition.Z);
229 if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 ||
230 npos.X > Constants.RegionSize ||
231 npos.Y > Constants.RegionSize))
232 {
233 if (npos.X < 0.0) npos.X = 1.0f;
234 if (npos.Y < 0.0) npos.Y = 1.0f;
235 if (npos.Z < 0.0) npos.Z = 0.0f;
236 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
237 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
238
239 foreach (SceneObjectPart part in sceneObject.Children.Values)
240 {
241 part.GroupPosition = npos;
242 }
243 sceneObject.RootPart.Velocity = Vector3.Zero;
244 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
245 sceneObject.RootPart.Acceleration = Vector3.Zero;
246 sceneObject.RootPart.Velocity = Vector3.Zero;
247 }
248
225 if (!alreadyPersisted) 249 if (!alreadyPersisted)
226 { 250 {
227 sceneObject.ForceInventoryPersistence(); 251 sceneObject.ForceInventoryPersistence();
@@ -558,6 +582,18 @@ namespace OpenSim.Region.Framework.Scenes
558 if (group.GetFromItemID() == itemID) 582 if (group.GetFromItemID() == itemID)
559 { 583 {
560 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); 584 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
585 bool hasScripts = false;
586 foreach (SceneObjectPart part in group.Children.Values)
587 {
588 if (part.Inventory.ContainsScripts())
589 {
590 hasScripts = true;
591 break;
592 }
593 }
594
595 if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
596 System.Threading.Thread.Sleep(100);
561 group.DetachToInventoryPrep(); 597 group.DetachToInventoryPrep();
562 m_log.Debug("[DETACH]: Saving attachpoint: " + 598 m_log.Debug("[DETACH]: Saving attachpoint: " +
563 ((uint)group.GetAttachmentPoint()).ToString()); 599 ((uint)group.GetAttachmentPoint()).ToString());
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 71354b4..8b58b3e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -46,12 +46,12 @@ namespace OpenSim.Region.Framework.Scenes
46 /// </summary> 46 /// </summary>
47 public void ForceInventoryPersistence() 47 public void ForceInventoryPersistence()
48 { 48 {
49 lock (m_parts) 49 lockPartsForRead(true);
50 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
51 lockPartsForRead(false);
52 foreach (SceneObjectPart part in values)
50 { 53 {
51 foreach (SceneObjectPart part in m_parts.Values) 54 part.Inventory.ForceInventoryPersistence();
52 {
53 part.Inventory.ForceInventoryPersistence();
54 }
55 } 55 }
56 } 56 }
57 57
@@ -74,19 +74,17 @@ namespace OpenSim.Region.Framework.Scenes
74 /// <summary> 74 /// <summary>
75 /// Stop the scripts contained in all the prims in this group 75 /// Stop the scripts contained in all the prims in this group
76 /// </summary> 76 /// </summary>
77 /// <param name="sceneObjectBeingDeleted">
78 /// Should be true if these scripts are being removed because the scene
79 /// object is being deleted. This will prevent spurious updates to the client.
80 /// </param>
81 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 77 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
82 { 78 {
83 lock (m_parts) 79 lockPartsForRead(true);
80 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
81 lockPartsForRead(false);
82
83 foreach (SceneObjectPart part in values)
84 { 84 {
85 foreach (SceneObjectPart part in m_parts.Values) 85 part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
86 {
87 part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
88 }
89 } 86 }
87
90 } 88 }
91 89
92 /// <summary> 90 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 8c56870..9cb1398 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -106,6 +106,72 @@ namespace OpenSim.Region.Framework.Scenes
106 private bool m_hasGroupChanged = false; 106 private bool m_hasGroupChanged = false;
107 private long timeFirstChanged; 107 private long timeFirstChanged;
108 private long timeLastChanged; 108 private long timeLastChanged;
109 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
110
111 public void lockPartsForRead(bool locked)
112 {
113 if (locked)
114 {
115 if (m_partsLock.RecursiveReadCount > 0)
116 {
117 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.");
118 m_partsLock.ExitReadLock();
119 }
120 if (m_partsLock.RecursiveWriteCount > 0)
121 {
122 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
123 m_partsLock.ExitWriteLock();
124 }
125
126 while (!m_partsLock.TryEnterReadLock(60000))
127 {
128 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.");
129 if (m_partsLock.IsWriteLockHeld)
130 {
131 m_partsLock = new System.Threading.ReaderWriterLockSlim();
132 }
133 }
134 }
135 else
136 {
137 if (m_partsLock.RecursiveReadCount > 0)
138 {
139 m_partsLock.ExitReadLock();
140 }
141 }
142 }
143 public void lockPartsForWrite(bool locked)
144 {
145 if (locked)
146 {
147 if (m_partsLock.RecursiveReadCount > 0)
148 {
149 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.");
150 m_partsLock.ExitReadLock();
151 }
152 if (m_partsLock.RecursiveWriteCount > 0)
153 {
154 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
155 m_partsLock.ExitWriteLock();
156 }
157
158 while (!m_partsLock.TryEnterWriteLock(60000))
159 {
160 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.");
161 if (m_partsLock.IsWriteLockHeld)
162 {
163 m_partsLock = new System.Threading.ReaderWriterLockSlim();
164 }
165 }
166 }
167 else
168 {
169 if (m_partsLock.RecursiveWriteCount > 0)
170 {
171 m_partsLock.ExitWriteLock();
172 }
173 }
174 }
109 175
110 public bool HasGroupChanged 176 public bool HasGroupChanged
111 { 177 {
@@ -258,13 +324,16 @@ namespace OpenSim.Region.Framework.Scenes
258 set 324 set
259 { 325 {
260 m_regionHandle = value; 326 m_regionHandle = value;
261 lock (m_parts) 327 lockPartsForRead(true);
262 { 328 {
263 foreach (SceneObjectPart part in m_parts.Values) 329 foreach (SceneObjectPart part in m_parts.Values)
264 { 330 {
331
265 part.RegionHandle = m_regionHandle; 332 part.RegionHandle = m_regionHandle;
333
266 } 334 }
267 } 335 }
336 lockPartsForRead(false);
268 } 337 }
269 } 338 }
270 339
@@ -290,13 +359,16 @@ namespace OpenSim.Region.Framework.Scenes
290 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 359 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
291 } 360 }
292 361
293 lock (m_parts) 362 lockPartsForRead(true);
294 { 363 {
295 foreach (SceneObjectPart part in m_parts.Values) 364 foreach (SceneObjectPart part in m_parts.Values)
296 { 365 {
366
297 part.GroupPosition = val; 367 part.GroupPosition = val;
368
298 } 369 }
299 } 370 }
371 lockPartsForRead(false);
300 372
301 //if (m_rootPart.PhysActor != null) 373 //if (m_rootPart.PhysActor != null)
302 //{ 374 //{
@@ -458,13 +530,16 @@ namespace OpenSim.Region.Framework.Scenes
458 530
459 public void SetFromItemID(UUID AssetId) 531 public void SetFromItemID(UUID AssetId)
460 { 532 {
461 lock (m_parts) 533 lockPartsForRead(true);
462 { 534 {
463 foreach (SceneObjectPart part in m_parts.Values) 535 foreach (SceneObjectPart part in m_parts.Values)
464 { 536 {
537
465 part.FromItemID = AssetId; 538 part.FromItemID = AssetId;
539
466 } 540 }
467 } 541 }
542 lockPartsForRead(false);
468 } 543 }
469 544
470 public UUID GetFromItemID() 545 public UUID GetFromItemID()
@@ -531,10 +606,11 @@ namespace OpenSim.Region.Framework.Scenes
531 Vector3 maxScale = Vector3.Zero; 606 Vector3 maxScale = Vector3.Zero;
532 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 607 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
533 608
534 lock (m_parts) 609 lockPartsForRead(true);
535 { 610 {
536 foreach (SceneObjectPart part in m_parts.Values) 611 foreach (SceneObjectPart part in m_parts.Values)
537 { 612 {
613
538 Vector3 partscale = part.Scale; 614 Vector3 partscale = part.Scale;
539 Vector3 partoffset = part.OffsetPosition; 615 Vector3 partoffset = part.OffsetPosition;
540 616
@@ -545,8 +621,11 @@ namespace OpenSim.Region.Framework.Scenes
545 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 621 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
546 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 622 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
547 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 623 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
624
548 } 625 }
549 } 626 }
627 lockPartsForRead(false);
628
550 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 629 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
551 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 630 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
552 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 631 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -562,10 +641,11 @@ namespace OpenSim.Region.Framework.Scenes
562 641
563 EntityIntersection result = new EntityIntersection(); 642 EntityIntersection result = new EntityIntersection();
564 643
565 lock (m_parts) 644 lockPartsForRead(true);
566 { 645 {
567 foreach (SceneObjectPart part in m_parts.Values) 646 foreach (SceneObjectPart part in m_parts.Values)
568 { 647 {
648
569 // Temporary commented to stop compiler warning 649 // Temporary commented to stop compiler warning
570 //Vector3 partPosition = 650 //Vector3 partPosition =
571 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 651 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -593,8 +673,10 @@ namespace OpenSim.Region.Framework.Scenes
593 result.distance = inter.distance; 673 result.distance = inter.distance;
594 } 674 }
595 } 675 }
676
596 } 677 }
597 } 678 }
679 lockPartsForRead(false);
598 return result; 680 return result;
599 } 681 }
600 682
@@ -607,10 +689,11 @@ namespace OpenSim.Region.Framework.Scenes
607 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 689 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
608 { 690 {
609 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 691 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
610 lock (m_parts) 692 lockPartsForRead(true);
611 { 693 {
612 foreach (SceneObjectPart part in m_parts.Values) 694 foreach (SceneObjectPart part in m_parts.Values)
613 { 695 {
696
614 Vector3 worldPos = part.GetWorldPosition(); 697 Vector3 worldPos = part.GetWorldPosition();
615 Vector3 offset = worldPos - AbsolutePosition; 698 Vector3 offset = worldPos - AbsolutePosition;
616 Quaternion worldRot; 699 Quaternion worldRot;
@@ -669,6 +752,8 @@ namespace OpenSim.Region.Framework.Scenes
669 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 752 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
670 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 753 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
671 754
755
756
672 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 757 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
673 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 758 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
674 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 759 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -840,6 +925,7 @@ namespace OpenSim.Region.Framework.Scenes
840 minZ = backBottomLeft.Z; 925 minZ = backBottomLeft.Z;
841 } 926 }
842 } 927 }
928 lockPartsForRead(false);
843 929
844 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 930 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
845 931
@@ -868,17 +954,20 @@ namespace OpenSim.Region.Framework.Scenes
868 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 954 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
869 955
870 // Capture script state while holding the lock 956 // Capture script state while holding the lock
871 lock (m_parts) 957 lockPartsForRead(true);
872 { 958 {
873 foreach (SceneObjectPart part in m_parts.Values) 959 foreach (SceneObjectPart part in m_parts.Values)
874 { 960 {
961
875 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 962 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
876 foreach (UUID itemid in pstates.Keys) 963 foreach (UUID itemid in pstates.Keys)
877 { 964 {
878 states.Add(itemid, pstates[itemid]); 965 states.Add(itemid, pstates[itemid]);
879 } 966 }
967
880 } 968 }
881 } 969 }
970 lockPartsForRead(false);
882 971
883 if (states.Count > 0) 972 if (states.Count > 0)
884 { 973 {
@@ -1040,13 +1129,16 @@ namespace OpenSim.Region.Framework.Scenes
1040 1129
1041 public override void UpdateMovement() 1130 public override void UpdateMovement()
1042 { 1131 {
1043 lock (m_parts) 1132 lockPartsForRead(true);
1044 { 1133 {
1045 foreach (SceneObjectPart part in m_parts.Values) 1134 foreach (SceneObjectPart part in m_parts.Values)
1046 { 1135 {
1136
1047 part.UpdateMovement(); 1137 part.UpdateMovement();
1138
1048 } 1139 }
1049 } 1140 }
1141 lockPartsForRead(false);
1050 } 1142 }
1051 1143
1052 public ushort GetTimeDilation() 1144 public ushort GetTimeDilation()
@@ -1090,7 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes
1090 /// <param name="part"></param> 1182 /// <param name="part"></param>
1091 public void AddPart(SceneObjectPart part) 1183 public void AddPart(SceneObjectPart part)
1092 { 1184 {
1093 lock (m_parts) 1185 lockPartsForWrite(true);
1094 { 1186 {
1095 part.SetParent(this); 1187 part.SetParent(this);
1096 m_parts.Add(part.UUID, part); 1188 m_parts.Add(part.UUID, part);
@@ -1100,6 +1192,7 @@ namespace OpenSim.Region.Framework.Scenes
1100 if (part.LinkNum == 2 && RootPart != null) 1192 if (part.LinkNum == 2 && RootPart != null)
1101 RootPart.LinkNum = 1; 1193 RootPart.LinkNum = 1;
1102 } 1194 }
1195 lockPartsForWrite(false);
1103 } 1196 }
1104 1197
1105 /// <summary> 1198 /// <summary>
@@ -1107,28 +1200,33 @@ namespace OpenSim.Region.Framework.Scenes
1107 /// </summary> 1200 /// </summary>
1108 private void UpdateParentIDs() 1201 private void UpdateParentIDs()
1109 { 1202 {
1110 lock (m_parts) 1203 lockPartsForRead(true);
1111 { 1204 {
1112 foreach (SceneObjectPart part in m_parts.Values) 1205 foreach (SceneObjectPart part in m_parts.Values)
1113 { 1206 {
1207
1114 if (part.UUID != m_rootPart.UUID) 1208 if (part.UUID != m_rootPart.UUID)
1115 { 1209 {
1116 part.ParentID = m_rootPart.LocalId; 1210 part.ParentID = m_rootPart.LocalId;
1117 } 1211 }
1212
1118 } 1213 }
1119 } 1214 }
1215 lockPartsForRead(false);
1120 } 1216 }
1121 1217
1122 public void RegenerateFullIDs() 1218 public void RegenerateFullIDs()
1123 { 1219 {
1124 lock (m_parts) 1220 lockPartsForRead(true);
1125 { 1221 {
1126 foreach (SceneObjectPart part in m_parts.Values) 1222 foreach (SceneObjectPart part in m_parts.Values)
1127 { 1223 {
1224
1128 part.UUID = UUID.Random(); 1225 part.UUID = UUID.Random();
1129 1226
1130 } 1227 }
1131 } 1228 }
1229 lockPartsForRead(false);
1132 } 1230 }
1133 1231
1134 // helper provided for parts. 1232 // helper provided for parts.
@@ -1209,29 +1307,33 @@ namespace OpenSim.Region.Framework.Scenes
1209 1307
1210 DetachFromBackup(); 1308 DetachFromBackup();
1211 1309
1212 lock (m_parts) 1310 lockPartsForRead(true);
1311 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1312 lockPartsForRead(false);
1313
1314 foreach (SceneObjectPart part in values)
1213 { 1315 {
1214 foreach (SceneObjectPart part in m_parts.Values)
1215 {
1216// part.Inventory.RemoveScriptInstances(); 1316// part.Inventory.RemoveScriptInstances();
1217 1317
1218 ScenePresence[] avatars = Scene.GetScenePresences(); 1318 ScenePresence[] avatars = Scene.GetScenePresences();
1219 for (int i = 0; i < avatars.Length; i++) 1319 for (int i = 0; i < avatars.Length; i++)
1320 {
1321 if (avatars[i].ParentID == LocalId)
1220 { 1322 {
1221 if (avatars[i].ParentID == LocalId) 1323 avatars[i].StandUp();
1222 { 1324 }
1223 avatars[i].StandUp();
1224 }
1225 1325
1226 if (!silent) 1326 if (!silent)
1227 { 1327 {
1228 part.UpdateFlag = 0; 1328 part.UpdateFlag = 0;
1229 if (part == m_rootPart) 1329 if (part == m_rootPart)
1230 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1330 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1231 }
1232 } 1331 }
1233 } 1332 }
1333
1234 } 1334 }
1335
1336
1235 } 1337 }
1236 1338
1237 public void AddScriptLPS(int count) 1339 public void AddScriptLPS(int count)
@@ -1256,17 +1358,20 @@ namespace OpenSim.Region.Framework.Scenes
1256 1358
1257 scriptEvents aggregateScriptEvents=0; 1359 scriptEvents aggregateScriptEvents=0;
1258 1360
1259 lock (m_parts) 1361 lockPartsForRead(true);
1260 { 1362 {
1261 foreach (SceneObjectPart part in m_parts.Values) 1363 foreach (SceneObjectPart part in m_parts.Values)
1262 { 1364 {
1365
1263 if (part == null) 1366 if (part == null)
1264 continue; 1367 continue;
1265 if (part != RootPart) 1368 if (part != RootPart)
1266 part.ObjectFlags = objectflagupdate; 1369 part.ObjectFlags = objectflagupdate;
1267 aggregateScriptEvents |= part.AggregateScriptEvents; 1370 aggregateScriptEvents |= part.AggregateScriptEvents;
1371
1268 } 1372 }
1269 } 1373 }
1374 lockPartsForRead(false);
1270 1375
1271 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1376 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1272 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1377 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1308,42 +1413,52 @@ namespace OpenSim.Region.Framework.Scenes
1308 /// <param name="m_physicalPrim"></param> 1413 /// <param name="m_physicalPrim"></param>
1309 public void ApplyPhysics(bool m_physicalPrim) 1414 public void ApplyPhysics(bool m_physicalPrim)
1310 { 1415 {
1311 lock (m_parts) 1416 lockPartsForRead(true);
1417
1418 if (m_parts.Count > 1)
1312 { 1419 {
1313 if (m_parts.Count > 1) 1420 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1421 lockPartsForRead(false);
1422 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1423 foreach (SceneObjectPart part in values)
1314 { 1424 {
1315 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1425
1316 foreach (SceneObjectPart part in m_parts.Values) 1426 if (part.LocalId != m_rootPart.LocalId)
1317 { 1427 {
1318 if (part.LocalId != m_rootPart.LocalId) 1428 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1319 {
1320 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1321 }
1322 } 1429 }
1323 1430
1324 // Hack to get the physics scene geometries in the right spot
1325 ResetChildPrimPhysicsPositions();
1326 }
1327 else
1328 {
1329 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1330 } 1431 }
1432 // Hack to get the physics scene geometries in the right spot
1433 ResetChildPrimPhysicsPositions();
1434 }
1435 else
1436 {
1437 lockPartsForRead(false);
1438 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1331 } 1439 }
1332 } 1440 }
1333 1441
1334 public void SetOwnerId(UUID userId) 1442 public void SetOwnerId(UUID userId)
1335 { 1443 {
1336 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1444 ForEachPart(delegate(SceneObjectPart part)
1445 {
1446
1447 part.OwnerID = userId;
1448
1449 });
1337 } 1450 }
1338 1451
1339 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1452 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1340 { 1453 {
1341 lock (m_parts) 1454 lockPartsForRead(true);
1455 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1456 lockPartsForRead(false);
1457 foreach (SceneObjectPart part in values)
1342 { 1458 {
1343 foreach (SceneObjectPart part in m_parts.Values) 1459
1344 { 1460 whatToDo(part);
1345 whatToDo(part); 1461
1346 }
1347 } 1462 }
1348 } 1463 }
1349 1464
@@ -1442,14 +1557,17 @@ namespace OpenSim.Region.Framework.Scenes
1442 { 1557 {
1443 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1558 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1444 1559
1445 lock (m_parts) 1560 lockPartsForRead(true);
1446 { 1561 {
1447 foreach (SceneObjectPart part in m_parts.Values) 1562 foreach (SceneObjectPart part in m_parts.Values)
1448 { 1563 {
1564
1449 if (part != RootPart) 1565 if (part != RootPart)
1450 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1566 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1567
1451 } 1568 }
1452 } 1569 }
1570 lockPartsForRead(false);
1453 } 1571 }
1454 1572
1455 /// <summary> 1573 /// <summary>
@@ -1544,10 +1662,11 @@ namespace OpenSim.Region.Framework.Scenes
1544 1662
1545 List<SceneObjectPart> partList; 1663 List<SceneObjectPart> partList;
1546 1664
1547 lock (m_parts) 1665 lockPartsForRead(true);
1548 { 1666
1549 partList = new List<SceneObjectPart>(m_parts.Values); 1667 partList = new List<SceneObjectPart>(m_parts.Values);
1550 } 1668
1669 lockPartsForRead(false);
1551 1670
1552 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1671 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1553 { 1672 {
@@ -1796,6 +1915,7 @@ namespace OpenSim.Region.Framework.Scenes
1796 } 1915 }
1797 } 1916 }
1798 } 1917 }
1918
1799 public void stopLookAt() 1919 public void stopLookAt()
1800 { 1920 {
1801 SceneObjectPart rootpart = m_rootPart; 1921 SceneObjectPart rootpart = m_rootPart;
@@ -1870,10 +1990,11 @@ namespace OpenSim.Region.Framework.Scenes
1870 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1990 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1871 newPart.SetParent(this); 1991 newPart.SetParent(this);
1872 1992
1873 lock (m_parts) 1993 lockPartsForWrite(true);
1874 { 1994 {
1875 m_parts.Add(newPart.UUID, newPart); 1995 m_parts.Add(newPart.UUID, newPart);
1876 } 1996 }
1997 lockPartsForWrite(false);
1877 1998
1878 SetPartAsNonRoot(newPart); 1999 SetPartAsNonRoot(newPart);
1879 2000
@@ -1936,7 +2057,7 @@ namespace OpenSim.Region.Framework.Scenes
1936 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2057 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1937 // return; 2058 // return;
1938 2059
1939 lock (m_parts) 2060 lockPartsForRead(true);
1940 { 2061 {
1941 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2062 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1942 2063
@@ -1954,34 +2075,43 @@ namespace OpenSim.Region.Framework.Scenes
1954 2075
1955 foreach (SceneObjectPart part in m_parts.Values) 2076 foreach (SceneObjectPart part in m_parts.Values)
1956 { 2077 {
2078
1957 part.SendScheduledUpdates(); 2079 part.SendScheduledUpdates();
2080
1958 } 2081 }
1959 } 2082 }
2083 lockPartsForRead(false);
1960 } 2084 }
1961 2085
1962 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2086 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1963 { 2087 {
1964 RootPart.AddFullUpdateToAvatar(presence); 2088 RootPart.AddFullUpdateToAvatar(presence);
1965 2089
1966 lock (m_parts) 2090 lockPartsForRead(true);
1967 { 2091 {
1968 foreach (SceneObjectPart part in m_parts.Values) 2092 foreach (SceneObjectPart part in m_parts.Values)
1969 { 2093 {
2094
1970 if (part != RootPart) 2095 if (part != RootPart)
1971 part.AddFullUpdateToAvatar(presence); 2096 part.AddFullUpdateToAvatar(presence);
2097
1972 } 2098 }
1973 } 2099 }
2100 lockPartsForRead(false);
1974 } 2101 }
1975 2102
1976 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2103 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1977 { 2104 {
1978 lock (m_parts) 2105 lockPartsForRead(true);
1979 { 2106 {
1980 foreach (SceneObjectPart part in m_parts.Values) 2107 foreach (SceneObjectPart part in m_parts.Values)
1981 { 2108 {
2109
1982 part.AddTerseUpdateToAvatar(presence); 2110 part.AddTerseUpdateToAvatar(presence);
2111
1983 } 2112 }
1984 } 2113 }
2114 lockPartsForRead(false);
1985 } 2115 }
1986 2116
1987 /// <summary> 2117 /// <summary>
@@ -1992,14 +2122,17 @@ namespace OpenSim.Region.Framework.Scenes
1992 checkAtTargets(); 2122 checkAtTargets();
1993 RootPart.ScheduleFullUpdate(); 2123 RootPart.ScheduleFullUpdate();
1994 2124
1995 lock (m_parts) 2125 lockPartsForRead(true);
1996 { 2126 {
1997 foreach (SceneObjectPart part in m_parts.Values) 2127 foreach (SceneObjectPart part in m_parts.Values)
1998 { 2128 {
2129
1999 if (part != RootPart) 2130 if (part != RootPart)
2000 part.ScheduleFullUpdate(); 2131 part.ScheduleFullUpdate();
2132
2001 } 2133 }
2002 } 2134 }
2135 lockPartsForRead(false);
2003 } 2136 }
2004 2137
2005 /// <summary> 2138 /// <summary>
@@ -2007,13 +2140,16 @@ namespace OpenSim.Region.Framework.Scenes
2007 /// </summary> 2140 /// </summary>
2008 public void ScheduleGroupForTerseUpdate() 2141 public void ScheduleGroupForTerseUpdate()
2009 { 2142 {
2010 lock (m_parts) 2143 lockPartsForRead(true);
2011 { 2144 {
2012 foreach (SceneObjectPart part in m_parts.Values) 2145 foreach (SceneObjectPart part in m_parts.Values)
2013 { 2146 {
2147
2014 part.ScheduleTerseUpdate(); 2148 part.ScheduleTerseUpdate();
2149
2015 } 2150 }
2016 } 2151 }
2152 lockPartsForRead(false);
2017 } 2153 }
2018 2154
2019 /// <summary> 2155 /// <summary>
@@ -2026,14 +2162,17 @@ namespace OpenSim.Region.Framework.Scenes
2026 2162
2027 RootPart.SendFullUpdateToAllClients(); 2163 RootPart.SendFullUpdateToAllClients();
2028 2164
2029 lock (m_parts) 2165 lockPartsForRead(true);
2030 { 2166 {
2031 foreach (SceneObjectPart part in m_parts.Values) 2167 foreach (SceneObjectPart part in m_parts.Values)
2032 { 2168 {
2169
2033 if (part != RootPart) 2170 if (part != RootPart)
2034 part.SendFullUpdateToAllClients(); 2171 part.SendFullUpdateToAllClients();
2172
2035 } 2173 }
2036 } 2174 }
2175 lockPartsForRead(false);
2037 } 2176 }
2038 2177
2039 /// <summary> 2178 /// <summary>
@@ -2064,14 +2203,15 @@ namespace OpenSim.Region.Framework.Scenes
2064 { 2203 {
2065 if (IsDeleted) 2204 if (IsDeleted)
2066 return; 2205 return;
2067 2206
2068 lock (m_parts) 2207 lockPartsForRead(true);
2069 { 2208 {
2070 foreach (SceneObjectPart part in m_parts.Values) 2209 foreach (SceneObjectPart part in m_parts.Values)
2071 { 2210 {
2072 part.SendTerseUpdateToAllClients(); 2211 part.SendTerseUpdateToAllClients();
2073 } 2212 }
2074 } 2213 }
2214 lockPartsForRead(false);
2075 } 2215 }
2076 2216
2077 #endregion 2217 #endregion
@@ -2085,16 +2225,18 @@ namespace OpenSim.Region.Framework.Scenes
2085 /// <returns>null if no child part with that linknum or child part</returns> 2225 /// <returns>null if no child part with that linknum or child part</returns>
2086 public SceneObjectPart GetLinkNumPart(int linknum) 2226 public SceneObjectPart GetLinkNumPart(int linknum)
2087 { 2227 {
2088 lock (m_parts) 2228 lockPartsForRead(true);
2089 { 2229 {
2090 foreach (SceneObjectPart part in m_parts.Values) 2230 foreach (SceneObjectPart part in m_parts.Values)
2091 { 2231 {
2092 if (part.LinkNum == linknum) 2232 if (part.LinkNum == linknum)
2093 { 2233 {
2234 lockPartsForRead(false);
2094 return part; 2235 return part;
2095 } 2236 }
2096 } 2237 }
2097 } 2238 }
2239 lockPartsForRead(false);
2098 2240
2099 return null; 2241 return null;
2100 } 2242 }
@@ -2122,17 +2264,19 @@ namespace OpenSim.Region.Framework.Scenes
2122 public SceneObjectPart GetChildPart(uint localID) 2264 public SceneObjectPart GetChildPart(uint localID)
2123 { 2265 {
2124 //m_log.DebugFormat("Entered looking for {0}", localID); 2266 //m_log.DebugFormat("Entered looking for {0}", localID);
2125 lock (m_parts) 2267 lockPartsForRead(true);
2126 { 2268 {
2127 foreach (SceneObjectPart part in m_parts.Values) 2269 foreach (SceneObjectPart part in m_parts.Values)
2128 { 2270 {
2129 //m_log.DebugFormat("Found {0}", part.LocalId); 2271 //m_log.DebugFormat("Found {0}", part.LocalId);
2130 if (part.LocalId == localID) 2272 if (part.LocalId == localID)
2131 { 2273 {
2274 lockPartsForRead(false);
2132 return part; 2275 return part;
2133 } 2276 }
2134 } 2277 }
2135 } 2278 }
2279 lockPartsForRead(false);
2136 2280
2137 return null; 2281 return null;
2138 } 2282 }
@@ -2162,17 +2306,19 @@ namespace OpenSim.Region.Framework.Scenes
2162 public bool HasChildPrim(uint localID) 2306 public bool HasChildPrim(uint localID)
2163 { 2307 {
2164 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2308 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2165 lock (m_parts) 2309 lockPartsForRead(true);
2166 { 2310 {
2167 foreach (SceneObjectPart part in m_parts.Values) 2311 foreach (SceneObjectPart part in m_parts.Values)
2168 { 2312 {
2169 //m_log.DebugFormat("Found {0}", part.LocalId); 2313 //m_log.DebugFormat("Found {0}", part.LocalId);
2170 if (part.LocalId == localID) 2314 if (part.LocalId == localID)
2171 { 2315 {
2316 lockPartsForRead(false);
2172 return true; 2317 return true;
2173 } 2318 }
2174 } 2319 }
2175 } 2320 }
2321 lockPartsForRead(false);
2176 2322
2177 return false; 2323 return false;
2178 } 2324 }
@@ -2222,53 +2368,57 @@ namespace OpenSim.Region.Framework.Scenes
2222 if (m_rootPart.LinkNum == 0) 2368 if (m_rootPart.LinkNum == 0)
2223 m_rootPart.LinkNum = 1; 2369 m_rootPart.LinkNum = 1;
2224 2370
2225 lock (m_parts) 2371 lockPartsForWrite(true);
2226 { 2372
2227 m_parts.Add(linkPart.UUID, linkPart); 2373 m_parts.Add(linkPart.UUID, linkPart);
2228 2374
2229 // Insert in terms of link numbers, the new links 2375 lockPartsForWrite(false);
2230 // before the current ones (with the exception of 2376
2231 // the root prim. Shuffle the old ones up 2377 // Insert in terms of link numbers, the new links
2232 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2378 // before the current ones (with the exception of
2379 // the root prim. Shuffle the old ones up
2380 lockPartsForRead(true);
2381 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2382 {
2383 if (kvp.Value.LinkNum != 1)
2233 { 2384 {
2234 if (kvp.Value.LinkNum != 1) 2385 // Don't update root prim link number
2235 { 2386 kvp.Value.LinkNum += objectGroup.PrimCount;
2236 // Don't update root prim link number
2237 kvp.Value.LinkNum += objectGroup.PrimCount;
2238 }
2239 } 2387 }
2388 }
2389 lockPartsForRead(false);
2240 2390
2241 linkPart.LinkNum = 2; 2391 linkPart.LinkNum = 2;
2242 2392
2243 linkPart.SetParent(this); 2393 linkPart.SetParent(this);
2244 linkPart.AddFlag(PrimFlags.CreateSelected); 2394 linkPart.AddFlag(PrimFlags.CreateSelected);
2245 2395
2246 //if (linkPart.PhysActor != null) 2396 //if (linkPart.PhysActor != null)
2247 //{ 2397 //{
2248 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2398 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2249 2399
2250 //linkPart.PhysActor = null; 2400 //linkPart.PhysActor = null;
2251 //} 2401 //}
2252 2402
2253 //TODO: rest of parts 2403 //TODO: rest of parts
2254 int linkNum = 3; 2404 int linkNum = 3;
2255 foreach (SceneObjectPart part in objectGroup.Children.Values) 2405 foreach (SceneObjectPart part in objectGroup.Children.Values)
2406 {
2407 if (part.UUID != objectGroup.m_rootPart.UUID)
2256 { 2408 {
2257 if (part.UUID != objectGroup.m_rootPart.UUID) 2409 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2258 {
2259 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2260 }
2261 part.ClearUndoState();
2262 } 2410 }
2411 part.ClearUndoState();
2263 } 2412 }
2264 2413
2265 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2414 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2266 objectGroup.m_isDeleted = true; 2415 objectGroup.m_isDeleted = true;
2416
2417 objectGroup.lockPartsForWrite(true);
2267 2418
2268 lock (objectGroup.m_parts) 2419 objectGroup.m_parts.Clear();
2269 { 2420
2270 objectGroup.m_parts.Clear(); 2421 objectGroup.lockPartsForWrite(false);
2271 }
2272 2422
2273 // Can't do this yet since backup still makes use of the root part without any synchronization 2423 // Can't do this yet since backup still makes use of the root part without any synchronization
2274// objectGroup.m_rootPart = null; 2424// objectGroup.m_rootPart = null;
@@ -2327,11 +2477,12 @@ namespace OpenSim.Region.Framework.Scenes
2327 Quaternion worldRot = linkPart.GetWorldRotation(); 2477 Quaternion worldRot = linkPart.GetWorldRotation();
2328 2478
2329 // Remove the part from this object 2479 // Remove the part from this object
2330 lock (m_parts) 2480 lockPartsForWrite(true);
2331 { 2481 {
2332 m_parts.Remove(linkPart.UUID); 2482 m_parts.Remove(linkPart.UUID);
2333 } 2483 }
2334 2484 lockPartsForWrite(false);
2485 lockPartsForRead(true);
2335 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2486 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2336 RootPart.LinkNum = 0; 2487 RootPart.LinkNum = 0;
2337 else 2488 else
@@ -2342,6 +2493,7 @@ namespace OpenSim.Region.Framework.Scenes
2342 p.LinkNum--; 2493 p.LinkNum--;
2343 } 2494 }
2344 } 2495 }
2496 lockPartsForRead(false);
2345 2497
2346 linkPart.ParentID = 0; 2498 linkPart.ParentID = 0;
2347 linkPart.LinkNum = 0; 2499 linkPart.LinkNum = 0;
@@ -2659,9 +2811,12 @@ namespace OpenSim.Region.Framework.Scenes
2659 2811
2660 if (selectionPart != null) 2812 if (selectionPart != null)
2661 { 2813 {
2662 lock (m_parts) 2814 lockPartsForRead(true);
2815 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2816 lockPartsForRead(false);
2817 foreach (SceneObjectPart part in parts)
2663 { 2818 {
2664 foreach (SceneObjectPart part in m_parts.Values) 2819 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2665 { 2820 {
2666 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2821 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2667 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2822 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2671,12 +2826,13 @@ namespace OpenSim.Region.Framework.Scenes
2671 break; 2826 break;
2672 } 2827 }
2673 } 2828 }
2829 }
2674 2830
2675 foreach (SceneObjectPart part in m_parts.Values) 2831 foreach (SceneObjectPart part in parts)
2676 { 2832 {
2677 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2833 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2678 }
2679 } 2834 }
2835
2680 } 2836 }
2681 } 2837 }
2682 2838
@@ -2762,11 +2918,9 @@ namespace OpenSim.Region.Framework.Scenes
2762 scale.Y = m_scene.m_maxNonphys; 2918 scale.Y = m_scene.m_maxNonphys;
2763 if (scale.Z > m_scene.m_maxNonphys) 2919 if (scale.Z > m_scene.m_maxNonphys)
2764 scale.Z = m_scene.m_maxNonphys; 2920 scale.Z = m_scene.m_maxNonphys;
2765
2766 SceneObjectPart part = GetChildPart(localID); 2921 SceneObjectPart part = GetChildPart(localID);
2767 if (part != null) 2922 if (part != null)
2768 { 2923 {
2769 part.Resize(scale);
2770 if (part.PhysActor != null) 2924 if (part.PhysActor != null)
2771 { 2925 {
2772 if (part.PhysActor.IsPhysical) 2926 if (part.PhysActor.IsPhysical)
@@ -2781,7 +2935,7 @@ namespace OpenSim.Region.Framework.Scenes
2781 part.PhysActor.Size = scale; 2935 part.PhysActor.Size = scale;
2782 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2936 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2783 } 2937 }
2784 //if (part.UUID != m_rootPart.UUID) 2938 part.Resize(scale);
2785 2939
2786 HasGroupChanged = true; 2940 HasGroupChanged = true;
2787 ScheduleGroupForFullUpdate(); 2941 ScheduleGroupForFullUpdate();
@@ -2822,77 +2976,76 @@ namespace OpenSim.Region.Framework.Scenes
2822 float y = (scale.Y / part.Scale.Y); 2976 float y = (scale.Y / part.Scale.Y);
2823 float z = (scale.Z / part.Scale.Z); 2977 float z = (scale.Z / part.Scale.Z);
2824 2978
2825 lock (m_parts) 2979 lockPartsForRead(true);
2980 if (x > 1.0f || y > 1.0f || z > 1.0f)
2826 { 2981 {
2827 if (x > 1.0f || y > 1.0f || z > 1.0f) 2982 foreach (SceneObjectPart obPart in m_parts.Values)
2828 { 2983 {
2829 foreach (SceneObjectPart obPart in m_parts.Values) 2984 if (obPart.UUID != m_rootPart.UUID)
2830 { 2985 {
2831 if (obPart.UUID != m_rootPart.UUID) 2986 Vector3 oldSize = new Vector3(obPart.Scale);
2832 {
2833 Vector3 oldSize = new Vector3(obPart.Scale);
2834 2987
2835 float f = 1.0f; 2988 float f = 1.0f;
2836 float a = 1.0f; 2989 float a = 1.0f;
2837 2990
2838 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2991 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2992 {
2993 if (oldSize.X*x > m_scene.m_maxPhys)
2839 { 2994 {
2840 if (oldSize.X*x > m_scene.m_maxPhys) 2995 f = m_scene.m_maxPhys / oldSize.X;
2841 { 2996 a = f / x;
2842 f = m_scene.m_maxPhys / oldSize.X; 2997 x *= a;
2843 a = f / x; 2998 y *= a;
2844 x *= a; 2999 z *= a;
2845 y *= a;
2846 z *= a;
2847 }
2848 if (oldSize.Y*y > m_scene.m_maxPhys)
2849 {
2850 f = m_scene.m_maxPhys / oldSize.Y;
2851 a = f / y;
2852 x *= a;
2853 y *= a;
2854 z *= a;
2855 }
2856 if (oldSize.Z*z > m_scene.m_maxPhys)
2857 {
2858 f = m_scene.m_maxPhys / oldSize.Z;
2859 a = f / z;
2860 x *= a;
2861 y *= a;
2862 z *= a;
2863 }
2864 } 3000 }
2865 else 3001 if (oldSize.Y*y > m_scene.m_maxPhys)
3002 {
3003 f = m_scene.m_maxPhys / oldSize.Y;
3004 a = f / y;
3005 x *= a;
3006 y *= a;
3007 z *= a;
3008 }
3009 if (oldSize.Z*z > m_scene.m_maxPhys)
3010 {
3011 f = m_scene.m_maxPhys / oldSize.Z;
3012 a = f / z;
3013 x *= a;
3014 y *= a;
3015 z *= a;
3016 }
3017 }
3018 else
3019 {
3020 if (oldSize.X*x > m_scene.m_maxNonphys)
3021 {
3022 f = m_scene.m_maxNonphys / oldSize.X;
3023 a = f / x;
3024 x *= a;
3025 y *= a;
3026 z *= a;
3027 }
3028 if (oldSize.Y*y > m_scene.m_maxNonphys)
3029 {
3030 f = m_scene.m_maxNonphys / oldSize.Y;
3031 a = f / y;
3032 x *= a;
3033 y *= a;
3034 z *= a;
3035 }
3036 if (oldSize.Z*z > m_scene.m_maxNonphys)
2866 { 3037 {
2867 if (oldSize.X*x > m_scene.m_maxNonphys) 3038 f = m_scene.m_maxNonphys / oldSize.Z;
2868 { 3039 a = f / z;
2869 f = m_scene.m_maxNonphys / oldSize.X; 3040 x *= a;
2870 a = f / x; 3041 y *= a;
2871 x *= a; 3042 z *= a;
2872 y *= a;
2873 z *= a;
2874 }
2875 if (oldSize.Y*y > m_scene.m_maxNonphys)
2876 {
2877 f = m_scene.m_maxNonphys / oldSize.Y;
2878 a = f / y;
2879 x *= a;
2880 y *= a;
2881 z *= a;
2882 }
2883 if (oldSize.Z*z > m_scene.m_maxNonphys)
2884 {
2885 f = m_scene.m_maxNonphys / oldSize.Z;
2886 a = f / z;
2887 x *= a;
2888 y *= a;
2889 z *= a;
2890 }
2891 } 3043 }
2892 } 3044 }
2893 } 3045 }
2894 } 3046 }
2895 } 3047 }
3048 lockPartsForRead(false);
2896 3049
2897 Vector3 prevScale = part.Scale; 3050 Vector3 prevScale = part.Scale;
2898 prevScale.X *= x; 3051 prevScale.X *= x;
@@ -2900,7 +3053,7 @@ namespace OpenSim.Region.Framework.Scenes
2900 prevScale.Z *= z; 3053 prevScale.Z *= z;
2901 part.Resize(prevScale); 3054 part.Resize(prevScale);
2902 3055
2903 lock (m_parts) 3056 lockPartsForRead(true);
2904 { 3057 {
2905 foreach (SceneObjectPart obPart in m_parts.Values) 3058 foreach (SceneObjectPart obPart in m_parts.Values)
2906 { 3059 {
@@ -2919,6 +3072,7 @@ namespace OpenSim.Region.Framework.Scenes
2919 } 3072 }
2920 } 3073 }
2921 } 3074 }
3075 lockPartsForRead(false);
2922 3076
2923 if (part.PhysActor != null) 3077 if (part.PhysActor != null)
2924 { 3078 {
@@ -2999,7 +3153,7 @@ namespace OpenSim.Region.Framework.Scenes
2999 axDiff *= Quaternion.Inverse(partRotation); 3153 axDiff *= Quaternion.Inverse(partRotation);
3000 diff = axDiff; 3154 diff = axDiff;
3001 3155
3002 lock (m_parts) 3156 lockPartsForRead(true);
3003 { 3157 {
3004 foreach (SceneObjectPart obPart in m_parts.Values) 3158 foreach (SceneObjectPart obPart in m_parts.Values)
3005 { 3159 {
@@ -3009,6 +3163,7 @@ namespace OpenSim.Region.Framework.Scenes
3009 } 3163 }
3010 } 3164 }
3011 } 3165 }
3166 lockPartsForRead(false);
3012 3167
3013 AbsolutePosition = newPos; 3168 AbsolutePosition = newPos;
3014 3169
@@ -3126,7 +3281,7 @@ namespace OpenSim.Region.Framework.Scenes
3126 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3281 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3127 } 3282 }
3128 3283
3129 lock (m_parts) 3284 lockPartsForRead(true);
3130 { 3285 {
3131 foreach (SceneObjectPart prim in m_parts.Values) 3286 foreach (SceneObjectPart prim in m_parts.Values)
3132 { 3287 {
@@ -3144,6 +3299,7 @@ namespace OpenSim.Region.Framework.Scenes
3144 } 3299 }
3145 } 3300 }
3146 } 3301 }
3302 lockPartsForRead(false);
3147 3303
3148 m_rootPart.ScheduleTerseUpdate(); 3304 m_rootPart.ScheduleTerseUpdate();
3149 } 3305 }
@@ -3266,7 +3422,7 @@ namespace OpenSim.Region.Framework.Scenes
3266 if (atTargets.Count > 0) 3422 if (atTargets.Count > 0)
3267 { 3423 {
3268 uint[] localids = new uint[0]; 3424 uint[] localids = new uint[0];
3269 lock (m_parts) 3425 lockPartsForRead(true);
3270 { 3426 {
3271 localids = new uint[m_parts.Count]; 3427 localids = new uint[m_parts.Count];
3272 int cntr = 0; 3428 int cntr = 0;
@@ -3276,6 +3432,7 @@ namespace OpenSim.Region.Framework.Scenes
3276 cntr++; 3432 cntr++;
3277 } 3433 }
3278 } 3434 }
3435 lockPartsForRead(false);
3279 3436
3280 for (int ctr = 0; ctr < localids.Length; ctr++) 3437 for (int ctr = 0; ctr < localids.Length; ctr++)
3281 { 3438 {
@@ -3294,7 +3451,7 @@ namespace OpenSim.Region.Framework.Scenes
3294 { 3451 {
3295 //trigger not_at_target 3452 //trigger not_at_target
3296 uint[] localids = new uint[0]; 3453 uint[] localids = new uint[0];
3297 lock (m_parts) 3454 lockPartsForRead(true);
3298 { 3455 {
3299 localids = new uint[m_parts.Count]; 3456 localids = new uint[m_parts.Count];
3300 int cntr = 0; 3457 int cntr = 0;
@@ -3304,7 +3461,8 @@ namespace OpenSim.Region.Framework.Scenes
3304 cntr++; 3461 cntr++;
3305 } 3462 }
3306 } 3463 }
3307 3464 lockPartsForRead(false);
3465
3308 for (int ctr = 0; ctr < localids.Length; ctr++) 3466 for (int ctr = 0; ctr < localids.Length; ctr++)
3309 { 3467 {
3310 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3468 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3396,19 +3554,20 @@ namespace OpenSim.Region.Framework.Scenes
3396 public float GetMass() 3554 public float GetMass()
3397 { 3555 {
3398 float retmass = 0f; 3556 float retmass = 0f;
3399 lock (m_parts) 3557 lockPartsForRead(true);
3400 { 3558 {
3401 foreach (SceneObjectPart part in m_parts.Values) 3559 foreach (SceneObjectPart part in m_parts.Values)
3402 { 3560 {
3403 retmass += part.GetMass(); 3561 retmass += part.GetMass();
3404 } 3562 }
3405 } 3563 }
3564 lockPartsForRead(false);
3406 return retmass; 3565 return retmass;
3407 } 3566 }
3408 3567
3409 public void CheckSculptAndLoad() 3568 public void CheckSculptAndLoad()
3410 { 3569 {
3411 lock (m_parts) 3570 lockPartsForRead(true);
3412 { 3571 {
3413 if (!IsDeleted) 3572 if (!IsDeleted)
3414 { 3573 {
@@ -3433,6 +3592,7 @@ namespace OpenSim.Region.Framework.Scenes
3433 } 3592 }
3434 } 3593 }
3435 } 3594 }
3595 lockPartsForRead(false);
3436 } 3596 }
3437 3597
3438 protected void AssetReceived(string id, Object sender, AssetBase asset) 3598 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3453,7 +3613,7 @@ namespace OpenSim.Region.Framework.Scenes
3453 /// <param name="client"></param> 3613 /// <param name="client"></param>
3454 public void SetGroup(UUID GroupID, IClientAPI client) 3614 public void SetGroup(UUID GroupID, IClientAPI client)
3455 { 3615 {
3456 lock (m_parts) 3616 lockPartsForRead(true);
3457 { 3617 {
3458 foreach (SceneObjectPart part in m_parts.Values) 3618 foreach (SceneObjectPart part in m_parts.Values)
3459 { 3619 {
@@ -3463,7 +3623,7 @@ namespace OpenSim.Region.Framework.Scenes
3463 3623
3464 HasGroupChanged = true; 3624 HasGroupChanged = true;
3465 } 3625 }
3466 3626 lockPartsForRead(false);
3467 ScheduleGroupForFullUpdate(); 3627 ScheduleGroupForFullUpdate();
3468 } 3628 }
3469 3629
@@ -3482,11 +3642,12 @@ namespace OpenSim.Region.Framework.Scenes
3482 3642
3483 public void SetAttachmentPoint(byte point) 3643 public void SetAttachmentPoint(byte point)
3484 { 3644 {
3485 lock (m_parts) 3645 lockPartsForRead(true);
3486 { 3646 {
3487 foreach (SceneObjectPart part in m_parts.Values) 3647 foreach (SceneObjectPart part in m_parts.Values)
3488 part.SetAttachmentPoint(point); 3648 part.SetAttachmentPoint(point);
3489 } 3649 }
3650 lockPartsForRead(false);
3490 } 3651 }
3491 3652
3492 #region ISceneObject 3653 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 61ba4da..fe1e218 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Region.Framework.Scenes
126 126
127 // TODO: This needs to be persisted in next XML version update! 127 // TODO: This needs to be persisted in next XML version update!
128 [XmlIgnore] 128 [XmlIgnore]
129 public readonly int[] PayPrice = {-2,-2,-2,-2,-2}; 129 public int[] PayPrice = {-2,-2,-2,-2,-2};
130 [XmlIgnore] 130 [XmlIgnore]
131 public PhysicsActor PhysActor; 131 public PhysicsActor PhysActor;
132 132
@@ -241,6 +241,7 @@ namespace OpenSim.Region.Framework.Scenes
241 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 241 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
242 private Vector3 m_sitTargetPosition; 242 private Vector3 m_sitTargetPosition;
243 private string m_sitAnimation = "SIT"; 243 private string m_sitAnimation = "SIT";
244 private bool m_occupied; // KF if any av is sitting on this prim
244 private string m_text = String.Empty; 245 private string m_text = String.Empty;
245 private string m_touchName = String.Empty; 246 private string m_touchName = String.Empty;
246 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 247 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -418,12 +419,16 @@ namespace OpenSim.Region.Framework.Scenes
418 } 419 }
419 420
420 /// <value> 421 /// <value>
421 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 422 /// Get the inventory list
422 /// </value> 423 /// </value>
423 public TaskInventoryDictionary TaskInventory 424 public TaskInventoryDictionary TaskInventory
424 { 425 {
425 get { return m_inventory.Items; } 426 get {
426 set { m_inventory.Items = value; } 427 return m_inventory.Items;
428 }
429 set {
430 m_inventory.Items = value;
431 }
427 } 432 }
428 433
429 public uint ObjectFlags 434 public uint ObjectFlags
@@ -567,7 +572,6 @@ namespace OpenSim.Region.Framework.Scenes
567 StoreUndoState(); 572 StoreUndoState();
568 573
569 m_groupPosition = value; 574 m_groupPosition = value;
570
571 PhysicsActor actor = PhysActor; 575 PhysicsActor actor = PhysActor;
572 if (actor != null) 576 if (actor != null)
573 { 577 {
@@ -880,7 +884,8 @@ namespace OpenSim.Region.Framework.Scenes
880 if (IsAttachment) 884 if (IsAttachment)
881 return GroupPosition; 885 return GroupPosition;
882 886
883 return m_offsetPosition + m_groupPosition; } 887// return m_offsetPosition + m_groupPosition; }
888 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
884 } 889 }
885 890
886 public SceneObjectGroup ParentGroup 891 public SceneObjectGroup ParentGroup
@@ -1032,6 +1037,13 @@ namespace OpenSim.Region.Framework.Scenes
1032 get { return _flags; } 1037 get { return _flags; }
1033 set { _flags = value; } 1038 set { _flags = value; }
1034 } 1039 }
1040
1041 [XmlIgnore]
1042 public bool IsOccupied // KF If an av is sittingon this prim
1043 {
1044 get { return m_occupied; }
1045 set { m_occupied = value; }
1046 }
1035 1047
1036 [XmlIgnore] 1048 [XmlIgnore]
1037 public UUID SitTargetAvatar 1049 public UUID SitTargetAvatar
@@ -1107,14 +1119,6 @@ namespace OpenSim.Region.Framework.Scenes
1107 } 1119 }
1108 } 1120 }
1109 1121
1110 /// <summary>
1111 /// Clear all pending updates of parts to clients
1112 /// </summary>
1113 private void ClearUpdateSchedule()
1114 {
1115 m_updateFlag = 0;
1116 }
1117
1118 private void SendObjectPropertiesToClient(UUID AgentID) 1122 private void SendObjectPropertiesToClient(UUID AgentID)
1119 { 1123 {
1120 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1124 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1793,12 +1797,17 @@ namespace OpenSim.Region.Framework.Scenes
1793 public Vector3 GetWorldPosition() 1797 public Vector3 GetWorldPosition()
1794 { 1798 {
1795 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1799 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1796
1797 Vector3 axPos = OffsetPosition; 1800 Vector3 axPos = OffsetPosition;
1798
1799 axPos *= parentRot; 1801 axPos *= parentRot;
1800 Vector3 translationOffsetPosition = axPos; 1802 Vector3 translationOffsetPosition = axPos;
1801 return GroupPosition + translationOffsetPosition; 1803 if(_parentID == 0)
1804 {
1805 return GroupPosition;
1806 }
1807 else
1808 {
1809 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
1810 }
1802 } 1811 }
1803 1812
1804 /// <summary> 1813 /// <summary>
@@ -1809,7 +1818,7 @@ namespace OpenSim.Region.Framework.Scenes
1809 { 1818 {
1810 Quaternion newRot; 1819 Quaternion newRot;
1811 1820
1812 if (this.LinkNum == 0) 1821 if (this.LinkNum < 2) //KF Single or root prim
1813 { 1822 {
1814 newRot = RotationOffset; 1823 newRot = RotationOffset;
1815 } 1824 }
@@ -2466,17 +2475,18 @@ namespace OpenSim.Region.Framework.Scenes
2466 //Trys to fetch sound id from prim's inventory. 2475 //Trys to fetch sound id from prim's inventory.
2467 //Prim's inventory doesn't support non script items yet 2476 //Prim's inventory doesn't support non script items yet
2468 2477
2469 lock (TaskInventory) 2478 TaskInventory.LockItemsForRead(true);
2479
2480 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2470 { 2481 {
2471 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2482 if (item.Value.Name == sound)
2472 { 2483 {
2473 if (item.Value.Name == sound) 2484 soundID = item.Value.ItemID;
2474 { 2485 break;
2475 soundID = item.Value.ItemID;
2476 break;
2477 }
2478 } 2486 }
2479 } 2487 }
2488
2489 TaskInventory.LockItemsForRead(false);
2480 } 2490 }
2481 2491
2482 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2492 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2753,8 +2763,8 @@ namespace OpenSim.Region.Framework.Scenes
2753 { 2763 {
2754 const float ROTATION_TOLERANCE = 0.01f; 2764 const float ROTATION_TOLERANCE = 0.01f;
2755 const float VELOCITY_TOLERANCE = 0.001f; 2765 const float VELOCITY_TOLERANCE = 0.001f;
2756 const float POSITION_TOLERANCE = 0.05f; 2766 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2757 const int TIME_MS_TOLERANCE = 3000; 2767 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2758 2768
2759 if (m_updateFlag == 1) 2769 if (m_updateFlag == 1)
2760 { 2770 {
@@ -2768,7 +2778,7 @@ namespace OpenSim.Region.Framework.Scenes
2768 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2778 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2769 { 2779 {
2770 AddTerseUpdateToAllAvatars(); 2780 AddTerseUpdateToAllAvatars();
2771 ClearUpdateSchedule(); 2781
2772 2782
2773 // This causes the Scene to 'poll' physical objects every couple of frames 2783 // This causes the Scene to 'poll' physical objects every couple of frames
2774 // bad, so it's been replaced by an event driven method. 2784 // bad, so it's been replaced by an event driven method.
@@ -2786,16 +2796,18 @@ namespace OpenSim.Region.Framework.Scenes
2786 m_lastAngularVelocity = AngularVelocity; 2796 m_lastAngularVelocity = AngularVelocity;
2787 m_lastTerseSent = Environment.TickCount; 2797 m_lastTerseSent = Environment.TickCount;
2788 } 2798 }
2799 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2800 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2789 } 2801 }
2790 else 2802 else
2791 { 2803 {
2792 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2804 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2793 { 2805 {
2794 AddFullUpdateToAllAvatars(); 2806 AddFullUpdateToAllAvatars();
2795 ClearUpdateSchedule(); 2807 m_updateFlag = 0; //Same here
2796 } 2808 }
2797 } 2809 }
2798 ClearUpdateSchedule(); 2810 m_updateFlag = 0;
2799 } 2811 }
2800 2812
2801 /// <summary> 2813 /// <summary>
@@ -2822,17 +2834,16 @@ namespace OpenSim.Region.Framework.Scenes
2822 if (!UUID.TryParse(sound, out soundID)) 2834 if (!UUID.TryParse(sound, out soundID))
2823 { 2835 {
2824 // search sound file from inventory 2836 // search sound file from inventory
2825 lock (TaskInventory) 2837 TaskInventory.LockItemsForRead(true);
2838 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2826 { 2839 {
2827 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2840 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2828 { 2841 {
2829 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2842 soundID = item.Value.ItemID;
2830 { 2843 break;
2831 soundID = item.Value.ItemID;
2832 break;
2833 }
2834 } 2844 }
2835 } 2845 }
2846 TaskInventory.LockItemsForRead(false);
2836 } 2847 }
2837 2848
2838 if (soundID == UUID.Zero) 2849 if (soundID == UUID.Zero)
@@ -2974,6 +2985,22 @@ namespace OpenSim.Region.Framework.Scenes
2974 PhysActor.VehicleRotationParam(param, rotation); 2985 PhysActor.VehicleRotationParam(param, rotation);
2975 } 2986 }
2976 } 2987 }
2988
2989 public void SetVehicleFlags(int flags)
2990 {
2991 if (PhysActor != null)
2992 {
2993 PhysActor.VehicleFlagsSet(flags);
2994 }
2995 }
2996
2997 public void RemoveVehicleFlags(int flags)
2998 {
2999 if (PhysActor != null)
3000 {
3001 PhysActor.VehicleFlagsRemove(flags);
3002 }
3003 }
2977 3004
2978 /// <summary> 3005 /// <summary>
2979 /// Set the color of prim faces 3006 /// Set the color of prim faces
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 87c1a95..3317dd3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -44,8 +44,6 @@ namespace OpenSim.Region.Framework.Scenes
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
48
49 private string m_inventoryFileName = String.Empty; 47 private string m_inventoryFileName = String.Empty;
50 private int m_inventoryFileNameSerial = 0; 48 private int m_inventoryFileNameSerial = 0;
51 49
@@ -84,7 +82,9 @@ namespace OpenSim.Region.Framework.Scenes
84 /// </value> 82 /// </value>
85 protected internal TaskInventoryDictionary Items 83 protected internal TaskInventoryDictionary Items
86 { 84 {
87 get { return m_items; } 85 get {
86 return m_items;
87 }
88 set 88 set
89 { 89 {
90 m_items = value; 90 m_items = value;
@@ -120,22 +120,25 @@ namespace OpenSim.Region.Framework.Scenes
120 /// <param name="linkNum">Link number for the part</param> 120 /// <param name="linkNum">Link number for the part</param>
121 public void ResetInventoryIDs() 121 public void ResetInventoryIDs()
122 { 122 {
123 lock (Items) 123 m_items.LockItemsForWrite(true);
124
125 if (0 == Items.Count)
124 { 126 {
125 if (0 == Items.Count) 127 m_items.LockItemsForWrite(false);
126 return; 128 return;
129 }
127 130
128 HasInventoryChanged = true; 131 HasInventoryChanged = true;
129 m_part.ParentGroup.HasGroupChanged = true; 132 m_part.ParentGroup.HasGroupChanged = true;
130 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 133 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
131 Items.Clear(); 134 Items.Clear();
132 135
133 foreach (TaskInventoryItem item in items) 136 foreach (TaskInventoryItem item in items)
134 { 137 {
135 item.ResetIDs(m_part.UUID); 138 item.ResetIDs(m_part.UUID);
136 Items.Add(item.ItemID, item); 139 Items.Add(item.ItemID, item);
137 }
138 } 140 }
141 m_items.LockItemsForWrite(false);
139 } 142 }
140 143
141 /// <summary> 144 /// <summary>
@@ -144,25 +147,25 @@ namespace OpenSim.Region.Framework.Scenes
144 /// <param name="ownerId"></param> 147 /// <param name="ownerId"></param>
145 public void ChangeInventoryOwner(UUID ownerId) 148 public void ChangeInventoryOwner(UUID ownerId)
146 { 149 {
147 lock (Items) 150 m_items.LockItemsForWrite(true);
151 if (0 == Items.Count)
148 { 152 {
149 if (0 == Items.Count) 153 m_items.LockItemsForWrite(false);
150 { 154 return;
151 return; 155 }
152 }
153 156
154 HasInventoryChanged = true; 157 HasInventoryChanged = true;
155 m_part.ParentGroup.HasGroupChanged = true; 158 m_part.ParentGroup.HasGroupChanged = true;
156 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 159 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
157 foreach (TaskInventoryItem item in items) 160 foreach (TaskInventoryItem item in items)
161 {
162 if (ownerId != item.OwnerID)
158 { 163 {
159 if (ownerId != item.OwnerID) 164 item.LastOwnerID = item.OwnerID;
160 { 165 item.OwnerID = ownerId;
161 item.LastOwnerID = item.OwnerID;
162 item.OwnerID = ownerId;
163 }
164 } 166 }
165 } 167 }
168 m_items.LockItemsForWrite(false);
166 } 169 }
167 170
168 /// <summary> 171 /// <summary>
@@ -171,24 +174,24 @@ namespace OpenSim.Region.Framework.Scenes
171 /// <param name="groupID"></param> 174 /// <param name="groupID"></param>
172 public void ChangeInventoryGroup(UUID groupID) 175 public void ChangeInventoryGroup(UUID groupID)
173 { 176 {
174 lock (Items) 177 m_items.LockItemsForWrite(true);
178 if (0 == Items.Count)
175 { 179 {
176 if (0 == Items.Count) 180 m_items.LockItemsForWrite(false);
177 { 181 return;
178 return; 182 }
179 }
180 183
181 HasInventoryChanged = true; 184 HasInventoryChanged = true;
182 m_part.ParentGroup.HasGroupChanged = true; 185 m_part.ParentGroup.HasGroupChanged = true;
183 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 186 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
184 foreach (TaskInventoryItem item in items) 187 foreach (TaskInventoryItem item in items)
188 {
189 if (groupID != item.GroupID)
185 { 190 {
186 if (groupID != item.GroupID) 191 item.GroupID = groupID;
187 {
188 item.GroupID = groupID;
189 }
190 } 192 }
191 } 193 }
194 m_items.LockItemsForWrite(false);
192 } 195 }
193 196
194 /// <summary> 197 /// <summary>
@@ -196,14 +199,14 @@ namespace OpenSim.Region.Framework.Scenes
196 /// </summary> 199 /// </summary>
197 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 200 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
198 { 201 {
199 lock (m_items) 202 Items.LockItemsForRead(true);
203 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
204 Items.LockItemsForRead(false);
205 foreach (TaskInventoryItem item in items)
200 { 206 {
201 foreach (TaskInventoryItem item in Items.Values) 207 if ((int)InventoryType.LSL == item.InvType)
202 { 208 {
203 if ((int)InventoryType.LSL == item.InvType) 209 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
204 {
205 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
206 }
207 } 210 }
208 } 211 }
209 } 212 }
@@ -238,16 +241,20 @@ namespace OpenSim.Region.Framework.Scenes
238 /// </param> 241 /// </param>
239 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 242 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
240 { 243 {
241 lock (Items) 244 Items.LockItemsForRead(true);
245 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
246 Items.LockItemsForRead(false);
247
248 foreach (TaskInventoryItem item in items)
242 { 249 {
243 foreach (TaskInventoryItem item in Items.Values) 250 if ((int)InventoryType.LSL == item.InvType)
244 { 251 {
245 if ((int)InventoryType.LSL == item.InvType) 252 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
246 { 253 m_part.RemoveScriptEvents(item.ItemID);
247 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
248 }
249 } 254 }
250 } 255 }
256
257
251 } 258 }
252 259
253 /// <summary> 260 /// <summary>
@@ -272,12 +279,10 @@ namespace OpenSim.Region.Framework.Scenes
272 if (stateSource == 1 && // Prim crossing 279 if (stateSource == 1 && // Prim crossing
273 m_part.ParentGroup.Scene.m_trustBinaries) 280 m_part.ParentGroup.Scene.m_trustBinaries)
274 { 281 {
275 lock (m_items) 282 m_items.LockItemsForWrite(true);
276 { 283 m_items[item.ItemID].PermsMask = 0;
277 m_items[item.ItemID].PermsMask = 0; 284 m_items[item.ItemID].PermsGranter = UUID.Zero;
278 m_items[item.ItemID].PermsGranter = UUID.Zero; 285 m_items.LockItemsForWrite(false);
279 }
280
281 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 286 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
282 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 287 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
283 m_part.ParentGroup.AddActiveScriptCount(1); 288 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -285,38 +290,35 @@ namespace OpenSim.Region.Framework.Scenes
285 return; 290 return;
286 } 291 }
287 292
288 m_part.ParentGroup.Scene.AssetService.Get( 293 m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset)
289 item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset) 294 {
290 { 295 if (null == asset)
291 if (null == asset) 296 {
292 { 297 m_log.ErrorFormat(
293 m_log.ErrorFormat( 298 "[PRIM INVENTORY]: " +
294 "[PRIM INVENTORY]: " + 299 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
295 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 300 item.Name, item.ItemID, m_part.AbsolutePosition,
296 item.Name, item.ItemID, m_part.AbsolutePosition, 301 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
297 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); 302 }
298 } 303 else
299 else 304 {
300 { 305 if (m_part.ParentGroup.m_savedScriptState != null)
301 if (m_part.ParentGroup.m_savedScriptState != null) 306 RestoreSavedScriptState(item.OldItemID, item.ItemID);
302 RestoreSavedScriptState(item.OldItemID, item.ItemID); 307 m_items.LockItemsForWrite(true);
303 308 m_items[item.ItemID].PermsMask = 0;
304 lock (m_items) 309 m_items[item.ItemID].PermsGranter = UUID.Zero;
305 { 310 m_items.LockItemsForWrite(false);
306 m_items[item.ItemID].PermsMask = 0; 311 string script = Utils.BytesToString(asset.Data);
307 m_items[item.ItemID].PermsGranter = UUID.Zero; 312 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
308 } 313 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
309 314 m_part.ParentGroup.AddActiveScriptCount(1);
310 string script = Utils.BytesToString(asset.Data); 315 m_part.ScheduleFullUpdate();
311 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 316 }
312 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 317 });
313 m_part.ParentGroup.AddActiveScriptCount(1);
314 m_part.ScheduleFullUpdate();
315 }
316 }
317 );
318 } 318 }
319 } 319 }
320
321 static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
320 322
321 private void RestoreSavedScriptState(UUID oldID, UUID newID) 323 private void RestoreSavedScriptState(UUID oldID, UUID newID)
322 { 324 {
@@ -381,14 +383,17 @@ namespace OpenSim.Region.Framework.Scenes
381 /// </param> 383 /// </param>
382 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 384 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
383 { 385 {
384 lock (m_items) 386 m_items.LockItemsForRead(true);
387 if (m_items.ContainsKey(itemId))
385 { 388 {
386 if (m_items.ContainsKey(itemId)) 389 if (m_items.ContainsKey(itemId))
387 { 390 {
391 m_items.LockItemsForRead(false);
388 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 392 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
389 } 393 }
390 else 394 else
391 { 395 {
396 m_items.LockItemsForRead(false);
392 m_log.ErrorFormat( 397 m_log.ErrorFormat(
393 "[PRIM INVENTORY]: " + 398 "[PRIM INVENTORY]: " +
394 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 399 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
@@ -396,6 +401,15 @@ namespace OpenSim.Region.Framework.Scenes
396 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 401 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
397 } 402 }
398 } 403 }
404 else
405 {
406 m_items.LockItemsForRead(false);
407 m_log.ErrorFormat(
408 "[PRIM INVENTORY]: " +
409 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
410 itemId, m_part.Name, m_part.UUID);
411 }
412
399 } 413 }
400 414
401 /// <summary> 415 /// <summary>
@@ -408,15 +422,7 @@ namespace OpenSim.Region.Framework.Scenes
408 /// </param> 422 /// </param>
409 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 423 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
410 { 424 {
411 bool scriptPresent = false; 425 if (m_items.ContainsKey(itemId))
412
413 lock (m_items)
414 {
415 if (m_items.ContainsKey(itemId))
416 scriptPresent = true;
417 }
418
419 if (scriptPresent)
420 { 426 {
421 if (!sceneObjectBeingDeleted) 427 if (!sceneObjectBeingDeleted)
422 m_part.RemoveScriptEvents(itemId); 428 m_part.RemoveScriptEvents(itemId);
@@ -442,11 +448,16 @@ namespace OpenSim.Region.Framework.Scenes
442 /// <returns></returns> 448 /// <returns></returns>
443 private bool InventoryContainsName(string name) 449 private bool InventoryContainsName(string name)
444 { 450 {
445 foreach (TaskInventoryItem item in Items.Values) 451 m_items.LockItemsForRead(true);
452 foreach (TaskInventoryItem item in m_items.Values)
446 { 453 {
447 if (item.Name == name) 454 if (item.Name == name)
455 {
456 m_items.LockItemsForRead(false);
448 return true; 457 return true;
458 }
449 } 459 }
460 m_items.LockItemsForRead(false);
450 return false; 461 return false;
451 } 462 }
452 463
@@ -488,13 +499,9 @@ namespace OpenSim.Region.Framework.Scenes
488 /// <param name="item"></param> 499 /// <param name="item"></param>
489 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 500 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
490 { 501 {
491 List<TaskInventoryItem> il; 502 m_items.LockItemsForRead(true);
492 503 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
493 lock (m_items) 504 m_items.LockItemsForRead(false);
494 {
495 il = new List<TaskInventoryItem>(m_items.Values);
496 }
497
498 foreach (TaskInventoryItem i in il) 505 foreach (TaskInventoryItem i in il)
499 { 506 {
500 if (i.Name == item.Name) 507 if (i.Name == item.Name)
@@ -531,15 +538,14 @@ namespace OpenSim.Region.Framework.Scenes
531 item.ParentPartID = m_part.UUID; 538 item.ParentPartID = m_part.UUID;
532 item.Name = name; 539 item.Name = name;
533 540
534 lock (m_items) 541 m_items.LockItemsForWrite(true);
535 { 542 m_items.Add(item.ItemID, item);
536 m_items.Add(item.ItemID, item); 543 m_items.LockItemsForWrite(false);
537
538 if (allowedDrop) 544 if (allowedDrop)
539 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 545 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
540 else 546 else
541 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 547 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
542 } 548
543 549
544 m_inventorySerial++; 550 m_inventorySerial++;
545 //m_inventorySerial += 2; 551 //m_inventorySerial += 2;
@@ -556,14 +562,13 @@ namespace OpenSim.Region.Framework.Scenes
556 /// <param name="items"></param> 562 /// <param name="items"></param>
557 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 563 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
558 { 564 {
559 lock (m_items) 565 m_items.LockItemsForWrite(true);
566 foreach (TaskInventoryItem item in items)
560 { 567 {
561 foreach (TaskInventoryItem item in items) 568 m_items.Add(item.ItemID, item);
562 { 569 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
563 m_items.Add(item.ItemID, item);
564 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
565 }
566 } 570 }
571 m_items.LockItemsForWrite(false);
567 572
568 m_inventorySerial++; 573 m_inventorySerial++;
569 } 574 }
@@ -576,10 +581,9 @@ namespace OpenSim.Region.Framework.Scenes
576 public TaskInventoryItem GetInventoryItem(UUID itemId) 581 public TaskInventoryItem GetInventoryItem(UUID itemId)
577 { 582 {
578 TaskInventoryItem item; 583 TaskInventoryItem item;
579 584 m_items.LockItemsForRead(true);
580 lock (m_items) 585 m_items.TryGetValue(itemId, out item);
581 m_items.TryGetValue(itemId, out item); 586 m_items.LockItemsForRead(false);
582
583 return item; 587 return item;
584 } 588 }
585 589
@@ -615,46 +619,46 @@ namespace OpenSim.Region.Framework.Scenes
615 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 619 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
616 public bool UpdateInventoryItem(TaskInventoryItem item) 620 public bool UpdateInventoryItem(TaskInventoryItem item)
617 { 621 {
618 lock (m_items) 622 m_items.LockItemsForWrite(true);
623
624 if (m_items.ContainsKey(item.ItemID))
619 { 625 {
620 if (m_items.ContainsKey(item.ItemID)) 626 item.ParentID = m_part.UUID;
627 item.ParentPartID = m_part.UUID;
628 item.Flags = m_items[item.ItemID].Flags;
629 if (item.AssetID == UUID.Zero)
621 { 630 {
622 item.ParentID = m_part.UUID; 631 item.AssetID = m_items[item.ItemID].AssetID;
623 item.ParentPartID = m_part.UUID; 632 }
624 item.Flags = m_items[item.ItemID].Flags; 633 else if ((InventoryType)item.Type == InventoryType.Notecard)
625 if (item.AssetID == UUID.Zero) 634 {
626 { 635 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
627 item.AssetID = m_items[item.ItemID].AssetID;
628 }
629 else if ((InventoryType)item.Type == InventoryType.Notecard)
630 {
631 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
632 636
633 if (presence != null) 637 if (presence != null)
634 { 638 {
635 presence.ControllingClient.SendAgentAlertMessage( 639 presence.ControllingClient.SendAgentAlertMessage(
636 "Notecard saved", false); 640 "Notecard saved", false);
637 }
638 } 641 }
642 }
639 643
640 m_items[item.ItemID] = item; 644 m_items[item.ItemID] = item;
641 m_inventorySerial++; 645 m_inventorySerial++;
642 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 646 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
643
644 HasInventoryChanged = true;
645 m_part.ParentGroup.HasGroupChanged = true;
646 647
647 return true; 648 HasInventoryChanged = true;
648 } 649 m_part.ParentGroup.HasGroupChanged = true;
649 else 650 m_items.LockItemsForWrite(false);
650 { 651 return true;
651 m_log.ErrorFormat( 652 }
652 "[PRIM INVENTORY]: " + 653 else
653 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 654 {
654 item.ItemID, m_part.Name, m_part.UUID, 655 m_log.ErrorFormat(
655 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 656 "[PRIM INVENTORY]: " +
656 } 657 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
658 item.ItemID, m_part.Name, m_part.UUID,
659 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
657 } 660 }
661 m_items.LockItemsForWrite(false);
658 662
659 return false; 663 return false;
660 } 664 }
@@ -667,53 +671,54 @@ namespace OpenSim.Region.Framework.Scenes
667 /// in this prim's inventory.</returns> 671 /// in this prim's inventory.</returns>
668 public int RemoveInventoryItem(UUID itemID) 672 public int RemoveInventoryItem(UUID itemID)
669 { 673 {
670 lock (m_items) 674 m_items.LockItemsForRead(true);
675
676 if (m_items.ContainsKey(itemID))
671 { 677 {
672 if (m_items.ContainsKey(itemID)) 678 int type = m_items[itemID].InvType;
679 m_items.LockItemsForRead(false);
680 if (type == 10) // Script
673 { 681 {
674 int type = m_items[itemID].InvType; 682 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
675 if (type == 10) // Script 683 }
676 { 684 m_items.LockItemsForWrite(true);
677 m_part.RemoveScriptEvents(itemID); 685 m_items.Remove(itemID);
678 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 686 m_items.LockItemsForWrite(false);
679 } 687 m_inventorySerial++;
680 m_items.Remove(itemID); 688 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
681 m_inventorySerial++;
682 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
683
684 HasInventoryChanged = true;
685 m_part.ParentGroup.HasGroupChanged = true;
686 689
687 int scriptcount = 0; 690 HasInventoryChanged = true;
688 lock (m_items) 691 m_part.ParentGroup.HasGroupChanged = true;
689 {
690 foreach (TaskInventoryItem item in m_items.Values)
691 {
692 if (item.Type == 10)
693 {
694 scriptcount++;
695 }
696 }
697 }
698 692
699 if (scriptcount <= 0) 693 int scriptcount = 0;
694 m_items.LockItemsForRead(true);
695 foreach (TaskInventoryItem item in m_items.Values)
696 {
697 if (item.Type == 10)
700 { 698 {
701 m_part.RemFlag(PrimFlags.Scripted); 699 scriptcount++;
702 } 700 }
703
704 m_part.ScheduleFullUpdate();
705
706 return type;
707 } 701 }
708 else 702 m_items.LockItemsForRead(false);
703
704
705 if (scriptcount <= 0)
709 { 706 {
710 m_log.ErrorFormat( 707 m_part.RemFlag(PrimFlags.Scripted);
711 "[PRIM INVENTORY]: " +
712 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
713 itemID, m_part.Name, m_part.UUID,
714 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
715 } 708 }
709
710 m_part.ScheduleFullUpdate();
711
712 return type;
716 } 713 }
714 else
715 {
716 m_log.ErrorFormat(
717 "[PRIM INVENTORY]: " +
718 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
719 itemID, m_part.Name, m_part.UUID);
720 }
721 m_items.LockItemsForWrite(false);
717 722
718 return -1; 723 return -1;
719 } 724 }
@@ -766,52 +771,53 @@ namespace OpenSim.Region.Framework.Scenes
766 // isn't available (such as drag from prim inventory to agent inventory) 771 // isn't available (such as drag from prim inventory to agent inventory)
767 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 772 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
768 773
769 lock (m_items) 774 m_items.LockItemsForRead(true);
775
776 foreach (TaskInventoryItem item in m_items.Values)
770 { 777 {
771 foreach (TaskInventoryItem item in m_items.Values) 778 UUID ownerID = item.OwnerID;
772 { 779 uint everyoneMask = 0;
773 UUID ownerID = item.OwnerID; 780 uint baseMask = item.BasePermissions;
774 uint everyoneMask = 0; 781 uint ownerMask = item.CurrentPermissions;
775 uint baseMask = item.BasePermissions;
776 uint ownerMask = item.CurrentPermissions;
777 782
778 invString.AddItemStart(); 783 invString.AddItemStart();
779 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 784 invString.AddNameValueLine("item_id", item.ItemID.ToString());
780 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 785 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
781 786
782 invString.AddPermissionsStart(); 787 invString.AddPermissionsStart();
783 788
784 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 789 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
785 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 790 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
786 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 791 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
787 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 792 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
788 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 793 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
789 794
790 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 795 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
791 invString.AddNameValueLine("owner_id", ownerID.ToString()); 796 invString.AddNameValueLine("owner_id", ownerID.ToString());
792 797
793 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 798 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
794 799
795 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 800 invString.AddNameValueLine("group_id", item.GroupID.ToString());
796 invString.AddSectionEnd(); 801 invString.AddSectionEnd();
797 802
798 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 803 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
799 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 804 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
800 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 805 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
801 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 806 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
802 807
803 invString.AddSaleStart(); 808 invString.AddSaleStart();
804 invString.AddNameValueLine("sale_type", "not"); 809 invString.AddNameValueLine("sale_type", "not");
805 invString.AddNameValueLine("sale_price", "0"); 810 invString.AddNameValueLine("sale_price", "0");
806 invString.AddSectionEnd(); 811 invString.AddSectionEnd();
807 812
808 invString.AddNameValueLine("name", item.Name + "|"); 813 invString.AddNameValueLine("name", item.Name + "|");
809 invString.AddNameValueLine("desc", item.Description + "|"); 814 invString.AddNameValueLine("desc", item.Description + "|");
810 815
811 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 816 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
812 invString.AddSectionEnd(); 817 invString.AddSectionEnd();
813 }
814 } 818 }
819 int count = m_items.Count;
820 m_items.LockItemsForRead(false);
815 821
816 fileData = Utils.StringToBytes(invString.BuildString); 822 fileData = Utils.StringToBytes(invString.BuildString);
817 823
@@ -832,10 +838,9 @@ namespace OpenSim.Region.Framework.Scenes
832 { 838 {
833 if (HasInventoryChanged) 839 if (HasInventoryChanged)
834 { 840 {
835 lock (Items) 841 Items.LockItemsForRead(true);
836 { 842 datastore.StorePrimInventory(m_part.UUID, Items.Values);
837 datastore.StorePrimInventory(m_part.UUID, Items.Values); 843 Items.LockItemsForRead(false);
838 }
839 844
840 HasInventoryChanged = false; 845 HasInventoryChanged = false;
841 } 846 }
@@ -904,61 +909,54 @@ namespace OpenSim.Region.Framework.Scenes
904 { 909 {
905 uint mask=0x7fffffff; 910 uint mask=0x7fffffff;
906 911
907 lock (m_items) 912 foreach (TaskInventoryItem item in m_items.Values)
908 { 913 {
909 foreach (TaskInventoryItem item in m_items.Values) 914 if (item.InvType != (int)InventoryType.Object)
910 { 915 {
911 if (item.InvType != (int)InventoryType.Object) 916 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
912 { 917 mask &= ~((uint)PermissionMask.Copy >> 13);
913 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 918 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
914 mask &= ~((uint)PermissionMask.Copy >> 13); 919 mask &= ~((uint)PermissionMask.Transfer >> 13);
915 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 920 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
916 mask &= ~((uint)PermissionMask.Transfer >> 13); 921 mask &= ~((uint)PermissionMask.Modify >> 13);
917 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
918 mask &= ~((uint)PermissionMask.Modify >> 13);
919 }
920 else
921 {
922 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
923 mask &= ~((uint)PermissionMask.Copy >> 13);
924 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
925 mask &= ~((uint)PermissionMask.Transfer >> 13);
926 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
927 mask &= ~((uint)PermissionMask.Modify >> 13);
928 }
929
930 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
931 mask &= ~(uint)PermissionMask.Copy;
932 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
933 mask &= ~(uint)PermissionMask.Transfer;
934 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
935 mask &= ~(uint)PermissionMask.Modify;
936 } 922 }
923 else
924 {
925 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
926 mask &= ~((uint)PermissionMask.Copy >> 13);
927 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
928 mask &= ~((uint)PermissionMask.Transfer >> 13);
929 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
930 mask &= ~((uint)PermissionMask.Modify >> 13);
931 }
932
933 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
934 mask &= ~(uint)PermissionMask.Copy;
935 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
936 mask &= ~(uint)PermissionMask.Transfer;
937 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
938 mask &= ~(uint)PermissionMask.Modify;
937 } 939 }
938
939 return mask; 940 return mask;
940 } 941 }
941 942
942 public void ApplyNextOwnerPermissions() 943 public void ApplyNextOwnerPermissions()
943 { 944 {
944 lock (m_items) 945 foreach (TaskInventoryItem item in m_items.Values)
945 { 946 {
946 foreach (TaskInventoryItem item in m_items.Values) 947 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
947 { 948 {
948 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 949 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
949 { 950 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
950 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 951 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
951 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 952 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
952 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 953 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
953 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 954 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
954 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 955 item.CurrentPermissions |= 8;
955 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
956 item.CurrentPermissions |= 8;
957 }
958 item.CurrentPermissions &= item.NextPermissions;
959 item.BasePermissions &= item.NextPermissions;
960 item.EveryonePermissions &= item.NextPermissions;
961 } 956 }
957 item.CurrentPermissions &= item.NextPermissions;
958 item.BasePermissions &= item.NextPermissions;
959 item.EveryonePermissions &= item.NextPermissions;
962 } 960 }
963 961
964 m_part.TriggerScriptChangedEvent(Changed.OWNER); 962 m_part.TriggerScriptChangedEvent(Changed.OWNER);
@@ -966,29 +964,22 @@ namespace OpenSim.Region.Framework.Scenes
966 964
967 public void ApplyGodPermissions(uint perms) 965 public void ApplyGodPermissions(uint perms)
968 { 966 {
969 lock (m_items) 967 foreach (TaskInventoryItem item in m_items.Values)
970 { 968 {
971 foreach (TaskInventoryItem item in m_items.Values) 969 item.CurrentPermissions = perms;
972 { 970 item.BasePermissions = perms;
973 item.CurrentPermissions = perms;
974 item.BasePermissions = perms;
975 }
976 } 971 }
977 } 972 }
978 973
979 public bool ContainsScripts() 974 public bool ContainsScripts()
980 { 975 {
981 lock (m_items) 976 foreach (TaskInventoryItem item in m_items.Values)
982 { 977 {
983 foreach (TaskInventoryItem item in m_items.Values) 978 if (item.InvType == (int)InventoryType.LSL)
984 { 979 {
985 if (item.InvType == (int)InventoryType.LSL) 980 return true;
986 {
987 return true;
988 }
989 } 981 }
990 } 982 }
991
992 return false; 983 return false;
993 } 984 }
994 985
@@ -996,11 +987,8 @@ namespace OpenSim.Region.Framework.Scenes
996 { 987 {
997 List<UUID> ret = new List<UUID>(); 988 List<UUID> ret = new List<UUID>();
998 989
999 lock (m_items) 990 foreach (TaskInventoryItem item in m_items.Values)
1000 { 991 ret.Add(item.ItemID);
1001 foreach (TaskInventoryItem item in m_items.Values)
1002 ret.Add(item.ItemID);
1003 }
1004 992
1005 return ret; 993 return ret;
1006 } 994 }
@@ -1013,30 +1001,26 @@ namespace OpenSim.Region.Framework.Scenes
1013 if (engines == null) // No engine at all 1001 if (engines == null) // No engine at all
1014 return ret; 1002 return ret;
1015 1003
1016 lock (m_items) 1004 foreach (TaskInventoryItem item in m_items.Values)
1017 { 1005 {
1018 foreach (TaskInventoryItem item in m_items.Values) 1006 if (item.InvType == (int)InventoryType.LSL)
1019 { 1007 {
1020 if (item.InvType == (int)InventoryType.LSL) 1008 foreach (IScriptModule e in engines)
1021 { 1009 {
1022 foreach (IScriptModule e in engines) 1010 if (e != null)
1023 { 1011 {
1024 if (e != null) 1012 string n = e.GetXMLState(item.ItemID);
1013 if (n != String.Empty)
1025 { 1014 {
1026 string n = e.GetXMLState(item.ItemID); 1015 if (!ret.ContainsKey(item.ItemID))
1027 if (n != String.Empty) 1016 ret[item.ItemID] = n;
1028 { 1017 break;
1029 if (!ret.ContainsKey(item.ItemID))
1030 ret[item.ItemID] = n;
1031 break;
1032 }
1033 } 1018 }
1034 } 1019 }
1035 } 1020 }
1036 } 1021 }
1037 } 1022 }
1038
1039 return ret; 1023 return ret;
1040 } 1024 }
1041 } 1025 }
1042} \ No newline at end of file 1026}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e26283d..27df3b2 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,8 +115,11 @@ 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
117 private Vector3 m_lastPosition; 119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
121 private Vector3 m_lastPosition;
122 private Vector3 m_lastWorldPosition;
118 private Quaternion m_lastRotation; 123 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 124 private Vector3 m_lastVelocity;
120 //private int m_lastTerseSent; 125 //private int m_lastTerseSent;
@@ -124,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes
124 private Vector3? m_forceToApply; 129 private Vector3? m_forceToApply;
125 private uint m_requestedSitTargetID; 130 private uint m_requestedSitTargetID;
126 private UUID m_requestedSitTargetUUID; 131 private UUID m_requestedSitTargetUUID;
127 public bool SitGround = false;
128 132
129 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 133 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
130 134
@@ -146,7 +150,6 @@ namespace OpenSim.Region.Framework.Scenes
146 private int m_perfMonMS; 150 private int m_perfMonMS;
147 151
148 private bool m_setAlwaysRun; 152 private bool m_setAlwaysRun;
149
150 private bool m_forceFly; 153 private bool m_forceFly;
151 private bool m_flyDisabled; 154 private bool m_flyDisabled;
152 155
@@ -170,7 +173,8 @@ namespace OpenSim.Region.Framework.Scenes
170 protected RegionInfo m_regionInfo; 173 protected RegionInfo m_regionInfo;
171 protected ulong crossingFromRegion; 174 protected ulong crossingFromRegion;
172 175
173 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 176 private readonly Vector3[] Dir_Vectors = new Vector3[11];
177 private bool m_isNudging = false;
174 178
175 // Position of agent's camera in world (region cordinates) 179 // Position of agent's camera in world (region cordinates)
176 protected Vector3 m_CameraCenter; 180 protected Vector3 m_CameraCenter;
@@ -195,6 +199,7 @@ namespace OpenSim.Region.Framework.Scenes
195 private bool m_autopilotMoving; 199 private bool m_autopilotMoving;
196 private Vector3 m_autoPilotTarget; 200 private Vector3 m_autoPilotTarget;
197 private bool m_sitAtAutoTarget; 201 private bool m_sitAtAutoTarget;
202 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
198 203
199 private string m_nextSitAnimation = String.Empty; 204 private string m_nextSitAnimation = String.Empty;
200 205
@@ -205,6 +210,9 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_followCamAuto; 210 private bool m_followCamAuto;
206 211
207 private int m_movementUpdateCount; 212 private int m_movementUpdateCount;
213 private int m_lastColCount = -1; //KF: Look for Collision chnages
214 private int m_updateCount = 0; //KF: Update Anims for a while
215 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
208 216
209 private const int NumMovementsBetweenRayCast = 5; 217 private const int NumMovementsBetweenRayCast = 5;
210 218
@@ -235,7 +243,9 @@ namespace OpenSim.Region.Framework.Scenes
235 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
236 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
237 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
238 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 246 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
247 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
248 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
239 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
240 } 250 }
241 251
@@ -661,10 +671,7 @@ namespace OpenSim.Region.Framework.Scenes
661 671
662 672
663 AdjustKnownSeeds(); 673 AdjustKnownSeeds();
664
665 // TODO: I think, this won't send anything, as we are still a child here...
666 Animator.TrySetMovementAnimation("STAND"); 674 Animator.TrySetMovementAnimation("STAND");
667
668 // we created a new ScenePresence (a new child agent) in a fresh region. 675 // we created a new ScenePresence (a new child agent) in a fresh region.
669 // Request info about all the (root) agents in this region 676 // Request info about all the (root) agents in this region
670 // Note: This won't send data *to* other clients in that region (children don't send) 677 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -720,25 +727,47 @@ namespace OpenSim.Region.Framework.Scenes
720 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 727 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
721 Dir_Vectors[4] = Vector3.UnitZ; //UP 728 Dir_Vectors[4] = Vector3.UnitZ; //UP
722 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 729 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
723 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 730 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
724 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 731 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
725 Dir_Vectors[7] = -Vector3.UnitX; //BACK 732 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
733 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
734 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
726 } 735 }
727 736
728 private Vector3[] GetWalkDirectionVectors() 737 private Vector3[] GetWalkDirectionVectors()
729 { 738 {
730 Vector3[] vector = new Vector3[9]; 739 Vector3[] vector = new Vector3[11];
731 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 740 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
732 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 741 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
733 vector[2] = Vector3.UnitY; //LEFT 742 vector[2] = Vector3.UnitY; //LEFT
734 vector[3] = -Vector3.UnitY; //RIGHT 743 vector[3] = -Vector3.UnitY; //RIGHT
735 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 744 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
736 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 745 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
737 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 746 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
738 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 747 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
739 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 748 vector[8] = Vector3.UnitY; //LEFT_NUDGE
749 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
750 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
740 return vector; 751 return vector;
741 } 752 }
753
754 private bool[] GetDirectionIsNudge()
755 {
756 bool[] isNudge = new bool[11];
757 isNudge[0] = false; //FORWARD
758 isNudge[1] = false; //BACK
759 isNudge[2] = false; //LEFT
760 isNudge[3] = false; //RIGHT
761 isNudge[4] = false; //UP
762 isNudge[5] = false; //DOWN
763 isNudge[6] = true; //FORWARD_NUDGE
764 isNudge[7] = true; //BACK_NUDGE
765 isNudge[8] = true; //LEFT_NUDGE
766 isNudge[9] = true; //RIGHT_NUDGE
767 isNudge[10] = true; //DOWN_Nudge
768 return isNudge;
769 }
770
742 771
743 #endregion 772 #endregion
744 773
@@ -807,9 +836,24 @@ namespace OpenSim.Region.Framework.Scenes
807 { 836 {
808 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 837 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
809 pos.Y = crossedBorder.BorderLine.Z - 1; 838 pos.Y = crossedBorder.BorderLine.Z - 1;
839 }
840
841 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
842 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
843 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
844 if (KnownChildRegionHandles.Count == 0)
845 {
846 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
847 if (land != null)
848 {
849 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
850 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
851 {
852 pos = land.LandData.UserLocation;
853 }
854 }
810 } 855 }
811 856
812
813 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 857 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
814 { 858 {
815 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 859 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -944,9 +988,10 @@ namespace OpenSim.Region.Framework.Scenes
944 public void Teleport(Vector3 pos) 988 public void Teleport(Vector3 pos)
945 { 989 {
946 bool isFlying = false; 990 bool isFlying = false;
947 if (m_physicsActor != null)
948 isFlying = m_physicsActor.Flying;
949 991
992 if (m_physicsActor != null)
993 isFlying = m_physicsActor.Flying;
994
950 RemoveFromPhysicalScene(); 995 RemoveFromPhysicalScene();
951 Velocity = Vector3.Zero; 996 Velocity = Vector3.Zero;
952 AbsolutePosition = pos; 997 AbsolutePosition = pos;
@@ -957,7 +1002,8 @@ namespace OpenSim.Region.Framework.Scenes
957 SetHeight(m_appearance.AvatarHeight); 1002 SetHeight(m_appearance.AvatarHeight);
958 } 1003 }
959 1004
960 SendTerseUpdateToAllClients(); 1005 SendTerseUpdateToAllClients();
1006
961 } 1007 }
962 1008
963 public void TeleportWithMomentum(Vector3 pos) 1009 public void TeleportWithMomentum(Vector3 pos)
@@ -1002,7 +1048,9 @@ namespace OpenSim.Region.Framework.Scenes
1002 { 1048 {
1003 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1049 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1004 } 1050 }
1005 1051
1052 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1053
1006 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1054 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1007 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1055 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1008 } 1056 }
@@ -1237,7 +1285,6 @@ namespace OpenSim.Region.Framework.Scenes
1237 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1285 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1238 } 1286 }
1239 } 1287 }
1240
1241 lock (scriptedcontrols) 1288 lock (scriptedcontrols)
1242 { 1289 {
1243 if (scriptedcontrols.Count > 0) 1290 if (scriptedcontrols.Count > 0)
@@ -1252,12 +1299,8 @@ namespace OpenSim.Region.Framework.Scenes
1252 1299
1253 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1300 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1254 { 1301 {
1255 // TODO: This doesn't prevent the user from walking yet. 1302 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1256 // Setting parent ID would fix this, if we knew what value 1303 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1257 // to use. Or we could add a m_isSitting variable.
1258 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1259 SitGround = true;
1260
1261 } 1304 }
1262 1305
1263 // In the future, these values might need to go global. 1306 // In the future, these values might need to go global.
@@ -1307,6 +1350,11 @@ namespace OpenSim.Region.Framework.Scenes
1307 update_rotation = true; 1350 update_rotation = true;
1308 } 1351 }
1309 1352
1353 //guilty until proven innocent..
1354 bool Nudging = true;
1355 //Basically, if there is at least one non-nudge control then we don't need
1356 //to worry about stopping the avatar
1357
1310 if (m_parentID == 0) 1358 if (m_parentID == 0)
1311 { 1359 {
1312 bool bAllowUpdateMoveToPosition = false; 1360 bool bAllowUpdateMoveToPosition = false;
@@ -1321,9 +1369,12 @@ namespace OpenSim.Region.Framework.Scenes
1321 else 1369 else
1322 dirVectors = Dir_Vectors; 1370 dirVectors = Dir_Vectors;
1323 1371
1324 // The fact that m_movementflag is a byte needs to be fixed 1372 bool[] isNudge = GetDirectionIsNudge();
1325 // it really should be a uint 1373
1326 uint nudgehack = 250; 1374
1375
1376
1377
1327 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1378 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1328 { 1379 {
1329 if (((uint)flags & (uint)DCF) != 0) 1380 if (((uint)flags & (uint)DCF) != 0)
@@ -1333,40 +1384,28 @@ namespace OpenSim.Region.Framework.Scenes
1333 try 1384 try
1334 { 1385 {
1335 agent_control_v3 += dirVectors[i]; 1386 agent_control_v3 += dirVectors[i];
1336 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1387 if (isNudge[i] == false)
1388 {
1389 Nudging = false;
1390 }
1337 } 1391 }
1338 catch (IndexOutOfRangeException) 1392 catch (IndexOutOfRangeException)
1339 { 1393 {
1340 // Why did I get this? 1394 // Why did I get this?
1341 } 1395 }
1342 1396
1343 if ((m_movementflag & (byte)(uint)DCF) == 0) 1397 if ((m_movementflag & (uint)DCF) == 0)
1344 { 1398 {
1345 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1346 {
1347 m_movementflag |= (byte)nudgehack;
1348 }
1349 m_movementflag += (byte)(uint)DCF; 1399 m_movementflag += (byte)(uint)DCF;
1350 update_movementflag = true; 1400 update_movementflag = true;
1351 } 1401 }
1352 } 1402 }
1353 else 1403 else
1354 { 1404 {
1355 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1405 if ((m_movementflag & (uint)DCF) != 0)
1356 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1357 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1358 ) // This or is for Nudge forward
1359 { 1406 {
1360 m_movementflag -= ((byte)(uint)DCF); 1407 m_movementflag -= (byte)(uint)DCF;
1361
1362 update_movementflag = true; 1408 update_movementflag = true;
1363 /*
1364 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1365 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1366 {
1367 m_log.Debug("Removed Hack flag");
1368 }
1369 */
1370 } 1409 }
1371 else 1410 else
1372 { 1411 {
@@ -1410,6 +1449,9 @@ namespace OpenSim.Region.Framework.Scenes
1410 // Ignore z component of vector 1449 // Ignore z component of vector
1411 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1450 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1412 LocalVectorToTarget2D.Normalize(); 1451 LocalVectorToTarget2D.Normalize();
1452
1453 //We're not nudging
1454 Nudging = false;
1413 agent_control_v3 += LocalVectorToTarget2D; 1455 agent_control_v3 += LocalVectorToTarget2D;
1414 1456
1415 // update avatar movement flags. the avatar coordinate system is as follows: 1457 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1498,13 +1540,13 @@ namespace OpenSim.Region.Framework.Scenes
1498 // m_log.DebugFormat( 1540 // m_log.DebugFormat(
1499 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1541 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1500 1542
1501 AddNewMovement(agent_control_v3, q); 1543 AddNewMovement(agent_control_v3, q, Nudging);
1502 1544
1503 1545
1504 } 1546 }
1505 } 1547 }
1506 1548
1507 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1549 if (update_movementflag)
1508 Animator.UpdateMovementAnimations(); 1550 Animator.UpdateMovementAnimations();
1509 1551
1510 m_scene.EventManager.TriggerOnClientMovement(this); 1552 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1519,7 +1561,6 @@ namespace OpenSim.Region.Framework.Scenes
1519 m_sitAtAutoTarget = false; 1561 m_sitAtAutoTarget = false;
1520 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1562 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1521 //proxy.PCode = (byte)PCode.ParticleSystem; 1563 //proxy.PCode = (byte)PCode.ParticleSystem;
1522
1523 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1564 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1524 proxyObjectGroup.AttachToScene(m_scene); 1565 proxyObjectGroup.AttachToScene(m_scene);
1525 1566
@@ -1561,7 +1602,7 @@ namespace OpenSim.Region.Framework.Scenes
1561 } 1602 }
1562 m_moveToPositionInProgress = true; 1603 m_moveToPositionInProgress = true;
1563 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1604 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1564 } 1605 }
1565 catch (Exception ex) 1606 catch (Exception ex)
1566 { 1607 {
1567 //Why did I get this error? 1608 //Why did I get this error?
@@ -1583,7 +1624,7 @@ namespace OpenSim.Region.Framework.Scenes
1583 Velocity = Vector3.Zero; 1624 Velocity = Vector3.Zero;
1584 SendFullUpdateToAllClients(); 1625 SendFullUpdateToAllClients();
1585 1626
1586 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1627 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1587 } 1628 }
1588 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1629 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1589 m_requestedSitTargetUUID = UUID.Zero; 1630 m_requestedSitTargetUUID = UUID.Zero;
@@ -1616,55 +1657,84 @@ namespace OpenSim.Region.Framework.Scenes
1616 /// </summary> 1657 /// </summary>
1617 public void StandUp() 1658 public void StandUp()
1618 { 1659 {
1619 if (SitGround)
1620 SitGround = false;
1621
1622 if (m_parentID != 0) 1660 if (m_parentID != 0)
1623 { 1661 {
1624 m_log.Debug("StandupCode Executed");
1625 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1662 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1626 if (part != null) 1663 if (part != null)
1627 { 1664 {
1665 part.TaskInventory.LockItemsForRead(true);
1628 TaskInventoryDictionary taskIDict = part.TaskInventory; 1666 TaskInventoryDictionary taskIDict = part.TaskInventory;
1629 if (taskIDict != null) 1667 if (taskIDict != null)
1630 { 1668 {
1631 lock (taskIDict) 1669 foreach (UUID taskID in taskIDict.Keys)
1632 { 1670 {
1633 foreach (UUID taskID in taskIDict.Keys) 1671 UnRegisterControlEventsToScript(LocalId, taskID);
1634 { 1672 taskIDict[taskID].PermsMask &= ~(
1635 UnRegisterControlEventsToScript(LocalId, taskID); 1673 2048 | //PERMISSION_CONTROL_CAMERA
1636 taskIDict[taskID].PermsMask &= ~( 1674 4); // PERMISSION_TAKE_CONTROLS
1637 2048 | //PERMISSION_CONTROL_CAMERA
1638 4); // PERMISSION_TAKE_CONTROLS
1639 }
1640 } 1675 }
1641
1642 } 1676 }
1677 part.TaskInventory.LockItemsForRead(false);
1643 // Reset sit target. 1678 // Reset sit target.
1644 if (part.GetAvatarOnSitTarget() == UUID) 1679 if (part.GetAvatarOnSitTarget() == UUID)
1645 part.SetAvatarOnSitTarget(UUID.Zero); 1680 part.SetAvatarOnSitTarget(UUID.Zero);
1646
1647 m_parentPosition = part.GetWorldPosition(); 1681 m_parentPosition = part.GetWorldPosition();
1648 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1682 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1649 } 1683 }
1650 1684 // part.GetWorldRotation() is the rotation of the object being sat on
1651 if (m_physicsActor == null) 1685 // Rotation is the sittiing Av's rotation
1652 { 1686
1653 AddToPhysicalScene(false); 1687 Quaternion partRot;
1688// if (part.LinkNum == 1)
1689// { // Root prim of linkset
1690// partRot = part.ParentGroup.RootPart.RotationOffset;
1691// }
1692// else
1693// { // single or child prim
1694
1695// }
1696 if (part == null) //CW: Part may be gone. llDie() for example.
1697 {
1698 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1699 }
1700 else
1701 {
1702 partRot = part.GetWorldRotation();
1703 }
1704
1705 Quaternion partIRot = Quaternion.Inverse(partRot);
1706
1707 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1708 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1709
1710
1711 if (m_physicsActor == null)
1712 {
1713 AddToPhysicalScene(false);
1714 }
1715 //CW: If the part isn't null then we can set the current position
1716 if (part != null)
1717 {
1718 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1719 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1720 part.IsOccupied = false;
1721 }
1722 else
1723 {
1724 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1725 AbsolutePosition = m_lastWorldPosition;
1654 } 1726 }
1655 1727
1656 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1728 m_parentPosition = Vector3.Zero;
1657 m_parentPosition = Vector3.Zero; 1729 m_parentID = 0;
1658
1659 m_parentID = 0;
1660 SendFullUpdateToAllClients(); 1730 SendFullUpdateToAllClients();
1661 m_requestedSitTargetID = 0; 1731 m_requestedSitTargetID = 0;
1732
1662 if ((m_physicsActor != null) && (m_avHeight > 0)) 1733 if ((m_physicsActor != null) && (m_avHeight > 0))
1663 { 1734 {
1664 SetHeight(m_avHeight); 1735 SetHeight(m_avHeight);
1665 } 1736 }
1666 } 1737 }
1667
1668 Animator.TrySetMovementAnimation("STAND"); 1738 Animator.TrySetMovementAnimation("STAND");
1669 } 1739 }
1670 1740
@@ -1695,13 +1765,9 @@ namespace OpenSim.Region.Framework.Scenes
1695 Vector3 avSitOffSet = part.SitTargetPosition; 1765 Vector3 avSitOffSet = part.SitTargetPosition;
1696 Quaternion avSitOrientation = part.SitTargetOrientation; 1766 Quaternion avSitOrientation = part.SitTargetOrientation;
1697 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1767 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1698 1768 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1699 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1769 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1700 bool SitTargetisSet = 1770 if (SitTargetisSet && !SitTargetOccupied)
1701 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1703
1704 if (SitTargetisSet && SitTargetUnOccupied)
1705 { 1771 {
1706 //switch the target to this prim 1772 //switch the target to this prim
1707 return part; 1773 return part;
@@ -1715,84 +1781,152 @@ namespace OpenSim.Region.Framework.Scenes
1715 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1781 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1716 { 1782 {
1717 bool autopilot = true; 1783 bool autopilot = true;
1784 Vector3 autopilotTarget = new Vector3();
1785 Quaternion sitOrientation = Quaternion.Identity;
1718 Vector3 pos = new Vector3(); 1786 Vector3 pos = new Vector3();
1719 Quaternion sitOrientation = pSitOrientation;
1720 Vector3 cameraEyeOffset = Vector3.Zero; 1787 Vector3 cameraEyeOffset = Vector3.Zero;
1721 Vector3 cameraAtOffset = Vector3.Zero; 1788 Vector3 cameraAtOffset = Vector3.Zero;
1722 bool forceMouselook = false; 1789 bool forceMouselook = false;
1723 1790
1724 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1791 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1725 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1792 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1726 if (part != null) 1793 if (part == null) return;
1727 { 1794
1728 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1795 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1729 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1796 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1730 1797
1731 // Is a sit target available? 1798 // part is the prim to sit on
1732 Vector3 avSitOffSet = part.SitTargetPosition; 1799 // offset is the world-ref vector distance from that prim center to the click-spot
1733 Quaternion avSitOrientation = part.SitTargetOrientation; 1800 // UUID is the UUID of the Avatar doing the clicking
1734 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1801
1735 1802 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1736 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1803
1737 bool SitTargetisSet = 1804 // Is a sit target available?
1738 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1805 Vector3 avSitOffSet = part.SitTargetPosition;
1739 ( 1806 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1807
1741 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1808 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1742 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1809 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1743 ) 1810 Quaternion partRot;
1744 )); 1811// if (part.LinkNum == 1)
1745 1812// { // Root prim of linkset
1746 if (SitTargetisSet && SitTargetUnOccupied) 1813// partRot = part.ParentGroup.RootPart.RotationOffset;
1747 { 1814// }
1748 part.SetAvatarOnSitTarget(UUID); 1815// else
1749 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1816// { // single or child prim
1750 sitOrientation = avSitOrientation; 1817 partRot = part.GetWorldRotation();
1751 autopilot = false; 1818// }
1752 } 1819 Quaternion partIRot = Quaternion.Inverse(partRot);
1753 1820//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1754 pos = part.AbsolutePosition + offset; 1821 // Sit analysis rewritten by KF 091125
1755 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1822 if (SitTargetisSet) // scipted sit
1756 //{ 1823 {
1757 // offset = pos; 1824 if (!part.IsOccupied)
1758 //autopilot = false; 1825 {
1759 //} 1826//Console.WriteLine("Scripted, unoccupied");
1760 if (m_physicsActor != null) 1827 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1761 { 1828 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1762 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1829 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1763 // We can remove the physicsActor until they stand up. 1830 autopilot = false; // Jump direct to scripted llSitPos()
1764 m_sitAvatarHeight = m_physicsActor.Size.Z; 1831 }
1765 1832 else
1766 if (autopilot) 1833 {
1767 { 1834//Console.WriteLine("Scripted, occupied");
1768 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1835 return;
1769 { 1836 }
1770 autopilot = false; 1837 }
1838 else // Not Scripted
1839 {
1840 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1841 {
1842 // large prim & offset, ignore if other Avs sitting
1843// offset.Z -= 0.05f;
1844 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1845 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1846
1847//Console.WriteLine(" offset ={0}", offset);
1848//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1849//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1850
1851 }
1852 else // small offset
1853 {
1854//Console.WriteLine("Small offset");
1855 if (!part.IsOccupied)
1856 {
1857 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1858 autopilotTarget = part.AbsolutePosition;
1859 }
1860 else return; // occupied small
1861 } // end large/small
1862 } // end Scripted/not
1863 cameraAtOffset = part.GetCameraAtOffset();
1864 cameraEyeOffset = part.GetCameraEyeOffset();
1865 forceMouselook = part.GetForceMouselook();
1866 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1867 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1771 1868
1772 RemoveFromPhysicalScene(); 1869 if (m_physicsActor != null)
1773 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1870 {
1774 } 1871 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1775 } 1872 // We can remove the physicsActor until they stand up.
1776 else 1873 m_sitAvatarHeight = m_physicsActor.Size.Z;
1874 if (autopilot)
1875 { // its not a scripted sit
1876// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1877 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1777 { 1878 {
1879 autopilot = false; // close enough
1880 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1881 Not using the part's position because returning the AV to the last known standing
1882 position is likely to be more friendly, isn't it? */
1778 RemoveFromPhysicalScene(); 1883 RemoveFromPhysicalScene();
1779 } 1884 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1885 } // else the autopilot will get us close
1886 }
1887 else
1888 { // its a scripted sit
1889 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1890 I *am* using the part's position this time because we have no real idea how far away
1891 the avatar is from the sit target. */
1892 RemoveFromPhysicalScene();
1780 } 1893 }
1781
1782 cameraAtOffset = part.GetCameraAtOffset();
1783 cameraEyeOffset = part.GetCameraEyeOffset();
1784 forceMouselook = part.GetForceMouselook();
1785 } 1894 }
1786 1895 else return; // physactor is null!
1787 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1896
1788 m_requestedSitTargetUUID = targetID; 1897 Vector3 offsetr; // = offset * partIRot;
1898 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1899 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1900 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1901 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1902 offsetr = offset * partIRot;
1903//
1904 // else
1905 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1906 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1907 // (offset * partRot);
1908 // }
1909
1910//Console.WriteLine(" ");
1911//Console.WriteLine("link number ={0}", part.LinkNum);
1912//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1913//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1914//Console.WriteLine("Click offst ={0}", offset);
1915//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1916//Console.WriteLine("offsetr ={0}", offsetr);
1917//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1918//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1919
1920 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1921 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1789 // This calls HandleAgentSit twice, once from here, and the client calls 1922 // This calls HandleAgentSit twice, once from here, and the client calls
1790 // HandleAgentSit itself after it gets to the location 1923 // HandleAgentSit itself after it gets to the location
1791 // It doesn't get to the location until we've moved them there though 1924 // It doesn't get to the location until we've moved them there though
1792 // which happens in HandleAgentSit :P 1925 // which happens in HandleAgentSit :P
1793 m_autopilotMoving = autopilot; 1926 m_autopilotMoving = autopilot;
1794 m_autoPilotTarget = pos; 1927 m_autoPilotTarget = autopilotTarget;
1795 m_sitAtAutoTarget = autopilot; 1928 m_sitAtAutoTarget = autopilot;
1929 m_initialSitTarget = autopilotTarget;
1796 if (!autopilot) 1930 if (!autopilot)
1797 HandleAgentSit(remoteClient, UUID); 1931 HandleAgentSit(remoteClient, UUID);
1798 } 1932 }
@@ -2087,31 +2221,65 @@ namespace OpenSim.Region.Framework.Scenes
2087 { 2221 {
2088 if (part != null) 2222 if (part != null)
2089 { 2223 {
2224//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2090 if (part.GetAvatarOnSitTarget() == UUID) 2225 if (part.GetAvatarOnSitTarget() == UUID)
2091 { 2226 {
2227//Console.WriteLine("Scripted Sit");
2228 // Scripted sit
2092 Vector3 sitTargetPos = part.SitTargetPosition; 2229 Vector3 sitTargetPos = part.SitTargetPosition;
2093 Quaternion sitTargetOrient = part.SitTargetOrientation; 2230 Quaternion sitTargetOrient = part.SitTargetOrientation;
2094
2095 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2096 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2097
2098 //Quaternion result = (sitTargetOrient * vq) * nq;
2099
2100 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2231 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2101 m_pos += SIT_TARGET_ADJUSTMENT; 2232 m_pos += SIT_TARGET_ADJUSTMENT;
2102 m_bodyRot = sitTargetOrient; 2233 m_bodyRot = sitTargetOrient;
2103 //Rotation = sitTargetOrient;
2104 m_parentPosition = part.AbsolutePosition; 2234 m_parentPosition = part.AbsolutePosition;
2105 2235 part.IsOccupied = true;
2106 //SendTerseUpdateToAllClients();
2107 } 2236 }
2108 else 2237 else
2109 { 2238 {
2110 m_pos -= part.AbsolutePosition; 2239 // if m_avUnscriptedSitPos is zero then Av sits above center
2240 // Else Av sits at m_avUnscriptedSitPos
2241
2242 // Non-scripted sit by Kitto Flora 21Nov09
2243 // Calculate angle of line from prim to Av
2244 Quaternion partIRot;
2245// if (part.LinkNum == 1)
2246// { // Root prim of linkset
2247// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2248// }
2249// else
2250// { // single or child prim
2251 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2252// }
2253 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2254 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2255 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2256 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2257 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2258 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2259 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2260 // Av sits at world euler <0,0, z>, translated by part rotation
2261 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2262
2111 m_parentPosition = part.AbsolutePosition; 2263 m_parentPosition = part.AbsolutePosition;
2112 } 2264 part.IsOccupied = true;
2113 } 2265 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2114 else 2266 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2267 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2268 m_avUnscriptedSitPos; // adds click offset, if any
2269 //Set up raytrace to find top surface of prim
2270 Vector3 size = part.Scale;
2271 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2272 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2273 Vector3 down = new Vector3(0f, 0f, -1f);
2274//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2275 m_scene.PhysicsScene.RaycastWorld(
2276 start, // Vector3 position,
2277 down, // Vector3 direction,
2278 mag, // float length,
2279 SitAltitudeCallback); // retMethod
2280 } // end scripted/not
2281 }
2282 else // no Av
2115 { 2283 {
2116 return; 2284 return;
2117 } 2285 }
@@ -2123,11 +2291,36 @@ namespace OpenSim.Region.Framework.Scenes
2123 2291
2124 Animator.TrySetMovementAnimation(sitAnimation); 2292 Animator.TrySetMovementAnimation(sitAnimation);
2125 SendFullUpdateToAllClients(); 2293 SendFullUpdateToAllClients();
2126 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2127 // So we're also sending a terse update (which has avatar rotation)
2128 // [Update] We do now.
2129 //SendTerseUpdateToAllClients();
2130 } 2294 }
2295
2296 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2297 {
2298 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2299 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2300 if(hitYN)
2301 {
2302 // m_pos = Av offset from prim center to make look like on center
2303 // m_parentPosition = Actual center pos of prim
2304 // collisionPoint = spot on prim where we want to sit
2305 // collisionPoint.Z = global sit surface height
2306 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2307 Quaternion partIRot;
2308// if (part.LinkNum == 1)
2309/// { // Root prim of linkset
2310// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2311// }
2312// else
2313// { // single or child prim
2314 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2315// }
2316 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2317 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2318//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2319 m_pos += offset;
2320// ControllingClient.SendClearFollowCamProperties(part.UUID);
2321
2322 }
2323 } // End SitAltitudeCallback KF.
2131 2324
2132 /// <summary> 2325 /// <summary>
2133 /// Event handler for the 'Always run' setting on the client 2326 /// Event handler for the 'Always run' setting on the client
@@ -2157,7 +2350,7 @@ namespace OpenSim.Region.Framework.Scenes
2157 /// </summary> 2350 /// </summary>
2158 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2351 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2159 /// <param name="rotation">The direction in which this avatar should now face. 2352 /// <param name="rotation">The direction in which this avatar should now face.
2160 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2353 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2161 { 2354 {
2162 if (m_isChildAgent) 2355 if (m_isChildAgent)
2163 { 2356 {
@@ -2231,7 +2424,7 @@ namespace OpenSim.Region.Framework.Scenes
2231 2424
2232 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2425 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2233 m_forceToApply = direc; 2426 m_forceToApply = direc;
2234 2427 m_isNudging = Nudging;
2235 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2428 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2236 } 2429 }
2237 2430
@@ -2246,7 +2439,7 @@ namespace OpenSim.Region.Framework.Scenes
2246 const float POSITION_TOLERANCE = 0.05f; 2439 const float POSITION_TOLERANCE = 0.05f;
2247 //const int TIME_MS_TOLERANCE = 3000; 2440 //const int TIME_MS_TOLERANCE = 3000;
2248 2441
2249 SendPrimUpdates(); 2442
2250 2443
2251 if (m_newCoarseLocations) 2444 if (m_newCoarseLocations)
2252 { 2445 {
@@ -2282,6 +2475,9 @@ namespace OpenSim.Region.Framework.Scenes
2282 CheckForBorderCrossing(); 2475 CheckForBorderCrossing();
2283 CheckForSignificantMovement(); // sends update to the modules. 2476 CheckForSignificantMovement(); // sends update to the modules.
2284 } 2477 }
2478
2479 //Sending prim updates AFTER the avatar terse updates are sent
2480 SendPrimUpdates();
2285 } 2481 }
2286 2482
2287 #endregion 2483 #endregion
@@ -3143,14 +3339,25 @@ namespace OpenSim.Region.Framework.Scenes
3143 { 3339 {
3144 if (m_forceToApply.HasValue) 3340 if (m_forceToApply.HasValue)
3145 { 3341 {
3146 Vector3 force = m_forceToApply.Value;
3147 3342
3343 Vector3 force = m_forceToApply.Value;
3148 m_updateflag = true; 3344 m_updateflag = true;
3149// movementvector = force;
3150 Velocity = force; 3345 Velocity = force;
3151 3346
3152 m_forceToApply = null; 3347 m_forceToApply = null;
3153 } 3348 }
3349 else
3350 {
3351 if (m_isNudging)
3352 {
3353 Vector3 force = Vector3.Zero;
3354
3355 m_updateflag = true;
3356 Velocity = force;
3357 m_isNudging = false;
3358 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3359 }
3360 }
3154 } 3361 }
3155 3362
3156 public override void SetText(string text, Vector3 color, double alpha) 3363 public override void SetText(string text, Vector3 color, double alpha)
@@ -3202,18 +3409,29 @@ namespace OpenSim.Region.Framework.Scenes
3202 { 3409 {
3203 if (e == null) 3410 if (e == null)
3204 return; 3411 return;
3205 3412
3206 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3413 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3207 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3208 // as of this comment the interval is set in AddToPhysicalScene 3414 // as of this comment the interval is set in AddToPhysicalScene
3209 if (Animator!=null) 3415 if (Animator!=null)
3210 Animator.UpdateMovementAnimations(); 3416 {
3417 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3418 { // else its will lock out other animation changes, like ground sit.
3419 Animator.UpdateMovementAnimations();
3420 m_updateCount--;
3421 }
3422 }
3211 3423
3212 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3424 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3213 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3425 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3214 3426
3215 CollisionPlane = Vector4.UnitW; 3427 CollisionPlane = Vector4.UnitW;
3216 3428
3429 if (m_lastColCount != coldata.Count)
3430 {
3431 m_updateCount = UPDATE_COUNT;
3432 m_lastColCount = coldata.Count;
3433 }
3434
3217 if (coldata.Count != 0 && Animator != null) 3435 if (coldata.Count != 0 && Animator != null)
3218 { 3436 {
3219 switch (Animator.CurrentMovementAnimation) 3437 switch (Animator.CurrentMovementAnimation)
@@ -3859,5 +4077,16 @@ namespace OpenSim.Region.Framework.Scenes
3859 m_reprioritization_called = false; 4077 m_reprioritization_called = false;
3860 } 4078 }
3861 } 4079 }
4080
4081 private Vector3 Quat2Euler(Quaternion rot){
4082 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4083 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4084 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4085 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4086 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4087 return(new Vector3(x,y,z));
4088 }
4089
4090
3862 } 4091 }
3863} 4092}
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index e4296ef..1cff0eb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes
76 76
77 foreach (EntityBase e in m_presence.Scene.Entities) 77 foreach (EntityBase e in m_presence.Scene.Entities)
78 { 78 {
79 if (e is SceneObjectGroup) 79 if (e != null && e is SceneObjectGroup)
80 m_pendingObjects.Enqueue((SceneObjectGroup)e); 80 m_pendingObjects.Enqueue((SceneObjectGroup)e);
81 } 81 }
82 } 82 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 8a27b7b..5abbb82 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -101,7 +101,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
101 { 101 {
102 throw new NotImplementedException(); 102 throw new NotImplementedException();
103 } 103 }
104 104 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
105 {
106 //This connector doesn't support the windlight module yet
107 //Return default LL windlight settings
108 return new RegionMeta7WindlightData();
109 }
110 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
111 {
112 //This connector doesn't support the windlight module yet
113 }
105 public RegionSettings LoadRegionSettings(UUID regionUUID) 114 public RegionSettings LoadRegionSettings(UUID regionUUID)
106 { 115 {
107 return null; 116 return null;