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.cs27
-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.cs585
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs103
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs592
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs571
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs11
14 files changed, 1381 insertions, 765 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 712dcc7..be0e985 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
@@ -451,4 +452,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
451 m_scenePresence = null; 452 m_scenePresence = null;
452 } 453 }
453 } 454 }
454} \ No newline at end of file 455}
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 57e1c37..7fb1cd8 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -203,7 +203,11 @@ namespace OpenSim.Region.Framework.Scenes
203 public event OnMakeChildAgentDelegate OnMakeChildAgent; 203 public event OnMakeChildAgentDelegate OnMakeChildAgent;
204 204
205 public delegate void OnMakeRootAgentDelegate(ScenePresence presence); 205 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
206 public delegate void OnSaveNewWindlightProfileDelegate();
207 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user);
206 public event OnMakeRootAgentDelegate OnMakeRootAgent; 208 public event OnMakeRootAgentDelegate OnMakeRootAgent;
209 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
210 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
207 211
208 /// <summary> 212 /// <summary>
209 /// Triggered when an object or attachment enters a scene 213 /// Triggered when an object or attachment enters a scene
@@ -1191,6 +1195,24 @@ namespace OpenSim.Region.Framework.Scenes
1191 } 1195 }
1192 } 1196 }
1193 1197
1198 public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
1199 {
1200 OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
1201 if (handlerSendNewWindlightProfileTargeted != null)
1202 {
1203 handlerSendNewWindlightProfileTargeted(wl, user);
1204 }
1205 }
1206
1207 public void TriggerOnSaveNewWindlightProfile()
1208 {
1209 OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
1210 if (handlerSaveNewWindlightProfile != null)
1211 {
1212 handlerSaveNewWindlightProfile();
1213 }
1214 }
1215
1194 public void TriggerOnMakeRootAgent(ScenePresence presence) 1216 public void TriggerOnMakeRootAgent(ScenePresence presence)
1195 { 1217 {
1196 OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent; 1218 OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent;
@@ -1967,4 +1989,4 @@ namespace OpenSim.Region.Framework.Scenes
1967 } 1989 }
1968 } 1990 }
1969 } 1991 }
1970} \ No newline at end of file 1992}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index c6cee75..b2b061e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -849,8 +849,12 @@ namespace OpenSim.Region.Framework.Scenes
849 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 849 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
850 { 850 {
851 SceneObjectPart part = GetSceneObjectPart(localID); 851 SceneObjectPart part = GetSceneObjectPart(localID);
852 SceneObjectGroup group = part.ParentGroup; 852 SceneObjectGroup group = null;
853 if (group != null) 853 if (part != null)
854 {
855 group = part.ParentGroup;
856 }
857 if (part != null && group != null)
854 { 858 {
855 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 859 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
856 if (item == null) 860 if (item == null)
@@ -1804,8 +1808,13 @@ namespace OpenSim.Region.Framework.Scenes
1804 } 1808 }
1805 else 1809 else
1806 { 1810 {
1807 item.BasePermissions = objectGroup.GetEffectivePermissions(); 1811 uint ownerPerms = objectGroup.GetEffectivePermissions();
1808 item.CurrentPermissions = objectGroup.GetEffectivePermissions(); 1812 if ((objectGroup.RootPart.OwnerMask & (uint)PermissionMask.Modify) != 0)
1813 ownerPerms |= (uint)PermissionMask.Modify;
1814
1815 item.BasePermissions = ownerPerms;
1816 item.CurrentPermissions = ownerPerms;
1817
1809 item.NextPermissions = objectGroup.RootPart.NextOwnerMask; 1818 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1810 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; 1819 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1811 item.GroupPermissions = objectGroup.RootPart.GroupMask; 1820 item.GroupPermissions = objectGroup.RootPart.GroupMask;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 41fd1e1..ab0d397 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>
@@ -3426,6 +3453,9 @@ namespace OpenSim.Region.Framework.Scenes
3426 3453
3427 CapsModule.AddCapsHandler(agent.AgentID); 3454 CapsModule.AddCapsHandler(agent.AgentID);
3428 3455
3456 if ((teleportFlags & ((uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.Default)) != 0)
3457 System.Threading.Thread.Sleep(2000);
3458
3429 if (!agent.child) 3459 if (!agent.child)
3430 { 3460 {
3431 if (TestBorderCross(agent.startpos,Cardinals.E)) 3461 if (TestBorderCross(agent.startpos,Cardinals.E))
@@ -3484,6 +3514,7 @@ namespace OpenSim.Region.Framework.Scenes
3484 } 3514 }
3485 } 3515 }
3486 // Honor parcel landing type and position. 3516 // Honor parcel landing type and position.
3517 /*
3487 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 3518 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3488 if (land != null) 3519 if (land != null)
3489 { 3520 {
@@ -3492,6 +3523,7 @@ namespace OpenSim.Region.Framework.Scenes
3492 agent.startpos = land.LandData.UserLocation; 3523 agent.startpos = land.LandData.UserLocation;
3493 } 3524 }
3494 } 3525 }
3526 */// This is now handled properly in ScenePresence.MakeRootAgent
3495 } 3527 }
3496 3528
3497 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3529 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 2f6a0db..5f84252 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -711,6 +711,33 @@ namespace OpenSim.Region.Framework.Scenes
711 position = emergencyPos; 711 position = emergencyPos;
712 } 712 }
713 713
714 Vector3 currentPos = avatar.AbsolutePosition;
715 ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y);
716 ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y);
717 if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0)
718 {
719 if (srcLand.LandData.LocalID == destLand.LandData.LocalID)
720 {
721 //TPing within the same parcel. If the landing point is restricted, block the TP.
722 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
723 if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID)
724 {
725 //Disabling this behaviour for now pending review. ~CasperW
726
727 //avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false);
728 //position = currentPos;
729 }
730 }
731 else
732 {
733 //Tping to a different parcel. Respect the landing point on the destination parcel.
734 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)
735 {
736 position = destLand.LandData.UserLocation;
737 }
738 }
739 }
740
714 // TODO: Get proper AVG Height 741 // TODO: Get proper AVG Height
715 float localAVHeight = 1.56f; 742 float localAVHeight = 1.56f;
716 float posZLimit = 22; 743 float posZLimit = 22;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 321cc45..e28d29f 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();
@@ -567,6 +591,18 @@ namespace OpenSim.Region.Framework.Scenes
567 if (group.GetFromItemID() == itemID) 591 if (group.GetFromItemID() == itemID)
568 { 592 {
569 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); 593 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
594 bool hasScripts = false;
595 foreach (SceneObjectPart part in group.Children.Values)
596 {
597 if (part.Inventory.ContainsScripts())
598 {
599 hasScripts = true;
600 break;
601 }
602 }
603
604 if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
605 System.Threading.Thread.Sleep(100);
570 group.DetachToInventoryPrep(); 606 group.DetachToInventoryPrep();
571 m_log.Debug("[DETACH]: Saving attachpoint: " + 607 m_log.Debug("[DETACH]: Saving attachpoint: " +
572 ((uint)group.GetAttachmentPoint()).ToString()); 608 ((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 c5a6171..f35a7c5 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
@@ -298,6 +367,9 @@ namespace OpenSim.Region.Framework.Scenes
298 { 367 {
299 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 368 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
300 } 369 }
370
371 lockPartsForRead(true);
372
301 if (RootPart.GetStatusSandbox()) 373 if (RootPart.GetStatusSandbox())
302 { 374 {
303 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) 375 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -308,14 +380,14 @@ namespace OpenSim.Region.Framework.Scenes
308 return; 380 return;
309 } 381 }
310 } 382 }
311 lock (m_parts) 383
384 foreach (SceneObjectPart part in m_parts.Values)
312 { 385 {
313 foreach (SceneObjectPart part in m_parts.Values) 386 part.GroupPosition = val;
314 {
315 part.GroupPosition = val;
316 }
317 } 387 }
318 388
389 lockPartsForRead(false);
390
319 //if (m_rootPart.PhysActor != null) 391 //if (m_rootPart.PhysActor != null)
320 //{ 392 //{
321 //m_rootPart.PhysActor.Position = 393 //m_rootPart.PhysActor.Position =
@@ -504,13 +576,16 @@ namespace OpenSim.Region.Framework.Scenes
504 576
505 public void SetFromItemID(UUID AssetId) 577 public void SetFromItemID(UUID AssetId)
506 { 578 {
507 lock (m_parts) 579 lockPartsForRead(true);
508 { 580 {
509 foreach (SceneObjectPart part in m_parts.Values) 581 foreach (SceneObjectPart part in m_parts.Values)
510 { 582 {
583
511 part.FromItemID = AssetId; 584 part.FromItemID = AssetId;
585
512 } 586 }
513 } 587 }
588 lockPartsForRead(false);
514 } 589 }
515 590
516 public UUID GetFromItemID() 591 public UUID GetFromItemID()
@@ -577,10 +652,11 @@ namespace OpenSim.Region.Framework.Scenes
577 Vector3 maxScale = Vector3.Zero; 652 Vector3 maxScale = Vector3.Zero;
578 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 653 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
579 654
580 lock (m_parts) 655 lockPartsForRead(true);
581 { 656 {
582 foreach (SceneObjectPart part in m_parts.Values) 657 foreach (SceneObjectPart part in m_parts.Values)
583 { 658 {
659
584 Vector3 partscale = part.Scale; 660 Vector3 partscale = part.Scale;
585 Vector3 partoffset = part.OffsetPosition; 661 Vector3 partoffset = part.OffsetPosition;
586 662
@@ -591,8 +667,11 @@ namespace OpenSim.Region.Framework.Scenes
591 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 667 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
592 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 668 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
593 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 669 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
670
594 } 671 }
595 } 672 }
673 lockPartsForRead(false);
674
596 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 675 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
597 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 676 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
598 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 677 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -608,10 +687,11 @@ namespace OpenSim.Region.Framework.Scenes
608 687
609 EntityIntersection result = new EntityIntersection(); 688 EntityIntersection result = new EntityIntersection();
610 689
611 lock (m_parts) 690 lockPartsForRead(true);
612 { 691 {
613 foreach (SceneObjectPart part in m_parts.Values) 692 foreach (SceneObjectPart part in m_parts.Values)
614 { 693 {
694
615 // Temporary commented to stop compiler warning 695 // Temporary commented to stop compiler warning
616 //Vector3 partPosition = 696 //Vector3 partPosition =
617 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 697 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -639,8 +719,10 @@ namespace OpenSim.Region.Framework.Scenes
639 result.distance = inter.distance; 719 result.distance = inter.distance;
640 } 720 }
641 } 721 }
722
642 } 723 }
643 } 724 }
725 lockPartsForRead(false);
644 return result; 726 return result;
645 } 727 }
646 728
@@ -653,10 +735,11 @@ namespace OpenSim.Region.Framework.Scenes
653 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 735 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
654 { 736 {
655 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 737 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
656 lock (m_parts) 738 lockPartsForRead(true);
657 { 739 {
658 foreach (SceneObjectPart part in m_parts.Values) 740 foreach (SceneObjectPart part in m_parts.Values)
659 { 741 {
742
660 Vector3 worldPos = part.GetWorldPosition(); 743 Vector3 worldPos = part.GetWorldPosition();
661 Vector3 offset = worldPos - AbsolutePosition; 744 Vector3 offset = worldPos - AbsolutePosition;
662 Quaternion worldRot; 745 Quaternion worldRot;
@@ -715,6 +798,8 @@ namespace OpenSim.Region.Framework.Scenes
715 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 798 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
716 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 799 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
717 800
801
802
718 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 803 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
719 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 804 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
720 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 805 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -886,6 +971,7 @@ namespace OpenSim.Region.Framework.Scenes
886 minZ = backBottomLeft.Z; 971 minZ = backBottomLeft.Z;
887 } 972 }
888 } 973 }
974 lockPartsForRead(false);
889 975
890 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 976 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
891 977
@@ -914,17 +1000,20 @@ namespace OpenSim.Region.Framework.Scenes
914 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 1000 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
915 1001
916 // Capture script state while holding the lock 1002 // Capture script state while holding the lock
917 lock (m_parts) 1003 lockPartsForRead(true);
918 { 1004 {
919 foreach (SceneObjectPart part in m_parts.Values) 1005 foreach (SceneObjectPart part in m_parts.Values)
920 { 1006 {
1007
921 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 1008 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
922 foreach (UUID itemid in pstates.Keys) 1009 foreach (UUID itemid in pstates.Keys)
923 { 1010 {
924 states.Add(itemid, pstates[itemid]); 1011 states.Add(itemid, pstates[itemid]);
925 } 1012 }
1013
926 } 1014 }
927 } 1015 }
1016 lockPartsForRead(false);
928 1017
929 if (states.Count > 0) 1018 if (states.Count > 0)
930 { 1019 {
@@ -1086,13 +1175,16 @@ namespace OpenSim.Region.Framework.Scenes
1086 1175
1087 public override void UpdateMovement() 1176 public override void UpdateMovement()
1088 { 1177 {
1089 lock (m_parts) 1178 lockPartsForRead(true);
1090 { 1179 {
1091 foreach (SceneObjectPart part in m_parts.Values) 1180 foreach (SceneObjectPart part in m_parts.Values)
1092 { 1181 {
1182
1093 part.UpdateMovement(); 1183 part.UpdateMovement();
1184
1094 } 1185 }
1095 } 1186 }
1187 lockPartsForRead(false);
1096 } 1188 }
1097 1189
1098 public ushort GetTimeDilation() 1190 public ushort GetTimeDilation()
@@ -1136,7 +1228,7 @@ namespace OpenSim.Region.Framework.Scenes
1136 /// <param name="part"></param> 1228 /// <param name="part"></param>
1137 public void AddPart(SceneObjectPart part) 1229 public void AddPart(SceneObjectPart part)
1138 { 1230 {
1139 lock (m_parts) 1231 lockPartsForWrite(true);
1140 { 1232 {
1141 part.SetParent(this); 1233 part.SetParent(this);
1142 m_parts.Add(part.UUID, part); 1234 m_parts.Add(part.UUID, part);
@@ -1146,6 +1238,7 @@ namespace OpenSim.Region.Framework.Scenes
1146 if (part.LinkNum == 2 && RootPart != null) 1238 if (part.LinkNum == 2 && RootPart != null)
1147 RootPart.LinkNum = 1; 1239 RootPart.LinkNum = 1;
1148 } 1240 }
1241 lockPartsForWrite(false);
1149 } 1242 }
1150 1243
1151 /// <summary> 1244 /// <summary>
@@ -1153,28 +1246,33 @@ namespace OpenSim.Region.Framework.Scenes
1153 /// </summary> 1246 /// </summary>
1154 private void UpdateParentIDs() 1247 private void UpdateParentIDs()
1155 { 1248 {
1156 lock (m_parts) 1249 lockPartsForRead(true);
1157 { 1250 {
1158 foreach (SceneObjectPart part in m_parts.Values) 1251 foreach (SceneObjectPart part in m_parts.Values)
1159 { 1252 {
1253
1160 if (part.UUID != m_rootPart.UUID) 1254 if (part.UUID != m_rootPart.UUID)
1161 { 1255 {
1162 part.ParentID = m_rootPart.LocalId; 1256 part.ParentID = m_rootPart.LocalId;
1163 } 1257 }
1258
1164 } 1259 }
1165 } 1260 }
1261 lockPartsForRead(false);
1166 } 1262 }
1167 1263
1168 public void RegenerateFullIDs() 1264 public void RegenerateFullIDs()
1169 { 1265 {
1170 lock (m_parts) 1266 lockPartsForRead(true);
1171 { 1267 {
1172 foreach (SceneObjectPart part in m_parts.Values) 1268 foreach (SceneObjectPart part in m_parts.Values)
1173 { 1269 {
1270
1174 part.UUID = UUID.Random(); 1271 part.UUID = UUID.Random();
1175 1272
1176 } 1273 }
1177 } 1274 }
1275 lockPartsForRead(false);
1178 } 1276 }
1179 1277
1180 // helper provided for parts. 1278 // helper provided for parts.
@@ -1255,29 +1353,33 @@ namespace OpenSim.Region.Framework.Scenes
1255 1353
1256 DetachFromBackup(); 1354 DetachFromBackup();
1257 1355
1258 lock (m_parts) 1356 lockPartsForRead(true);
1357 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1358 lockPartsForRead(false);
1359
1360 foreach (SceneObjectPart part in values)
1259 { 1361 {
1260 foreach (SceneObjectPart part in m_parts.Values)
1261 {
1262// part.Inventory.RemoveScriptInstances(); 1362// part.Inventory.RemoveScriptInstances();
1263 1363
1264 ScenePresence[] avatars = Scene.GetScenePresences(); 1364 ScenePresence[] avatars = Scene.GetScenePresences();
1265 for (int i = 0; i < avatars.Length; i++) 1365 for (int i = 0; i < avatars.Length; i++)
1366 {
1367 if (avatars[i].ParentID == LocalId)
1266 { 1368 {
1267 if (avatars[i].ParentID == LocalId) 1369 avatars[i].StandUp();
1268 { 1370 }
1269 avatars[i].StandUp();
1270 }
1271 1371
1272 if (!silent) 1372 if (!silent)
1273 { 1373 {
1274 part.UpdateFlag = 0; 1374 part.UpdateFlag = 0;
1275 if (part == m_rootPart) 1375 if (part == m_rootPart)
1276 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1376 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1277 }
1278 } 1377 }
1279 } 1378 }
1379
1280 } 1380 }
1381
1382
1281 } 1383 }
1282 1384
1283 public void AddScriptLPS(int count) 1385 public void AddScriptLPS(int count)
@@ -1302,17 +1404,20 @@ namespace OpenSim.Region.Framework.Scenes
1302 1404
1303 scriptEvents aggregateScriptEvents=0; 1405 scriptEvents aggregateScriptEvents=0;
1304 1406
1305 lock (m_parts) 1407 lockPartsForRead(true);
1306 { 1408 {
1307 foreach (SceneObjectPart part in m_parts.Values) 1409 foreach (SceneObjectPart part in m_parts.Values)
1308 { 1410 {
1411
1309 if (part == null) 1412 if (part == null)
1310 continue; 1413 continue;
1311 if (part != RootPart) 1414 if (part != RootPart)
1312 part.ObjectFlags = objectflagupdate; 1415 part.ObjectFlags = objectflagupdate;
1313 aggregateScriptEvents |= part.AggregateScriptEvents; 1416 aggregateScriptEvents |= part.AggregateScriptEvents;
1417
1314 } 1418 }
1315 } 1419 }
1420 lockPartsForRead(false);
1316 1421
1317 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1422 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1318 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1423 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1354,42 +1459,52 @@ namespace OpenSim.Region.Framework.Scenes
1354 /// <param name="m_physicalPrim"></param> 1459 /// <param name="m_physicalPrim"></param>
1355 public void ApplyPhysics(bool m_physicalPrim) 1460 public void ApplyPhysics(bool m_physicalPrim)
1356 { 1461 {
1357 lock (m_parts) 1462 lockPartsForRead(true);
1463
1464 if (m_parts.Count > 1)
1358 { 1465 {
1359 if (m_parts.Count > 1) 1466 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1467 lockPartsForRead(false);
1468 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1469 foreach (SceneObjectPart part in values)
1360 { 1470 {
1361 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1471
1362 foreach (SceneObjectPart part in m_parts.Values) 1472 if (part.LocalId != m_rootPart.LocalId)
1363 { 1473 {
1364 if (part.LocalId != m_rootPart.LocalId) 1474 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1365 {
1366 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1367 }
1368 } 1475 }
1369 1476
1370 // Hack to get the physics scene geometries in the right spot
1371 ResetChildPrimPhysicsPositions();
1372 }
1373 else
1374 {
1375 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1376 } 1477 }
1478 // Hack to get the physics scene geometries in the right spot
1479 ResetChildPrimPhysicsPositions();
1480 }
1481 else
1482 {
1483 lockPartsForRead(false);
1484 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1377 } 1485 }
1378 } 1486 }
1379 1487
1380 public void SetOwnerId(UUID userId) 1488 public void SetOwnerId(UUID userId)
1381 { 1489 {
1382 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1490 ForEachPart(delegate(SceneObjectPart part)
1491 {
1492
1493 part.OwnerID = userId;
1494
1495 });
1383 } 1496 }
1384 1497
1385 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1498 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1386 { 1499 {
1387 lock (m_parts) 1500 lockPartsForRead(true);
1501 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1502 lockPartsForRead(false);
1503 foreach (SceneObjectPart part in values)
1388 { 1504 {
1389 foreach (SceneObjectPart part in m_parts.Values) 1505
1390 { 1506 whatToDo(part);
1391 whatToDo(part); 1507
1392 }
1393 } 1508 }
1394 } 1509 }
1395 1510
@@ -1488,14 +1603,17 @@ namespace OpenSim.Region.Framework.Scenes
1488 { 1603 {
1489 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1604 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1490 1605
1491 lock (m_parts) 1606 lockPartsForRead(true);
1492 { 1607 {
1493 foreach (SceneObjectPart part in m_parts.Values) 1608 foreach (SceneObjectPart part in m_parts.Values)
1494 { 1609 {
1610
1495 if (part != RootPart) 1611 if (part != RootPart)
1496 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1612 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1613
1497 } 1614 }
1498 } 1615 }
1616 lockPartsForRead(false);
1499 } 1617 }
1500 1618
1501 /// <summary> 1619 /// <summary>
@@ -1593,10 +1711,11 @@ namespace OpenSim.Region.Framework.Scenes
1593 1711
1594 List<SceneObjectPart> partList; 1712 List<SceneObjectPart> partList;
1595 1713
1596 lock (m_parts) 1714 lockPartsForRead(true);
1597 { 1715
1598 partList = new List<SceneObjectPart>(m_parts.Values); 1716 partList = new List<SceneObjectPart>(m_parts.Values);
1599 } 1717
1718 lockPartsForRead(false);
1600 1719
1601 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1720 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1602 { 1721 {
@@ -1819,6 +1938,33 @@ namespace OpenSim.Region.Framework.Scenes
1819 } 1938 }
1820 } 1939 }
1821 1940
1941 public void rotLookAt(Quaternion target, float strength, float damping)
1942 {
1943 SceneObjectPart rootpart = m_rootPart;
1944 if (rootpart != null)
1945 {
1946 if (IsAttachment)
1947 {
1948 /*
1949 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1950 if (avatar != null)
1951 {
1952 Rotate the Av?
1953 } */
1954 }
1955 else
1956 {
1957 if (rootpart.PhysActor != null)
1958 {
1959 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1960 rootpart.PhysActor.APIDStrength = strength;
1961 rootpart.PhysActor.APIDDamping = damping;
1962 rootpart.PhysActor.APIDActive = true;
1963 }
1964 }
1965 }
1966 }
1967
1822 public void stopLookAt() 1968 public void stopLookAt()
1823 { 1969 {
1824 SceneObjectPart rootpart = m_rootPart; 1970 SceneObjectPart rootpart = m_rootPart;
@@ -1893,10 +2039,11 @@ namespace OpenSim.Region.Framework.Scenes
1893 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 2039 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1894 newPart.SetParent(this); 2040 newPart.SetParent(this);
1895 2041
1896 lock (m_parts) 2042 lockPartsForWrite(true);
1897 { 2043 {
1898 m_parts.Add(newPart.UUID, newPart); 2044 m_parts.Add(newPart.UUID, newPart);
1899 } 2045 }
2046 lockPartsForWrite(false);
1900 2047
1901 SetPartAsNonRoot(newPart); 2048 SetPartAsNonRoot(newPart);
1902 2049
@@ -1959,7 +2106,7 @@ namespace OpenSim.Region.Framework.Scenes
1959 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2106 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1960 // return; 2107 // return;
1961 2108
1962 lock (m_parts) 2109 lockPartsForRead(true);
1963 { 2110 {
1964 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2111 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1965 2112
@@ -1979,34 +2126,43 @@ namespace OpenSim.Region.Framework.Scenes
1979 { 2126 {
1980 if (!IsSelected) 2127 if (!IsSelected)
1981 part.UpdateLookAt(); 2128 part.UpdateLookAt();
2129
1982 part.SendScheduledUpdates(); 2130 part.SendScheduledUpdates();
2131
1983 } 2132 }
1984 } 2133 }
2134 lockPartsForRead(false);
1985 } 2135 }
1986 2136
1987 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2137 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1988 { 2138 {
1989 RootPart.AddFullUpdateToAvatar(presence); 2139 RootPart.AddFullUpdateToAvatar(presence);
1990 2140
1991 lock (m_parts) 2141 lockPartsForRead(true);
1992 { 2142 {
1993 foreach (SceneObjectPart part in m_parts.Values) 2143 foreach (SceneObjectPart part in m_parts.Values)
1994 { 2144 {
2145
1995 if (part != RootPart) 2146 if (part != RootPart)
1996 part.AddFullUpdateToAvatar(presence); 2147 part.AddFullUpdateToAvatar(presence);
2148
1997 } 2149 }
1998 } 2150 }
2151 lockPartsForRead(false);
1999 } 2152 }
2000 2153
2001 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2154 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
2002 { 2155 {
2003 lock (m_parts) 2156 lockPartsForRead(true);
2004 { 2157 {
2005 foreach (SceneObjectPart part in m_parts.Values) 2158 foreach (SceneObjectPart part in m_parts.Values)
2006 { 2159 {
2160
2007 part.AddTerseUpdateToAvatar(presence); 2161 part.AddTerseUpdateToAvatar(presence);
2162
2008 } 2163 }
2009 } 2164 }
2165 lockPartsForRead(false);
2010 } 2166 }
2011 2167
2012 /// <summary> 2168 /// <summary>
@@ -2017,14 +2173,17 @@ namespace OpenSim.Region.Framework.Scenes
2017 checkAtTargets(); 2173 checkAtTargets();
2018 RootPart.ScheduleFullUpdate(); 2174 RootPart.ScheduleFullUpdate();
2019 2175
2020 lock (m_parts) 2176 lockPartsForRead(true);
2021 { 2177 {
2022 foreach (SceneObjectPart part in m_parts.Values) 2178 foreach (SceneObjectPart part in m_parts.Values)
2023 { 2179 {
2180
2024 if (part != RootPart) 2181 if (part != RootPart)
2025 part.ScheduleFullUpdate(); 2182 part.ScheduleFullUpdate();
2183
2026 } 2184 }
2027 } 2185 }
2186 lockPartsForRead(false);
2028 } 2187 }
2029 2188
2030 /// <summary> 2189 /// <summary>
@@ -2032,13 +2191,16 @@ namespace OpenSim.Region.Framework.Scenes
2032 /// </summary> 2191 /// </summary>
2033 public void ScheduleGroupForTerseUpdate() 2192 public void ScheduleGroupForTerseUpdate()
2034 { 2193 {
2035 lock (m_parts) 2194 lockPartsForRead(true);
2036 { 2195 {
2037 foreach (SceneObjectPart part in m_parts.Values) 2196 foreach (SceneObjectPart part in m_parts.Values)
2038 { 2197 {
2198
2039 part.ScheduleTerseUpdate(); 2199 part.ScheduleTerseUpdate();
2200
2040 } 2201 }
2041 } 2202 }
2203 lockPartsForRead(false);
2042 } 2204 }
2043 2205
2044 /// <summary> 2206 /// <summary>
@@ -2051,14 +2213,17 @@ namespace OpenSim.Region.Framework.Scenes
2051 2213
2052 RootPart.SendFullUpdateToAllClients(); 2214 RootPart.SendFullUpdateToAllClients();
2053 2215
2054 lock (m_parts) 2216 lockPartsForRead(true);
2055 { 2217 {
2056 foreach (SceneObjectPart part in m_parts.Values) 2218 foreach (SceneObjectPart part in m_parts.Values)
2057 { 2219 {
2220
2058 if (part != RootPart) 2221 if (part != RootPart)
2059 part.SendFullUpdateToAllClients(); 2222 part.SendFullUpdateToAllClients();
2223
2060 } 2224 }
2061 } 2225 }
2226 lockPartsForRead(false);
2062 } 2227 }
2063 2228
2064 /// <summary> 2229 /// <summary>
@@ -2089,14 +2254,15 @@ namespace OpenSim.Region.Framework.Scenes
2089 { 2254 {
2090 if (IsDeleted) 2255 if (IsDeleted)
2091 return; 2256 return;
2092 2257
2093 lock (m_parts) 2258 lockPartsForRead(true);
2094 { 2259 {
2095 foreach (SceneObjectPart part in m_parts.Values) 2260 foreach (SceneObjectPart part in m_parts.Values)
2096 { 2261 {
2097 part.SendTerseUpdateToAllClients(); 2262 part.SendTerseUpdateToAllClients();
2098 } 2263 }
2099 } 2264 }
2265 lockPartsForRead(false);
2100 } 2266 }
2101 2267
2102 #endregion 2268 #endregion
@@ -2110,16 +2276,18 @@ namespace OpenSim.Region.Framework.Scenes
2110 /// <returns>null if no child part with that linknum or child part</returns> 2276 /// <returns>null if no child part with that linknum or child part</returns>
2111 public SceneObjectPart GetLinkNumPart(int linknum) 2277 public SceneObjectPart GetLinkNumPart(int linknum)
2112 { 2278 {
2113 lock (m_parts) 2279 lockPartsForRead(true);
2114 { 2280 {
2115 foreach (SceneObjectPart part in m_parts.Values) 2281 foreach (SceneObjectPart part in m_parts.Values)
2116 { 2282 {
2117 if (part.LinkNum == linknum) 2283 if (part.LinkNum == linknum)
2118 { 2284 {
2285 lockPartsForRead(false);
2119 return part; 2286 return part;
2120 } 2287 }
2121 } 2288 }
2122 } 2289 }
2290 lockPartsForRead(false);
2123 2291
2124 return null; 2292 return null;
2125 } 2293 }
@@ -2147,17 +2315,19 @@ namespace OpenSim.Region.Framework.Scenes
2147 public SceneObjectPart GetChildPart(uint localID) 2315 public SceneObjectPart GetChildPart(uint localID)
2148 { 2316 {
2149 //m_log.DebugFormat("Entered looking for {0}", localID); 2317 //m_log.DebugFormat("Entered looking for {0}", localID);
2150 lock (m_parts) 2318 lockPartsForRead(true);
2151 { 2319 {
2152 foreach (SceneObjectPart part in m_parts.Values) 2320 foreach (SceneObjectPart part in m_parts.Values)
2153 { 2321 {
2154 //m_log.DebugFormat("Found {0}", part.LocalId); 2322 //m_log.DebugFormat("Found {0}", part.LocalId);
2155 if (part.LocalId == localID) 2323 if (part.LocalId == localID)
2156 { 2324 {
2325 lockPartsForRead(false);
2157 return part; 2326 return part;
2158 } 2327 }
2159 } 2328 }
2160 } 2329 }
2330 lockPartsForRead(false);
2161 2331
2162 return null; 2332 return null;
2163 } 2333 }
@@ -2187,17 +2357,19 @@ namespace OpenSim.Region.Framework.Scenes
2187 public bool HasChildPrim(uint localID) 2357 public bool HasChildPrim(uint localID)
2188 { 2358 {
2189 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2359 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2190 lock (m_parts) 2360 lockPartsForRead(true);
2191 { 2361 {
2192 foreach (SceneObjectPart part in m_parts.Values) 2362 foreach (SceneObjectPart part in m_parts.Values)
2193 { 2363 {
2194 //m_log.DebugFormat("Found {0}", part.LocalId); 2364 //m_log.DebugFormat("Found {0}", part.LocalId);
2195 if (part.LocalId == localID) 2365 if (part.LocalId == localID)
2196 { 2366 {
2367 lockPartsForRead(false);
2197 return true; 2368 return true;
2198 } 2369 }
2199 } 2370 }
2200 } 2371 }
2372 lockPartsForRead(false);
2201 2373
2202 return false; 2374 return false;
2203 } 2375 }
@@ -2247,53 +2419,57 @@ namespace OpenSim.Region.Framework.Scenes
2247 if (m_rootPart.LinkNum == 0) 2419 if (m_rootPart.LinkNum == 0)
2248 m_rootPart.LinkNum = 1; 2420 m_rootPart.LinkNum = 1;
2249 2421
2250 lock (m_parts) 2422 lockPartsForWrite(true);
2251 { 2423
2252 m_parts.Add(linkPart.UUID, linkPart); 2424 m_parts.Add(linkPart.UUID, linkPart);
2425
2426 lockPartsForWrite(false);
2253 2427
2254 // Insert in terms of link numbers, the new links 2428 // Insert in terms of link numbers, the new links
2255 // before the current ones (with the exception of 2429 // before the current ones (with the exception of
2256 // the root prim. Shuffle the old ones up 2430 // the root prim. Shuffle the old ones up
2257 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2431 lockPartsForRead(true);
2432 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2433 {
2434 if (kvp.Value.LinkNum != 1)
2258 { 2435 {
2259 if (kvp.Value.LinkNum != 1) 2436 // Don't update root prim link number
2260 { 2437 kvp.Value.LinkNum += objectGroup.PrimCount;
2261 // Don't update root prim link number
2262 kvp.Value.LinkNum += objectGroup.PrimCount;
2263 }
2264 } 2438 }
2439 }
2440 lockPartsForRead(false);
2265 2441
2266 linkPart.LinkNum = 2; 2442 linkPart.LinkNum = 2;
2267 2443
2268 linkPart.SetParent(this); 2444 linkPart.SetParent(this);
2269 linkPart.AddFlag(PrimFlags.CreateSelected); 2445 linkPart.AddFlag(PrimFlags.CreateSelected);
2270 2446
2271 //if (linkPart.PhysActor != null) 2447 //if (linkPart.PhysActor != null)
2272 //{ 2448 //{
2273 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2449 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2274 2450
2275 //linkPart.PhysActor = null; 2451 //linkPart.PhysActor = null;
2276 //} 2452 //}
2277 2453
2278 //TODO: rest of parts 2454 //TODO: rest of parts
2279 int linkNum = 3; 2455 int linkNum = 3;
2280 foreach (SceneObjectPart part in objectGroup.Children.Values) 2456 foreach (SceneObjectPart part in objectGroup.Children.Values)
2457 {
2458 if (part.UUID != objectGroup.m_rootPart.UUID)
2281 { 2459 {
2282 if (part.UUID != objectGroup.m_rootPart.UUID) 2460 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2283 {
2284 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2285 }
2286 part.ClearUndoState();
2287 } 2461 }
2462 part.ClearUndoState();
2288 } 2463 }
2289 2464
2290 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2465 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2291 objectGroup.m_isDeleted = true; 2466 objectGroup.m_isDeleted = true;
2467
2468 objectGroup.lockPartsForWrite(true);
2292 2469
2293 lock (objectGroup.m_parts) 2470 objectGroup.m_parts.Clear();
2294 { 2471
2295 objectGroup.m_parts.Clear(); 2472 objectGroup.lockPartsForWrite(false);
2296 }
2297 2473
2298 // Can't do this yet since backup still makes use of the root part without any synchronization 2474 // Can't do this yet since backup still makes use of the root part without any synchronization
2299// objectGroup.m_rootPart = null; 2475// objectGroup.m_rootPart = null;
@@ -2363,11 +2539,12 @@ namespace OpenSim.Region.Framework.Scenes
2363 Quaternion worldRot = linkPart.GetWorldRotation(); 2539 Quaternion worldRot = linkPart.GetWorldRotation();
2364 2540
2365 // Remove the part from this object 2541 // Remove the part from this object
2366 lock (m_parts) 2542 lockPartsForWrite(true);
2367 { 2543 {
2368 m_parts.Remove(linkPart.UUID); 2544 m_parts.Remove(linkPart.UUID);
2369 } 2545 }
2370 2546 lockPartsForWrite(false);
2547 lockPartsForRead(true);
2371 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2548 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2372 RootPart.LinkNum = 0; 2549 RootPart.LinkNum = 0;
2373 else 2550 else
@@ -2378,6 +2555,7 @@ namespace OpenSim.Region.Framework.Scenes
2378 p.LinkNum--; 2555 p.LinkNum--;
2379 } 2556 }
2380 } 2557 }
2558 lockPartsForRead(false);
2381 2559
2382 linkPart.ParentID = 0; 2560 linkPart.ParentID = 0;
2383 linkPart.LinkNum = 0; 2561 linkPart.LinkNum = 0;
@@ -2699,9 +2877,12 @@ namespace OpenSim.Region.Framework.Scenes
2699 2877
2700 if (selectionPart != null) 2878 if (selectionPart != null)
2701 { 2879 {
2702 lock (m_parts) 2880 lockPartsForRead(true);
2881 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2882 lockPartsForRead(false);
2883 foreach (SceneObjectPart part in parts)
2703 { 2884 {
2704 foreach (SceneObjectPart part in m_parts.Values) 2885 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2705 { 2886 {
2706 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2887 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2707 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2888 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2711,12 +2892,13 @@ namespace OpenSim.Region.Framework.Scenes
2711 break; 2892 break;
2712 } 2893 }
2713 } 2894 }
2895 }
2714 2896
2715 foreach (SceneObjectPart part in m_parts.Values) 2897 foreach (SceneObjectPart part in parts)
2716 { 2898 {
2717 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2899 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2718 }
2719 } 2900 }
2901
2720 } 2902 }
2721 } 2903 }
2722 2904
@@ -2802,11 +2984,9 @@ namespace OpenSim.Region.Framework.Scenes
2802 scale.Y = m_scene.m_maxNonphys; 2984 scale.Y = m_scene.m_maxNonphys;
2803 if (scale.Z > m_scene.m_maxNonphys) 2985 if (scale.Z > m_scene.m_maxNonphys)
2804 scale.Z = m_scene.m_maxNonphys; 2986 scale.Z = m_scene.m_maxNonphys;
2805
2806 SceneObjectPart part = GetChildPart(localID); 2987 SceneObjectPart part = GetChildPart(localID);
2807 if (part != null) 2988 if (part != null)
2808 { 2989 {
2809 part.Resize(scale);
2810 if (part.PhysActor != null) 2990 if (part.PhysActor != null)
2811 { 2991 {
2812 if (part.PhysActor.IsPhysical) 2992 if (part.PhysActor.IsPhysical)
@@ -2821,7 +3001,7 @@ namespace OpenSim.Region.Framework.Scenes
2821 part.PhysActor.Size = scale; 3001 part.PhysActor.Size = scale;
2822 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 3002 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2823 } 3003 }
2824 //if (part.UUID != m_rootPart.UUID) 3004 part.Resize(scale);
2825 3005
2826 HasGroupChanged = true; 3006 HasGroupChanged = true;
2827 ScheduleGroupForFullUpdate(); 3007 ScheduleGroupForFullUpdate();
@@ -2863,73 +3043,71 @@ namespace OpenSim.Region.Framework.Scenes
2863 float y = (scale.Y / part.Scale.Y); 3043 float y = (scale.Y / part.Scale.Y);
2864 float z = (scale.Z / part.Scale.Z); 3044 float z = (scale.Z / part.Scale.Z);
2865 3045
2866 lock (m_parts) 3046 lockPartsForRead(true);
3047 if (x > 1.0f || y > 1.0f || z > 1.0f)
2867 { 3048 {
2868 if (x > 1.0f || y > 1.0f || z > 1.0f) 3049 foreach (SceneObjectPart obPart in m_parts.Values)
2869 { 3050 {
2870 foreach (SceneObjectPart obPart in m_parts.Values) 3051 if (obPart.UUID != m_rootPart.UUID)
2871 { 3052 {
2872 if (obPart.UUID != m_rootPart.UUID) 3053 obPart.IgnoreUndoUpdate = true;
2873 { 3054 Vector3 oldSize = new Vector3(obPart.Scale);
2874 obPart.IgnoreUndoUpdate = true;
2875 Vector3 oldSize = new Vector3(obPart.Scale);
2876 3055
2877 float f = 1.0f; 3056 float f = 1.0f;
2878 float a = 1.0f; 3057 float a = 1.0f;
2879 3058
2880 if (part.PhysActor != null && part.PhysActor.IsPhysical) 3059 if (part.PhysActor != null && part.PhysActor.IsPhysical)
3060 {
3061 if (oldSize.X*x > m_scene.m_maxPhys)
2881 { 3062 {
2882 if (oldSize.X*x > m_scene.m_maxPhys) 3063 f = m_scene.m_maxPhys / oldSize.X;
2883 { 3064 a = f / x;
2884 f = m_scene.m_maxPhys / oldSize.X; 3065 x *= a;
2885 a = f / x; 3066 y *= a;
2886 x *= a; 3067 z *= a;
2887 y *= a;
2888 z *= a;
2889 }
2890 if (oldSize.Y*y > m_scene.m_maxPhys)
2891 {
2892 f = m_scene.m_maxPhys / oldSize.Y;
2893 a = f / y;
2894 x *= a;
2895 y *= a;
2896 z *= a;
2897 }
2898 if (oldSize.Z*z > m_scene.m_maxPhys)
2899 {
2900 f = m_scene.m_maxPhys / oldSize.Z;
2901 a = f / z;
2902 x *= a;
2903 y *= a;
2904 z *= a;
2905 }
2906 } 3068 }
2907 else 3069 if (oldSize.Y*y > m_scene.m_maxPhys)
3070 {
3071 f = m_scene.m_maxPhys / oldSize.Y;
3072 a = f / y;
3073 x *= a;
3074 y *= a;
3075 z *= a;
3076 }
3077 if (oldSize.Z*z > m_scene.m_maxPhys)
3078 {
3079 f = m_scene.m_maxPhys / oldSize.Z;
3080 a = f / z;
3081 x *= a;
3082 y *= a;
3083 z *= a;
3084 }
3085 }
3086 else
3087 {
3088 if (oldSize.X*x > m_scene.m_maxNonphys)
3089 {
3090 f = m_scene.m_maxNonphys / oldSize.X;
3091 a = f / x;
3092 x *= a;
3093 y *= a;
3094 z *= a;
3095 }
3096 if (oldSize.Y*y > m_scene.m_maxNonphys)
3097 {
3098 f = m_scene.m_maxNonphys / oldSize.Y;
3099 a = f / y;
3100 x *= a;
3101 y *= a;
3102 z *= a;
3103 }
3104 if (oldSize.Z*z > m_scene.m_maxNonphys)
2908 { 3105 {
2909 if (oldSize.X*x > m_scene.m_maxNonphys) 3106 f = m_scene.m_maxNonphys / oldSize.Z;
2910 { 3107 a = f / z;
2911 f = m_scene.m_maxNonphys / oldSize.X; 3108 x *= a;
2912 a = f / x; 3109 y *= a;
2913 x *= a; 3110 z *= a;
2914 y *= a;
2915 z *= a;
2916 }
2917 if (oldSize.Y*y > m_scene.m_maxNonphys)
2918 {
2919 f = m_scene.m_maxNonphys / oldSize.Y;
2920 a = f / y;
2921 x *= a;
2922 y *= a;
2923 z *= a;
2924 }
2925 if (oldSize.Z*z > m_scene.m_maxNonphys)
2926 {
2927 f = m_scene.m_maxNonphys / oldSize.Z;
2928 a = f / z;
2929 x *= a;
2930 y *= a;
2931 z *= a;
2932 }
2933 } 3111 }
2934 obPart.IgnoreUndoUpdate = false; 3112 obPart.IgnoreUndoUpdate = false;
2935 obPart.StoreUndoState(); 3113 obPart.StoreUndoState();
@@ -2937,6 +3115,7 @@ namespace OpenSim.Region.Framework.Scenes
2937 } 3115 }
2938 } 3116 }
2939 } 3117 }
3118 lockPartsForRead(false);
2940 3119
2941 Vector3 prevScale = part.Scale; 3120 Vector3 prevScale = part.Scale;
2942 prevScale.X *= x; 3121 prevScale.X *= x;
@@ -2944,7 +3123,7 @@ namespace OpenSim.Region.Framework.Scenes
2944 prevScale.Z *= z; 3123 prevScale.Z *= z;
2945 part.Resize(prevScale); 3124 part.Resize(prevScale);
2946 3125
2947 lock (m_parts) 3126 lockPartsForRead(true);
2948 { 3127 {
2949 foreach (SceneObjectPart obPart in m_parts.Values) 3128 foreach (SceneObjectPart obPart in m_parts.Values)
2950 { 3129 {
@@ -2966,6 +3145,7 @@ namespace OpenSim.Region.Framework.Scenes
2966 obPart.StoreUndoState(); 3145 obPart.StoreUndoState();
2967 } 3146 }
2968 } 3147 }
3148 lockPartsForRead(false);
2969 3149
2970 if (part.PhysActor != null) 3150 if (part.PhysActor != null)
2971 { 3151 {
@@ -3068,7 +3248,7 @@ namespace OpenSim.Region.Framework.Scenes
3068 axDiff *= Quaternion.Inverse(partRotation); 3248 axDiff *= Quaternion.Inverse(partRotation);
3069 diff = axDiff; 3249 diff = axDiff;
3070 3250
3071 lock (m_parts) 3251 lockPartsForRead(true);
3072 { 3252 {
3073 foreach (SceneObjectPart obPart in m_parts.Values) 3253 foreach (SceneObjectPart obPart in m_parts.Values)
3074 { 3254 {
@@ -3078,6 +3258,7 @@ namespace OpenSim.Region.Framework.Scenes
3078 } 3258 }
3079 } 3259 }
3080 } 3260 }
3261 lockPartsForRead(false);
3081 3262
3082 AbsolutePosition = newPos; 3263 AbsolutePosition = newPos;
3083 3264
@@ -3211,25 +3392,25 @@ namespace OpenSim.Region.Framework.Scenes
3211 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3392 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3212 } 3393 }
3213 3394
3214 lock (m_parts) 3395 lockPartsForRead(true);
3396
3397 foreach (SceneObjectPart prim in m_parts.Values)
3215 { 3398 {
3216 foreach (SceneObjectPart prim in m_parts.Values) 3399 if (prim.UUID != m_rootPart.UUID)
3217 { 3400 {
3218 if (prim.UUID != m_rootPart.UUID) 3401 prim.IgnoreUndoUpdate = true;
3219 { 3402 Vector3 axPos = prim.OffsetPosition;
3220 prim.IgnoreUndoUpdate = true; 3403 axPos *= oldParentRot;
3221 Vector3 axPos = prim.OffsetPosition; 3404 axPos *= Quaternion.Inverse(axRot);
3222 axPos *= oldParentRot; 3405 prim.OffsetPosition = axPos;
3223 axPos *= Quaternion.Inverse(axRot); 3406 Quaternion primsRot = prim.RotationOffset;
3224 prim.OffsetPosition = axPos; 3407 Quaternion newRot = primsRot * oldParentRot;
3225 Quaternion primsRot = prim.RotationOffset; 3408 newRot *= Quaternion.Inverse(axRot);
3226 Quaternion newRot = primsRot * oldParentRot; 3409 prim.RotationOffset = newRot;
3227 newRot *= Quaternion.Inverse(axRot); 3410 prim.ScheduleTerseUpdate();
3228 prim.RotationOffset = newRot;
3229 prim.ScheduleTerseUpdate();
3230 }
3231 } 3411 }
3232 } 3412 }
3413
3233 foreach (SceneObjectPart childpart in Children.Values) 3414 foreach (SceneObjectPart childpart in Children.Values)
3234 { 3415 {
3235 if (childpart != m_rootPart) 3416 if (childpart != m_rootPart)
@@ -3238,6 +3419,9 @@ namespace OpenSim.Region.Framework.Scenes
3238 childpart.StoreUndoState(); 3419 childpart.StoreUndoState();
3239 } 3420 }
3240 } 3421 }
3422
3423 lockPartsForRead(false);
3424
3241 m_rootPart.ScheduleTerseUpdate(); 3425 m_rootPart.ScheduleTerseUpdate();
3242 } 3426 }
3243 3427
@@ -3359,7 +3543,7 @@ namespace OpenSim.Region.Framework.Scenes
3359 if (atTargets.Count > 0) 3543 if (atTargets.Count > 0)
3360 { 3544 {
3361 uint[] localids = new uint[0]; 3545 uint[] localids = new uint[0];
3362 lock (m_parts) 3546 lockPartsForRead(true);
3363 { 3547 {
3364 localids = new uint[m_parts.Count]; 3548 localids = new uint[m_parts.Count];
3365 int cntr = 0; 3549 int cntr = 0;
@@ -3369,6 +3553,7 @@ namespace OpenSim.Region.Framework.Scenes
3369 cntr++; 3553 cntr++;
3370 } 3554 }
3371 } 3555 }
3556 lockPartsForRead(false);
3372 3557
3373 for (int ctr = 0; ctr < localids.Length; ctr++) 3558 for (int ctr = 0; ctr < localids.Length; ctr++)
3374 { 3559 {
@@ -3387,7 +3572,7 @@ namespace OpenSim.Region.Framework.Scenes
3387 { 3572 {
3388 //trigger not_at_target 3573 //trigger not_at_target
3389 uint[] localids = new uint[0]; 3574 uint[] localids = new uint[0];
3390 lock (m_parts) 3575 lockPartsForRead(true);
3391 { 3576 {
3392 localids = new uint[m_parts.Count]; 3577 localids = new uint[m_parts.Count];
3393 int cntr = 0; 3578 int cntr = 0;
@@ -3397,7 +3582,8 @@ namespace OpenSim.Region.Framework.Scenes
3397 cntr++; 3582 cntr++;
3398 } 3583 }
3399 } 3584 }
3400 3585 lockPartsForRead(false);
3586
3401 for (int ctr = 0; ctr < localids.Length; ctr++) 3587 for (int ctr = 0; ctr < localids.Length; ctr++)
3402 { 3588 {
3403 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3589 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3489,19 +3675,20 @@ namespace OpenSim.Region.Framework.Scenes
3489 public float GetMass() 3675 public float GetMass()
3490 { 3676 {
3491 float retmass = 0f; 3677 float retmass = 0f;
3492 lock (m_parts) 3678 lockPartsForRead(true);
3493 { 3679 {
3494 foreach (SceneObjectPart part in m_parts.Values) 3680 foreach (SceneObjectPart part in m_parts.Values)
3495 { 3681 {
3496 retmass += part.GetMass(); 3682 retmass += part.GetMass();
3497 } 3683 }
3498 } 3684 }
3685 lockPartsForRead(false);
3499 return retmass; 3686 return retmass;
3500 } 3687 }
3501 3688
3502 public void CheckSculptAndLoad() 3689 public void CheckSculptAndLoad()
3503 { 3690 {
3504 lock (m_parts) 3691 lockPartsForRead(true);
3505 { 3692 {
3506 if (!IsDeleted) 3693 if (!IsDeleted)
3507 { 3694 {
@@ -3526,6 +3713,7 @@ namespace OpenSim.Region.Framework.Scenes
3526 } 3713 }
3527 } 3714 }
3528 } 3715 }
3716 lockPartsForRead(false);
3529 } 3717 }
3530 3718
3531 protected void AssetReceived(string id, Object sender, AssetBase asset) 3719 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3546,7 +3734,7 @@ namespace OpenSim.Region.Framework.Scenes
3546 /// <param name="client"></param> 3734 /// <param name="client"></param>
3547 public void SetGroup(UUID GroupID, IClientAPI client) 3735 public void SetGroup(UUID GroupID, IClientAPI client)
3548 { 3736 {
3549 lock (m_parts) 3737 lockPartsForRead(true);
3550 { 3738 {
3551 foreach (SceneObjectPart part in m_parts.Values) 3739 foreach (SceneObjectPart part in m_parts.Values)
3552 { 3740 {
@@ -3556,7 +3744,7 @@ namespace OpenSim.Region.Framework.Scenes
3556 3744
3557 HasGroupChanged = true; 3745 HasGroupChanged = true;
3558 } 3746 }
3559 3747 lockPartsForRead(false);
3560 ScheduleGroupForFullUpdate(); 3748 ScheduleGroupForFullUpdate();
3561 } 3749 }
3562 3750
@@ -3575,11 +3763,12 @@ namespace OpenSim.Region.Framework.Scenes
3575 3763
3576 public void SetAttachmentPoint(byte point) 3764 public void SetAttachmentPoint(byte point)
3577 { 3765 {
3578 lock (m_parts) 3766 lockPartsForRead(true);
3579 { 3767 {
3580 foreach (SceneObjectPart part in m_parts.Values) 3768 foreach (SceneObjectPart part in m_parts.Values)
3581 part.SetAttachmentPoint(point); 3769 part.SetAttachmentPoint(point);
3582 } 3770 }
3771 lockPartsForRead(false);
3583 } 3772 }
3584 3773
3585 #region ISceneObject 3774 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index a85a4b3..e7f9f31 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -147,7 +147,7 @@ namespace OpenSim.Region.Framework.Scenes
147 147
148 // TODO: This needs to be persisted in next XML version update! 148 // TODO: This needs to be persisted in next XML version update!
149 [XmlIgnore] 149 [XmlIgnore]
150 public readonly int[] PayPrice = {-2,-2,-2,-2,-2}; 150 public int[] PayPrice = {-2,-2,-2,-2,-2};
151 [XmlIgnore] 151 [XmlIgnore]
152 public PhysicsActor PhysActor; 152 public PhysicsActor PhysActor;
153 153
@@ -274,6 +274,7 @@ namespace OpenSim.Region.Framework.Scenes
274 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 274 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
275 private Vector3 m_sitTargetPosition; 275 private Vector3 m_sitTargetPosition;
276 private string m_sitAnimation = "SIT"; 276 private string m_sitAnimation = "SIT";
277 private bool m_occupied; // KF if any av is sitting on this prim
277 private string m_text = String.Empty; 278 private string m_text = String.Empty;
278 private string m_touchName = String.Empty; 279 private string m_touchName = String.Empty;
279 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 280 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -452,12 +453,16 @@ namespace OpenSim.Region.Framework.Scenes
452 } 453 }
453 454
454 /// <value> 455 /// <value>
455 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 456 /// Get the inventory list
456 /// </value> 457 /// </value>
457 public TaskInventoryDictionary TaskInventory 458 public TaskInventoryDictionary TaskInventory
458 { 459 {
459 get { return m_inventory.Items; } 460 get {
460 set { m_inventory.Items = value; } 461 return m_inventory.Items;
462 }
463 set {
464 m_inventory.Items = value;
465 }
461 } 466 }
462 467
463 public uint ObjectFlags 468 public uint ObjectFlags
@@ -586,14 +591,12 @@ namespace OpenSim.Region.Framework.Scenes
586 set { m_LoopSoundSlavePrims = value; } 591 set { m_LoopSoundSlavePrims = value; }
587 } 592 }
588 593
589 [XmlIgnore]
590 public Byte[] TextureAnimation 594 public Byte[] TextureAnimation
591 { 595 {
592 get { return m_TextureAnimation; } 596 get { return m_TextureAnimation; }
593 set { m_TextureAnimation = value; } 597 set { m_TextureAnimation = value; }
594 } 598 }
595 599
596 [XmlIgnore]
597 public Byte[] ParticleSystem 600 public Byte[] ParticleSystem
598 { 601 {
599 get { return m_particleSystem; } 602 get { return m_particleSystem; }
@@ -647,7 +650,6 @@ namespace OpenSim.Region.Framework.Scenes
647 set 650 set
648 { 651 {
649 m_groupPosition = value; 652 m_groupPosition = value;
650
651 PhysicsActor actor = PhysActor; 653 PhysicsActor actor = PhysActor;
652 if (actor != null) 654 if (actor != null)
653 { 655 {
@@ -960,7 +962,8 @@ namespace OpenSim.Region.Framework.Scenes
960 if (IsAttachment) 962 if (IsAttachment)
961 return GroupPosition; 963 return GroupPosition;
962 964
963 return m_offsetPosition + m_groupPosition; } 965// return m_offsetPosition + m_groupPosition; }
966 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
964 } 967 }
965 968
966 public SceneObjectGroup ParentGroup 969 public SceneObjectGroup ParentGroup
@@ -1112,6 +1115,13 @@ namespace OpenSim.Region.Framework.Scenes
1112 get { return _flags; } 1115 get { return _flags; }
1113 set { _flags = value; } 1116 set { _flags = value; }
1114 } 1117 }
1118
1119 [XmlIgnore]
1120 public bool IsOccupied // KF If an av is sittingon this prim
1121 {
1122 get { return m_occupied; }
1123 set { m_occupied = value; }
1124 }
1115 1125
1116 [XmlIgnore] 1126 [XmlIgnore]
1117 public UUID SitTargetAvatar 1127 public UUID SitTargetAvatar
@@ -1187,14 +1197,6 @@ namespace OpenSim.Region.Framework.Scenes
1187 } 1197 }
1188 } 1198 }
1189 1199
1190 /// <summary>
1191 /// Clear all pending updates of parts to clients
1192 /// </summary>
1193 private void ClearUpdateSchedule()
1194 {
1195 m_updateFlag = 0;
1196 }
1197
1198 private void SendObjectPropertiesToClient(UUID AgentID) 1200 private void SendObjectPropertiesToClient(UUID AgentID)
1199 { 1201 {
1200 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1202 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1937,12 +1939,17 @@ namespace OpenSim.Region.Framework.Scenes
1937 public Vector3 GetWorldPosition() 1939 public Vector3 GetWorldPosition()
1938 { 1940 {
1939 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1941 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1940
1941 Vector3 axPos = OffsetPosition; 1942 Vector3 axPos = OffsetPosition;
1942
1943 axPos *= parentRot; 1943 axPos *= parentRot;
1944 Vector3 translationOffsetPosition = axPos; 1944 Vector3 translationOffsetPosition = axPos;
1945 return GroupPosition + translationOffsetPosition; 1945 if(_parentID == 0)
1946 {
1947 return GroupPosition;
1948 }
1949 else
1950 {
1951 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
1952 }
1946 } 1953 }
1947 1954
1948 /// <summary> 1955 /// <summary>
@@ -1953,7 +1960,7 @@ namespace OpenSim.Region.Framework.Scenes
1953 { 1960 {
1954 Quaternion newRot; 1961 Quaternion newRot;
1955 1962
1956 if (this.LinkNum == 0) 1963 if (this.LinkNum < 2) //KF Single or root prim
1957 { 1964 {
1958 newRot = RotationOffset; 1965 newRot = RotationOffset;
1959 } 1966 }
@@ -2610,17 +2617,18 @@ namespace OpenSim.Region.Framework.Scenes
2610 //Trys to fetch sound id from prim's inventory. 2617 //Trys to fetch sound id from prim's inventory.
2611 //Prim's inventory doesn't support non script items yet 2618 //Prim's inventory doesn't support non script items yet
2612 2619
2613 lock (TaskInventory) 2620 TaskInventory.LockItemsForRead(true);
2621
2622 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2614 { 2623 {
2615 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2624 if (item.Value.Name == sound)
2616 { 2625 {
2617 if (item.Value.Name == sound) 2626 soundID = item.Value.ItemID;
2618 { 2627 break;
2619 soundID = item.Value.ItemID;
2620 break;
2621 }
2622 } 2628 }
2623 } 2629 }
2630
2631 TaskInventory.LockItemsForRead(false);
2624 } 2632 }
2625 2633
2626 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2634 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2927,8 +2935,8 @@ namespace OpenSim.Region.Framework.Scenes
2927 { 2935 {
2928 const float ROTATION_TOLERANCE = 0.01f; 2936 const float ROTATION_TOLERANCE = 0.01f;
2929 const float VELOCITY_TOLERANCE = 0.001f; 2937 const float VELOCITY_TOLERANCE = 0.001f;
2930 const float POSITION_TOLERANCE = 0.05f; 2938 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2931 const int TIME_MS_TOLERANCE = 3000; 2939 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2932 2940
2933 if (m_updateFlag == 1) 2941 if (m_updateFlag == 1)
2934 { 2942 {
@@ -2942,7 +2950,7 @@ namespace OpenSim.Region.Framework.Scenes
2942 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2950 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2943 { 2951 {
2944 AddTerseUpdateToAllAvatars(); 2952 AddTerseUpdateToAllAvatars();
2945 ClearUpdateSchedule(); 2953
2946 2954
2947 // This causes the Scene to 'poll' physical objects every couple of frames 2955 // This causes the Scene to 'poll' physical objects every couple of frames
2948 // bad, so it's been replaced by an event driven method. 2956 // bad, so it's been replaced by an event driven method.
@@ -2960,16 +2968,18 @@ namespace OpenSim.Region.Framework.Scenes
2960 m_lastAngularVelocity = AngularVelocity; 2968 m_lastAngularVelocity = AngularVelocity;
2961 m_lastTerseSent = Environment.TickCount; 2969 m_lastTerseSent = Environment.TickCount;
2962 } 2970 }
2971 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2972 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2963 } 2973 }
2964 else 2974 else
2965 { 2975 {
2966 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2976 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2967 { 2977 {
2968 AddFullUpdateToAllAvatars(); 2978 AddFullUpdateToAllAvatars();
2969 ClearUpdateSchedule(); 2979 m_updateFlag = 0; //Same here
2970 } 2980 }
2971 } 2981 }
2972 ClearUpdateSchedule(); 2982 m_updateFlag = 0;
2973 } 2983 }
2974 2984
2975 /// <summary> 2985 /// <summary>
@@ -2996,17 +3006,16 @@ namespace OpenSim.Region.Framework.Scenes
2996 if (!UUID.TryParse(sound, out soundID)) 3006 if (!UUID.TryParse(sound, out soundID))
2997 { 3007 {
2998 // search sound file from inventory 3008 // search sound file from inventory
2999 lock (TaskInventory) 3009 TaskInventory.LockItemsForRead(true);
3010 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
3000 { 3011 {
3001 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3012 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
3002 { 3013 {
3003 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3014 soundID = item.Value.ItemID;
3004 { 3015 break;
3005 soundID = item.Value.ItemID;
3006 break;
3007 }
3008 } 3016 }
3009 } 3017 }
3018 TaskInventory.LockItemsForRead(false);
3010 } 3019 }
3011 3020
3012 if (soundID == UUID.Zero) 3021 if (soundID == UUID.Zero)
@@ -3189,6 +3198,22 @@ namespace OpenSim.Region.Framework.Scenes
3189 PhysActor.VehicleRotationParam(param, rotation); 3198 PhysActor.VehicleRotationParam(param, rotation);
3190 } 3199 }
3191 } 3200 }
3201
3202 public void SetVehicleFlags(int flags)
3203 {
3204 if (PhysActor != null)
3205 {
3206 PhysActor.VehicleFlagsSet(flags);
3207 }
3208 }
3209
3210 public void RemoveVehicleFlags(int flags)
3211 {
3212 if (PhysActor != null)
3213 {
3214 PhysActor.VehicleFlagsRemove(flags);
3215 }
3216 }
3192 3217
3193 /// <summary> 3218 /// <summary>
3194 /// Set the color of prim faces 3219 /// Set the color of prim faces
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index a555eae..5d00917 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,36 +290,31 @@ 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 }
318 320
@@ -379,14 +381,17 @@ namespace OpenSim.Region.Framework.Scenes
379 /// </param> 381 /// </param>
380 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 382 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
381 { 383 {
382 lock (m_items) 384 m_items.LockItemsForRead(true);
385 if (m_items.ContainsKey(itemId))
383 { 386 {
384 if (m_items.ContainsKey(itemId)) 387 if (m_items.ContainsKey(itemId))
385 { 388 {
389 m_items.LockItemsForRead(false);
386 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 390 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
387 } 391 }
388 else 392 else
389 { 393 {
394 m_items.LockItemsForRead(false);
390 m_log.ErrorFormat( 395 m_log.ErrorFormat(
391 "[PRIM INVENTORY]: " + 396 "[PRIM INVENTORY]: " +
392 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 397 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
@@ -394,6 +399,15 @@ namespace OpenSim.Region.Framework.Scenes
394 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 399 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
395 } 400 }
396 } 401 }
402 else
403 {
404 m_items.LockItemsForRead(false);
405 m_log.ErrorFormat(
406 "[PRIM INVENTORY]: " +
407 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
408 itemId, m_part.Name, m_part.UUID);
409 }
410
397 } 411 }
398 412
399 /// <summary> 413 /// <summary>
@@ -406,15 +420,7 @@ namespace OpenSim.Region.Framework.Scenes
406 /// </param> 420 /// </param>
407 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 421 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
408 { 422 {
409 bool scriptPresent = false; 423 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 { 424 {
419 if (!sceneObjectBeingDeleted) 425 if (!sceneObjectBeingDeleted)
420 m_part.RemoveScriptEvents(itemId); 426 m_part.RemoveScriptEvents(itemId);
@@ -440,11 +446,16 @@ namespace OpenSim.Region.Framework.Scenes
440 /// <returns></returns> 446 /// <returns></returns>
441 private bool InventoryContainsName(string name) 447 private bool InventoryContainsName(string name)
442 { 448 {
443 foreach (TaskInventoryItem item in Items.Values) 449 m_items.LockItemsForRead(true);
450 foreach (TaskInventoryItem item in m_items.Values)
444 { 451 {
445 if (item.Name == name) 452 if (item.Name == name)
453 {
454 m_items.LockItemsForRead(false);
446 return true; 455 return true;
456 }
447 } 457 }
458 m_items.LockItemsForRead(false);
448 return false; 459 return false;
449 } 460 }
450 461
@@ -486,13 +497,9 @@ namespace OpenSim.Region.Framework.Scenes
486 /// <param name="item"></param> 497 /// <param name="item"></param>
487 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 498 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
488 { 499 {
489 List<TaskInventoryItem> il; 500 m_items.LockItemsForRead(true);
490 501 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
491 lock (m_items) 502 m_items.LockItemsForRead(false);
492 {
493 il = new List<TaskInventoryItem>(m_items.Values);
494 }
495
496 foreach (TaskInventoryItem i in il) 503 foreach (TaskInventoryItem i in il)
497 { 504 {
498 if (i.Name == item.Name) 505 if (i.Name == item.Name)
@@ -529,15 +536,14 @@ namespace OpenSim.Region.Framework.Scenes
529 item.ParentPartID = m_part.UUID; 536 item.ParentPartID = m_part.UUID;
530 item.Name = name; 537 item.Name = name;
531 538
532 lock (m_items) 539 m_items.LockItemsForWrite(true);
533 { 540 m_items.Add(item.ItemID, item);
534 m_items.Add(item.ItemID, item); 541 m_items.LockItemsForWrite(false);
535
536 if (allowedDrop) 542 if (allowedDrop)
537 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 543 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
538 else 544 else
539 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 545 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
540 } 546
541 547
542 m_inventorySerial++; 548 m_inventorySerial++;
543 //m_inventorySerial += 2; 549 //m_inventorySerial += 2;
@@ -554,14 +560,13 @@ namespace OpenSim.Region.Framework.Scenes
554 /// <param name="items"></param> 560 /// <param name="items"></param>
555 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 561 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
556 { 562 {
557 lock (m_items) 563 m_items.LockItemsForWrite(true);
564 foreach (TaskInventoryItem item in items)
558 { 565 {
559 foreach (TaskInventoryItem item in items) 566 m_items.Add(item.ItemID, item);
560 { 567 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
561 m_items.Add(item.ItemID, item);
562 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
563 }
564 } 568 }
569 m_items.LockItemsForWrite(false);
565 570
566 m_inventorySerial++; 571 m_inventorySerial++;
567 } 572 }
@@ -574,10 +579,9 @@ namespace OpenSim.Region.Framework.Scenes
574 public TaskInventoryItem GetInventoryItem(UUID itemId) 579 public TaskInventoryItem GetInventoryItem(UUID itemId)
575 { 580 {
576 TaskInventoryItem item; 581 TaskInventoryItem item;
577 582 m_items.LockItemsForRead(true);
578 lock (m_items) 583 m_items.TryGetValue(itemId, out item);
579 m_items.TryGetValue(itemId, out item); 584 m_items.LockItemsForRead(false);
580
581 return item; 585 return item;
582 } 586 }
583 587
@@ -613,46 +617,46 @@ namespace OpenSim.Region.Framework.Scenes
613 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 617 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
614 public bool UpdateInventoryItem(TaskInventoryItem item) 618 public bool UpdateInventoryItem(TaskInventoryItem item)
615 { 619 {
616 lock (m_items) 620 m_items.LockItemsForWrite(true);
621
622 if (m_items.ContainsKey(item.ItemID))
617 { 623 {
618 if (m_items.ContainsKey(item.ItemID)) 624 item.ParentID = m_part.UUID;
625 item.ParentPartID = m_part.UUID;
626 item.Flags = m_items[item.ItemID].Flags;
627 if (item.AssetID == UUID.Zero)
619 { 628 {
620 item.ParentID = m_part.UUID; 629 item.AssetID = m_items[item.ItemID].AssetID;
621 item.ParentPartID = m_part.UUID; 630 }
622 item.Flags = m_items[item.ItemID].Flags; 631 else if ((InventoryType)item.Type == InventoryType.Notecard)
623 if (item.AssetID == UUID.Zero) 632 {
624 { 633 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 634
631 if (presence != null) 635 if (presence != null)
632 { 636 {
633 presence.ControllingClient.SendAgentAlertMessage( 637 presence.ControllingClient.SendAgentAlertMessage(
634 "Notecard saved", false); 638 "Notecard saved", false);
635 }
636 } 639 }
640 }
637 641
638 m_items[item.ItemID] = item; 642 m_items[item.ItemID] = item;
639 m_inventorySerial++; 643 m_inventorySerial++;
640 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 644 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
641
642 HasInventoryChanged = true;
643 m_part.ParentGroup.HasGroupChanged = true;
644 645
645 return true; 646 HasInventoryChanged = true;
646 } 647 m_part.ParentGroup.HasGroupChanged = true;
647 else 648 m_items.LockItemsForWrite(false);
648 { 649 return true;
649 m_log.ErrorFormat( 650 }
650 "[PRIM INVENTORY]: " + 651 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", 652 {
652 item.ItemID, m_part.Name, m_part.UUID, 653 m_log.ErrorFormat(
653 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 654 "[PRIM INVENTORY]: " +
654 } 655 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
656 item.ItemID, m_part.Name, m_part.UUID,
657 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
655 } 658 }
659 m_items.LockItemsForWrite(false);
656 660
657 return false; 661 return false;
658 } 662 }
@@ -665,53 +669,54 @@ namespace OpenSim.Region.Framework.Scenes
665 /// in this prim's inventory.</returns> 669 /// in this prim's inventory.</returns>
666 public int RemoveInventoryItem(UUID itemID) 670 public int RemoveInventoryItem(UUID itemID)
667 { 671 {
668 lock (m_items) 672 m_items.LockItemsForRead(true);
673
674 if (m_items.ContainsKey(itemID))
669 { 675 {
670 if (m_items.ContainsKey(itemID)) 676 int type = m_items[itemID].InvType;
677 m_items.LockItemsForRead(false);
678 if (type == 10) // Script
671 { 679 {
672 int type = m_items[itemID].InvType; 680 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
673 if (type == 10) // Script 681 }
674 { 682 m_items.LockItemsForWrite(true);
675 m_part.RemoveScriptEvents(itemID); 683 m_items.Remove(itemID);
676 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 684 m_items.LockItemsForWrite(false);
677 } 685 m_inventorySerial++;
678 m_items.Remove(itemID); 686 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 687
685 int scriptcount = 0; 688 HasInventoryChanged = true;
686 lock (m_items) 689 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 690
697 if (scriptcount <= 0) 691 int scriptcount = 0;
692 m_items.LockItemsForRead(true);
693 foreach (TaskInventoryItem item in m_items.Values)
694 {
695 if (item.Type == 10)
698 { 696 {
699 m_part.RemFlag(PrimFlags.Scripted); 697 scriptcount++;
700 } 698 }
701
702 m_part.ScheduleFullUpdate();
703
704 return type;
705 } 699 }
706 else 700 m_items.LockItemsForRead(false);
701
702
703 if (scriptcount <= 0)
707 { 704 {
708 m_log.ErrorFormat( 705 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 } 706 }
707
708 m_part.ScheduleFullUpdate();
709
710 return type;
711 }
712 else
713 {
714 m_log.ErrorFormat(
715 "[PRIM INVENTORY]: " +
716 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
717 itemID, m_part.Name, m_part.UUID);
714 } 718 }
719 m_items.LockItemsForWrite(false);
715 720
716 return -1; 721 return -1;
717 } 722 }
@@ -764,52 +769,53 @@ namespace OpenSim.Region.Framework.Scenes
764 // isn't available (such as drag from prim inventory to agent inventory) 769 // isn't available (such as drag from prim inventory to agent inventory)
765 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 770 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
766 771
767 lock (m_items) 772 m_items.LockItemsForRead(true);
773
774 foreach (TaskInventoryItem item in m_items.Values)
768 { 775 {
769 foreach (TaskInventoryItem item in m_items.Values) 776 UUID ownerID = item.OwnerID;
770 { 777 uint everyoneMask = 0;
771 UUID ownerID = item.OwnerID; 778 uint baseMask = item.BasePermissions;
772 uint everyoneMask = 0; 779 uint ownerMask = item.CurrentPermissions;
773 uint baseMask = item.BasePermissions;
774 uint ownerMask = item.CurrentPermissions;
775 780
776 invString.AddItemStart(); 781 invString.AddItemStart();
777 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 782 invString.AddNameValueLine("item_id", item.ItemID.ToString());
778 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 783 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
779 784
780 invString.AddPermissionsStart(); 785 invString.AddPermissionsStart();
781 786
782 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 787 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
783 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 788 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
784 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 789 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
785 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 790 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
786 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 791 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
787 792
788 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 793 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
789 invString.AddNameValueLine("owner_id", ownerID.ToString()); 794 invString.AddNameValueLine("owner_id", ownerID.ToString());
790 795
791 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 796 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
792 797
793 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 798 invString.AddNameValueLine("group_id", item.GroupID.ToString());
794 invString.AddSectionEnd(); 799 invString.AddSectionEnd();
795 800
796 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 801 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
797 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 802 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
798 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 803 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
799 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 804 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
800 805
801 invString.AddSaleStart(); 806 invString.AddSaleStart();
802 invString.AddNameValueLine("sale_type", "not"); 807 invString.AddNameValueLine("sale_type", "not");
803 invString.AddNameValueLine("sale_price", "0"); 808 invString.AddNameValueLine("sale_price", "0");
804 invString.AddSectionEnd(); 809 invString.AddSectionEnd();
805 810
806 invString.AddNameValueLine("name", item.Name + "|"); 811 invString.AddNameValueLine("name", item.Name + "|");
807 invString.AddNameValueLine("desc", item.Description + "|"); 812 invString.AddNameValueLine("desc", item.Description + "|");
808 813
809 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 814 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
810 invString.AddSectionEnd(); 815 invString.AddSectionEnd();
811 }
812 } 816 }
817 int count = m_items.Count;
818 m_items.LockItemsForRead(false);
813 819
814 fileData = Utils.StringToBytes(invString.BuildString); 820 fileData = Utils.StringToBytes(invString.BuildString);
815 821
@@ -830,10 +836,9 @@ namespace OpenSim.Region.Framework.Scenes
830 { 836 {
831 if (HasInventoryChanged) 837 if (HasInventoryChanged)
832 { 838 {
833 lock (Items) 839 Items.LockItemsForRead(true);
834 { 840 datastore.StorePrimInventory(m_part.UUID, Items.Values);
835 datastore.StorePrimInventory(m_part.UUID, Items.Values); 841 Items.LockItemsForRead(false);
836 }
837 842
838 HasInventoryChanged = false; 843 HasInventoryChanged = false;
839 } 844 }
@@ -902,61 +907,54 @@ namespace OpenSim.Region.Framework.Scenes
902 { 907 {
903 uint mask=0x7fffffff; 908 uint mask=0x7fffffff;
904 909
905 lock (m_items) 910 foreach (TaskInventoryItem item in m_items.Values)
906 { 911 {
907 foreach (TaskInventoryItem item in m_items.Values) 912 if (item.InvType != (int)InventoryType.Object)
908 { 913 {
909 if (item.InvType != (int)InventoryType.Object) 914 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
910 { 915 mask &= ~((uint)PermissionMask.Copy >> 13);
911 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 916 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
912 mask &= ~((uint)PermissionMask.Copy >> 13); 917 mask &= ~((uint)PermissionMask.Transfer >> 13);
913 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 918 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
914 mask &= ~((uint)PermissionMask.Transfer >> 13); 919 mask &= ~((uint)PermissionMask.Modify >> 13);
915 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 920 }
916 mask &= ~((uint)PermissionMask.Modify >> 13); 921 else
917 } 922 {
918 else 923 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
919 { 924 mask &= ~((uint)PermissionMask.Copy >> 13);
920 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 925 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
921 mask &= ~((uint)PermissionMask.Copy >> 13); 926 mask &= ~((uint)PermissionMask.Transfer >> 13);
922 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 927 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
923 mask &= ~((uint)PermissionMask.Transfer >> 13); 928 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 } 929 }
930
931 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
932 mask &= ~(uint)PermissionMask.Copy;
933 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
934 mask &= ~(uint)PermissionMask.Transfer;
935 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
936 mask &= ~(uint)PermissionMask.Modify;
935 } 937 }
936
937 return mask; 938 return mask;
938 } 939 }
939 940
940 public void ApplyNextOwnerPermissions() 941 public void ApplyNextOwnerPermissions()
941 { 942 {
942 lock (m_items) 943 foreach (TaskInventoryItem item in m_items.Values)
943 { 944 {
944 foreach (TaskInventoryItem item in m_items.Values) 945 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
945 { 946 {
946 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 947 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
947 { 948 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
948 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 949 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
949 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 950 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
950 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 951 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
951 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 952 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
952 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 953 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 } 954 }
955 item.CurrentPermissions &= item.NextPermissions;
956 item.BasePermissions &= item.NextPermissions;
957 item.EveryonePermissions &= item.NextPermissions;
960 } 958 }
961 959
962 m_part.TriggerScriptChangedEvent(Changed.OWNER); 960 m_part.TriggerScriptChangedEvent(Changed.OWNER);
@@ -964,29 +962,22 @@ namespace OpenSim.Region.Framework.Scenes
964 962
965 public void ApplyGodPermissions(uint perms) 963 public void ApplyGodPermissions(uint perms)
966 { 964 {
967 lock (m_items) 965 foreach (TaskInventoryItem item in m_items.Values)
968 { 966 {
969 foreach (TaskInventoryItem item in m_items.Values) 967 item.CurrentPermissions = perms;
970 { 968 item.BasePermissions = perms;
971 item.CurrentPermissions = perms;
972 item.BasePermissions = perms;
973 }
974 } 969 }
975 } 970 }
976 971
977 public bool ContainsScripts() 972 public bool ContainsScripts()
978 { 973 {
979 lock (m_items) 974 foreach (TaskInventoryItem item in m_items.Values)
980 { 975 {
981 foreach (TaskInventoryItem item in m_items.Values) 976 if (item.InvType == (int)InventoryType.LSL)
982 { 977 {
983 if (item.InvType == (int)InventoryType.LSL) 978 return true;
984 {
985 return true;
986 }
987 } 979 }
988 } 980 }
989
990 return false; 981 return false;
991 } 982 }
992 983
@@ -994,11 +985,8 @@ namespace OpenSim.Region.Framework.Scenes
994 { 985 {
995 List<UUID> ret = new List<UUID>(); 986 List<UUID> ret = new List<UUID>();
996 987
997 lock (m_items) 988 foreach (TaskInventoryItem item in m_items.Values)
998 { 989 ret.Add(item.ItemID);
999 foreach (TaskInventoryItem item in m_items.Values)
1000 ret.Add(item.ItemID);
1001 }
1002 990
1003 return ret; 991 return ret;
1004 } 992 }
@@ -1011,30 +999,26 @@ namespace OpenSim.Region.Framework.Scenes
1011 if (engines == null) // No engine at all 999 if (engines == null) // No engine at all
1012 return ret; 1000 return ret;
1013 1001
1014 lock (m_items) 1002 foreach (TaskInventoryItem item in m_items.Values)
1015 { 1003 {
1016 foreach (TaskInventoryItem item in m_items.Values) 1004 if (item.InvType == (int)InventoryType.LSL)
1017 { 1005 {
1018 if (item.InvType == (int)InventoryType.LSL) 1006 foreach (IScriptModule e in engines)
1019 { 1007 {
1020 foreach (IScriptModule e in engines) 1008 if (e != null)
1021 { 1009 {
1022 if (e != null) 1010 string n = e.GetXMLState(item.ItemID);
1011 if (n != String.Empty)
1023 { 1012 {
1024 string n = e.GetXMLState(item.ItemID); 1013 if (!ret.ContainsKey(item.ItemID))
1025 if (n != String.Empty) 1014 ret[item.ItemID] = n;
1026 { 1015 break;
1027 if (!ret.ContainsKey(item.ItemID))
1028 ret[item.ItemID] = n;
1029 break;
1030 }
1031 } 1016 }
1032 } 1017 }
1033 } 1018 }
1034 } 1019 }
1035 } 1020 }
1036
1037 return ret; 1021 return ret;
1038 } 1022 }
1039 } 1023 }
1040} \ No newline at end of file 1024}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4973663..123d6f3 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -123,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
126 128
127 private Vector3 m_lastPosition; 129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -134,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes
134 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
135 private uint m_requestedSitTargetID; 140 private uint m_requestedSitTargetID;
136 private UUID m_requestedSitTargetUUID; 141 private UUID m_requestedSitTargetUUID;
137 public bool SitGround = false;
138 142
139 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 143 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
140 144
@@ -156,7 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
156 private int m_perfMonMS; 160 private int m_perfMonMS;
157 161
158 private bool m_setAlwaysRun; 162 private bool m_setAlwaysRun;
159
160 private bool m_forceFly; 163 private bool m_forceFly;
161 private bool m_flyDisabled; 164 private bool m_flyDisabled;
162 165
@@ -182,7 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
182 protected RegionInfo m_regionInfo; 185 protected RegionInfo m_regionInfo;
183 protected ulong crossingFromRegion; 186 protected ulong crossingFromRegion;
184 187
185 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 188 private readonly Vector3[] Dir_Vectors = new Vector3[11];
189 private bool m_isNudging = false;
186 190
187 // Position of agent's camera in world (region cordinates) 191 // Position of agent's camera in world (region cordinates)
188 protected Vector3 m_CameraCenter; 192 protected Vector3 m_CameraCenter;
@@ -207,6 +211,7 @@ namespace OpenSim.Region.Framework.Scenes
207 private bool m_autopilotMoving; 211 private bool m_autopilotMoving;
208 private Vector3 m_autoPilotTarget; 212 private Vector3 m_autoPilotTarget;
209 private bool m_sitAtAutoTarget; 213 private bool m_sitAtAutoTarget;
214 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
210 215
211 private string m_nextSitAnimation = String.Empty; 216 private string m_nextSitAnimation = String.Empty;
212 217
@@ -217,6 +222,9 @@ namespace OpenSim.Region.Framework.Scenes
217 private bool m_followCamAuto; 222 private bool m_followCamAuto;
218 223
219 private int m_movementUpdateCount; 224 private int m_movementUpdateCount;
225 private int m_lastColCount = -1; //KF: Look for Collision chnages
226 private int m_updateCount = 0; //KF: Update Anims for a while
227 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
220 228
221 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
222 230
@@ -245,7 +253,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 253 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 254 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 255 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 256 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
257 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
258 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 259 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 260 }
251 261
@@ -680,10 +690,7 @@ namespace OpenSim.Region.Framework.Scenes
680 m_reprioritization_timer.AutoReset = false; 690 m_reprioritization_timer.AutoReset = false;
681 691
682 AdjustKnownSeeds(); 692 AdjustKnownSeeds();
683
684 // TODO: I think, this won't send anything, as we are still a child here...
685 Animator.TrySetMovementAnimation("STAND"); 693 Animator.TrySetMovementAnimation("STAND");
686
687 // we created a new ScenePresence (a new child agent) in a fresh region. 694 // we created a new ScenePresence (a new child agent) in a fresh region.
688 // Request info about all the (root) agents in this region 695 // Request info about all the (root) agents in this region
689 // Note: This won't send data *to* other clients in that region (children don't send) 696 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -739,25 +746,47 @@ namespace OpenSim.Region.Framework.Scenes
739 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 746 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
740 Dir_Vectors[4] = Vector3.UnitZ; //UP 747 Dir_Vectors[4] = Vector3.UnitZ; //UP
741 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 748 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
742 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 749 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
743 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 750 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
744 Dir_Vectors[7] = -Vector3.UnitX; //BACK 751 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
752 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
753 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
745 } 754 }
746 755
747 private Vector3[] GetWalkDirectionVectors() 756 private Vector3[] GetWalkDirectionVectors()
748 { 757 {
749 Vector3[] vector = new Vector3[9]; 758 Vector3[] vector = new Vector3[11];
750 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 759 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
751 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 760 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
752 vector[2] = Vector3.UnitY; //LEFT 761 vector[2] = Vector3.UnitY; //LEFT
753 vector[3] = -Vector3.UnitY; //RIGHT 762 vector[3] = -Vector3.UnitY; //RIGHT
754 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 763 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
755 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 764 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
756 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 765 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
757 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 766 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
758 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 767 vector[8] = Vector3.UnitY; //LEFT_NUDGE
768 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
769 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
759 return vector; 770 return vector;
760 } 771 }
772
773 private bool[] GetDirectionIsNudge()
774 {
775 bool[] isNudge = new bool[11];
776 isNudge[0] = false; //FORWARD
777 isNudge[1] = false; //BACK
778 isNudge[2] = false; //LEFT
779 isNudge[3] = false; //RIGHT
780 isNudge[4] = false; //UP
781 isNudge[5] = false; //DOWN
782 isNudge[6] = true; //FORWARD_NUDGE
783 isNudge[7] = true; //BACK_NUDGE
784 isNudge[8] = true; //LEFT_NUDGE
785 isNudge[9] = true; //RIGHT_NUDGE
786 isNudge[10] = true; //DOWN_Nudge
787 return isNudge;
788 }
789
761 790
762 #endregion 791 #endregion
763 792
@@ -826,9 +855,24 @@ namespace OpenSim.Region.Framework.Scenes
826 { 855 {
827 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 856 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
828 pos.Y = crossedBorder.BorderLine.Z - 1; 857 pos.Y = crossedBorder.BorderLine.Z - 1;
858 }
859
860 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
861 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
862 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
863 if (KnownChildRegionHandles.Count == 0)
864 {
865 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
866 if (land != null)
867 {
868 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
869 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)
870 {
871 pos = land.LandData.UserLocation;
872 }
873 }
829 } 874 }
830 875
831
832 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 876 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
833 { 877 {
834 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 878 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -988,9 +1032,10 @@ namespace OpenSim.Region.Framework.Scenes
988 public void Teleport(Vector3 pos) 1032 public void Teleport(Vector3 pos)
989 { 1033 {
990 bool isFlying = false; 1034 bool isFlying = false;
991 if (m_physicsActor != null)
992 isFlying = m_physicsActor.Flying;
993 1035
1036 if (m_physicsActor != null)
1037 isFlying = m_physicsActor.Flying;
1038
994 RemoveFromPhysicalScene(); 1039 RemoveFromPhysicalScene();
995 Velocity = Vector3.Zero; 1040 Velocity = Vector3.Zero;
996 AbsolutePosition = pos; 1041 AbsolutePosition = pos;
@@ -1001,7 +1046,8 @@ namespace OpenSim.Region.Framework.Scenes
1001 SetHeight(m_appearance.AvatarHeight); 1046 SetHeight(m_appearance.AvatarHeight);
1002 } 1047 }
1003 1048
1004 SendTerseUpdateToAllClients(); 1049 SendTerseUpdateToAllClients();
1050
1005 } 1051 }
1006 1052
1007 public void TeleportWithMomentum(Vector3 pos) 1053 public void TeleportWithMomentum(Vector3 pos)
@@ -1046,7 +1092,9 @@ namespace OpenSim.Region.Framework.Scenes
1046 { 1092 {
1047 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1093 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1048 } 1094 }
1049 1095
1096 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1097
1050 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1098 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1051 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1099 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1052 } 1100 }
@@ -1280,7 +1328,6 @@ namespace OpenSim.Region.Framework.Scenes
1280 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1328 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1281 } 1329 }
1282 } 1330 }
1283
1284 lock (scriptedcontrols) 1331 lock (scriptedcontrols)
1285 { 1332 {
1286 if (scriptedcontrols.Count > 0) 1333 if (scriptedcontrols.Count > 0)
@@ -1295,12 +1342,8 @@ namespace OpenSim.Region.Framework.Scenes
1295 1342
1296 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1343 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1297 { 1344 {
1298 // TODO: This doesn't prevent the user from walking yet. 1345 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1299 // Setting parent ID would fix this, if we knew what value 1346 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1300 // to use. Or we could add a m_isSitting variable.
1301 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1302 SitGround = true;
1303
1304 } 1347 }
1305 1348
1306 // In the future, these values might need to go global. 1349 // In the future, these values might need to go global.
@@ -1350,6 +1393,11 @@ namespace OpenSim.Region.Framework.Scenes
1350 update_rotation = true; 1393 update_rotation = true;
1351 } 1394 }
1352 1395
1396 //guilty until proven innocent..
1397 bool Nudging = true;
1398 //Basically, if there is at least one non-nudge control then we don't need
1399 //to worry about stopping the avatar
1400
1353 if (m_parentID == 0) 1401 if (m_parentID == 0)
1354 { 1402 {
1355 bool bAllowUpdateMoveToPosition = false; 1403 bool bAllowUpdateMoveToPosition = false;
@@ -1364,9 +1412,12 @@ namespace OpenSim.Region.Framework.Scenes
1364 else 1412 else
1365 dirVectors = Dir_Vectors; 1413 dirVectors = Dir_Vectors;
1366 1414
1367 // The fact that m_movementflag is a byte needs to be fixed 1415 bool[] isNudge = GetDirectionIsNudge();
1368 // it really should be a uint 1416
1369 uint nudgehack = 250; 1417
1418
1419
1420
1370 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1421 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1371 { 1422 {
1372 if (((uint)flags & (uint)DCF) != 0) 1423 if (((uint)flags & (uint)DCF) != 0)
@@ -1376,40 +1427,28 @@ namespace OpenSim.Region.Framework.Scenes
1376 try 1427 try
1377 { 1428 {
1378 agent_control_v3 += dirVectors[i]; 1429 agent_control_v3 += dirVectors[i];
1379 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1430 if (isNudge[i] == false)
1431 {
1432 Nudging = false;
1433 }
1380 } 1434 }
1381 catch (IndexOutOfRangeException) 1435 catch (IndexOutOfRangeException)
1382 { 1436 {
1383 // Why did I get this? 1437 // Why did I get this?
1384 } 1438 }
1385 1439
1386 if ((m_movementflag & (byte)(uint)DCF) == 0) 1440 if ((m_movementflag & (uint)DCF) == 0)
1387 { 1441 {
1388 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1389 {
1390 m_movementflag |= (byte)nudgehack;
1391 }
1392 m_movementflag += (byte)(uint)DCF; 1442 m_movementflag += (byte)(uint)DCF;
1393 update_movementflag = true; 1443 update_movementflag = true;
1394 } 1444 }
1395 } 1445 }
1396 else 1446 else
1397 { 1447 {
1398 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1448 if ((m_movementflag & (uint)DCF) != 0)
1399 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1400 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1401 ) // This or is for Nudge forward
1402 { 1449 {
1403 m_movementflag -= ((byte)(uint)DCF); 1450 m_movementflag -= (byte)(uint)DCF;
1404
1405 update_movementflag = true; 1451 update_movementflag = true;
1406 /*
1407 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1408 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1409 {
1410 m_log.Debug("Removed Hack flag");
1411 }
1412 */
1413 } 1452 }
1414 else 1453 else
1415 { 1454 {
@@ -1453,6 +1492,9 @@ namespace OpenSim.Region.Framework.Scenes
1453 // Ignore z component of vector 1492 // Ignore z component of vector
1454 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1493 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1455 LocalVectorToTarget2D.Normalize(); 1494 LocalVectorToTarget2D.Normalize();
1495
1496 //We're not nudging
1497 Nudging = false;
1456 agent_control_v3 += LocalVectorToTarget2D; 1498 agent_control_v3 += LocalVectorToTarget2D;
1457 1499
1458 // update avatar movement flags. the avatar coordinate system is as follows: 1500 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1541,13 +1583,13 @@ namespace OpenSim.Region.Framework.Scenes
1541 // m_log.DebugFormat( 1583 // m_log.DebugFormat(
1542 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1584 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1543 1585
1544 AddNewMovement(agent_control_v3, q); 1586 AddNewMovement(agent_control_v3, q, Nudging);
1545 1587
1546 1588
1547 } 1589 }
1548 } 1590 }
1549 1591
1550 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1592 if (update_movementflag)
1551 Animator.UpdateMovementAnimations(); 1593 Animator.UpdateMovementAnimations();
1552 1594
1553 m_scene.EventManager.TriggerOnClientMovement(this); 1595 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1562,7 +1604,6 @@ namespace OpenSim.Region.Framework.Scenes
1562 m_sitAtAutoTarget = false; 1604 m_sitAtAutoTarget = false;
1563 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1605 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1564 //proxy.PCode = (byte)PCode.ParticleSystem; 1606 //proxy.PCode = (byte)PCode.ParticleSystem;
1565
1566 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1607 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1567 proxyObjectGroup.AttachToScene(m_scene); 1608 proxyObjectGroup.AttachToScene(m_scene);
1568 1609
@@ -1604,7 +1645,7 @@ namespace OpenSim.Region.Framework.Scenes
1604 } 1645 }
1605 m_moveToPositionInProgress = true; 1646 m_moveToPositionInProgress = true;
1606 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1647 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1607 } 1648 }
1608 catch (Exception ex) 1649 catch (Exception ex)
1609 { 1650 {
1610 //Why did I get this error? 1651 //Why did I get this error?
@@ -1626,7 +1667,7 @@ namespace OpenSim.Region.Framework.Scenes
1626 Velocity = Vector3.Zero; 1667 Velocity = Vector3.Zero;
1627 SendFullUpdateToAllClients(); 1668 SendFullUpdateToAllClients();
1628 1669
1629 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1670 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1630 } 1671 }
1631 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1672 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1632 m_requestedSitTargetUUID = UUID.Zero; 1673 m_requestedSitTargetUUID = UUID.Zero;
@@ -1659,55 +1700,84 @@ namespace OpenSim.Region.Framework.Scenes
1659 /// </summary> 1700 /// </summary>
1660 public void StandUp() 1701 public void StandUp()
1661 { 1702 {
1662 if (SitGround)
1663 SitGround = false;
1664
1665 if (m_parentID != 0) 1703 if (m_parentID != 0)
1666 { 1704 {
1667 m_log.Debug("StandupCode Executed");
1668 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1705 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1669 if (part != null) 1706 if (part != null)
1670 { 1707 {
1708 part.TaskInventory.LockItemsForRead(true);
1671 TaskInventoryDictionary taskIDict = part.TaskInventory; 1709 TaskInventoryDictionary taskIDict = part.TaskInventory;
1672 if (taskIDict != null) 1710 if (taskIDict != null)
1673 { 1711 {
1674 lock (taskIDict) 1712 foreach (UUID taskID in taskIDict.Keys)
1675 { 1713 {
1676 foreach (UUID taskID in taskIDict.Keys) 1714 UnRegisterControlEventsToScript(LocalId, taskID);
1677 { 1715 taskIDict[taskID].PermsMask &= ~(
1678 UnRegisterControlEventsToScript(LocalId, taskID); 1716 2048 | //PERMISSION_CONTROL_CAMERA
1679 taskIDict[taskID].PermsMask &= ~( 1717 4); // PERMISSION_TAKE_CONTROLS
1680 2048 | //PERMISSION_CONTROL_CAMERA
1681 4); // PERMISSION_TAKE_CONTROLS
1682 }
1683 } 1718 }
1684
1685 } 1719 }
1720 part.TaskInventory.LockItemsForRead(false);
1686 // Reset sit target. 1721 // Reset sit target.
1687 if (part.GetAvatarOnSitTarget() == UUID) 1722 if (part.GetAvatarOnSitTarget() == UUID)
1688 part.SetAvatarOnSitTarget(UUID.Zero); 1723 part.SetAvatarOnSitTarget(UUID.Zero);
1689
1690 m_parentPosition = part.GetWorldPosition(); 1724 m_parentPosition = part.GetWorldPosition();
1691 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1725 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1692 } 1726 }
1693 1727 // part.GetWorldRotation() is the rotation of the object being sat on
1694 if (m_physicsActor == null) 1728 // Rotation is the sittiing Av's rotation
1695 { 1729
1696 AddToPhysicalScene(false); 1730 Quaternion partRot;
1731// if (part.LinkNum == 1)
1732// { // Root prim of linkset
1733// partRot = part.ParentGroup.RootPart.RotationOffset;
1734// }
1735// else
1736// { // single or child prim
1737
1738// }
1739 if (part == null) //CW: Part may be gone. llDie() for example.
1740 {
1741 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1742 }
1743 else
1744 {
1745 partRot = part.GetWorldRotation();
1697 } 1746 }
1698 1747
1699 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1748 Quaternion partIRot = Quaternion.Inverse(partRot);
1700 m_parentPosition = Vector3.Zero; 1749
1750 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1751 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1701 1752
1702 m_parentID = 0; 1753
1754 if (m_physicsActor == null)
1755 {
1756 AddToPhysicalScene(false);
1757 }
1758 //CW: If the part isn't null then we can set the current position
1759 if (part != null)
1760 {
1761 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1762 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1763 part.IsOccupied = false;
1764 }
1765 else
1766 {
1767 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1768 AbsolutePosition = m_lastWorldPosition;
1769 }
1770
1771 m_parentPosition = Vector3.Zero;
1772 m_parentID = 0;
1703 SendFullUpdateToAllClients(); 1773 SendFullUpdateToAllClients();
1704 m_requestedSitTargetID = 0; 1774 m_requestedSitTargetID = 0;
1775
1705 if ((m_physicsActor != null) && (m_avHeight > 0)) 1776 if ((m_physicsActor != null) && (m_avHeight > 0))
1706 { 1777 {
1707 SetHeight(m_avHeight); 1778 SetHeight(m_avHeight);
1708 } 1779 }
1709 } 1780 }
1710
1711 Animator.TrySetMovementAnimation("STAND"); 1781 Animator.TrySetMovementAnimation("STAND");
1712 } 1782 }
1713 1783
@@ -1738,13 +1808,9 @@ namespace OpenSim.Region.Framework.Scenes
1738 Vector3 avSitOffSet = part.SitTargetPosition; 1808 Vector3 avSitOffSet = part.SitTargetPosition;
1739 Quaternion avSitOrientation = part.SitTargetOrientation; 1809 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1810 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1741 1811 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1742 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1812 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1743 bool SitTargetisSet = 1813 if (SitTargetisSet && !SitTargetOccupied)
1744 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1745 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1746
1747 if (SitTargetisSet && SitTargetUnOccupied)
1748 { 1814 {
1749 //switch the target to this prim 1815 //switch the target to this prim
1750 return part; 1816 return part;
@@ -1758,84 +1824,152 @@ namespace OpenSim.Region.Framework.Scenes
1758 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1824 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1759 { 1825 {
1760 bool autopilot = true; 1826 bool autopilot = true;
1827 Vector3 autopilotTarget = new Vector3();
1828 Quaternion sitOrientation = Quaternion.Identity;
1761 Vector3 pos = new Vector3(); 1829 Vector3 pos = new Vector3();
1762 Quaternion sitOrientation = pSitOrientation;
1763 Vector3 cameraEyeOffset = Vector3.Zero; 1830 Vector3 cameraEyeOffset = Vector3.Zero;
1764 Vector3 cameraAtOffset = Vector3.Zero; 1831 Vector3 cameraAtOffset = Vector3.Zero;
1765 bool forceMouselook = false; 1832 bool forceMouselook = false;
1766 1833
1767 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1834 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1768 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1835 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1769 if (part != null) 1836 if (part == null) return;
1770 { 1837
1771 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1838 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1772 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1839 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1773 1840
1774 // Is a sit target available? 1841 // part is the prim to sit on
1775 Vector3 avSitOffSet = part.SitTargetPosition; 1842 // offset is the world-ref vector distance from that prim center to the click-spot
1776 Quaternion avSitOrientation = part.SitTargetOrientation; 1843 // UUID is the UUID of the Avatar doing the clicking
1777 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1844
1778 1845 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1779 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1846
1780 bool SitTargetisSet = 1847 // Is a sit target available?
1781 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1848 Vector3 avSitOffSet = part.SitTargetPosition;
1782 ( 1849 Quaternion avSitOrientation = part.SitTargetOrientation;
1783 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1850
1784 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1851 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1785 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1852 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1786 ) 1853 Quaternion partRot;
1787 )); 1854// if (part.LinkNum == 1)
1788 1855// { // Root prim of linkset
1789 if (SitTargetisSet && SitTargetUnOccupied) 1856// partRot = part.ParentGroup.RootPart.RotationOffset;
1790 { 1857// }
1791 part.SetAvatarOnSitTarget(UUID); 1858// else
1792 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1859// { // single or child prim
1793 sitOrientation = avSitOrientation; 1860 partRot = part.GetWorldRotation();
1794 autopilot = false; 1861// }
1795 } 1862 Quaternion partIRot = Quaternion.Inverse(partRot);
1796 1863//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1797 pos = part.AbsolutePosition + offset; 1864 // Sit analysis rewritten by KF 091125
1798 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1865 if (SitTargetisSet) // scipted sit
1799 //{ 1866 {
1800 // offset = pos; 1867 if (!part.IsOccupied)
1801 //autopilot = false; 1868 {
1802 //} 1869//Console.WriteLine("Scripted, unoccupied");
1803 if (m_physicsActor != null) 1870 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1804 { 1871 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1805 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1872 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1806 // We can remove the physicsActor until they stand up. 1873 autopilot = false; // Jump direct to scripted llSitPos()
1807 m_sitAvatarHeight = m_physicsActor.Size.Z; 1874 }
1808 1875 else
1809 if (autopilot) 1876 {
1810 { 1877//Console.WriteLine("Scripted, occupied");
1811 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1878 return;
1812 { 1879 }
1813 autopilot = false; 1880 }
1881 else // Not Scripted
1882 {
1883 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1884 {
1885 // large prim & offset, ignore if other Avs sitting
1886// offset.Z -= 0.05f;
1887 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1888 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1889
1890//Console.WriteLine(" offset ={0}", offset);
1891//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1892//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1893
1894 }
1895 else // small offset
1896 {
1897//Console.WriteLine("Small offset");
1898 if (!part.IsOccupied)
1899 {
1900 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1901 autopilotTarget = part.AbsolutePosition;
1902 }
1903 else return; // occupied small
1904 } // end large/small
1905 } // end Scripted/not
1906 cameraAtOffset = part.GetCameraAtOffset();
1907 cameraEyeOffset = part.GetCameraEyeOffset();
1908 forceMouselook = part.GetForceMouselook();
1909 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1910 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1814 1911
1815 RemoveFromPhysicalScene(); 1912 if (m_physicsActor != null)
1816 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1913 {
1817 } 1914 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1818 } 1915 // We can remove the physicsActor until they stand up.
1819 else 1916 m_sitAvatarHeight = m_physicsActor.Size.Z;
1917 if (autopilot)
1918 { // its not a scripted sit
1919// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1920 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1820 { 1921 {
1922 autopilot = false; // close enough
1923 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1924 Not using the part's position because returning the AV to the last known standing
1925 position is likely to be more friendly, isn't it? */
1821 RemoveFromPhysicalScene(); 1926 RemoveFromPhysicalScene();
1822 } 1927 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1928 } // else the autopilot will get us close
1929 }
1930 else
1931 { // its a scripted sit
1932 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1933 I *am* using the part's position this time because we have no real idea how far away
1934 the avatar is from the sit target. */
1935 RemoveFromPhysicalScene();
1823 } 1936 }
1824
1825 cameraAtOffset = part.GetCameraAtOffset();
1826 cameraEyeOffset = part.GetCameraEyeOffset();
1827 forceMouselook = part.GetForceMouselook();
1828 } 1937 }
1829 1938 else return; // physactor is null!
1830 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1939
1831 m_requestedSitTargetUUID = targetID; 1940 Vector3 offsetr; // = offset * partIRot;
1941 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1942 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1943 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1944 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1945 offsetr = offset * partIRot;
1946//
1947 // else
1948 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1949 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1950 // (offset * partRot);
1951 // }
1952
1953//Console.WriteLine(" ");
1954//Console.WriteLine("link number ={0}", part.LinkNum);
1955//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1956//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1957//Console.WriteLine("Click offst ={0}", offset);
1958//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1959//Console.WriteLine("offsetr ={0}", offsetr);
1960//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1961//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1962
1963 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1964 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1832 // This calls HandleAgentSit twice, once from here, and the client calls 1965 // This calls HandleAgentSit twice, once from here, and the client calls
1833 // HandleAgentSit itself after it gets to the location 1966 // HandleAgentSit itself after it gets to the location
1834 // It doesn't get to the location until we've moved them there though 1967 // It doesn't get to the location until we've moved them there though
1835 // which happens in HandleAgentSit :P 1968 // which happens in HandleAgentSit :P
1836 m_autopilotMoving = autopilot; 1969 m_autopilotMoving = autopilot;
1837 m_autoPilotTarget = pos; 1970 m_autoPilotTarget = autopilotTarget;
1838 m_sitAtAutoTarget = autopilot; 1971 m_sitAtAutoTarget = autopilot;
1972 m_initialSitTarget = autopilotTarget;
1839 if (!autopilot) 1973 if (!autopilot)
1840 HandleAgentSit(remoteClient, UUID); 1974 HandleAgentSit(remoteClient, UUID);
1841 } 1975 }
@@ -2130,31 +2264,65 @@ namespace OpenSim.Region.Framework.Scenes
2130 { 2264 {
2131 if (part != null) 2265 if (part != null)
2132 { 2266 {
2267//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2133 if (part.GetAvatarOnSitTarget() == UUID) 2268 if (part.GetAvatarOnSitTarget() == UUID)
2134 { 2269 {
2270//Console.WriteLine("Scripted Sit");
2271 // Scripted sit
2135 Vector3 sitTargetPos = part.SitTargetPosition; 2272 Vector3 sitTargetPos = part.SitTargetPosition;
2136 Quaternion sitTargetOrient = part.SitTargetOrientation; 2273 Quaternion sitTargetOrient = part.SitTargetOrientation;
2137
2138 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2139 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2140
2141 //Quaternion result = (sitTargetOrient * vq) * nq;
2142
2143 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2274 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2144 m_pos += SIT_TARGET_ADJUSTMENT; 2275 m_pos += SIT_TARGET_ADJUSTMENT;
2145 m_bodyRot = sitTargetOrient; 2276 m_bodyRot = sitTargetOrient;
2146 //Rotation = sitTargetOrient;
2147 m_parentPosition = part.AbsolutePosition; 2277 m_parentPosition = part.AbsolutePosition;
2148 2278 part.IsOccupied = true;
2149 //SendTerseUpdateToAllClients();
2150 } 2279 }
2151 else 2280 else
2152 { 2281 {
2153 m_pos -= part.AbsolutePosition; 2282 // if m_avUnscriptedSitPos is zero then Av sits above center
2283 // Else Av sits at m_avUnscriptedSitPos
2284
2285 // Non-scripted sit by Kitto Flora 21Nov09
2286 // Calculate angle of line from prim to Av
2287 Quaternion partIRot;
2288// if (part.LinkNum == 1)
2289// { // Root prim of linkset
2290// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2291// }
2292// else
2293// { // single or child prim
2294 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2295// }
2296 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2297 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2298 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2299 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2300 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2301 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2302 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2303 // Av sits at world euler <0,0, z>, translated by part rotation
2304 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2305
2154 m_parentPosition = part.AbsolutePosition; 2306 m_parentPosition = part.AbsolutePosition;
2155 } 2307 part.IsOccupied = true;
2308 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2309 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2310 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2311 m_avUnscriptedSitPos; // adds click offset, if any
2312 //Set up raytrace to find top surface of prim
2313 Vector3 size = part.Scale;
2314 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2315 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2316 Vector3 down = new Vector3(0f, 0f, -1f);
2317//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2318 m_scene.PhysicsScene.RaycastWorld(
2319 start, // Vector3 position,
2320 down, // Vector3 direction,
2321 mag, // float length,
2322 SitAltitudeCallback); // retMethod
2323 } // end scripted/not
2156 } 2324 }
2157 else 2325 else // no Av
2158 { 2326 {
2159 return; 2327 return;
2160 } 2328 }
@@ -2166,11 +2334,36 @@ namespace OpenSim.Region.Framework.Scenes
2166 2334
2167 Animator.TrySetMovementAnimation(sitAnimation); 2335 Animator.TrySetMovementAnimation(sitAnimation);
2168 SendFullUpdateToAllClients(); 2336 SendFullUpdateToAllClients();
2169 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2170 // So we're also sending a terse update (which has avatar rotation)
2171 // [Update] We do now.
2172 //SendTerseUpdateToAllClients();
2173 } 2337 }
2338
2339 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2340 {
2341 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2342 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2343 if(hitYN)
2344 {
2345 // m_pos = Av offset from prim center to make look like on center
2346 // m_parentPosition = Actual center pos of prim
2347 // collisionPoint = spot on prim where we want to sit
2348 // collisionPoint.Z = global sit surface height
2349 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2350 Quaternion partIRot;
2351// if (part.LinkNum == 1)
2352/// { // Root prim of linkset
2353// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2354// }
2355// else
2356// { // single or child prim
2357 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2358// }
2359 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2360 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2361//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2362 m_pos += offset;
2363// ControllingClient.SendClearFollowCamProperties(part.UUID);
2364
2365 }
2366 } // End SitAltitudeCallback KF.
2174 2367
2175 /// <summary> 2368 /// <summary>
2176 /// Event handler for the 'Always run' setting on the client 2369 /// Event handler for the 'Always run' setting on the client
@@ -2200,7 +2393,7 @@ namespace OpenSim.Region.Framework.Scenes
2200 /// </summary> 2393 /// </summary>
2201 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2394 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2202 /// <param name="rotation">The direction in which this avatar should now face. 2395 /// <param name="rotation">The direction in which this avatar should now face.
2203 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2396 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2204 { 2397 {
2205 if (m_isChildAgent) 2398 if (m_isChildAgent)
2206 { 2399 {
@@ -2274,7 +2467,7 @@ namespace OpenSim.Region.Framework.Scenes
2274 2467
2275 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2468 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2276 m_forceToApply = direc; 2469 m_forceToApply = direc;
2277 2470 m_isNudging = Nudging;
2278 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2471 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2279 } 2472 }
2280 2473
@@ -2289,7 +2482,7 @@ namespace OpenSim.Region.Framework.Scenes
2289 const float POSITION_TOLERANCE = 0.05f; 2482 const float POSITION_TOLERANCE = 0.05f;
2290 //const int TIME_MS_TOLERANCE = 3000; 2483 //const int TIME_MS_TOLERANCE = 3000;
2291 2484
2292 SendPrimUpdates(); 2485
2293 2486
2294 if (m_newCoarseLocations) 2487 if (m_newCoarseLocations)
2295 { 2488 {
@@ -2325,6 +2518,9 @@ namespace OpenSim.Region.Framework.Scenes
2325 CheckForBorderCrossing(); 2518 CheckForBorderCrossing();
2326 CheckForSignificantMovement(); // sends update to the modules. 2519 CheckForSignificantMovement(); // sends update to the modules.
2327 } 2520 }
2521
2522 //Sending prim updates AFTER the avatar terse updates are sent
2523 SendPrimUpdates();
2328 } 2524 }
2329 2525
2330 #endregion 2526 #endregion
@@ -3225,14 +3421,25 @@ namespace OpenSim.Region.Framework.Scenes
3225 { 3421 {
3226 if (m_forceToApply.HasValue) 3422 if (m_forceToApply.HasValue)
3227 { 3423 {
3228 Vector3 force = m_forceToApply.Value;
3229 3424
3425 Vector3 force = m_forceToApply.Value;
3230 m_updateflag = true; 3426 m_updateflag = true;
3231// movementvector = force;
3232 Velocity = force; 3427 Velocity = force;
3233 3428
3234 m_forceToApply = null; 3429 m_forceToApply = null;
3235 } 3430 }
3431 else
3432 {
3433 if (m_isNudging)
3434 {
3435 Vector3 force = Vector3.Zero;
3436
3437 m_updateflag = true;
3438 Velocity = force;
3439 m_isNudging = false;
3440 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3441 }
3442 }
3236 } 3443 }
3237 3444
3238 public override void SetText(string text, Vector3 color, double alpha) 3445 public override void SetText(string text, Vector3 color, double alpha)
@@ -3283,18 +3490,29 @@ namespace OpenSim.Region.Framework.Scenes
3283 { 3490 {
3284 if (e == null) 3491 if (e == null)
3285 return; 3492 return;
3286 3493
3287 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3494 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3288 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3289 // as of this comment the interval is set in AddToPhysicalScene 3495 // as of this comment the interval is set in AddToPhysicalScene
3290 if (Animator!=null) 3496 if (Animator!=null)
3291 Animator.UpdateMovementAnimations(); 3497 {
3498 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3499 { // else its will lock out other animation changes, like ground sit.
3500 Animator.UpdateMovementAnimations();
3501 m_updateCount--;
3502 }
3503 }
3292 3504
3293 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3505 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3294 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3506 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3295 3507
3296 CollisionPlane = Vector4.UnitW; 3508 CollisionPlane = Vector4.UnitW;
3297 3509
3510 if (m_lastColCount != coldata.Count)
3511 {
3512 m_updateCount = UPDATE_COUNT;
3513 m_lastColCount = coldata.Count;
3514 }
3515
3298 if (coldata.Count != 0 && Animator != null) 3516 if (coldata.Count != 0 && Animator != null)
3299 { 3517 {
3300 switch (Animator.CurrentMovementAnimation) 3518 switch (Animator.CurrentMovementAnimation)
@@ -3931,5 +4149,16 @@ namespace OpenSim.Region.Framework.Scenes
3931 m_reprioritization_called = false; 4149 m_reprioritization_called = false;
3932 } 4150 }
3933 } 4151 }
4152
4153 private Vector3 Quat2Euler(Quaternion rot){
4154 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4155 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4156 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4157 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4158 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4159 return(new Vector3(x,y,z));
4160 }
4161
4162
3934 } 4163 }
3935} 4164}
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;