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