aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs2
-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.cs25
-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.cs596
-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
15 files changed, 1340 insertions, 748 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
index 78bd622..7312799 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
@@ -103,6 +103,8 @@ namespace OpenSim.Region.Framework.Interfaces
103 103
104 void StoreRegionSettings(RegionSettings rs); 104 void StoreRegionSettings(RegionSettings rs);
105 RegionSettings LoadRegionSettings(UUID regionUUID); 105 RegionSettings LoadRegionSettings(UUID regionUUID);
106 RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID);
107 void StoreRegionWindlightSettings(RegionMeta7WindlightData wl);
106 108
107 void Shutdown(); 109 void Shutdown();
108 } 110 }
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 9f74b2a..22909bc 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -203,7 +203,11 @@ namespace OpenSim.Region.Framework.Scenes
203 public event OnMakeChildAgentDelegate OnMakeChildAgent; 203 public event OnMakeChildAgentDelegate OnMakeChildAgent;
204 204
205 public delegate void OnMakeRootAgentDelegate(ScenePresence presence); 205 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
206 public delegate void OnSaveNewWindlightProfileDelegate();
207 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user);
206 public event OnMakeRootAgentDelegate OnMakeRootAgent; 208 public event OnMakeRootAgentDelegate OnMakeRootAgent;
209 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
210 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
207 211
208 /// <summary> 212 /// <summary>
209 /// Triggered when an object or attachment enters a scene 213 /// Triggered when an object or attachment enters a scene
@@ -1191,6 +1195,24 @@ namespace OpenSim.Region.Framework.Scenes
1191 } 1195 }
1192 } 1196 }
1193 1197
1198 public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
1199 {
1200 OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
1201 if (handlerSendNewWindlightProfileTargeted != null)
1202 {
1203 handlerSendNewWindlightProfileTargeted(wl, user);
1204 }
1205 }
1206
1207 public void TriggerOnSaveNewWindlightProfile()
1208 {
1209 OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
1210 if (handlerSaveNewWindlightProfile != null)
1211 {
1212 handlerSaveNewWindlightProfile();
1213 }
1214 }
1215
1194 public void TriggerOnMakeRootAgent(ScenePresence presence) 1216 public void TriggerOnMakeRootAgent(ScenePresence presence)
1195 { 1217 {
1196 OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent; 1218 OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent;
@@ -1967,4 +1989,4 @@ namespace OpenSim.Region.Framework.Scenes
1967 } 1989 }
1968 } 1990 }
1969 } 1991 }
1970} \ No newline at end of file 1992}
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 ddebd0b..12f0489 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>
@@ -3402,6 +3429,9 @@ namespace OpenSim.Region.Framework.Scenes
3402 3429
3403 CapsModule.AddCapsHandler(agent.AgentID); 3430 CapsModule.AddCapsHandler(agent.AgentID);
3404 3431
3432 if ((teleportFlags & ((uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.Default)) != 0)
3433 System.Threading.Thread.Sleep(2000);
3434
3405 if (!agent.child) 3435 if (!agent.child)
3406 { 3436 {
3407 if (TestBorderCross(agent.startpos,Cardinals.E)) 3437 if (TestBorderCross(agent.startpos,Cardinals.E))
@@ -3460,6 +3490,7 @@ namespace OpenSim.Region.Framework.Scenes
3460 } 3490 }
3461 } 3491 }
3462 // Honor parcel landing type and position. 3492 // Honor parcel landing type and position.
3493 /*
3463 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 3494 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3464 if (land != null) 3495 if (land != null)
3465 { 3496 {
@@ -3468,6 +3499,7 @@ namespace OpenSim.Region.Framework.Scenes
3468 agent.startpos = land.LandData.UserLocation; 3499 agent.startpos = land.LandData.UserLocation;
3469 } 3500 }
3470 } 3501 }
3502 */// This is now handled properly in ScenePresence.MakeRootAgent
3471 } 3503 }
3472 3504
3473 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3505 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 2f6a0db..9ceab19 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -711,6 +711,31 @@ namespace OpenSim.Region.Framework.Scenes
711 position = emergencyPos; 711 position = emergencyPos;
712 } 712 }
713 713
714 Vector3 currentPos = avatar.AbsolutePosition;
715 ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y);
716 ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y);
717 if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0)
718 {
719 if (srcLand.LandData.LocalID == destLand.LandData.LocalID)
720 {
721 //TPing within the same parcel. If the landing point is restricted, block the TP.
722 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
723 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)
724 {
725 avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false);
726 position = currentPos;
727 }
728 }
729 else
730 {
731 //Tping to a different parcel. Respect the landing point on the destination parcel.
732 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)
733 {
734 position = destLand.LandData.UserLocation;
735 }
736 }
737 }
738
714 // TODO: Get proper AVG Height 739 // TODO: Get proper AVG Height
715 float localAVHeight = 1.56f; 740 float localAVHeight = 1.56f;
716 float posZLimit = 22; 741 float posZLimit = 22;
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 af46659..4676a30 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
@@ -299,13 +368,16 @@ namespace OpenSim.Region.Framework.Scenes
299 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 368 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
300 } 369 }
301 370
302 lock (m_parts) 371 lockPartsForRead(true);
303 { 372 {
304 foreach (SceneObjectPart part in m_parts.Values) 373 foreach (SceneObjectPart part in m_parts.Values)
305 { 374 {
375
306 part.GroupPosition = val; 376 part.GroupPosition = val;
377
307 } 378 }
308 } 379 }
380 lockPartsForRead(false);
309 381
310 //if (m_rootPart.PhysActor != null) 382 //if (m_rootPart.PhysActor != null)
311 //{ 383 //{
@@ -467,13 +539,16 @@ namespace OpenSim.Region.Framework.Scenes
467 539
468 public void SetFromItemID(UUID AssetId) 540 public void SetFromItemID(UUID AssetId)
469 { 541 {
470 lock (m_parts) 542 lockPartsForRead(true);
471 { 543 {
472 foreach (SceneObjectPart part in m_parts.Values) 544 foreach (SceneObjectPart part in m_parts.Values)
473 { 545 {
546
474 part.FromItemID = AssetId; 547 part.FromItemID = AssetId;
548
475 } 549 }
476 } 550 }
551 lockPartsForRead(false);
477 } 552 }
478 553
479 public UUID GetFromItemID() 554 public UUID GetFromItemID()
@@ -540,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes
540 Vector3 maxScale = Vector3.Zero; 615 Vector3 maxScale = Vector3.Zero;
541 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 616 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
542 617
543 lock (m_parts) 618 lockPartsForRead(true);
544 { 619 {
545 foreach (SceneObjectPart part in m_parts.Values) 620 foreach (SceneObjectPart part in m_parts.Values)
546 { 621 {
622
547 Vector3 partscale = part.Scale; 623 Vector3 partscale = part.Scale;
548 Vector3 partoffset = part.OffsetPosition; 624 Vector3 partoffset = part.OffsetPosition;
549 625
@@ -554,8 +630,11 @@ namespace OpenSim.Region.Framework.Scenes
554 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 630 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
555 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 631 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
556 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 632 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
633
557 } 634 }
558 } 635 }
636 lockPartsForRead(false);
637
559 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 638 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
560 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 639 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
561 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 640 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -571,10 +650,11 @@ namespace OpenSim.Region.Framework.Scenes
571 650
572 EntityIntersection result = new EntityIntersection(); 651 EntityIntersection result = new EntityIntersection();
573 652
574 lock (m_parts) 653 lockPartsForRead(true);
575 { 654 {
576 foreach (SceneObjectPart part in m_parts.Values) 655 foreach (SceneObjectPart part in m_parts.Values)
577 { 656 {
657
578 // Temporary commented to stop compiler warning 658 // Temporary commented to stop compiler warning
579 //Vector3 partPosition = 659 //Vector3 partPosition =
580 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 660 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -602,8 +682,10 @@ namespace OpenSim.Region.Framework.Scenes
602 result.distance = inter.distance; 682 result.distance = inter.distance;
603 } 683 }
604 } 684 }
685
605 } 686 }
606 } 687 }
688 lockPartsForRead(false);
607 return result; 689 return result;
608 } 690 }
609 691
@@ -616,10 +698,11 @@ namespace OpenSim.Region.Framework.Scenes
616 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 698 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
617 { 699 {
618 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 700 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
619 lock (m_parts) 701 lockPartsForRead(true);
620 { 702 {
621 foreach (SceneObjectPart part in m_parts.Values) 703 foreach (SceneObjectPart part in m_parts.Values)
622 { 704 {
705
623 Vector3 worldPos = part.GetWorldPosition(); 706 Vector3 worldPos = part.GetWorldPosition();
624 Vector3 offset = worldPos - AbsolutePosition; 707 Vector3 offset = worldPos - AbsolutePosition;
625 Quaternion worldRot; 708 Quaternion worldRot;
@@ -678,6 +761,8 @@ namespace OpenSim.Region.Framework.Scenes
678 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 761 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
679 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 762 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
680 763
764
765
681 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 766 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
682 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 767 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
683 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 768 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -849,6 +934,7 @@ namespace OpenSim.Region.Framework.Scenes
849 minZ = backBottomLeft.Z; 934 minZ = backBottomLeft.Z;
850 } 935 }
851 } 936 }
937 lockPartsForRead(false);
852 938
853 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 939 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
854 940
@@ -877,17 +963,20 @@ namespace OpenSim.Region.Framework.Scenes
877 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 963 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
878 964
879 // Capture script state while holding the lock 965 // Capture script state while holding the lock
880 lock (m_parts) 966 lockPartsForRead(true);
881 { 967 {
882 foreach (SceneObjectPart part in m_parts.Values) 968 foreach (SceneObjectPart part in m_parts.Values)
883 { 969 {
970
884 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 971 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
885 foreach (UUID itemid in pstates.Keys) 972 foreach (UUID itemid in pstates.Keys)
886 { 973 {
887 states.Add(itemid, pstates[itemid]); 974 states.Add(itemid, pstates[itemid]);
888 } 975 }
976
889 } 977 }
890 } 978 }
979 lockPartsForRead(false);
891 980
892 if (states.Count > 0) 981 if (states.Count > 0)
893 { 982 {
@@ -1049,13 +1138,16 @@ namespace OpenSim.Region.Framework.Scenes
1049 1138
1050 public override void UpdateMovement() 1139 public override void UpdateMovement()
1051 { 1140 {
1052 lock (m_parts) 1141 lockPartsForRead(true);
1053 { 1142 {
1054 foreach (SceneObjectPart part in m_parts.Values) 1143 foreach (SceneObjectPart part in m_parts.Values)
1055 { 1144 {
1145
1056 part.UpdateMovement(); 1146 part.UpdateMovement();
1147
1057 } 1148 }
1058 } 1149 }
1150 lockPartsForRead(false);
1059 } 1151 }
1060 1152
1061 public ushort GetTimeDilation() 1153 public ushort GetTimeDilation()
@@ -1099,7 +1191,7 @@ namespace OpenSim.Region.Framework.Scenes
1099 /// <param name="part"></param> 1191 /// <param name="part"></param>
1100 public void AddPart(SceneObjectPart part) 1192 public void AddPart(SceneObjectPart part)
1101 { 1193 {
1102 lock (m_parts) 1194 lockPartsForWrite(true);
1103 { 1195 {
1104 part.SetParent(this); 1196 part.SetParent(this);
1105 m_parts.Add(part.UUID, part); 1197 m_parts.Add(part.UUID, part);
@@ -1109,6 +1201,7 @@ namespace OpenSim.Region.Framework.Scenes
1109 if (part.LinkNum == 2 && RootPart != null) 1201 if (part.LinkNum == 2 && RootPart != null)
1110 RootPart.LinkNum = 1; 1202 RootPart.LinkNum = 1;
1111 } 1203 }
1204 lockPartsForWrite(false);
1112 } 1205 }
1113 1206
1114 /// <summary> 1207 /// <summary>
@@ -1116,28 +1209,33 @@ namespace OpenSim.Region.Framework.Scenes
1116 /// </summary> 1209 /// </summary>
1117 private void UpdateParentIDs() 1210 private void UpdateParentIDs()
1118 { 1211 {
1119 lock (m_parts) 1212 lockPartsForRead(true);
1120 { 1213 {
1121 foreach (SceneObjectPart part in m_parts.Values) 1214 foreach (SceneObjectPart part in m_parts.Values)
1122 { 1215 {
1216
1123 if (part.UUID != m_rootPart.UUID) 1217 if (part.UUID != m_rootPart.UUID)
1124 { 1218 {
1125 part.ParentID = m_rootPart.LocalId; 1219 part.ParentID = m_rootPart.LocalId;
1126 } 1220 }
1221
1127 } 1222 }
1128 } 1223 }
1224 lockPartsForRead(false);
1129 } 1225 }
1130 1226
1131 public void RegenerateFullIDs() 1227 public void RegenerateFullIDs()
1132 { 1228 {
1133 lock (m_parts) 1229 lockPartsForRead(true);
1134 { 1230 {
1135 foreach (SceneObjectPart part in m_parts.Values) 1231 foreach (SceneObjectPart part in m_parts.Values)
1136 { 1232 {
1233
1137 part.UUID = UUID.Random(); 1234 part.UUID = UUID.Random();
1138 1235
1139 } 1236 }
1140 } 1237 }
1238 lockPartsForRead(false);
1141 } 1239 }
1142 1240
1143 // helper provided for parts. 1241 // helper provided for parts.
@@ -1218,29 +1316,33 @@ namespace OpenSim.Region.Framework.Scenes
1218 1316
1219 DetachFromBackup(); 1317 DetachFromBackup();
1220 1318
1221 lock (m_parts) 1319 lockPartsForRead(true);
1320 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1321 lockPartsForRead(false);
1322
1323 foreach (SceneObjectPart part in values)
1222 { 1324 {
1223 foreach (SceneObjectPart part in m_parts.Values)
1224 {
1225// part.Inventory.RemoveScriptInstances(); 1325// part.Inventory.RemoveScriptInstances();
1226 1326
1227 ScenePresence[] avatars = Scene.GetScenePresences(); 1327 ScenePresence[] avatars = Scene.GetScenePresences();
1228 for (int i = 0; i < avatars.Length; i++) 1328 for (int i = 0; i < avatars.Length; i++)
1329 {
1330 if (avatars[i].ParentID == LocalId)
1229 { 1331 {
1230 if (avatars[i].ParentID == LocalId) 1332 avatars[i].StandUp();
1231 { 1333 }
1232 avatars[i].StandUp();
1233 }
1234 1334
1235 if (!silent) 1335 if (!silent)
1236 { 1336 {
1237 part.UpdateFlag = 0; 1337 part.UpdateFlag = 0;
1238 if (part == m_rootPart) 1338 if (part == m_rootPart)
1239 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1339 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1240 }
1241 } 1340 }
1242 } 1341 }
1342
1243 } 1343 }
1344
1345
1244 } 1346 }
1245 1347
1246 public void AddScriptLPS(int count) 1348 public void AddScriptLPS(int count)
@@ -1265,17 +1367,20 @@ namespace OpenSim.Region.Framework.Scenes
1265 1367
1266 scriptEvents aggregateScriptEvents=0; 1368 scriptEvents aggregateScriptEvents=0;
1267 1369
1268 lock (m_parts) 1370 lockPartsForRead(true);
1269 { 1371 {
1270 foreach (SceneObjectPart part in m_parts.Values) 1372 foreach (SceneObjectPart part in m_parts.Values)
1271 { 1373 {
1374
1272 if (part == null) 1375 if (part == null)
1273 continue; 1376 continue;
1274 if (part != RootPart) 1377 if (part != RootPart)
1275 part.ObjectFlags = objectflagupdate; 1378 part.ObjectFlags = objectflagupdate;
1276 aggregateScriptEvents |= part.AggregateScriptEvents; 1379 aggregateScriptEvents |= part.AggregateScriptEvents;
1380
1277 } 1381 }
1278 } 1382 }
1383 lockPartsForRead(false);
1279 1384
1280 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1385 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1281 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1386 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1317,42 +1422,52 @@ namespace OpenSim.Region.Framework.Scenes
1317 /// <param name="m_physicalPrim"></param> 1422 /// <param name="m_physicalPrim"></param>
1318 public void ApplyPhysics(bool m_physicalPrim) 1423 public void ApplyPhysics(bool m_physicalPrim)
1319 { 1424 {
1320 lock (m_parts) 1425 lockPartsForRead(true);
1426
1427 if (m_parts.Count > 1)
1321 { 1428 {
1322 if (m_parts.Count > 1) 1429 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1430 lockPartsForRead(false);
1431 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1432 foreach (SceneObjectPart part in values)
1323 { 1433 {
1324 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1434
1325 foreach (SceneObjectPart part in m_parts.Values) 1435 if (part.LocalId != m_rootPart.LocalId)
1326 { 1436 {
1327 if (part.LocalId != m_rootPart.LocalId) 1437 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1328 {
1329 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1330 }
1331 } 1438 }
1332 1439
1333 // Hack to get the physics scene geometries in the right spot
1334 ResetChildPrimPhysicsPositions();
1335 }
1336 else
1337 {
1338 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1339 } 1440 }
1441 // Hack to get the physics scene geometries in the right spot
1442 ResetChildPrimPhysicsPositions();
1443 }
1444 else
1445 {
1446 lockPartsForRead(false);
1447 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1340 } 1448 }
1341 } 1449 }
1342 1450
1343 public void SetOwnerId(UUID userId) 1451 public void SetOwnerId(UUID userId)
1344 { 1452 {
1345 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1453 ForEachPart(delegate(SceneObjectPart part)
1454 {
1455
1456 part.OwnerID = userId;
1457
1458 });
1346 } 1459 }
1347 1460
1348 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1461 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1349 { 1462 {
1350 lock (m_parts) 1463 lockPartsForRead(true);
1464 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1465 lockPartsForRead(false);
1466 foreach (SceneObjectPart part in values)
1351 { 1467 {
1352 foreach (SceneObjectPart part in m_parts.Values) 1468
1353 { 1469 whatToDo(part);
1354 whatToDo(part); 1470
1355 }
1356 } 1471 }
1357 } 1472 }
1358 1473
@@ -1451,14 +1566,17 @@ namespace OpenSim.Region.Framework.Scenes
1451 { 1566 {
1452 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1567 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1453 1568
1454 lock (m_parts) 1569 lockPartsForRead(true);
1455 { 1570 {
1456 foreach (SceneObjectPart part in m_parts.Values) 1571 foreach (SceneObjectPart part in m_parts.Values)
1457 { 1572 {
1573
1458 if (part != RootPart) 1574 if (part != RootPart)
1459 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1575 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1576
1460 } 1577 }
1461 } 1578 }
1579 lockPartsForRead(false);
1462 } 1580 }
1463 1581
1464 /// <summary> 1582 /// <summary>
@@ -1553,10 +1671,11 @@ namespace OpenSim.Region.Framework.Scenes
1553 1671
1554 List<SceneObjectPart> partList; 1672 List<SceneObjectPart> partList;
1555 1673
1556 lock (m_parts) 1674 lockPartsForRead(true);
1557 { 1675
1558 partList = new List<SceneObjectPart>(m_parts.Values); 1676 partList = new List<SceneObjectPart>(m_parts.Values);
1559 } 1677
1678 lockPartsForRead(false);
1560 1679
1561 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1680 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1562 { 1681 {
@@ -1805,6 +1924,7 @@ namespace OpenSim.Region.Framework.Scenes
1805 } 1924 }
1806 } 1925 }
1807 } 1926 }
1927
1808 public void stopLookAt() 1928 public void stopLookAt()
1809 { 1929 {
1810 SceneObjectPart rootpart = m_rootPart; 1930 SceneObjectPart rootpart = m_rootPart;
@@ -1879,10 +1999,11 @@ namespace OpenSim.Region.Framework.Scenes
1879 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1999 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1880 newPart.SetParent(this); 2000 newPart.SetParent(this);
1881 2001
1882 lock (m_parts) 2002 lockPartsForWrite(true);
1883 { 2003 {
1884 m_parts.Add(newPart.UUID, newPart); 2004 m_parts.Add(newPart.UUID, newPart);
1885 } 2005 }
2006 lockPartsForWrite(false);
1886 2007
1887 SetPartAsNonRoot(newPart); 2008 SetPartAsNonRoot(newPart);
1888 2009
@@ -1945,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes
1945 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2066 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1946 // return; 2067 // return;
1947 2068
1948 lock (m_parts) 2069 lockPartsForRead(true);
1949 { 2070 {
1950 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2071 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1951 2072
@@ -1963,34 +2084,43 @@ namespace OpenSim.Region.Framework.Scenes
1963 2084
1964 foreach (SceneObjectPart part in m_parts.Values) 2085 foreach (SceneObjectPart part in m_parts.Values)
1965 { 2086 {
2087
1966 part.SendScheduledUpdates(); 2088 part.SendScheduledUpdates();
2089
1967 } 2090 }
1968 } 2091 }
2092 lockPartsForRead(false);
1969 } 2093 }
1970 2094
1971 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2095 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1972 { 2096 {
1973 RootPart.AddFullUpdateToAvatar(presence); 2097 RootPart.AddFullUpdateToAvatar(presence);
1974 2098
1975 lock (m_parts) 2099 lockPartsForRead(true);
1976 { 2100 {
1977 foreach (SceneObjectPart part in m_parts.Values) 2101 foreach (SceneObjectPart part in m_parts.Values)
1978 { 2102 {
2103
1979 if (part != RootPart) 2104 if (part != RootPart)
1980 part.AddFullUpdateToAvatar(presence); 2105 part.AddFullUpdateToAvatar(presence);
2106
1981 } 2107 }
1982 } 2108 }
2109 lockPartsForRead(false);
1983 } 2110 }
1984 2111
1985 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2112 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1986 { 2113 {
1987 lock (m_parts) 2114 lockPartsForRead(true);
1988 { 2115 {
1989 foreach (SceneObjectPart part in m_parts.Values) 2116 foreach (SceneObjectPart part in m_parts.Values)
1990 { 2117 {
2118
1991 part.AddTerseUpdateToAvatar(presence); 2119 part.AddTerseUpdateToAvatar(presence);
2120
1992 } 2121 }
1993 } 2122 }
2123 lockPartsForRead(false);
1994 } 2124 }
1995 2125
1996 /// <summary> 2126 /// <summary>
@@ -2001,14 +2131,17 @@ namespace OpenSim.Region.Framework.Scenes
2001 checkAtTargets(); 2131 checkAtTargets();
2002 RootPart.ScheduleFullUpdate(); 2132 RootPart.ScheduleFullUpdate();
2003 2133
2004 lock (m_parts) 2134 lockPartsForRead(true);
2005 { 2135 {
2006 foreach (SceneObjectPart part in m_parts.Values) 2136 foreach (SceneObjectPart part in m_parts.Values)
2007 { 2137 {
2138
2008 if (part != RootPart) 2139 if (part != RootPart)
2009 part.ScheduleFullUpdate(); 2140 part.ScheduleFullUpdate();
2141
2010 } 2142 }
2011 } 2143 }
2144 lockPartsForRead(false);
2012 } 2145 }
2013 2146
2014 /// <summary> 2147 /// <summary>
@@ -2016,13 +2149,16 @@ namespace OpenSim.Region.Framework.Scenes
2016 /// </summary> 2149 /// </summary>
2017 public void ScheduleGroupForTerseUpdate() 2150 public void ScheduleGroupForTerseUpdate()
2018 { 2151 {
2019 lock (m_parts) 2152 lockPartsForRead(true);
2020 { 2153 {
2021 foreach (SceneObjectPart part in m_parts.Values) 2154 foreach (SceneObjectPart part in m_parts.Values)
2022 { 2155 {
2156
2023 part.ScheduleTerseUpdate(); 2157 part.ScheduleTerseUpdate();
2158
2024 } 2159 }
2025 } 2160 }
2161 lockPartsForRead(false);
2026 } 2162 }
2027 2163
2028 /// <summary> 2164 /// <summary>
@@ -2035,14 +2171,17 @@ namespace OpenSim.Region.Framework.Scenes
2035 2171
2036 RootPart.SendFullUpdateToAllClients(); 2172 RootPart.SendFullUpdateToAllClients();
2037 2173
2038 lock (m_parts) 2174 lockPartsForRead(true);
2039 { 2175 {
2040 foreach (SceneObjectPart part in m_parts.Values) 2176 foreach (SceneObjectPart part in m_parts.Values)
2041 { 2177 {
2178
2042 if (part != RootPart) 2179 if (part != RootPart)
2043 part.SendFullUpdateToAllClients(); 2180 part.SendFullUpdateToAllClients();
2181
2044 } 2182 }
2045 } 2183 }
2184 lockPartsForRead(false);
2046 } 2185 }
2047 2186
2048 /// <summary> 2187 /// <summary>
@@ -2073,14 +2212,15 @@ namespace OpenSim.Region.Framework.Scenes
2073 { 2212 {
2074 if (IsDeleted) 2213 if (IsDeleted)
2075 return; 2214 return;
2076 2215
2077 lock (m_parts) 2216 lockPartsForRead(true);
2078 { 2217 {
2079 foreach (SceneObjectPart part in m_parts.Values) 2218 foreach (SceneObjectPart part in m_parts.Values)
2080 { 2219 {
2081 part.SendTerseUpdateToAllClients(); 2220 part.SendTerseUpdateToAllClients();
2082 } 2221 }
2083 } 2222 }
2223 lockPartsForRead(false);
2084 } 2224 }
2085 2225
2086 #endregion 2226 #endregion
@@ -2094,16 +2234,18 @@ namespace OpenSim.Region.Framework.Scenes
2094 /// <returns>null if no child part with that linknum or child part</returns> 2234 /// <returns>null if no child part with that linknum or child part</returns>
2095 public SceneObjectPart GetLinkNumPart(int linknum) 2235 public SceneObjectPart GetLinkNumPart(int linknum)
2096 { 2236 {
2097 lock (m_parts) 2237 lockPartsForRead(true);
2098 { 2238 {
2099 foreach (SceneObjectPart part in m_parts.Values) 2239 foreach (SceneObjectPart part in m_parts.Values)
2100 { 2240 {
2101 if (part.LinkNum == linknum) 2241 if (part.LinkNum == linknum)
2102 { 2242 {
2243 lockPartsForRead(false);
2103 return part; 2244 return part;
2104 } 2245 }
2105 } 2246 }
2106 } 2247 }
2248 lockPartsForRead(false);
2107 2249
2108 return null; 2250 return null;
2109 } 2251 }
@@ -2131,17 +2273,19 @@ namespace OpenSim.Region.Framework.Scenes
2131 public SceneObjectPart GetChildPart(uint localID) 2273 public SceneObjectPart GetChildPart(uint localID)
2132 { 2274 {
2133 //m_log.DebugFormat("Entered looking for {0}", localID); 2275 //m_log.DebugFormat("Entered looking for {0}", localID);
2134 lock (m_parts) 2276 lockPartsForRead(true);
2135 { 2277 {
2136 foreach (SceneObjectPart part in m_parts.Values) 2278 foreach (SceneObjectPart part in m_parts.Values)
2137 { 2279 {
2138 //m_log.DebugFormat("Found {0}", part.LocalId); 2280 //m_log.DebugFormat("Found {0}", part.LocalId);
2139 if (part.LocalId == localID) 2281 if (part.LocalId == localID)
2140 { 2282 {
2283 lockPartsForRead(false);
2141 return part; 2284 return part;
2142 } 2285 }
2143 } 2286 }
2144 } 2287 }
2288 lockPartsForRead(false);
2145 2289
2146 return null; 2290 return null;
2147 } 2291 }
@@ -2171,17 +2315,19 @@ namespace OpenSim.Region.Framework.Scenes
2171 public bool HasChildPrim(uint localID) 2315 public bool HasChildPrim(uint localID)
2172 { 2316 {
2173 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2317 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2174 lock (m_parts) 2318 lockPartsForRead(true);
2175 { 2319 {
2176 foreach (SceneObjectPart part in m_parts.Values) 2320 foreach (SceneObjectPart part in m_parts.Values)
2177 { 2321 {
2178 //m_log.DebugFormat("Found {0}", part.LocalId); 2322 //m_log.DebugFormat("Found {0}", part.LocalId);
2179 if (part.LocalId == localID) 2323 if (part.LocalId == localID)
2180 { 2324 {
2325 lockPartsForRead(false);
2181 return true; 2326 return true;
2182 } 2327 }
2183 } 2328 }
2184 } 2329 }
2330 lockPartsForRead(false);
2185 2331
2186 return false; 2332 return false;
2187 } 2333 }
@@ -2231,53 +2377,57 @@ namespace OpenSim.Region.Framework.Scenes
2231 if (m_rootPart.LinkNum == 0) 2377 if (m_rootPart.LinkNum == 0)
2232 m_rootPart.LinkNum = 1; 2378 m_rootPart.LinkNum = 1;
2233 2379
2234 lock (m_parts) 2380 lockPartsForWrite(true);
2235 { 2381
2236 m_parts.Add(linkPart.UUID, linkPart); 2382 m_parts.Add(linkPart.UUID, linkPart);
2237 2383
2238 // Insert in terms of link numbers, the new links 2384 lockPartsForWrite(false);
2239 // before the current ones (with the exception of 2385
2240 // the root prim. Shuffle the old ones up 2386 // Insert in terms of link numbers, the new links
2241 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2387 // before the current ones (with the exception of
2388 // the root prim. Shuffle the old ones up
2389 lockPartsForRead(true);
2390 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2391 {
2392 if (kvp.Value.LinkNum != 1)
2242 { 2393 {
2243 if (kvp.Value.LinkNum != 1) 2394 // Don't update root prim link number
2244 { 2395 kvp.Value.LinkNum += objectGroup.PrimCount;
2245 // Don't update root prim link number
2246 kvp.Value.LinkNum += objectGroup.PrimCount;
2247 }
2248 } 2396 }
2397 }
2398 lockPartsForRead(false);
2249 2399
2250 linkPart.LinkNum = 2; 2400 linkPart.LinkNum = 2;
2251 2401
2252 linkPart.SetParent(this); 2402 linkPart.SetParent(this);
2253 linkPart.AddFlag(PrimFlags.CreateSelected); 2403 linkPart.AddFlag(PrimFlags.CreateSelected);
2254 2404
2255 //if (linkPart.PhysActor != null) 2405 //if (linkPart.PhysActor != null)
2256 //{ 2406 //{
2257 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2407 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2258 2408
2259 //linkPart.PhysActor = null; 2409 //linkPart.PhysActor = null;
2260 //} 2410 //}
2261 2411
2262 //TODO: rest of parts 2412 //TODO: rest of parts
2263 int linkNum = 3; 2413 int linkNum = 3;
2264 foreach (SceneObjectPart part in objectGroup.Children.Values) 2414 foreach (SceneObjectPart part in objectGroup.Children.Values)
2415 {
2416 if (part.UUID != objectGroup.m_rootPart.UUID)
2265 { 2417 {
2266 if (part.UUID != objectGroup.m_rootPart.UUID) 2418 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2267 {
2268 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2269 }
2270 part.ClearUndoState();
2271 } 2419 }
2420 part.ClearUndoState();
2272 } 2421 }
2273 2422
2274 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2423 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2275 objectGroup.m_isDeleted = true; 2424 objectGroup.m_isDeleted = true;
2425
2426 objectGroup.lockPartsForWrite(true);
2276 2427
2277 lock (objectGroup.m_parts) 2428 objectGroup.m_parts.Clear();
2278 { 2429
2279 objectGroup.m_parts.Clear(); 2430 objectGroup.lockPartsForWrite(false);
2280 }
2281 2431
2282 // Can't do this yet since backup still makes use of the root part without any synchronization 2432 // Can't do this yet since backup still makes use of the root part without any synchronization
2283// objectGroup.m_rootPart = null; 2433// objectGroup.m_rootPart = null;
@@ -2336,11 +2486,12 @@ namespace OpenSim.Region.Framework.Scenes
2336 Quaternion worldRot = linkPart.GetWorldRotation(); 2486 Quaternion worldRot = linkPart.GetWorldRotation();
2337 2487
2338 // Remove the part from this object 2488 // Remove the part from this object
2339 lock (m_parts) 2489 lockPartsForWrite(true);
2340 { 2490 {
2341 m_parts.Remove(linkPart.UUID); 2491 m_parts.Remove(linkPart.UUID);
2342 } 2492 }
2343 2493 lockPartsForWrite(false);
2494 lockPartsForRead(true);
2344 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2495 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2345 RootPart.LinkNum = 0; 2496 RootPart.LinkNum = 0;
2346 else 2497 else
@@ -2351,6 +2502,7 @@ namespace OpenSim.Region.Framework.Scenes
2351 p.LinkNum--; 2502 p.LinkNum--;
2352 } 2503 }
2353 } 2504 }
2505 lockPartsForRead(false);
2354 2506
2355 linkPart.ParentID = 0; 2507 linkPart.ParentID = 0;
2356 linkPart.LinkNum = 0; 2508 linkPart.LinkNum = 0;
@@ -2668,9 +2820,12 @@ namespace OpenSim.Region.Framework.Scenes
2668 2820
2669 if (selectionPart != null) 2821 if (selectionPart != null)
2670 { 2822 {
2671 lock (m_parts) 2823 lockPartsForRead(true);
2824 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2825 lockPartsForRead(false);
2826 foreach (SceneObjectPart part in parts)
2672 { 2827 {
2673 foreach (SceneObjectPart part in m_parts.Values) 2828 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2674 { 2829 {
2675 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2830 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2676 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2831 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2680,12 +2835,13 @@ namespace OpenSim.Region.Framework.Scenes
2680 break; 2835 break;
2681 } 2836 }
2682 } 2837 }
2838 }
2683 2839
2684 foreach (SceneObjectPart part in m_parts.Values) 2840 foreach (SceneObjectPart part in parts)
2685 { 2841 {
2686 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2842 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2687 }
2688 } 2843 }
2844
2689 } 2845 }
2690 } 2846 }
2691 2847
@@ -2771,11 +2927,9 @@ namespace OpenSim.Region.Framework.Scenes
2771 scale.Y = m_scene.m_maxNonphys; 2927 scale.Y = m_scene.m_maxNonphys;
2772 if (scale.Z > m_scene.m_maxNonphys) 2928 if (scale.Z > m_scene.m_maxNonphys)
2773 scale.Z = m_scene.m_maxNonphys; 2929 scale.Z = m_scene.m_maxNonphys;
2774
2775 SceneObjectPart part = GetChildPart(localID); 2930 SceneObjectPart part = GetChildPart(localID);
2776 if (part != null) 2931 if (part != null)
2777 { 2932 {
2778 part.Resize(scale);
2779 if (part.PhysActor != null) 2933 if (part.PhysActor != null)
2780 { 2934 {
2781 if (part.PhysActor.IsPhysical) 2935 if (part.PhysActor.IsPhysical)
@@ -2790,7 +2944,7 @@ namespace OpenSim.Region.Framework.Scenes
2790 part.PhysActor.Size = scale; 2944 part.PhysActor.Size = scale;
2791 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2945 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2792 } 2946 }
2793 //if (part.UUID != m_rootPart.UUID) 2947 part.Resize(scale);
2794 2948
2795 HasGroupChanged = true; 2949 HasGroupChanged = true;
2796 ScheduleGroupForFullUpdate(); 2950 ScheduleGroupForFullUpdate();
@@ -2831,77 +2985,76 @@ namespace OpenSim.Region.Framework.Scenes
2831 float y = (scale.Y / part.Scale.Y); 2985 float y = (scale.Y / part.Scale.Y);
2832 float z = (scale.Z / part.Scale.Z); 2986 float z = (scale.Z / part.Scale.Z);
2833 2987
2834 lock (m_parts) 2988 lockPartsForRead(true);
2989 if (x > 1.0f || y > 1.0f || z > 1.0f)
2835 { 2990 {
2836 if (x > 1.0f || y > 1.0f || z > 1.0f) 2991 foreach (SceneObjectPart obPart in m_parts.Values)
2837 { 2992 {
2838 foreach (SceneObjectPart obPart in m_parts.Values) 2993 if (obPart.UUID != m_rootPart.UUID)
2839 { 2994 {
2840 if (obPart.UUID != m_rootPart.UUID) 2995 Vector3 oldSize = new Vector3(obPart.Scale);
2841 {
2842 Vector3 oldSize = new Vector3(obPart.Scale);
2843 2996
2844 float f = 1.0f; 2997 float f = 1.0f;
2845 float a = 1.0f; 2998 float a = 1.0f;
2846 2999
2847 if (part.PhysActor != null && part.PhysActor.IsPhysical) 3000 if (part.PhysActor != null && part.PhysActor.IsPhysical)
3001 {
3002 if (oldSize.X*x > m_scene.m_maxPhys)
2848 { 3003 {
2849 if (oldSize.X*x > m_scene.m_maxPhys) 3004 f = m_scene.m_maxPhys / oldSize.X;
2850 { 3005 a = f / x;
2851 f = m_scene.m_maxPhys / oldSize.X; 3006 x *= a;
2852 a = f / x; 3007 y *= a;
2853 x *= a; 3008 z *= a;
2854 y *= a;
2855 z *= a;
2856 }
2857 if (oldSize.Y*y > m_scene.m_maxPhys)
2858 {
2859 f = m_scene.m_maxPhys / oldSize.Y;
2860 a = f / y;
2861 x *= a;
2862 y *= a;
2863 z *= a;
2864 }
2865 if (oldSize.Z*z > m_scene.m_maxPhys)
2866 {
2867 f = m_scene.m_maxPhys / oldSize.Z;
2868 a = f / z;
2869 x *= a;
2870 y *= a;
2871 z *= a;
2872 }
2873 } 3009 }
2874 else 3010 if (oldSize.Y*y > m_scene.m_maxPhys)
3011 {
3012 f = m_scene.m_maxPhys / oldSize.Y;
3013 a = f / y;
3014 x *= a;
3015 y *= a;
3016 z *= a;
3017 }
3018 if (oldSize.Z*z > m_scene.m_maxPhys)
3019 {
3020 f = m_scene.m_maxPhys / oldSize.Z;
3021 a = f / z;
3022 x *= a;
3023 y *= a;
3024 z *= a;
3025 }
3026 }
3027 else
3028 {
3029 if (oldSize.X*x > m_scene.m_maxNonphys)
3030 {
3031 f = m_scene.m_maxNonphys / oldSize.X;
3032 a = f / x;
3033 x *= a;
3034 y *= a;
3035 z *= a;
3036 }
3037 if (oldSize.Y*y > m_scene.m_maxNonphys)
3038 {
3039 f = m_scene.m_maxNonphys / oldSize.Y;
3040 a = f / y;
3041 x *= a;
3042 y *= a;
3043 z *= a;
3044 }
3045 if (oldSize.Z*z > m_scene.m_maxNonphys)
2875 { 3046 {
2876 if (oldSize.X*x > m_scene.m_maxNonphys) 3047 f = m_scene.m_maxNonphys / oldSize.Z;
2877 { 3048 a = f / z;
2878 f = m_scene.m_maxNonphys / oldSize.X; 3049 x *= a;
2879 a = f / x; 3050 y *= a;
2880 x *= a; 3051 z *= a;
2881 y *= a;
2882 z *= a;
2883 }
2884 if (oldSize.Y*y > m_scene.m_maxNonphys)
2885 {
2886 f = m_scene.m_maxNonphys / oldSize.Y;
2887 a = f / y;
2888 x *= a;
2889 y *= a;
2890 z *= a;
2891 }
2892 if (oldSize.Z*z > m_scene.m_maxNonphys)
2893 {
2894 f = m_scene.m_maxNonphys / oldSize.Z;
2895 a = f / z;
2896 x *= a;
2897 y *= a;
2898 z *= a;
2899 }
2900 } 3052 }
2901 } 3053 }
2902 } 3054 }
2903 } 3055 }
2904 } 3056 }
3057 lockPartsForRead(false);
2905 3058
2906 Vector3 prevScale = part.Scale; 3059 Vector3 prevScale = part.Scale;
2907 prevScale.X *= x; 3060 prevScale.X *= x;
@@ -2909,7 +3062,7 @@ namespace OpenSim.Region.Framework.Scenes
2909 prevScale.Z *= z; 3062 prevScale.Z *= z;
2910 part.Resize(prevScale); 3063 part.Resize(prevScale);
2911 3064
2912 lock (m_parts) 3065 lockPartsForRead(true);
2913 { 3066 {
2914 foreach (SceneObjectPart obPart in m_parts.Values) 3067 foreach (SceneObjectPart obPart in m_parts.Values)
2915 { 3068 {
@@ -2928,6 +3081,7 @@ namespace OpenSim.Region.Framework.Scenes
2928 } 3081 }
2929 } 3082 }
2930 } 3083 }
3084 lockPartsForRead(false);
2931 3085
2932 if (part.PhysActor != null) 3086 if (part.PhysActor != null)
2933 { 3087 {
@@ -3008,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes
3008 axDiff *= Quaternion.Inverse(partRotation); 3162 axDiff *= Quaternion.Inverse(partRotation);
3009 diff = axDiff; 3163 diff = axDiff;
3010 3164
3011 lock (m_parts) 3165 lockPartsForRead(true);
3012 { 3166 {
3013 foreach (SceneObjectPart obPart in m_parts.Values) 3167 foreach (SceneObjectPart obPart in m_parts.Values)
3014 { 3168 {
@@ -3018,6 +3172,7 @@ namespace OpenSim.Region.Framework.Scenes
3018 } 3172 }
3019 } 3173 }
3020 } 3174 }
3175 lockPartsForRead(false);
3021 3176
3022 AbsolutePosition = newPos; 3177 AbsolutePosition = newPos;
3023 3178
@@ -3135,7 +3290,7 @@ namespace OpenSim.Region.Framework.Scenes
3135 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3290 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3136 } 3291 }
3137 3292
3138 lock (m_parts) 3293 lockPartsForRead(true);
3139 { 3294 {
3140 foreach (SceneObjectPart prim in m_parts.Values) 3295 foreach (SceneObjectPart prim in m_parts.Values)
3141 { 3296 {
@@ -3153,6 +3308,7 @@ namespace OpenSim.Region.Framework.Scenes
3153 } 3308 }
3154 } 3309 }
3155 } 3310 }
3311 lockPartsForRead(false);
3156 3312
3157 m_rootPart.ScheduleTerseUpdate(); 3313 m_rootPart.ScheduleTerseUpdate();
3158 } 3314 }
@@ -3275,7 +3431,7 @@ namespace OpenSim.Region.Framework.Scenes
3275 if (atTargets.Count > 0) 3431 if (atTargets.Count > 0)
3276 { 3432 {
3277 uint[] localids = new uint[0]; 3433 uint[] localids = new uint[0];
3278 lock (m_parts) 3434 lockPartsForRead(true);
3279 { 3435 {
3280 localids = new uint[m_parts.Count]; 3436 localids = new uint[m_parts.Count];
3281 int cntr = 0; 3437 int cntr = 0;
@@ -3285,6 +3441,7 @@ namespace OpenSim.Region.Framework.Scenes
3285 cntr++; 3441 cntr++;
3286 } 3442 }
3287 } 3443 }
3444 lockPartsForRead(false);
3288 3445
3289 for (int ctr = 0; ctr < localids.Length; ctr++) 3446 for (int ctr = 0; ctr < localids.Length; ctr++)
3290 { 3447 {
@@ -3303,7 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes
3303 { 3460 {
3304 //trigger not_at_target 3461 //trigger not_at_target
3305 uint[] localids = new uint[0]; 3462 uint[] localids = new uint[0];
3306 lock (m_parts) 3463 lockPartsForRead(true);
3307 { 3464 {
3308 localids = new uint[m_parts.Count]; 3465 localids = new uint[m_parts.Count];
3309 int cntr = 0; 3466 int cntr = 0;
@@ -3313,7 +3470,8 @@ namespace OpenSim.Region.Framework.Scenes
3313 cntr++; 3470 cntr++;
3314 } 3471 }
3315 } 3472 }
3316 3473 lockPartsForRead(false);
3474
3317 for (int ctr = 0; ctr < localids.Length; ctr++) 3475 for (int ctr = 0; ctr < localids.Length; ctr++)
3318 { 3476 {
3319 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3477 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3405,19 +3563,20 @@ namespace OpenSim.Region.Framework.Scenes
3405 public float GetMass() 3563 public float GetMass()
3406 { 3564 {
3407 float retmass = 0f; 3565 float retmass = 0f;
3408 lock (m_parts) 3566 lockPartsForRead(true);
3409 { 3567 {
3410 foreach (SceneObjectPart part in m_parts.Values) 3568 foreach (SceneObjectPart part in m_parts.Values)
3411 { 3569 {
3412 retmass += part.GetMass(); 3570 retmass += part.GetMass();
3413 } 3571 }
3414 } 3572 }
3573 lockPartsForRead(false);
3415 return retmass; 3574 return retmass;
3416 } 3575 }
3417 3576
3418 public void CheckSculptAndLoad() 3577 public void CheckSculptAndLoad()
3419 { 3578 {
3420 lock (m_parts) 3579 lockPartsForRead(true);
3421 { 3580 {
3422 if (!IsDeleted) 3581 if (!IsDeleted)
3423 { 3582 {
@@ -3442,6 +3601,7 @@ namespace OpenSim.Region.Framework.Scenes
3442 } 3601 }
3443 } 3602 }
3444 } 3603 }
3604 lockPartsForRead(false);
3445 } 3605 }
3446 3606
3447 protected void AssetReceived(string id, Object sender, AssetBase asset) 3607 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3462,7 +3622,7 @@ namespace OpenSim.Region.Framework.Scenes
3462 /// <param name="client"></param> 3622 /// <param name="client"></param>
3463 public void SetGroup(UUID GroupID, IClientAPI client) 3623 public void SetGroup(UUID GroupID, IClientAPI client)
3464 { 3624 {
3465 lock (m_parts) 3625 lockPartsForRead(true);
3466 { 3626 {
3467 foreach (SceneObjectPart part in m_parts.Values) 3627 foreach (SceneObjectPart part in m_parts.Values)
3468 { 3628 {
@@ -3472,7 +3632,7 @@ namespace OpenSim.Region.Framework.Scenes
3472 3632
3473 HasGroupChanged = true; 3633 HasGroupChanged = true;
3474 } 3634 }
3475 3635 lockPartsForRead(false);
3476 ScheduleGroupForFullUpdate(); 3636 ScheduleGroupForFullUpdate();
3477 } 3637 }
3478 3638
@@ -3491,11 +3651,12 @@ namespace OpenSim.Region.Framework.Scenes
3491 3651
3492 public void SetAttachmentPoint(byte point) 3652 public void SetAttachmentPoint(byte point)
3493 { 3653 {
3494 lock (m_parts) 3654 lockPartsForRead(true);
3495 { 3655 {
3496 foreach (SceneObjectPart part in m_parts.Values) 3656 foreach (SceneObjectPart part in m_parts.Values)
3497 part.SetAttachmentPoint(point); 3657 part.SetAttachmentPoint(point);
3498 } 3658 }
3659 lockPartsForRead(false);
3499 } 3660 }
3500 3661
3501 #region ISceneObject 3662 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index dd797fc..11682d9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -135,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
135 135
136 // TODO: This needs to be persisted in next XML version update! 136 // TODO: This needs to be persisted in next XML version update!
137 [XmlIgnore] 137 [XmlIgnore]
138 public readonly int[] PayPrice = {-2,-2,-2,-2,-2}; 138 public int[] PayPrice = {-2,-2,-2,-2,-2};
139 [XmlIgnore] 139 [XmlIgnore]
140 public PhysicsActor PhysActor; 140 public PhysicsActor PhysActor;
141 141
@@ -250,6 +250,7 @@ namespace OpenSim.Region.Framework.Scenes
250 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 250 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
251 private Vector3 m_sitTargetPosition; 251 private Vector3 m_sitTargetPosition;
252 private string m_sitAnimation = "SIT"; 252 private string m_sitAnimation = "SIT";
253 private bool m_occupied; // KF if any av is sitting on this prim
253 private string m_text = String.Empty; 254 private string m_text = String.Empty;
254 private string m_touchName = String.Empty; 255 private string m_touchName = String.Empty;
255 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 256 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -427,12 +428,16 @@ namespace OpenSim.Region.Framework.Scenes
427 } 428 }
428 429
429 /// <value> 430 /// <value>
430 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 431 /// Get the inventory list
431 /// </value> 432 /// </value>
432 public TaskInventoryDictionary TaskInventory 433 public TaskInventoryDictionary TaskInventory
433 { 434 {
434 get { return m_inventory.Items; } 435 get {
435 set { m_inventory.Items = value; } 436 return m_inventory.Items;
437 }
438 set {
439 m_inventory.Items = value;
440 }
436 } 441 }
437 442
438 public uint ObjectFlags 443 public uint ObjectFlags
@@ -576,7 +581,6 @@ namespace OpenSim.Region.Framework.Scenes
576 StoreUndoState(); 581 StoreUndoState();
577 582
578 m_groupPosition = value; 583 m_groupPosition = value;
579
580 PhysicsActor actor = PhysActor; 584 PhysicsActor actor = PhysActor;
581 if (actor != null) 585 if (actor != null)
582 { 586 {
@@ -889,7 +893,8 @@ namespace OpenSim.Region.Framework.Scenes
889 if (IsAttachment) 893 if (IsAttachment)
890 return GroupPosition; 894 return GroupPosition;
891 895
892 return m_offsetPosition + m_groupPosition; } 896// return m_offsetPosition + m_groupPosition; }
897 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
893 } 898 }
894 899
895 public SceneObjectGroup ParentGroup 900 public SceneObjectGroup ParentGroup
@@ -1041,6 +1046,13 @@ namespace OpenSim.Region.Framework.Scenes
1041 get { return _flags; } 1046 get { return _flags; }
1042 set { _flags = value; } 1047 set { _flags = value; }
1043 } 1048 }
1049
1050 [XmlIgnore]
1051 public bool IsOccupied // KF If an av is sittingon this prim
1052 {
1053 get { return m_occupied; }
1054 set { m_occupied = value; }
1055 }
1044 1056
1045 [XmlIgnore] 1057 [XmlIgnore]
1046 public UUID SitTargetAvatar 1058 public UUID SitTargetAvatar
@@ -1116,14 +1128,6 @@ namespace OpenSim.Region.Framework.Scenes
1116 } 1128 }
1117 } 1129 }
1118 1130
1119 /// <summary>
1120 /// Clear all pending updates of parts to clients
1121 /// </summary>
1122 private void ClearUpdateSchedule()
1123 {
1124 m_updateFlag = 0;
1125 }
1126
1127 private void SendObjectPropertiesToClient(UUID AgentID) 1131 private void SendObjectPropertiesToClient(UUID AgentID)
1128 { 1132 {
1129 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1133 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1802,12 +1806,17 @@ namespace OpenSim.Region.Framework.Scenes
1802 public Vector3 GetWorldPosition() 1806 public Vector3 GetWorldPosition()
1803 { 1807 {
1804 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1808 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1805
1806 Vector3 axPos = OffsetPosition; 1809 Vector3 axPos = OffsetPosition;
1807
1808 axPos *= parentRot; 1810 axPos *= parentRot;
1809 Vector3 translationOffsetPosition = axPos; 1811 Vector3 translationOffsetPosition = axPos;
1810 return GroupPosition + translationOffsetPosition; 1812 if(_parentID == 0)
1813 {
1814 return GroupPosition;
1815 }
1816 else
1817 {
1818 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
1819 }
1811 } 1820 }
1812 1821
1813 /// <summary> 1822 /// <summary>
@@ -1818,7 +1827,7 @@ namespace OpenSim.Region.Framework.Scenes
1818 { 1827 {
1819 Quaternion newRot; 1828 Quaternion newRot;
1820 1829
1821 if (this.LinkNum == 0) 1830 if (this.LinkNum < 2) //KF Single or root prim
1822 { 1831 {
1823 newRot = RotationOffset; 1832 newRot = RotationOffset;
1824 } 1833 }
@@ -2475,17 +2484,18 @@ namespace OpenSim.Region.Framework.Scenes
2475 //Trys to fetch sound id from prim's inventory. 2484 //Trys to fetch sound id from prim's inventory.
2476 //Prim's inventory doesn't support non script items yet 2485 //Prim's inventory doesn't support non script items yet
2477 2486
2478 lock (TaskInventory) 2487 TaskInventory.LockItemsForRead(true);
2488
2489 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2479 { 2490 {
2480 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2491 if (item.Value.Name == sound)
2481 { 2492 {
2482 if (item.Value.Name == sound) 2493 soundID = item.Value.ItemID;
2483 { 2494 break;
2484 soundID = item.Value.ItemID;
2485 break;
2486 }
2487 } 2495 }
2488 } 2496 }
2497
2498 TaskInventory.LockItemsForRead(false);
2489 } 2499 }
2490 2500
2491 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2501 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2762,8 +2772,8 @@ namespace OpenSim.Region.Framework.Scenes
2762 { 2772 {
2763 const float ROTATION_TOLERANCE = 0.01f; 2773 const float ROTATION_TOLERANCE = 0.01f;
2764 const float VELOCITY_TOLERANCE = 0.001f; 2774 const float VELOCITY_TOLERANCE = 0.001f;
2765 const float POSITION_TOLERANCE = 0.05f; 2775 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2766 const int TIME_MS_TOLERANCE = 3000; 2776 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2767 2777
2768 if (m_updateFlag == 1) 2778 if (m_updateFlag == 1)
2769 { 2779 {
@@ -2777,7 +2787,7 @@ namespace OpenSim.Region.Framework.Scenes
2777 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2787 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2778 { 2788 {
2779 AddTerseUpdateToAllAvatars(); 2789 AddTerseUpdateToAllAvatars();
2780 ClearUpdateSchedule(); 2790
2781 2791
2782 // This causes the Scene to 'poll' physical objects every couple of frames 2792 // This causes the Scene to 'poll' physical objects every couple of frames
2783 // bad, so it's been replaced by an event driven method. 2793 // bad, so it's been replaced by an event driven method.
@@ -2795,16 +2805,18 @@ namespace OpenSim.Region.Framework.Scenes
2795 m_lastAngularVelocity = AngularVelocity; 2805 m_lastAngularVelocity = AngularVelocity;
2796 m_lastTerseSent = Environment.TickCount; 2806 m_lastTerseSent = Environment.TickCount;
2797 } 2807 }
2808 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2809 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2798 } 2810 }
2799 else 2811 else
2800 { 2812 {
2801 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2813 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2802 { 2814 {
2803 AddFullUpdateToAllAvatars(); 2815 AddFullUpdateToAllAvatars();
2804 ClearUpdateSchedule(); 2816 m_updateFlag = 0; //Same here
2805 } 2817 }
2806 } 2818 }
2807 ClearUpdateSchedule(); 2819 m_updateFlag = 0;
2808 } 2820 }
2809 2821
2810 /// <summary> 2822 /// <summary>
@@ -2831,17 +2843,16 @@ namespace OpenSim.Region.Framework.Scenes
2831 if (!UUID.TryParse(sound, out soundID)) 2843 if (!UUID.TryParse(sound, out soundID))
2832 { 2844 {
2833 // search sound file from inventory 2845 // search sound file from inventory
2834 lock (TaskInventory) 2846 TaskInventory.LockItemsForRead(true);
2847 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2835 { 2848 {
2836 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2849 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2837 { 2850 {
2838 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2851 soundID = item.Value.ItemID;
2839 { 2852 break;
2840 soundID = item.Value.ItemID;
2841 break;
2842 }
2843 } 2853 }
2844 } 2854 }
2855 TaskInventory.LockItemsForRead(false);
2845 } 2856 }
2846 2857
2847 if (soundID == UUID.Zero) 2858 if (soundID == UUID.Zero)
@@ -2983,6 +2994,22 @@ namespace OpenSim.Region.Framework.Scenes
2983 PhysActor.VehicleRotationParam(param, rotation); 2994 PhysActor.VehicleRotationParam(param, rotation);
2984 } 2995 }
2985 } 2996 }
2997
2998 public void SetVehicleFlags(int flags)
2999 {
3000 if (PhysActor != null)
3001 {
3002 PhysActor.VehicleFlagsSet(flags);
3003 }
3004 }
3005
3006 public void RemoveVehicleFlags(int flags)
3007 {
3008 if (PhysActor != null)
3009 {
3010 PhysActor.VehicleFlagsRemove(flags);
3011 }
3012 }
2986 3013
2987 /// <summary> 3014 /// <summary>
2988 /// Set the color of prim faces 3015 /// Set the color of prim faces
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 298ede9..3317dd3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -82,7 +82,9 @@ namespace OpenSim.Region.Framework.Scenes
82 /// </value> 82 /// </value>
83 protected internal TaskInventoryDictionary Items 83 protected internal TaskInventoryDictionary Items
84 { 84 {
85 get { return m_items; } 85 get {
86 return m_items;
87 }
86 set 88 set
87 { 89 {
88 m_items = value; 90 m_items = value;
@@ -118,22 +120,25 @@ namespace OpenSim.Region.Framework.Scenes
118 /// <param name="linkNum">Link number for the part</param> 120 /// <param name="linkNum">Link number for the part</param>
119 public void ResetInventoryIDs() 121 public void ResetInventoryIDs()
120 { 122 {
121 lock (Items) 123 m_items.LockItemsForWrite(true);
124
125 if (0 == Items.Count)
122 { 126 {
123 if (0 == Items.Count) 127 m_items.LockItemsForWrite(false);
124 return; 128 return;
129 }
125 130
126 HasInventoryChanged = true; 131 HasInventoryChanged = true;
127 m_part.ParentGroup.HasGroupChanged = true; 132 m_part.ParentGroup.HasGroupChanged = true;
128 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 133 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
129 Items.Clear(); 134 Items.Clear();
130 135
131 foreach (TaskInventoryItem item in items) 136 foreach (TaskInventoryItem item in items)
132 { 137 {
133 item.ResetIDs(m_part.UUID); 138 item.ResetIDs(m_part.UUID);
134 Items.Add(item.ItemID, item); 139 Items.Add(item.ItemID, item);
135 }
136 } 140 }
141 m_items.LockItemsForWrite(false);
137 } 142 }
138 143
139 /// <summary> 144 /// <summary>
@@ -142,25 +147,25 @@ namespace OpenSim.Region.Framework.Scenes
142 /// <param name="ownerId"></param> 147 /// <param name="ownerId"></param>
143 public void ChangeInventoryOwner(UUID ownerId) 148 public void ChangeInventoryOwner(UUID ownerId)
144 { 149 {
145 lock (Items) 150 m_items.LockItemsForWrite(true);
151 if (0 == Items.Count)
146 { 152 {
147 if (0 == Items.Count) 153 m_items.LockItemsForWrite(false);
148 { 154 return;
149 return; 155 }
150 }
151 156
152 HasInventoryChanged = true; 157 HasInventoryChanged = true;
153 m_part.ParentGroup.HasGroupChanged = true; 158 m_part.ParentGroup.HasGroupChanged = true;
154 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 159 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
155 foreach (TaskInventoryItem item in items) 160 foreach (TaskInventoryItem item in items)
161 {
162 if (ownerId != item.OwnerID)
156 { 163 {
157 if (ownerId != item.OwnerID) 164 item.LastOwnerID = item.OwnerID;
158 { 165 item.OwnerID = ownerId;
159 item.LastOwnerID = item.OwnerID;
160 item.OwnerID = ownerId;
161 }
162 } 166 }
163 } 167 }
168 m_items.LockItemsForWrite(false);
164 } 169 }
165 170
166 /// <summary> 171 /// <summary>
@@ -169,24 +174,24 @@ namespace OpenSim.Region.Framework.Scenes
169 /// <param name="groupID"></param> 174 /// <param name="groupID"></param>
170 public void ChangeInventoryGroup(UUID groupID) 175 public void ChangeInventoryGroup(UUID groupID)
171 { 176 {
172 lock (Items) 177 m_items.LockItemsForWrite(true);
178 if (0 == Items.Count)
173 { 179 {
174 if (0 == Items.Count) 180 m_items.LockItemsForWrite(false);
175 { 181 return;
176 return; 182 }
177 }
178 183
179 HasInventoryChanged = true; 184 HasInventoryChanged = true;
180 m_part.ParentGroup.HasGroupChanged = true; 185 m_part.ParentGroup.HasGroupChanged = true;
181 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 186 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
182 foreach (TaskInventoryItem item in items) 187 foreach (TaskInventoryItem item in items)
188 {
189 if (groupID != item.GroupID)
183 { 190 {
184 if (groupID != item.GroupID) 191 item.GroupID = groupID;
185 {
186 item.GroupID = groupID;
187 }
188 } 192 }
189 } 193 }
194 m_items.LockItemsForWrite(false);
190 } 195 }
191 196
192 /// <summary> 197 /// <summary>
@@ -194,14 +199,14 @@ namespace OpenSim.Region.Framework.Scenes
194 /// </summary> 199 /// </summary>
195 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 200 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
196 { 201 {
197 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)
198 { 206 {
199 foreach (TaskInventoryItem item in Items.Values) 207 if ((int)InventoryType.LSL == item.InvType)
200 { 208 {
201 if ((int)InventoryType.LSL == item.InvType) 209 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 {
203 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
204 }
205 } 210 }
206 } 211 }
207 } 212 }
@@ -236,16 +241,20 @@ namespace OpenSim.Region.Framework.Scenes
236 /// </param> 241 /// </param>
237 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 242 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
238 { 243 {
239 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)
240 { 249 {
241 foreach (TaskInventoryItem item in Items.Values) 250 if ((int)InventoryType.LSL == item.InvType)
242 { 251 {
243 if ((int)InventoryType.LSL == item.InvType) 252 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
244 { 253 m_part.RemoveScriptEvents(item.ItemID);
245 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
246 }
247 } 254 }
248 } 255 }
256
257
249 } 258 }
250 259
251 /// <summary> 260 /// <summary>
@@ -270,12 +279,10 @@ namespace OpenSim.Region.Framework.Scenes
270 if (stateSource == 1 && // Prim crossing 279 if (stateSource == 1 && // Prim crossing
271 m_part.ParentGroup.Scene.m_trustBinaries) 280 m_part.ParentGroup.Scene.m_trustBinaries)
272 { 281 {
273 lock (m_items) 282 m_items.LockItemsForWrite(true);
274 { 283 m_items[item.ItemID].PermsMask = 0;
275 m_items[item.ItemID].PermsMask = 0; 284 m_items[item.ItemID].PermsGranter = UUID.Zero;
276 m_items[item.ItemID].PermsGranter = UUID.Zero; 285 m_items.LockItemsForWrite(false);
277 }
278
279 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 286 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
280 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 287 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
281 m_part.ParentGroup.AddActiveScriptCount(1); 288 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -283,38 +290,35 @@ namespace OpenSim.Region.Framework.Scenes
283 return; 290 return;
284 } 291 }
285 292
286 m_part.ParentGroup.Scene.AssetService.Get( 293 m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset)
287 item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset) 294 {
288 { 295 if (null == asset)
289 if (null == asset) 296 {
290 { 297 m_log.ErrorFormat(
291 m_log.ErrorFormat( 298 "[PRIM INVENTORY]: " +
292 "[PRIM INVENTORY]: " + 299 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
293 "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,
294 item.Name, item.ItemID, m_part.AbsolutePosition, 301 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
295 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); 302 }
296 } 303 else
297 else 304 {
298 { 305 if (m_part.ParentGroup.m_savedScriptState != null)
299 if (m_part.ParentGroup.m_savedScriptState != null) 306 RestoreSavedScriptState(item.OldItemID, item.ItemID);
300 RestoreSavedScriptState(item.OldItemID, item.ItemID); 307 m_items.LockItemsForWrite(true);
301 308 m_items[item.ItemID].PermsMask = 0;
302 lock (m_items) 309 m_items[item.ItemID].PermsGranter = UUID.Zero;
303 { 310 m_items.LockItemsForWrite(false);
304 m_items[item.ItemID].PermsMask = 0; 311 string script = Utils.BytesToString(asset.Data);
305 m_items[item.ItemID].PermsGranter = UUID.Zero; 312 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
306 } 313 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
307 314 m_part.ParentGroup.AddActiveScriptCount(1);
308 string script = Utils.BytesToString(asset.Data); 315 m_part.ScheduleFullUpdate();
309 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 316 }
310 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 317 });
311 m_part.ParentGroup.AddActiveScriptCount(1);
312 m_part.ScheduleFullUpdate();
313 }
314 }
315 );
316 } 318 }
317 } 319 }
320
321 static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
318 322
319 private void RestoreSavedScriptState(UUID oldID, UUID newID) 323 private void RestoreSavedScriptState(UUID oldID, UUID newID)
320 { 324 {
@@ -379,14 +383,17 @@ namespace OpenSim.Region.Framework.Scenes
379 /// </param> 383 /// </param>
380 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)
381 { 385 {
382 lock (m_items) 386 m_items.LockItemsForRead(true);
387 if (m_items.ContainsKey(itemId))
383 { 388 {
384 if (m_items.ContainsKey(itemId)) 389 if (m_items.ContainsKey(itemId))
385 { 390 {
391 m_items.LockItemsForRead(false);
386 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 392 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
387 } 393 }
388 else 394 else
389 { 395 {
396 m_items.LockItemsForRead(false);
390 m_log.ErrorFormat( 397 m_log.ErrorFormat(
391 "[PRIM INVENTORY]: " + 398 "[PRIM INVENTORY]: " +
392 "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}",
@@ -394,6 +401,15 @@ namespace OpenSim.Region.Framework.Scenes
394 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 401 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
395 } 402 }
396 } 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
397 } 413 }
398 414
399 /// <summary> 415 /// <summary>
@@ -406,15 +422,7 @@ namespace OpenSim.Region.Framework.Scenes
406 /// </param> 422 /// </param>
407 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 423 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
408 { 424 {
409 bool scriptPresent = false; 425 if (m_items.ContainsKey(itemId))
410
411 lock (m_items)
412 {
413 if (m_items.ContainsKey(itemId))
414 scriptPresent = true;
415 }
416
417 if (scriptPresent)
418 { 426 {
419 if (!sceneObjectBeingDeleted) 427 if (!sceneObjectBeingDeleted)
420 m_part.RemoveScriptEvents(itemId); 428 m_part.RemoveScriptEvents(itemId);
@@ -440,11 +448,16 @@ namespace OpenSim.Region.Framework.Scenes
440 /// <returns></returns> 448 /// <returns></returns>
441 private bool InventoryContainsName(string name) 449 private bool InventoryContainsName(string name)
442 { 450 {
443 foreach (TaskInventoryItem item in Items.Values) 451 m_items.LockItemsForRead(true);
452 foreach (TaskInventoryItem item in m_items.Values)
444 { 453 {
445 if (item.Name == name) 454 if (item.Name == name)
455 {
456 m_items.LockItemsForRead(false);
446 return true; 457 return true;
458 }
447 } 459 }
460 m_items.LockItemsForRead(false);
448 return false; 461 return false;
449 } 462 }
450 463
@@ -486,13 +499,9 @@ namespace OpenSim.Region.Framework.Scenes
486 /// <param name="item"></param> 499 /// <param name="item"></param>
487 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 500 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
488 { 501 {
489 List<TaskInventoryItem> il; 502 m_items.LockItemsForRead(true);
490 503 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
491 lock (m_items) 504 m_items.LockItemsForRead(false);
492 {
493 il = new List<TaskInventoryItem>(m_items.Values);
494 }
495
496 foreach (TaskInventoryItem i in il) 505 foreach (TaskInventoryItem i in il)
497 { 506 {
498 if (i.Name == item.Name) 507 if (i.Name == item.Name)
@@ -529,15 +538,14 @@ namespace OpenSim.Region.Framework.Scenes
529 item.ParentPartID = m_part.UUID; 538 item.ParentPartID = m_part.UUID;
530 item.Name = name; 539 item.Name = name;
531 540
532 lock (m_items) 541 m_items.LockItemsForWrite(true);
533 { 542 m_items.Add(item.ItemID, item);
534 m_items.Add(item.ItemID, item); 543 m_items.LockItemsForWrite(false);
535
536 if (allowedDrop) 544 if (allowedDrop)
537 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 545 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
538 else 546 else
539 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 547 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
540 } 548
541 549
542 m_inventorySerial++; 550 m_inventorySerial++;
543 //m_inventorySerial += 2; 551 //m_inventorySerial += 2;
@@ -554,14 +562,13 @@ namespace OpenSim.Region.Framework.Scenes
554 /// <param name="items"></param> 562 /// <param name="items"></param>
555 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 563 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
556 { 564 {
557 lock (m_items) 565 m_items.LockItemsForWrite(true);
566 foreach (TaskInventoryItem item in items)
558 { 567 {
559 foreach (TaskInventoryItem item in items) 568 m_items.Add(item.ItemID, item);
560 { 569 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
561 m_items.Add(item.ItemID, item);
562 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
563 }
564 } 570 }
571 m_items.LockItemsForWrite(false);
565 572
566 m_inventorySerial++; 573 m_inventorySerial++;
567 } 574 }
@@ -574,10 +581,9 @@ namespace OpenSim.Region.Framework.Scenes
574 public TaskInventoryItem GetInventoryItem(UUID itemId) 581 public TaskInventoryItem GetInventoryItem(UUID itemId)
575 { 582 {
576 TaskInventoryItem item; 583 TaskInventoryItem item;
577 584 m_items.LockItemsForRead(true);
578 lock (m_items) 585 m_items.TryGetValue(itemId, out item);
579 m_items.TryGetValue(itemId, out item); 586 m_items.LockItemsForRead(false);
580
581 return item; 587 return item;
582 } 588 }
583 589
@@ -613,46 +619,46 @@ namespace OpenSim.Region.Framework.Scenes
613 /// <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>
614 public bool UpdateInventoryItem(TaskInventoryItem item) 620 public bool UpdateInventoryItem(TaskInventoryItem item)
615 { 621 {
616 lock (m_items) 622 m_items.LockItemsForWrite(true);
623
624 if (m_items.ContainsKey(item.ItemID))
617 { 625 {
618 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)
619 { 630 {
620 item.ParentID = m_part.UUID; 631 item.AssetID = m_items[item.ItemID].AssetID;
621 item.ParentPartID = m_part.UUID; 632 }
622 item.Flags = m_items[item.ItemID].Flags; 633 else if ((InventoryType)item.Type == InventoryType.Notecard)
623 if (item.AssetID == UUID.Zero) 634 {
624 { 635 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
625 item.AssetID = m_items[item.ItemID].AssetID;
626 }
627 else if ((InventoryType)item.Type == InventoryType.Notecard)
628 {
629 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
630 636
631 if (presence != null) 637 if (presence != null)
632 { 638 {
633 presence.ControllingClient.SendAgentAlertMessage( 639 presence.ControllingClient.SendAgentAlertMessage(
634 "Notecard saved", false); 640 "Notecard saved", false);
635 }
636 } 641 }
642 }
637 643
638 m_items[item.ItemID] = item; 644 m_items[item.ItemID] = item;
639 m_inventorySerial++; 645 m_inventorySerial++;
640 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 646 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
641
642 HasInventoryChanged = true;
643 m_part.ParentGroup.HasGroupChanged = true;
644 647
645 return true; 648 HasInventoryChanged = true;
646 } 649 m_part.ParentGroup.HasGroupChanged = true;
647 else 650 m_items.LockItemsForWrite(false);
648 { 651 return true;
649 m_log.ErrorFormat( 652 }
650 "[PRIM INVENTORY]: " + 653 else
651 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 654 {
652 item.ItemID, m_part.Name, m_part.UUID, 655 m_log.ErrorFormat(
653 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 656 "[PRIM INVENTORY]: " +
654 } 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);
655 } 660 }
661 m_items.LockItemsForWrite(false);
656 662
657 return false; 663 return false;
658 } 664 }
@@ -665,53 +671,54 @@ namespace OpenSim.Region.Framework.Scenes
665 /// in this prim's inventory.</returns> 671 /// in this prim's inventory.</returns>
666 public int RemoveInventoryItem(UUID itemID) 672 public int RemoveInventoryItem(UUID itemID)
667 { 673 {
668 lock (m_items) 674 m_items.LockItemsForRead(true);
675
676 if (m_items.ContainsKey(itemID))
669 { 677 {
670 if (m_items.ContainsKey(itemID)) 678 int type = m_items[itemID].InvType;
679 m_items.LockItemsForRead(false);
680 if (type == 10) // Script
671 { 681 {
672 int type = m_items[itemID].InvType; 682 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
673 if (type == 10) // Script 683 }
674 { 684 m_items.LockItemsForWrite(true);
675 m_part.RemoveScriptEvents(itemID); 685 m_items.Remove(itemID);
676 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 686 m_items.LockItemsForWrite(false);
677 } 687 m_inventorySerial++;
678 m_items.Remove(itemID); 688 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
679 m_inventorySerial++;
680 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
681
682 HasInventoryChanged = true;
683 m_part.ParentGroup.HasGroupChanged = true;
684 689
685 int scriptcount = 0; 690 HasInventoryChanged = true;
686 lock (m_items) 691 m_part.ParentGroup.HasGroupChanged = true;
687 {
688 foreach (TaskInventoryItem item in m_items.Values)
689 {
690 if (item.Type == 10)
691 {
692 scriptcount++;
693 }
694 }
695 }
696 692
697 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)
698 { 698 {
699 m_part.RemFlag(PrimFlags.Scripted); 699 scriptcount++;
700 } 700 }
701
702 m_part.ScheduleFullUpdate();
703
704 return type;
705 } 701 }
706 else 702 m_items.LockItemsForRead(false);
703
704
705 if (scriptcount <= 0)
707 { 706 {
708 m_log.ErrorFormat( 707 m_part.RemFlag(PrimFlags.Scripted);
709 "[PRIM INVENTORY]: " +
710 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
711 itemID, m_part.Name, m_part.UUID,
712 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
713 } 708 }
709
710 m_part.ScheduleFullUpdate();
711
712 return type;
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);
714 } 720 }
721 m_items.LockItemsForWrite(false);
715 722
716 return -1; 723 return -1;
717 } 724 }
@@ -764,52 +771,53 @@ namespace OpenSim.Region.Framework.Scenes
764 // 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)
765 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 772 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
766 773
767 lock (m_items) 774 m_items.LockItemsForRead(true);
775
776 foreach (TaskInventoryItem item in m_items.Values)
768 { 777 {
769 foreach (TaskInventoryItem item in m_items.Values) 778 UUID ownerID = item.OwnerID;
770 { 779 uint everyoneMask = 0;
771 UUID ownerID = item.OwnerID; 780 uint baseMask = item.BasePermissions;
772 uint everyoneMask = 0; 781 uint ownerMask = item.CurrentPermissions;
773 uint baseMask = item.BasePermissions;
774 uint ownerMask = item.CurrentPermissions;
775 782
776 invString.AddItemStart(); 783 invString.AddItemStart();
777 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 784 invString.AddNameValueLine("item_id", item.ItemID.ToString());
778 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 785 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
779 786
780 invString.AddPermissionsStart(); 787 invString.AddPermissionsStart();
781 788
782 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 789 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
783 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 790 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
784 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 791 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
785 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 792 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
786 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 793 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
787 794
788 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 795 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
789 invString.AddNameValueLine("owner_id", ownerID.ToString()); 796 invString.AddNameValueLine("owner_id", ownerID.ToString());
790 797
791 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 798 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
792 799
793 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 800 invString.AddNameValueLine("group_id", item.GroupID.ToString());
794 invString.AddSectionEnd(); 801 invString.AddSectionEnd();
795 802
796 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 803 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
797 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 804 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
798 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 805 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
799 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 806 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
800 807
801 invString.AddSaleStart(); 808 invString.AddSaleStart();
802 invString.AddNameValueLine("sale_type", "not"); 809 invString.AddNameValueLine("sale_type", "not");
803 invString.AddNameValueLine("sale_price", "0"); 810 invString.AddNameValueLine("sale_price", "0");
804 invString.AddSectionEnd(); 811 invString.AddSectionEnd();
805 812
806 invString.AddNameValueLine("name", item.Name + "|"); 813 invString.AddNameValueLine("name", item.Name + "|");
807 invString.AddNameValueLine("desc", item.Description + "|"); 814 invString.AddNameValueLine("desc", item.Description + "|");
808 815
809 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 816 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
810 invString.AddSectionEnd(); 817 invString.AddSectionEnd();
811 }
812 } 818 }
819 int count = m_items.Count;
820 m_items.LockItemsForRead(false);
813 821
814 fileData = Utils.StringToBytes(invString.BuildString); 822 fileData = Utils.StringToBytes(invString.BuildString);
815 823
@@ -830,10 +838,9 @@ namespace OpenSim.Region.Framework.Scenes
830 { 838 {
831 if (HasInventoryChanged) 839 if (HasInventoryChanged)
832 { 840 {
833 lock (Items) 841 Items.LockItemsForRead(true);
834 { 842 datastore.StorePrimInventory(m_part.UUID, Items.Values);
835 datastore.StorePrimInventory(m_part.UUID, Items.Values); 843 Items.LockItemsForRead(false);
836 }
837 844
838 HasInventoryChanged = false; 845 HasInventoryChanged = false;
839 } 846 }
@@ -902,61 +909,54 @@ namespace OpenSim.Region.Framework.Scenes
902 { 909 {
903 uint mask=0x7fffffff; 910 uint mask=0x7fffffff;
904 911
905 lock (m_items) 912 foreach (TaskInventoryItem item in m_items.Values)
906 { 913 {
907 foreach (TaskInventoryItem item in m_items.Values) 914 if (item.InvType != (int)InventoryType.Object)
908 { 915 {
909 if (item.InvType != (int)InventoryType.Object) 916 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
910 { 917 mask &= ~((uint)PermissionMask.Copy >> 13);
911 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 918 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
912 mask &= ~((uint)PermissionMask.Copy >> 13); 919 mask &= ~((uint)PermissionMask.Transfer >> 13);
913 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 920 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
914 mask &= ~((uint)PermissionMask.Transfer >> 13); 921 mask &= ~((uint)PermissionMask.Modify >> 13);
915 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 922 }
916 mask &= ~((uint)PermissionMask.Modify >> 13); 923 else
917 } 924 {
918 else 925 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
919 { 926 mask &= ~((uint)PermissionMask.Copy >> 13);
920 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 927 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
921 mask &= ~((uint)PermissionMask.Copy >> 13); 928 mask &= ~((uint)PermissionMask.Transfer >> 13);
922 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 929 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
923 mask &= ~((uint)PermissionMask.Transfer >> 13); 930 mask &= ~((uint)PermissionMask.Modify >> 13);
924 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
925 mask &= ~((uint)PermissionMask.Modify >> 13);
926 }
927
928 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
929 mask &= ~(uint)PermissionMask.Copy;
930 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
931 mask &= ~(uint)PermissionMask.Transfer;
932 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
933 mask &= ~(uint)PermissionMask.Modify;
934 } 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;
935 } 939 }
936
937 return mask; 940 return mask;
938 } 941 }
939 942
940 public void ApplyNextOwnerPermissions() 943 public void ApplyNextOwnerPermissions()
941 { 944 {
942 lock (m_items) 945 foreach (TaskInventoryItem item in m_items.Values)
943 { 946 {
944 foreach (TaskInventoryItem item in m_items.Values) 947 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
945 { 948 {
946 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 949 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
947 { 950 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
948 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 951 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
949 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 952 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
950 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 953 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
951 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 954 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
952 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 955 item.CurrentPermissions |= 8;
953 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
954 item.CurrentPermissions |= 8;
955 }
956 item.CurrentPermissions &= item.NextPermissions;
957 item.BasePermissions &= item.NextPermissions;
958 item.EveryonePermissions &= item.NextPermissions;
959 } 956 }
957 item.CurrentPermissions &= item.NextPermissions;
958 item.BasePermissions &= item.NextPermissions;
959 item.EveryonePermissions &= item.NextPermissions;
960 } 960 }
961 961
962 m_part.TriggerScriptChangedEvent(Changed.OWNER); 962 m_part.TriggerScriptChangedEvent(Changed.OWNER);
@@ -964,29 +964,22 @@ namespace OpenSim.Region.Framework.Scenes
964 964
965 public void ApplyGodPermissions(uint perms) 965 public void ApplyGodPermissions(uint perms)
966 { 966 {
967 lock (m_items) 967 foreach (TaskInventoryItem item in m_items.Values)
968 { 968 {
969 foreach (TaskInventoryItem item in m_items.Values) 969 item.CurrentPermissions = perms;
970 { 970 item.BasePermissions = perms;
971 item.CurrentPermissions = perms;
972 item.BasePermissions = perms;
973 }
974 } 971 }
975 } 972 }
976 973
977 public bool ContainsScripts() 974 public bool ContainsScripts()
978 { 975 {
979 lock (m_items) 976 foreach (TaskInventoryItem item in m_items.Values)
980 { 977 {
981 foreach (TaskInventoryItem item in m_items.Values) 978 if (item.InvType == (int)InventoryType.LSL)
982 { 979 {
983 if (item.InvType == (int)InventoryType.LSL) 980 return true;
984 {
985 return true;
986 }
987 } 981 }
988 } 982 }
989
990 return false; 983 return false;
991 } 984 }
992 985
@@ -994,11 +987,8 @@ namespace OpenSim.Region.Framework.Scenes
994 { 987 {
995 List<UUID> ret = new List<UUID>(); 988 List<UUID> ret = new List<UUID>();
996 989
997 lock (m_items) 990 foreach (TaskInventoryItem item in m_items.Values)
998 { 991 ret.Add(item.ItemID);
999 foreach (TaskInventoryItem item in m_items.Values)
1000 ret.Add(item.ItemID);
1001 }
1002 992
1003 return ret; 993 return ret;
1004 } 994 }
@@ -1011,30 +1001,26 @@ namespace OpenSim.Region.Framework.Scenes
1011 if (engines == null) // No engine at all 1001 if (engines == null) // No engine at all
1012 return ret; 1002 return ret;
1013 1003
1014 lock (m_items) 1004 foreach (TaskInventoryItem item in m_items.Values)
1015 { 1005 {
1016 foreach (TaskInventoryItem item in m_items.Values) 1006 if (item.InvType == (int)InventoryType.LSL)
1017 { 1007 {
1018 if (item.InvType == (int)InventoryType.LSL) 1008 foreach (IScriptModule e in engines)
1019 { 1009 {
1020 foreach (IScriptModule e in engines) 1010 if (e != null)
1021 { 1011 {
1022 if (e != null) 1012 string n = e.GetXMLState(item.ItemID);
1013 if (n != String.Empty)
1023 { 1014 {
1024 string n = e.GetXMLState(item.ItemID); 1015 if (!ret.ContainsKey(item.ItemID))
1025 if (n != String.Empty) 1016 ret[item.ItemID] = n;
1026 { 1017 break;
1027 if (!ret.ContainsKey(item.ItemID))
1028 ret[item.ItemID] = n;
1029 break;
1030 }
1031 } 1018 }
1032 } 1019 }
1033 } 1020 }
1034 } 1021 }
1035 } 1022 }
1036
1037 return ret; 1023 return ret;
1038 } 1024 }
1039 } 1025 }
1040} \ No newline at end of file 1026}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6b95624..1b7ca8b 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
@@ -123,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
126 128
127 private Vector3 m_lastPosition; 129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -134,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes
134 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
135 private uint m_requestedSitTargetID; 140 private uint m_requestedSitTargetID;
136 private UUID m_requestedSitTargetUUID; 141 private UUID m_requestedSitTargetUUID;
137 public bool SitGround = false;
138 142
139 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 143 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
140 144
@@ -156,7 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
156 private int m_perfMonMS; 160 private int m_perfMonMS;
157 161
158 private bool m_setAlwaysRun; 162 private bool m_setAlwaysRun;
159
160 private bool m_forceFly; 163 private bool m_forceFly;
161 private bool m_flyDisabled; 164 private bool m_flyDisabled;
162 165
@@ -180,7 +183,8 @@ namespace OpenSim.Region.Framework.Scenes
180 protected RegionInfo m_regionInfo; 183 protected RegionInfo m_regionInfo;
181 protected ulong crossingFromRegion; 184 protected ulong crossingFromRegion;
182 185
183 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 186 private readonly Vector3[] Dir_Vectors = new Vector3[11];
187 private bool m_isNudging = false;
184 188
185 // Position of agent's camera in world (region cordinates) 189 // Position of agent's camera in world (region cordinates)
186 protected Vector3 m_CameraCenter; 190 protected Vector3 m_CameraCenter;
@@ -205,6 +209,7 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_autopilotMoving; 209 private bool m_autopilotMoving;
206 private Vector3 m_autoPilotTarget; 210 private Vector3 m_autoPilotTarget;
207 private bool m_sitAtAutoTarget; 211 private bool m_sitAtAutoTarget;
212 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
208 213
209 private string m_nextSitAnimation = String.Empty; 214 private string m_nextSitAnimation = String.Empty;
210 215
@@ -215,6 +220,9 @@ namespace OpenSim.Region.Framework.Scenes
215 private bool m_followCamAuto; 220 private bool m_followCamAuto;
216 221
217 private int m_movementUpdateCount; 222 private int m_movementUpdateCount;
223 private int m_lastColCount = -1; //KF: Look for Collision chnages
224 private int m_updateCount = 0; //KF: Update Anims for a while
225 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
218 226
219 private const int NumMovementsBetweenRayCast = 5; 227 private const int NumMovementsBetweenRayCast = 5;
220 228
@@ -243,7 +251,9 @@ namespace OpenSim.Region.Framework.Scenes
243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 251 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 252 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 253 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
246 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 254 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
255 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
256 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
247 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 257 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
248 } 258 }
249 259
@@ -672,10 +682,7 @@ namespace OpenSim.Region.Framework.Scenes
672 m_reprioritization_timer.AutoReset = false; 682 m_reprioritization_timer.AutoReset = false;
673 683
674 AdjustKnownSeeds(); 684 AdjustKnownSeeds();
675
676 // TODO: I think, this won't send anything, as we are still a child here...
677 Animator.TrySetMovementAnimation("STAND"); 685 Animator.TrySetMovementAnimation("STAND");
678
679 // we created a new ScenePresence (a new child agent) in a fresh region. 686 // we created a new ScenePresence (a new child agent) in a fresh region.
680 // Request info about all the (root) agents in this region 687 // Request info about all the (root) agents in this region
681 // Note: This won't send data *to* other clients in that region (children don't send) 688 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -731,25 +738,47 @@ namespace OpenSim.Region.Framework.Scenes
731 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 738 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
732 Dir_Vectors[4] = Vector3.UnitZ; //UP 739 Dir_Vectors[4] = Vector3.UnitZ; //UP
733 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 740 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
734 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 741 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
735 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 742 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
736 Dir_Vectors[7] = -Vector3.UnitX; //BACK 743 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
744 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
745 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
737 } 746 }
738 747
739 private Vector3[] GetWalkDirectionVectors() 748 private Vector3[] GetWalkDirectionVectors()
740 { 749 {
741 Vector3[] vector = new Vector3[9]; 750 Vector3[] vector = new Vector3[11];
742 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 751 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
743 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 752 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
744 vector[2] = Vector3.UnitY; //LEFT 753 vector[2] = Vector3.UnitY; //LEFT
745 vector[3] = -Vector3.UnitY; //RIGHT 754 vector[3] = -Vector3.UnitY; //RIGHT
746 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 755 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
747 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 756 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
748 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 757 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
749 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 758 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
750 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 759 vector[8] = Vector3.UnitY; //LEFT_NUDGE
760 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
761 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
751 return vector; 762 return vector;
752 } 763 }
764
765 private bool[] GetDirectionIsNudge()
766 {
767 bool[] isNudge = new bool[11];
768 isNudge[0] = false; //FORWARD
769 isNudge[1] = false; //BACK
770 isNudge[2] = false; //LEFT
771 isNudge[3] = false; //RIGHT
772 isNudge[4] = false; //UP
773 isNudge[5] = false; //DOWN
774 isNudge[6] = true; //FORWARD_NUDGE
775 isNudge[7] = true; //BACK_NUDGE
776 isNudge[8] = true; //LEFT_NUDGE
777 isNudge[9] = true; //RIGHT_NUDGE
778 isNudge[10] = true; //DOWN_Nudge
779 return isNudge;
780 }
781
753 782
754 #endregion 783 #endregion
755 784
@@ -818,9 +847,24 @@ namespace OpenSim.Region.Framework.Scenes
818 { 847 {
819 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 848 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
820 pos.Y = crossedBorder.BorderLine.Z - 1; 849 pos.Y = crossedBorder.BorderLine.Z - 1;
850 }
851
852 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
853 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
854 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
855 if (KnownChildRegionHandles.Count == 0)
856 {
857 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
858 if (land != null)
859 {
860 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
861 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)
862 {
863 pos = land.LandData.UserLocation;
864 }
865 }
821 } 866 }
822 867
823
824 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 868 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
825 { 869 {
826 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 870 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -955,9 +999,10 @@ namespace OpenSim.Region.Framework.Scenes
955 public void Teleport(Vector3 pos) 999 public void Teleport(Vector3 pos)
956 { 1000 {
957 bool isFlying = false; 1001 bool isFlying = false;
958 if (m_physicsActor != null)
959 isFlying = m_physicsActor.Flying;
960 1002
1003 if (m_physicsActor != null)
1004 isFlying = m_physicsActor.Flying;
1005
961 RemoveFromPhysicalScene(); 1006 RemoveFromPhysicalScene();
962 Velocity = Vector3.Zero; 1007 Velocity = Vector3.Zero;
963 AbsolutePosition = pos; 1008 AbsolutePosition = pos;
@@ -968,7 +1013,8 @@ namespace OpenSim.Region.Framework.Scenes
968 SetHeight(m_appearance.AvatarHeight); 1013 SetHeight(m_appearance.AvatarHeight);
969 } 1014 }
970 1015
971 SendTerseUpdateToAllClients(); 1016 SendTerseUpdateToAllClients();
1017
972 } 1018 }
973 1019
974 public void TeleportWithMomentum(Vector3 pos) 1020 public void TeleportWithMomentum(Vector3 pos)
@@ -1013,7 +1059,9 @@ namespace OpenSim.Region.Framework.Scenes
1013 { 1059 {
1014 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1060 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1015 } 1061 }
1016 1062
1063 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1064
1017 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1065 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1018 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1066 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1019 } 1067 }
@@ -1247,7 +1295,6 @@ namespace OpenSim.Region.Framework.Scenes
1247 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1295 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1248 } 1296 }
1249 } 1297 }
1250
1251 lock (scriptedcontrols) 1298 lock (scriptedcontrols)
1252 { 1299 {
1253 if (scriptedcontrols.Count > 0) 1300 if (scriptedcontrols.Count > 0)
@@ -1262,12 +1309,8 @@ namespace OpenSim.Region.Framework.Scenes
1262 1309
1263 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1310 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1264 { 1311 {
1265 // TODO: This doesn't prevent the user from walking yet. 1312 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1266 // Setting parent ID would fix this, if we knew what value 1313 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1267 // to use. Or we could add a m_isSitting variable.
1268 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1269 SitGround = true;
1270
1271 } 1314 }
1272 1315
1273 // In the future, these values might need to go global. 1316 // In the future, these values might need to go global.
@@ -1317,6 +1360,11 @@ namespace OpenSim.Region.Framework.Scenes
1317 update_rotation = true; 1360 update_rotation = true;
1318 } 1361 }
1319 1362
1363 //guilty until proven innocent..
1364 bool Nudging = true;
1365 //Basically, if there is at least one non-nudge control then we don't need
1366 //to worry about stopping the avatar
1367
1320 if (m_parentID == 0) 1368 if (m_parentID == 0)
1321 { 1369 {
1322 bool bAllowUpdateMoveToPosition = false; 1370 bool bAllowUpdateMoveToPosition = false;
@@ -1331,9 +1379,12 @@ namespace OpenSim.Region.Framework.Scenes
1331 else 1379 else
1332 dirVectors = Dir_Vectors; 1380 dirVectors = Dir_Vectors;
1333 1381
1334 // The fact that m_movementflag is a byte needs to be fixed 1382 bool[] isNudge = GetDirectionIsNudge();
1335 // it really should be a uint 1383
1336 uint nudgehack = 250; 1384
1385
1386
1387
1337 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1388 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1338 { 1389 {
1339 if (((uint)flags & (uint)DCF) != 0) 1390 if (((uint)flags & (uint)DCF) != 0)
@@ -1343,40 +1394,28 @@ namespace OpenSim.Region.Framework.Scenes
1343 try 1394 try
1344 { 1395 {
1345 agent_control_v3 += dirVectors[i]; 1396 agent_control_v3 += dirVectors[i];
1346 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1397 if (isNudge[i] == false)
1398 {
1399 Nudging = false;
1400 }
1347 } 1401 }
1348 catch (IndexOutOfRangeException) 1402 catch (IndexOutOfRangeException)
1349 { 1403 {
1350 // Why did I get this? 1404 // Why did I get this?
1351 } 1405 }
1352 1406
1353 if ((m_movementflag & (byte)(uint)DCF) == 0) 1407 if ((m_movementflag & (uint)DCF) == 0)
1354 { 1408 {
1355 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1356 {
1357 m_movementflag |= (byte)nudgehack;
1358 }
1359 m_movementflag += (byte)(uint)DCF; 1409 m_movementflag += (byte)(uint)DCF;
1360 update_movementflag = true; 1410 update_movementflag = true;
1361 } 1411 }
1362 } 1412 }
1363 else 1413 else
1364 { 1414 {
1365 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1415 if ((m_movementflag & (uint)DCF) != 0)
1366 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1367 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1368 ) // This or is for Nudge forward
1369 { 1416 {
1370 m_movementflag -= ((byte)(uint)DCF); 1417 m_movementflag -= (byte)(uint)DCF;
1371
1372 update_movementflag = true; 1418 update_movementflag = true;
1373 /*
1374 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1375 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1376 {
1377 m_log.Debug("Removed Hack flag");
1378 }
1379 */
1380 } 1419 }
1381 else 1420 else
1382 { 1421 {
@@ -1420,6 +1459,9 @@ namespace OpenSim.Region.Framework.Scenes
1420 // Ignore z component of vector 1459 // Ignore z component of vector
1421 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1460 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1422 LocalVectorToTarget2D.Normalize(); 1461 LocalVectorToTarget2D.Normalize();
1462
1463 //We're not nudging
1464 Nudging = false;
1423 agent_control_v3 += LocalVectorToTarget2D; 1465 agent_control_v3 += LocalVectorToTarget2D;
1424 1466
1425 // update avatar movement flags. the avatar coordinate system is as follows: 1467 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1508,13 +1550,13 @@ namespace OpenSim.Region.Framework.Scenes
1508 // m_log.DebugFormat( 1550 // m_log.DebugFormat(
1509 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1551 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1510 1552
1511 AddNewMovement(agent_control_v3, q); 1553 AddNewMovement(agent_control_v3, q, Nudging);
1512 1554
1513 1555
1514 } 1556 }
1515 } 1557 }
1516 1558
1517 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1559 if (update_movementflag)
1518 Animator.UpdateMovementAnimations(); 1560 Animator.UpdateMovementAnimations();
1519 1561
1520 m_scene.EventManager.TriggerOnClientMovement(this); 1562 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1529,7 +1571,6 @@ namespace OpenSim.Region.Framework.Scenes
1529 m_sitAtAutoTarget = false; 1571 m_sitAtAutoTarget = false;
1530 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1572 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1531 //proxy.PCode = (byte)PCode.ParticleSystem; 1573 //proxy.PCode = (byte)PCode.ParticleSystem;
1532
1533 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1574 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1534 proxyObjectGroup.AttachToScene(m_scene); 1575 proxyObjectGroup.AttachToScene(m_scene);
1535 1576
@@ -1571,7 +1612,7 @@ namespace OpenSim.Region.Framework.Scenes
1571 } 1612 }
1572 m_moveToPositionInProgress = true; 1613 m_moveToPositionInProgress = true;
1573 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1614 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1574 } 1615 }
1575 catch (Exception ex) 1616 catch (Exception ex)
1576 { 1617 {
1577 //Why did I get this error? 1618 //Why did I get this error?
@@ -1593,7 +1634,7 @@ namespace OpenSim.Region.Framework.Scenes
1593 Velocity = Vector3.Zero; 1634 Velocity = Vector3.Zero;
1594 SendFullUpdateToAllClients(); 1635 SendFullUpdateToAllClients();
1595 1636
1596 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1637 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1597 } 1638 }
1598 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1639 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1599 m_requestedSitTargetUUID = UUID.Zero; 1640 m_requestedSitTargetUUID = UUID.Zero;
@@ -1626,55 +1667,84 @@ namespace OpenSim.Region.Framework.Scenes
1626 /// </summary> 1667 /// </summary>
1627 public void StandUp() 1668 public void StandUp()
1628 { 1669 {
1629 if (SitGround)
1630 SitGround = false;
1631
1632 if (m_parentID != 0) 1670 if (m_parentID != 0)
1633 { 1671 {
1634 m_log.Debug("StandupCode Executed");
1635 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1672 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1636 if (part != null) 1673 if (part != null)
1637 { 1674 {
1675 part.TaskInventory.LockItemsForRead(true);
1638 TaskInventoryDictionary taskIDict = part.TaskInventory; 1676 TaskInventoryDictionary taskIDict = part.TaskInventory;
1639 if (taskIDict != null) 1677 if (taskIDict != null)
1640 { 1678 {
1641 lock (taskIDict) 1679 foreach (UUID taskID in taskIDict.Keys)
1642 { 1680 {
1643 foreach (UUID taskID in taskIDict.Keys) 1681 UnRegisterControlEventsToScript(LocalId, taskID);
1644 { 1682 taskIDict[taskID].PermsMask &= ~(
1645 UnRegisterControlEventsToScript(LocalId, taskID); 1683 2048 | //PERMISSION_CONTROL_CAMERA
1646 taskIDict[taskID].PermsMask &= ~( 1684 4); // PERMISSION_TAKE_CONTROLS
1647 2048 | //PERMISSION_CONTROL_CAMERA
1648 4); // PERMISSION_TAKE_CONTROLS
1649 }
1650 } 1685 }
1651
1652 } 1686 }
1687 part.TaskInventory.LockItemsForRead(false);
1653 // Reset sit target. 1688 // Reset sit target.
1654 if (part.GetAvatarOnSitTarget() == UUID) 1689 if (part.GetAvatarOnSitTarget() == UUID)
1655 part.SetAvatarOnSitTarget(UUID.Zero); 1690 part.SetAvatarOnSitTarget(UUID.Zero);
1656
1657 m_parentPosition = part.GetWorldPosition(); 1691 m_parentPosition = part.GetWorldPosition();
1658 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1692 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1659 } 1693 }
1660 1694 // part.GetWorldRotation() is the rotation of the object being sat on
1661 if (m_physicsActor == null) 1695 // Rotation is the sittiing Av's rotation
1662 { 1696
1663 AddToPhysicalScene(false); 1697 Quaternion partRot;
1698// if (part.LinkNum == 1)
1699// { // Root prim of linkset
1700// partRot = part.ParentGroup.RootPart.RotationOffset;
1701// }
1702// else
1703// { // single or child prim
1704
1705// }
1706 if (part == null) //CW: Part may be gone. llDie() for example.
1707 {
1708 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1709 }
1710 else
1711 {
1712 partRot = part.GetWorldRotation();
1713 }
1714
1715 Quaternion partIRot = Quaternion.Inverse(partRot);
1716
1717 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1718 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1719
1720
1721 if (m_physicsActor == null)
1722 {
1723 AddToPhysicalScene(false);
1724 }
1725 //CW: If the part isn't null then we can set the current position
1726 if (part != null)
1727 {
1728 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1729 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1730 part.IsOccupied = false;
1731 }
1732 else
1733 {
1734 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1735 AbsolutePosition = m_lastWorldPosition;
1664 } 1736 }
1665 1737
1666 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1738 m_parentPosition = Vector3.Zero;
1667 m_parentPosition = Vector3.Zero; 1739 m_parentID = 0;
1668
1669 m_parentID = 0;
1670 SendFullUpdateToAllClients(); 1740 SendFullUpdateToAllClients();
1671 m_requestedSitTargetID = 0; 1741 m_requestedSitTargetID = 0;
1742
1672 if ((m_physicsActor != null) && (m_avHeight > 0)) 1743 if ((m_physicsActor != null) && (m_avHeight > 0))
1673 { 1744 {
1674 SetHeight(m_avHeight); 1745 SetHeight(m_avHeight);
1675 } 1746 }
1676 } 1747 }
1677
1678 Animator.TrySetMovementAnimation("STAND"); 1748 Animator.TrySetMovementAnimation("STAND");
1679 } 1749 }
1680 1750
@@ -1705,13 +1775,9 @@ namespace OpenSim.Region.Framework.Scenes
1705 Vector3 avSitOffSet = part.SitTargetPosition; 1775 Vector3 avSitOffSet = part.SitTargetPosition;
1706 Quaternion avSitOrientation = part.SitTargetOrientation; 1776 Quaternion avSitOrientation = part.SitTargetOrientation;
1707 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1777 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1708 1778 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1709 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1779 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1710 bool SitTargetisSet = 1780 if (SitTargetisSet && !SitTargetOccupied)
1711 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1712 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1713
1714 if (SitTargetisSet && SitTargetUnOccupied)
1715 { 1781 {
1716 //switch the target to this prim 1782 //switch the target to this prim
1717 return part; 1783 return part;
@@ -1725,84 +1791,152 @@ namespace OpenSim.Region.Framework.Scenes
1725 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1791 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1726 { 1792 {
1727 bool autopilot = true; 1793 bool autopilot = true;
1794 Vector3 autopilotTarget = new Vector3();
1795 Quaternion sitOrientation = Quaternion.Identity;
1728 Vector3 pos = new Vector3(); 1796 Vector3 pos = new Vector3();
1729 Quaternion sitOrientation = pSitOrientation;
1730 Vector3 cameraEyeOffset = Vector3.Zero; 1797 Vector3 cameraEyeOffset = Vector3.Zero;
1731 Vector3 cameraAtOffset = Vector3.Zero; 1798 Vector3 cameraAtOffset = Vector3.Zero;
1732 bool forceMouselook = false; 1799 bool forceMouselook = false;
1733 1800
1734 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1801 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1735 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1802 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1736 if (part != null) 1803 if (part == null) return;
1737 { 1804
1738 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1805 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1739 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1806 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1740 1807
1741 // Is a sit target available? 1808 // part is the prim to sit on
1742 Vector3 avSitOffSet = part.SitTargetPosition; 1809 // offset is the world-ref vector distance from that prim center to the click-spot
1743 Quaternion avSitOrientation = part.SitTargetOrientation; 1810 // UUID is the UUID of the Avatar doing the clicking
1744 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1811
1745 1812 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1746 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1813
1747 bool SitTargetisSet = 1814 // Is a sit target available?
1748 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1815 Vector3 avSitOffSet = part.SitTargetPosition;
1749 ( 1816 Quaternion avSitOrientation = part.SitTargetOrientation;
1750 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1817
1751 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1818 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1752 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1819 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1753 ) 1820 Quaternion partRot;
1754 )); 1821// if (part.LinkNum == 1)
1755 1822// { // Root prim of linkset
1756 if (SitTargetisSet && SitTargetUnOccupied) 1823// partRot = part.ParentGroup.RootPart.RotationOffset;
1757 { 1824// }
1758 part.SetAvatarOnSitTarget(UUID); 1825// else
1759 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1826// { // single or child prim
1760 sitOrientation = avSitOrientation; 1827 partRot = part.GetWorldRotation();
1761 autopilot = false; 1828// }
1762 } 1829 Quaternion partIRot = Quaternion.Inverse(partRot);
1763 1830//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1764 pos = part.AbsolutePosition + offset; 1831 // Sit analysis rewritten by KF 091125
1765 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1832 if (SitTargetisSet) // scipted sit
1766 //{ 1833 {
1767 // offset = pos; 1834 if (!part.IsOccupied)
1768 //autopilot = false; 1835 {
1769 //} 1836//Console.WriteLine("Scripted, unoccupied");
1770 if (m_physicsActor != null) 1837 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1771 { 1838 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1772 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1839 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1773 // We can remove the physicsActor until they stand up. 1840 autopilot = false; // Jump direct to scripted llSitPos()
1774 m_sitAvatarHeight = m_physicsActor.Size.Z; 1841 }
1775 1842 else
1776 if (autopilot) 1843 {
1777 { 1844//Console.WriteLine("Scripted, occupied");
1778 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1845 return;
1779 { 1846 }
1780 autopilot = false; 1847 }
1848 else // Not Scripted
1849 {
1850 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1851 {
1852 // large prim & offset, ignore if other Avs sitting
1853// offset.Z -= 0.05f;
1854 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1855 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1856
1857//Console.WriteLine(" offset ={0}", offset);
1858//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1859//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1860
1861 }
1862 else // small offset
1863 {
1864//Console.WriteLine("Small offset");
1865 if (!part.IsOccupied)
1866 {
1867 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1868 autopilotTarget = part.AbsolutePosition;
1869 }
1870 else return; // occupied small
1871 } // end large/small
1872 } // end Scripted/not
1873 cameraAtOffset = part.GetCameraAtOffset();
1874 cameraEyeOffset = part.GetCameraEyeOffset();
1875 forceMouselook = part.GetForceMouselook();
1876 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1877 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1781 1878
1782 RemoveFromPhysicalScene(); 1879 if (m_physicsActor != null)
1783 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1880 {
1784 } 1881 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1785 } 1882 // We can remove the physicsActor until they stand up.
1786 else 1883 m_sitAvatarHeight = m_physicsActor.Size.Z;
1884 if (autopilot)
1885 { // its not a scripted sit
1886// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1887 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1787 { 1888 {
1889 autopilot = false; // close enough
1890 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1891 Not using the part's position because returning the AV to the last known standing
1892 position is likely to be more friendly, isn't it? */
1788 RemoveFromPhysicalScene(); 1893 RemoveFromPhysicalScene();
1789 } 1894 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1895 } // else the autopilot will get us close
1896 }
1897 else
1898 { // its a scripted sit
1899 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1900 I *am* using the part's position this time because we have no real idea how far away
1901 the avatar is from the sit target. */
1902 RemoveFromPhysicalScene();
1790 } 1903 }
1791
1792 cameraAtOffset = part.GetCameraAtOffset();
1793 cameraEyeOffset = part.GetCameraEyeOffset();
1794 forceMouselook = part.GetForceMouselook();
1795 } 1904 }
1796 1905 else return; // physactor is null!
1797 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1906
1798 m_requestedSitTargetUUID = targetID; 1907 Vector3 offsetr; // = offset * partIRot;
1908 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1909 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1910 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1911 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1912 offsetr = offset * partIRot;
1913//
1914 // else
1915 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1916 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1917 // (offset * partRot);
1918 // }
1919
1920//Console.WriteLine(" ");
1921//Console.WriteLine("link number ={0}", part.LinkNum);
1922//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1923//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1924//Console.WriteLine("Click offst ={0}", offset);
1925//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1926//Console.WriteLine("offsetr ={0}", offsetr);
1927//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1928//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1929
1930 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1931 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1799 // This calls HandleAgentSit twice, once from here, and the client calls 1932 // This calls HandleAgentSit twice, once from here, and the client calls
1800 // HandleAgentSit itself after it gets to the location 1933 // HandleAgentSit itself after it gets to the location
1801 // It doesn't get to the location until we've moved them there though 1934 // It doesn't get to the location until we've moved them there though
1802 // which happens in HandleAgentSit :P 1935 // which happens in HandleAgentSit :P
1803 m_autopilotMoving = autopilot; 1936 m_autopilotMoving = autopilot;
1804 m_autoPilotTarget = pos; 1937 m_autoPilotTarget = autopilotTarget;
1805 m_sitAtAutoTarget = autopilot; 1938 m_sitAtAutoTarget = autopilot;
1939 m_initialSitTarget = autopilotTarget;
1806 if (!autopilot) 1940 if (!autopilot)
1807 HandleAgentSit(remoteClient, UUID); 1941 HandleAgentSit(remoteClient, UUID);
1808 } 1942 }
@@ -2097,31 +2231,65 @@ namespace OpenSim.Region.Framework.Scenes
2097 { 2231 {
2098 if (part != null) 2232 if (part != null)
2099 { 2233 {
2234//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2100 if (part.GetAvatarOnSitTarget() == UUID) 2235 if (part.GetAvatarOnSitTarget() == UUID)
2101 { 2236 {
2237//Console.WriteLine("Scripted Sit");
2238 // Scripted sit
2102 Vector3 sitTargetPos = part.SitTargetPosition; 2239 Vector3 sitTargetPos = part.SitTargetPosition;
2103 Quaternion sitTargetOrient = part.SitTargetOrientation; 2240 Quaternion sitTargetOrient = part.SitTargetOrientation;
2104
2105 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2106 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2107
2108 //Quaternion result = (sitTargetOrient * vq) * nq;
2109
2110 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2241 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2111 m_pos += SIT_TARGET_ADJUSTMENT; 2242 m_pos += SIT_TARGET_ADJUSTMENT;
2112 m_bodyRot = sitTargetOrient; 2243 m_bodyRot = sitTargetOrient;
2113 //Rotation = sitTargetOrient;
2114 m_parentPosition = part.AbsolutePosition; 2244 m_parentPosition = part.AbsolutePosition;
2115 2245 part.IsOccupied = true;
2116 //SendTerseUpdateToAllClients();
2117 } 2246 }
2118 else 2247 else
2119 { 2248 {
2120 m_pos -= part.AbsolutePosition; 2249 // if m_avUnscriptedSitPos is zero then Av sits above center
2250 // Else Av sits at m_avUnscriptedSitPos
2251
2252 // Non-scripted sit by Kitto Flora 21Nov09
2253 // Calculate angle of line from prim to Av
2254 Quaternion partIRot;
2255// if (part.LinkNum == 1)
2256// { // Root prim of linkset
2257// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2258// }
2259// else
2260// { // single or child prim
2261 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2262// }
2263 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2264 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2265 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2266 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2267 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2268 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2269 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2270 // Av sits at world euler <0,0, z>, translated by part rotation
2271 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2272
2121 m_parentPosition = part.AbsolutePosition; 2273 m_parentPosition = part.AbsolutePosition;
2122 } 2274 part.IsOccupied = true;
2123 } 2275 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2124 else 2276 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2277 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2278 m_avUnscriptedSitPos; // adds click offset, if any
2279 //Set up raytrace to find top surface of prim
2280 Vector3 size = part.Scale;
2281 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2282 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2283 Vector3 down = new Vector3(0f, 0f, -1f);
2284//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2285 m_scene.PhysicsScene.RaycastWorld(
2286 start, // Vector3 position,
2287 down, // Vector3 direction,
2288 mag, // float length,
2289 SitAltitudeCallback); // retMethod
2290 } // end scripted/not
2291 }
2292 else // no Av
2125 { 2293 {
2126 return; 2294 return;
2127 } 2295 }
@@ -2133,11 +2301,36 @@ namespace OpenSim.Region.Framework.Scenes
2133 2301
2134 Animator.TrySetMovementAnimation(sitAnimation); 2302 Animator.TrySetMovementAnimation(sitAnimation);
2135 SendFullUpdateToAllClients(); 2303 SendFullUpdateToAllClients();
2136 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2137 // So we're also sending a terse update (which has avatar rotation)
2138 // [Update] We do now.
2139 //SendTerseUpdateToAllClients();
2140 } 2304 }
2305
2306 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2307 {
2308 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2309 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2310 if(hitYN)
2311 {
2312 // m_pos = Av offset from prim center to make look like on center
2313 // m_parentPosition = Actual center pos of prim
2314 // collisionPoint = spot on prim where we want to sit
2315 // collisionPoint.Z = global sit surface height
2316 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2317 Quaternion partIRot;
2318// if (part.LinkNum == 1)
2319/// { // Root prim of linkset
2320// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2321// }
2322// else
2323// { // single or child prim
2324 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2325// }
2326 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2327 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2328//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2329 m_pos += offset;
2330// ControllingClient.SendClearFollowCamProperties(part.UUID);
2331
2332 }
2333 } // End SitAltitudeCallback KF.
2141 2334
2142 /// <summary> 2335 /// <summary>
2143 /// Event handler for the 'Always run' setting on the client 2336 /// Event handler for the 'Always run' setting on the client
@@ -2167,7 +2360,7 @@ namespace OpenSim.Region.Framework.Scenes
2167 /// </summary> 2360 /// </summary>
2168 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2361 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2169 /// <param name="rotation">The direction in which this avatar should now face. 2362 /// <param name="rotation">The direction in which this avatar should now face.
2170 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2363 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2171 { 2364 {
2172 if (m_isChildAgent) 2365 if (m_isChildAgent)
2173 { 2366 {
@@ -2241,7 +2434,7 @@ namespace OpenSim.Region.Framework.Scenes
2241 2434
2242 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2435 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2243 m_forceToApply = direc; 2436 m_forceToApply = direc;
2244 2437 m_isNudging = Nudging;
2245 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2438 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2246 } 2439 }
2247 2440
@@ -2256,7 +2449,7 @@ namespace OpenSim.Region.Framework.Scenes
2256 const float POSITION_TOLERANCE = 0.05f; 2449 const float POSITION_TOLERANCE = 0.05f;
2257 //const int TIME_MS_TOLERANCE = 3000; 2450 //const int TIME_MS_TOLERANCE = 3000;
2258 2451
2259 SendPrimUpdates(); 2452
2260 2453
2261 if (m_newCoarseLocations) 2454 if (m_newCoarseLocations)
2262 { 2455 {
@@ -2292,6 +2485,9 @@ namespace OpenSim.Region.Framework.Scenes
2292 CheckForBorderCrossing(); 2485 CheckForBorderCrossing();
2293 CheckForSignificantMovement(); // sends update to the modules. 2486 CheckForSignificantMovement(); // sends update to the modules.
2294 } 2487 }
2488
2489 //Sending prim updates AFTER the avatar terse updates are sent
2490 SendPrimUpdates();
2295 } 2491 }
2296 2492
2297 #endregion 2493 #endregion
@@ -3151,14 +3347,25 @@ namespace OpenSim.Region.Framework.Scenes
3151 { 3347 {
3152 if (m_forceToApply.HasValue) 3348 if (m_forceToApply.HasValue)
3153 { 3349 {
3154 Vector3 force = m_forceToApply.Value;
3155 3350
3351 Vector3 force = m_forceToApply.Value;
3156 m_updateflag = true; 3352 m_updateflag = true;
3157// movementvector = force;
3158 Velocity = force; 3353 Velocity = force;
3159 3354
3160 m_forceToApply = null; 3355 m_forceToApply = null;
3161 } 3356 }
3357 else
3358 {
3359 if (m_isNudging)
3360 {
3361 Vector3 force = Vector3.Zero;
3362
3363 m_updateflag = true;
3364 Velocity = force;
3365 m_isNudging = false;
3366 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3367 }
3368 }
3162 } 3369 }
3163 3370
3164 public override void SetText(string text, Vector3 color, double alpha) 3371 public override void SetText(string text, Vector3 color, double alpha)
@@ -3209,18 +3416,29 @@ namespace OpenSim.Region.Framework.Scenes
3209 { 3416 {
3210 if (e == null) 3417 if (e == null)
3211 return; 3418 return;
3212 3419
3213 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3420 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3214 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3215 // as of this comment the interval is set in AddToPhysicalScene 3421 // as of this comment the interval is set in AddToPhysicalScene
3216 if (Animator!=null) 3422 if (Animator!=null)
3217 Animator.UpdateMovementAnimations(); 3423 {
3424 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3425 { // else its will lock out other animation changes, like ground sit.
3426 Animator.UpdateMovementAnimations();
3427 m_updateCount--;
3428 }
3429 }
3218 3430
3219 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3431 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3220 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3432 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3221 3433
3222 CollisionPlane = Vector4.UnitW; 3434 CollisionPlane = Vector4.UnitW;
3223 3435
3436 if (m_lastColCount != coldata.Count)
3437 {
3438 m_updateCount = UPDATE_COUNT;
3439 m_lastColCount = coldata.Count;
3440 }
3441
3224 if (coldata.Count != 0 && Animator != null) 3442 if (coldata.Count != 0 && Animator != null)
3225 { 3443 {
3226 switch (Animator.CurrentMovementAnimation) 3444 switch (Animator.CurrentMovementAnimation)
@@ -3857,5 +4075,16 @@ namespace OpenSim.Region.Framework.Scenes
3857 m_reprioritization_called = false; 4075 m_reprioritization_called = false;
3858 } 4076 }
3859 } 4077 }
4078
4079 private Vector3 Quat2Euler(Quaternion rot){
4080 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4081 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4082 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4083 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4084 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4085 return(new Vector3(x,y,z));
4086 }
4087
4088
3860 } 4089 }
3861} 4090}
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;