aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs22
-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.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs41
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs47
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs519
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs97
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs380
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs549
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs11
14 files changed, 1263 insertions, 576 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
index 78bd622..7312799 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
@@ -103,6 +103,8 @@ namespace OpenSim.Region.Framework.Interfaces
103 103
104 void StoreRegionSettings(RegionSettings rs); 104 void StoreRegionSettings(RegionSettings rs);
105 RegionSettings LoadRegionSettings(UUID regionUUID); 105 RegionSettings LoadRegionSettings(UUID regionUUID);
106 RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID);
107 void StoreRegionWindlightSettings(RegionMeta7WindlightData wl);
106 108
107 void Shutdown(); 109 void Shutdown();
108 } 110 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 8b1d705..8f62855 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
@@ -156,11 +161,18 @@ namespace OpenSim.Region.Framework.Scenes.Animation
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 161 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157 162
158 // Check control flags 163 // Check control flags
164<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
165 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);
166 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);
167 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);
168 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);
169=======
159 bool heldForward = 170 bool heldForward =
160 (((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)); 171 (((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));
161 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 172 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
162 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 173 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
163 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; 174 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
175>>>>>>> master:OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
164 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 176 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
165 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 177 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
166 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 178 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
@@ -313,7 +325,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
313 public void UpdateMovementAnimations() 325 public void UpdateMovementAnimations()
314 { 326 {
315 m_movementAnimation = GetMovementAnimation(); 327 m_movementAnimation = GetMovementAnimation();
316 328//Console.WriteLine("UMA got {0}", m_movementAnimation);
317 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) 329 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
318 { 330 {
319 // This was the previous behavior before PREJUMP 331 // This was the previous behavior before PREJUMP
@@ -451,4 +463,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
451 m_scenePresence = null; 463 m_scenePresence = null;
452 } 464 }
453 } 465 }
454} \ No newline at end of file 466}
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 753344d..68e73b1 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -193,7 +193,11 @@ namespace OpenSim.Region.Framework.Scenes
193 public event OnMakeChildAgentDelegate OnMakeChildAgent; 193 public event OnMakeChildAgentDelegate OnMakeChildAgent;
194 194
195 public delegate void OnMakeRootAgentDelegate(ScenePresence presence); 195 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
196 public delegate void OnSaveNewWindlightProfileDelegate();
197 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user);
196 public event OnMakeRootAgentDelegate OnMakeRootAgent; 198 public event OnMakeRootAgentDelegate OnMakeRootAgent;
199 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
200 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
197 201
198 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); 202 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
199 203
@@ -411,6 +415,8 @@ namespace OpenSim.Region.Framework.Scenes
411 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage; 415 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
412 private ClientClosed handlerClientClosed = null; //OnClientClosed; 416 private ClientClosed handlerClientClosed = null; //OnClientClosed;
413 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; 417 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
418 private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile;
419 private OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = null; //OnSendNewWindlightProfileTargeted;
414 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; 420 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
415 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; 421 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
416 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; 422 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
@@ -772,6 +778,24 @@ namespace OpenSim.Region.Framework.Scenes
772 } 778 }
773 } 779 }
774 780
781 public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
782 {
783 handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
784 if (handlerSendNewWindlightProfileTargeted != null)
785 {
786 handlerSendNewWindlightProfileTargeted(wl, user);
787 }
788 }
789
790 public void TriggerOnSaveNewWindlightProfile()
791 {
792 handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
793 if (handlerSaveNewWindlightProfile != null)
794 {
795 handlerSaveNewWindlightProfile();
796 }
797 }
798
775 public void TriggerOnMakeRootAgent(ScenePresence presence) 799 public void TriggerOnMakeRootAgent(ScenePresence presence)
776 { 800 {
777 handlerMakeRootAgent = OnMakeRootAgent; 801 handlerMakeRootAgent = OnMakeRootAgent;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 89ce4ae..bce7d32 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -846,8 +846,12 @@ namespace OpenSim.Region.Framework.Scenes
846 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 846 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
847 { 847 {
848 SceneObjectPart part = GetSceneObjectPart(localID); 848 SceneObjectPart part = GetSceneObjectPart(localID);
849 SceneObjectGroup group = part.ParentGroup; 849 SceneObjectGroup group = null;
850 if (group != null) 850 if (part != null)
851 {
852 group = part.ParentGroup;
853 }
854 if (part != null && group != null)
851 { 855 {
852 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 856 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
853 if (item == null) 857 if (item == null)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0e1e2be..2091bf0 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();
@@ -1505,6 +1519,19 @@ namespace OpenSim.Region.Framework.Scenes
1505 public void SaveTerrain() 1519 public void SaveTerrain()
1506 { 1520 {
1507 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1521 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1522 }
1523
1524 public void StoreWindlightProfile(RegionMeta7WindlightData wl)
1525 {
1526 m_regInfo.WindlightSettings = wl;
1527 m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
1528 m_eventManager.TriggerOnSaveNewWindlightProfile();
1529 }
1530
1531 public void LoadWindlightProfile()
1532 {
1533 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID);
1534 m_eventManager.TriggerOnSaveNewWindlightProfile();
1508 } 1535 }
1509 1536
1510 /// <summary> 1537 /// <summary>
@@ -3445,6 +3472,7 @@ namespace OpenSim.Region.Framework.Scenes
3445 } 3472 }
3446 } 3473 }
3447 // Honor parcel landing type and position. 3474 // Honor parcel landing type and position.
3475 /*
3448 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 3476 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3449 if (land != null) 3477 if (land != null)
3450 { 3478 {
@@ -3453,6 +3481,7 @@ namespace OpenSim.Region.Framework.Scenes
3453 agent.startpos = land.LandData.UserLocation; 3481 agent.startpos = land.LandData.UserLocation;
3454 } 3482 }
3455 } 3483 }
3484 */// This is now handled properly in ScenePresence.MakeRootAgent
3456 } 3485 }
3457 3486
3458 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3487 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index f49d072..8c808ab 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -706,17 +706,42 @@ namespace OpenSim.Region.Framework.Scenes
706 { 706 {
707 m_log.DebugFormat( 707 m_log.DebugFormat(
708 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", 708 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}",
709 position, m_regionInfo.RegionName); 709 position, m_regionInfo.RegionName);
710 710
711 // Teleport within the same region 711 // Teleport within the same region
712 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) 712 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0)
713 { 713 {
714 Vector3 emergencyPos = new Vector3(128, 128, 128); 714 Vector3 emergencyPos = new Vector3(128, 128, 128);
715 715
716 m_log.WarnFormat( 716 m_log.WarnFormat(
717 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 717 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
718 position, avatar.Name, avatar.UUID, emergencyPos); 718 position, avatar.Name, avatar.UUID, emergencyPos);
719 position = emergencyPos; 719 position = emergencyPos;
720 }
721
722 Vector3 currentPos = avatar.AbsolutePosition;
723 ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y);
724 ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y);
725 if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0)
726 {
727 if (srcLand.LandData.LocalID == destLand.LandData.LocalID)
728 {
729 //TPing within the same parcel. If the landing point is restricted, block the TP.
730 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
731 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)
732 {
733 avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false);
734 position = currentPos;
735 }
736 }
737 else
738 {
739 //Tping to a different parcel. Respect the landing point on the destination parcel.
740 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)
741 {
742 position = destLand.LandData.UserLocation;
743 }
744 }
720 } 745 }
721 746
722 // TODO: Get proper AVG Height 747 // TODO: Get proper AVG Height
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index f74fd5d..34a92fe 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();
@@ -542,6 +566,18 @@ namespace OpenSim.Region.Framework.Scenes
542 if (group.GetFromItemID() == itemID) 566 if (group.GetFromItemID() == itemID)
543 { 567 {
544 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); 568 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
569 bool hasScripts = false;
570 foreach (SceneObjectPart part in group.Children.Values)
571 {
572 if (part.Inventory.ContainsScripts())
573 {
574 hasScripts = true;
575 break;
576 }
577 }
578
579 if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
580 System.Threading.Thread.Sleep(100);
545 group.DetachToInventoryPrep(); 581 group.DetachToInventoryPrep();
546 m_log.Debug("[DETACH]: Saving attachpoint: " + 582 m_log.Debug("[DETACH]: Saving attachpoint: " +
547 ((uint)group.GetAttachmentPoint()).ToString()); 583 ((uint)group.GetAttachmentPoint()).ToString());
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 5a06bdb..65ce13a 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
@@ -75,14 +75,16 @@ namespace OpenSim.Region.Framework.Scenes
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 public void RemoveScriptInstances() 77 public void RemoveScriptInstances()
78 { 78 {
79 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)
80 { 84 {
81 foreach (SceneObjectPart part in m_parts.Values) 85 part.Inventory.RemoveScriptInstances();
82 {
83 part.Inventory.RemoveScriptInstances();
84 }
85 } 86 }
87
86 } 88 }
87 89
88 /// <summary> 90 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index e9ed066..f8498c6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -98,6 +98,72 @@ namespace OpenSim.Region.Framework.Scenes
98 private bool m_hasGroupChanged = false; 98 private bool m_hasGroupChanged = false;
99 private long timeFirstChanged; 99 private long timeFirstChanged;
100 private long timeLastChanged; 100 private long timeLastChanged;
101 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
102
103 public void lockPartsForRead(bool locked)
104 {
105 if (locked)
106 {
107 if (m_partsLock.RecursiveReadCount > 0)
108 {
109 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
110 m_partsLock.ExitReadLock();
111 }
112 if (m_partsLock.RecursiveWriteCount > 0)
113 {
114 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
115 m_partsLock.ExitWriteLock();
116 }
117
118 while (!m_partsLock.TryEnterReadLock(60000))
119 {
120 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
121 if (m_partsLock.IsWriteLockHeld)
122 {
123 m_partsLock = new System.Threading.ReaderWriterLockSlim();
124 }
125 }
126 }
127 else
128 {
129 if (m_partsLock.RecursiveReadCount > 0)
130 {
131 m_partsLock.ExitReadLock();
132 }
133 }
134 }
135 public void lockPartsForWrite(bool locked)
136 {
137 if (locked)
138 {
139 if (m_partsLock.RecursiveReadCount > 0)
140 {
141 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.");
142 m_partsLock.ExitReadLock();
143 }
144 if (m_partsLock.RecursiveWriteCount > 0)
145 {
146 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
147 m_partsLock.ExitWriteLock();
148 }
149
150 while (!m_partsLock.TryEnterWriteLock(60000))
151 {
152 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.");
153 if (m_partsLock.IsWriteLockHeld)
154 {
155 m_partsLock = new System.Threading.ReaderWriterLockSlim();
156 }
157 }
158 }
159 else
160 {
161 if (m_partsLock.RecursiveWriteCount > 0)
162 {
163 m_partsLock.ExitWriteLock();
164 }
165 }
166 }
101 167
102 public bool HasGroupChanged 168 public bool HasGroupChanged
103 { 169 {
@@ -243,13 +309,16 @@ namespace OpenSim.Region.Framework.Scenes
243 set 309 set
244 { 310 {
245 m_regionHandle = value; 311 m_regionHandle = value;
246 lock (m_parts) 312 lockPartsForRead(true);
247 { 313 {
248 foreach (SceneObjectPart part in m_parts.Values) 314 foreach (SceneObjectPart part in m_parts.Values)
249 { 315 {
316
250 part.RegionHandle = m_regionHandle; 317 part.RegionHandle = m_regionHandle;
318
251 } 319 }
252 } 320 }
321 lockPartsForRead(false);
253 } 322 }
254 } 323 }
255 324
@@ -275,13 +344,16 @@ namespace OpenSim.Region.Framework.Scenes
275 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 344 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
276 } 345 }
277 346
278 lock (m_parts) 347 lockPartsForRead(true);
279 { 348 {
280 foreach (SceneObjectPart part in m_parts.Values) 349 foreach (SceneObjectPart part in m_parts.Values)
281 { 350 {
351
282 part.GroupPosition = val; 352 part.GroupPosition = val;
353
283 } 354 }
284 } 355 }
356 lockPartsForRead(false);
285 357
286 //if (m_rootPart.PhysActor != null) 358 //if (m_rootPart.PhysActor != null)
287 //{ 359 //{
@@ -432,13 +504,16 @@ namespace OpenSim.Region.Framework.Scenes
432 504
433 public void SetFromItemID(UUID AssetId) 505 public void SetFromItemID(UUID AssetId)
434 { 506 {
435 lock (m_parts) 507 lockPartsForRead(true);
436 { 508 {
437 foreach (SceneObjectPart part in m_parts.Values) 509 foreach (SceneObjectPart part in m_parts.Values)
438 { 510 {
511
439 part.FromItemID = AssetId; 512 part.FromItemID = AssetId;
513
440 } 514 }
441 } 515 }
516 lockPartsForRead(false);
442 } 517 }
443 518
444 public UUID GetFromItemID() 519 public UUID GetFromItemID()
@@ -505,10 +580,11 @@ namespace OpenSim.Region.Framework.Scenes
505 Vector3 maxScale = Vector3.Zero; 580 Vector3 maxScale = Vector3.Zero;
506 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 581 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
507 582
508 lock (m_parts) 583 lockPartsForRead(true);
509 { 584 {
510 foreach (SceneObjectPart part in m_parts.Values) 585 foreach (SceneObjectPart part in m_parts.Values)
511 { 586 {
587
512 Vector3 partscale = part.Scale; 588 Vector3 partscale = part.Scale;
513 Vector3 partoffset = part.OffsetPosition; 589 Vector3 partoffset = part.OffsetPosition;
514 590
@@ -519,8 +595,11 @@ namespace OpenSim.Region.Framework.Scenes
519 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 595 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
520 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 596 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
521 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 597 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
598
522 } 599 }
523 } 600 }
601 lockPartsForRead(false);
602
524 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 603 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
525 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 604 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
526 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 605 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -536,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes
536 615
537 EntityIntersection result = new EntityIntersection(); 616 EntityIntersection result = new EntityIntersection();
538 617
539 lock (m_parts) 618 lockPartsForRead(true);
540 { 619 {
541 foreach (SceneObjectPart part in m_parts.Values) 620 foreach (SceneObjectPart part in m_parts.Values)
542 { 621 {
622
543 // Temporary commented to stop compiler warning 623 // Temporary commented to stop compiler warning
544 //Vector3 partPosition = 624 //Vector3 partPosition =
545 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 625 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -567,8 +647,10 @@ namespace OpenSim.Region.Framework.Scenes
567 result.distance = inter.distance; 647 result.distance = inter.distance;
568 } 648 }
569 } 649 }
650
570 } 651 }
571 } 652 }
653 lockPartsForRead(false);
572 return result; 654 return result;
573 } 655 }
574 656
@@ -581,10 +663,11 @@ namespace OpenSim.Region.Framework.Scenes
581 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 663 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
582 { 664 {
583 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 665 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
584 lock (m_parts) 666 lockPartsForRead(true);
585 { 667 {
586 foreach (SceneObjectPart part in m_parts.Values) 668 foreach (SceneObjectPart part in m_parts.Values)
587 { 669 {
670
588 Vector3 worldPos = part.GetWorldPosition(); 671 Vector3 worldPos = part.GetWorldPosition();
589 Vector3 offset = worldPos - AbsolutePosition; 672 Vector3 offset = worldPos - AbsolutePosition;
590 Quaternion worldRot; 673 Quaternion worldRot;
@@ -643,6 +726,8 @@ namespace OpenSim.Region.Framework.Scenes
643 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 726 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
644 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 727 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
645 728
729
730
646 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 731 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
647 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 732 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
648 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 733 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -814,6 +899,7 @@ namespace OpenSim.Region.Framework.Scenes
814 minZ = backBottomLeft.Z; 899 minZ = backBottomLeft.Z;
815 } 900 }
816 } 901 }
902 lockPartsForRead(false);
817 903
818 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 904 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
819 905
@@ -842,17 +928,20 @@ namespace OpenSim.Region.Framework.Scenes
842 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 928 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
843 929
844 // Capture script state while holding the lock 930 // Capture script state while holding the lock
845 lock (m_parts) 931 lockPartsForRead(true);
846 { 932 {
847 foreach (SceneObjectPart part in m_parts.Values) 933 foreach (SceneObjectPart part in m_parts.Values)
848 { 934 {
935
849 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 936 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
850 foreach (UUID itemid in pstates.Keys) 937 foreach (UUID itemid in pstates.Keys)
851 { 938 {
852 states.Add(itemid, pstates[itemid]); 939 states.Add(itemid, pstates[itemid]);
853 } 940 }
941
854 } 942 }
855 } 943 }
944 lockPartsForRead(false);
856 945
857 if (states.Count > 0) 946 if (states.Count > 0)
858 { 947 {
@@ -1014,13 +1103,16 @@ namespace OpenSim.Region.Framework.Scenes
1014 1103
1015 public override void UpdateMovement() 1104 public override void UpdateMovement()
1016 { 1105 {
1017 lock (m_parts) 1106 lockPartsForRead(true);
1018 { 1107 {
1019 foreach (SceneObjectPart part in m_parts.Values) 1108 foreach (SceneObjectPart part in m_parts.Values)
1020 { 1109 {
1110
1021 part.UpdateMovement(); 1111 part.UpdateMovement();
1112
1022 } 1113 }
1023 } 1114 }
1115 lockPartsForRead(false);
1024 } 1116 }
1025 1117
1026 public ushort GetTimeDilation() 1118 public ushort GetTimeDilation()
@@ -1064,7 +1156,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 /// <param name="part"></param> 1156 /// <param name="part"></param>
1065 public void AddPart(SceneObjectPart part) 1157 public void AddPart(SceneObjectPart part)
1066 { 1158 {
1067 lock (m_parts) 1159 lockPartsForWrite(true);
1068 { 1160 {
1069 part.SetParent(this); 1161 part.SetParent(this);
1070 m_parts.Add(part.UUID, part); 1162 m_parts.Add(part.UUID, part);
@@ -1074,6 +1166,7 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (part.LinkNum == 2 && RootPart != null) 1166 if (part.LinkNum == 2 && RootPart != null)
1075 RootPart.LinkNum = 1; 1167 RootPart.LinkNum = 1;
1076 } 1168 }
1169 lockPartsForWrite(false);
1077 } 1170 }
1078 1171
1079 /// <summary> 1172 /// <summary>
@@ -1081,28 +1174,33 @@ namespace OpenSim.Region.Framework.Scenes
1081 /// </summary> 1174 /// </summary>
1082 private void UpdateParentIDs() 1175 private void UpdateParentIDs()
1083 { 1176 {
1084 lock (m_parts) 1177 lockPartsForRead(true);
1085 { 1178 {
1086 foreach (SceneObjectPart part in m_parts.Values) 1179 foreach (SceneObjectPart part in m_parts.Values)
1087 { 1180 {
1181
1088 if (part.UUID != m_rootPart.UUID) 1182 if (part.UUID != m_rootPart.UUID)
1089 { 1183 {
1090 part.ParentID = m_rootPart.LocalId; 1184 part.ParentID = m_rootPart.LocalId;
1091 } 1185 }
1186
1092 } 1187 }
1093 } 1188 }
1189 lockPartsForRead(false);
1094 } 1190 }
1095 1191
1096 public void RegenerateFullIDs() 1192 public void RegenerateFullIDs()
1097 { 1193 {
1098 lock (m_parts) 1194 lockPartsForRead(true);
1099 { 1195 {
1100 foreach (SceneObjectPart part in m_parts.Values) 1196 foreach (SceneObjectPart part in m_parts.Values)
1101 { 1197 {
1198
1102 part.UUID = UUID.Random(); 1199 part.UUID = UUID.Random();
1103 1200
1104 } 1201 }
1105 } 1202 }
1203 lockPartsForRead(false);
1106 } 1204 }
1107 1205
1108 // helper provided for parts. 1206 // helper provided for parts.
@@ -1183,29 +1281,33 @@ namespace OpenSim.Region.Framework.Scenes
1183 1281
1184 DetachFromBackup(); 1282 DetachFromBackup();
1185 1283
1186 lock (m_parts) 1284 lockPartsForRead(true);
1285 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1286 lockPartsForRead(false);
1287
1288 foreach (SceneObjectPart part in values)
1187 { 1289 {
1188 foreach (SceneObjectPart part in m_parts.Values)
1189 {
1190// part.Inventory.RemoveScriptInstances(); 1290// part.Inventory.RemoveScriptInstances();
1191 1291
1192 ScenePresence[] avatars = Scene.GetScenePresences(); 1292 ScenePresence[] avatars = Scene.GetScenePresences();
1193 for (int i = 0; i < avatars.Length; i++) 1293 for (int i = 0; i < avatars.Length; i++)
1294 {
1295 if (avatars[i].ParentID == LocalId)
1194 { 1296 {
1195 if (avatars[i].ParentID == LocalId) 1297 avatars[i].StandUp();
1196 { 1298 }
1197 avatars[i].StandUp();
1198 }
1199 1299
1200 if (!silent) 1300 if (!silent)
1201 { 1301 {
1202 part.UpdateFlag = 0; 1302 part.UpdateFlag = 0;
1203 if (part == m_rootPart) 1303 if (part == m_rootPart)
1204 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1304 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1205 }
1206 } 1305 }
1207 } 1306 }
1307
1208 } 1308 }
1309
1310
1209 } 1311 }
1210 1312
1211 public void AddScriptLPS(int count) 1313 public void AddScriptLPS(int count)
@@ -1230,17 +1332,20 @@ namespace OpenSim.Region.Framework.Scenes
1230 1332
1231 scriptEvents aggregateScriptEvents=0; 1333 scriptEvents aggregateScriptEvents=0;
1232 1334
1233 lock (m_parts) 1335 lockPartsForRead(true);
1234 { 1336 {
1235 foreach (SceneObjectPart part in m_parts.Values) 1337 foreach (SceneObjectPart part in m_parts.Values)
1236 { 1338 {
1339
1237 if (part == null) 1340 if (part == null)
1238 continue; 1341 continue;
1239 if (part != RootPart) 1342 if (part != RootPart)
1240 part.ObjectFlags = objectflagupdate; 1343 part.ObjectFlags = objectflagupdate;
1241 aggregateScriptEvents |= part.AggregateScriptEvents; 1344 aggregateScriptEvents |= part.AggregateScriptEvents;
1345
1242 } 1346 }
1243 } 1347 }
1348 lockPartsForRead(false);
1244 1349
1245 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1350 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1246 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1351 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1273,42 +1378,52 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <param name="m_physicalPrim"></param> 1378 /// <param name="m_physicalPrim"></param>
1274 public void ApplyPhysics(bool m_physicalPrim) 1379 public void ApplyPhysics(bool m_physicalPrim)
1275 { 1380 {
1276 lock (m_parts) 1381 lockPartsForRead(true);
1382
1383 if (m_parts.Count > 1)
1277 { 1384 {
1278 if (m_parts.Count > 1) 1385 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1386 lockPartsForRead(false);
1387 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1388 foreach (SceneObjectPart part in values)
1279 { 1389 {
1280 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1390
1281 foreach (SceneObjectPart part in m_parts.Values) 1391 if (part.LocalId != m_rootPart.LocalId)
1282 { 1392 {
1283 if (part.LocalId != m_rootPart.LocalId) 1393 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1284 {
1285 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1286 }
1287 } 1394 }
1288 1395
1289 // Hack to get the physics scene geometries in the right spot
1290 ResetChildPrimPhysicsPositions();
1291 }
1292 else
1293 {
1294 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1295 } 1396 }
1397 // Hack to get the physics scene geometries in the right spot
1398 ResetChildPrimPhysicsPositions();
1399 }
1400 else
1401 {
1402 lockPartsForRead(false);
1403 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1296 } 1404 }
1297 } 1405 }
1298 1406
1299 public void SetOwnerId(UUID userId) 1407 public void SetOwnerId(UUID userId)
1300 { 1408 {
1301 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1409 ForEachPart(delegate(SceneObjectPart part)
1410 {
1411
1412 part.OwnerID = userId;
1413
1414 });
1302 } 1415 }
1303 1416
1304 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1417 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1305 { 1418 {
1306 lock (m_parts) 1419 lockPartsForRead(true);
1420 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1421 lockPartsForRead(false);
1422 foreach (SceneObjectPart part in values)
1307 { 1423 {
1308 foreach (SceneObjectPart part in m_parts.Values) 1424
1309 { 1425 whatToDo(part);
1310 whatToDo(part); 1426
1311 }
1312 } 1427 }
1313 } 1428 }
1314 1429
@@ -1407,14 +1522,17 @@ namespace OpenSim.Region.Framework.Scenes
1407 { 1522 {
1408 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1523 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1409 1524
1410 lock (m_parts) 1525 lockPartsForRead(true);
1411 { 1526 {
1412 foreach (SceneObjectPart part in m_parts.Values) 1527 foreach (SceneObjectPart part in m_parts.Values)
1413 { 1528 {
1529
1414 if (part != RootPart) 1530 if (part != RootPart)
1415 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1531 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1532
1416 } 1533 }
1417 } 1534 }
1535 lockPartsForRead(false);
1418 } 1536 }
1419 1537
1420 /// <summary> 1538 /// <summary>
@@ -1509,10 +1627,11 @@ namespace OpenSim.Region.Framework.Scenes
1509 1627
1510 List<SceneObjectPart> partList; 1628 List<SceneObjectPart> partList;
1511 1629
1512 lock (m_parts) 1630 lockPartsForRead(true);
1513 { 1631
1514 partList = new List<SceneObjectPart>(m_parts.Values); 1632 partList = new List<SceneObjectPart>(m_parts.Values);
1515 } 1633
1634 lockPartsForRead(false);
1516 1635
1517 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1636 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1518 { 1637 {
@@ -1761,6 +1880,7 @@ namespace OpenSim.Region.Framework.Scenes
1761 } 1880 }
1762 } 1881 }
1763 } 1882 }
1883
1764 public void stopLookAt() 1884 public void stopLookAt()
1765 { 1885 {
1766 SceneObjectPart rootpart = m_rootPart; 1886 SceneObjectPart rootpart = m_rootPart;
@@ -1835,10 +1955,11 @@ namespace OpenSim.Region.Framework.Scenes
1835 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1955 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1836 newPart.SetParent(this); 1956 newPart.SetParent(this);
1837 1957
1838 lock (m_parts) 1958 lockPartsForWrite(true);
1839 { 1959 {
1840 m_parts.Add(newPart.UUID, newPart); 1960 m_parts.Add(newPart.UUID, newPart);
1841 } 1961 }
1962 lockPartsForWrite(false);
1842 1963
1843 SetPartAsNonRoot(newPart); 1964 SetPartAsNonRoot(newPart);
1844 1965
@@ -1901,7 +2022,7 @@ namespace OpenSim.Region.Framework.Scenes
1901 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2022 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1902 // return; 2023 // return;
1903 2024
1904 lock (m_parts) 2025 lockPartsForRead(true);
1905 { 2026 {
1906 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2027 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1907 2028
@@ -1919,34 +2040,43 @@ namespace OpenSim.Region.Framework.Scenes
1919 2040
1920 foreach (SceneObjectPart part in m_parts.Values) 2041 foreach (SceneObjectPart part in m_parts.Values)
1921 { 2042 {
2043
1922 part.SendScheduledUpdates(); 2044 part.SendScheduledUpdates();
2045
1923 } 2046 }
1924 } 2047 }
2048 lockPartsForRead(false);
1925 } 2049 }
1926 2050
1927 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2051 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1928 { 2052 {
1929 RootPart.AddFullUpdateToAvatar(presence); 2053 RootPart.AddFullUpdateToAvatar(presence);
1930 2054
1931 lock (m_parts) 2055 lockPartsForRead(true);
1932 { 2056 {
1933 foreach (SceneObjectPart part in m_parts.Values) 2057 foreach (SceneObjectPart part in m_parts.Values)
1934 { 2058 {
2059
1935 if (part != RootPart) 2060 if (part != RootPart)
1936 part.AddFullUpdateToAvatar(presence); 2061 part.AddFullUpdateToAvatar(presence);
2062
1937 } 2063 }
1938 } 2064 }
2065 lockPartsForRead(false);
1939 } 2066 }
1940 2067
1941 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2068 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1942 { 2069 {
1943 lock (m_parts) 2070 lockPartsForRead(true);
1944 { 2071 {
1945 foreach (SceneObjectPart part in m_parts.Values) 2072 foreach (SceneObjectPart part in m_parts.Values)
1946 { 2073 {
2074
1947 part.AddTerseUpdateToAvatar(presence); 2075 part.AddTerseUpdateToAvatar(presence);
2076
1948 } 2077 }
1949 } 2078 }
2079 lockPartsForRead(false);
1950 } 2080 }
1951 2081
1952 /// <summary> 2082 /// <summary>
@@ -1957,14 +2087,17 @@ namespace OpenSim.Region.Framework.Scenes
1957 checkAtTargets(); 2087 checkAtTargets();
1958 RootPart.ScheduleFullUpdate(); 2088 RootPart.ScheduleFullUpdate();
1959 2089
1960 lock (m_parts) 2090 lockPartsForRead(true);
1961 { 2091 {
1962 foreach (SceneObjectPart part in m_parts.Values) 2092 foreach (SceneObjectPart part in m_parts.Values)
1963 { 2093 {
2094
1964 if (part != RootPart) 2095 if (part != RootPart)
1965 part.ScheduleFullUpdate(); 2096 part.ScheduleFullUpdate();
2097
1966 } 2098 }
1967 } 2099 }
2100 lockPartsForRead(false);
1968 } 2101 }
1969 2102
1970 /// <summary> 2103 /// <summary>
@@ -1972,13 +2105,16 @@ namespace OpenSim.Region.Framework.Scenes
1972 /// </summary> 2105 /// </summary>
1973 public void ScheduleGroupForTerseUpdate() 2106 public void ScheduleGroupForTerseUpdate()
1974 { 2107 {
1975 lock (m_parts) 2108 lockPartsForRead(true);
1976 { 2109 {
1977 foreach (SceneObjectPart part in m_parts.Values) 2110 foreach (SceneObjectPart part in m_parts.Values)
1978 { 2111 {
2112
1979 part.ScheduleTerseUpdate(); 2113 part.ScheduleTerseUpdate();
2114
1980 } 2115 }
1981 } 2116 }
2117 lockPartsForRead(false);
1982 } 2118 }
1983 2119
1984 /// <summary> 2120 /// <summary>
@@ -1991,14 +2127,17 @@ namespace OpenSim.Region.Framework.Scenes
1991 2127
1992 RootPart.SendFullUpdateToAllClients(); 2128 RootPart.SendFullUpdateToAllClients();
1993 2129
1994 lock (m_parts) 2130 lockPartsForRead(true);
1995 { 2131 {
1996 foreach (SceneObjectPart part in m_parts.Values) 2132 foreach (SceneObjectPart part in m_parts.Values)
1997 { 2133 {
2134
1998 if (part != RootPart) 2135 if (part != RootPart)
1999 part.SendFullUpdateToAllClients(); 2136 part.SendFullUpdateToAllClients();
2137
2000 } 2138 }
2001 } 2139 }
2140 lockPartsForRead(false);
2002 } 2141 }
2003 2142
2004 /// <summary> 2143 /// <summary>
@@ -2029,14 +2168,15 @@ namespace OpenSim.Region.Framework.Scenes
2029 { 2168 {
2030 if (IsDeleted) 2169 if (IsDeleted)
2031 return; 2170 return;
2032 2171
2033 lock (m_parts) 2172 lockPartsForRead(true);
2034 { 2173 {
2035 foreach (SceneObjectPart part in m_parts.Values) 2174 foreach (SceneObjectPart part in m_parts.Values)
2036 { 2175 {
2037 part.SendTerseUpdateToAllClients(); 2176 part.SendTerseUpdateToAllClients();
2038 } 2177 }
2039 } 2178 }
2179 lockPartsForRead(false);
2040 } 2180 }
2041 2181
2042 #endregion 2182 #endregion
@@ -2050,16 +2190,18 @@ namespace OpenSim.Region.Framework.Scenes
2050 /// <returns>null if no child part with that linknum or child part</returns> 2190 /// <returns>null if no child part with that linknum or child part</returns>
2051 public SceneObjectPart GetLinkNumPart(int linknum) 2191 public SceneObjectPart GetLinkNumPart(int linknum)
2052 { 2192 {
2053 lock (m_parts) 2193 lockPartsForRead(true);
2054 { 2194 {
2055 foreach (SceneObjectPart part in m_parts.Values) 2195 foreach (SceneObjectPart part in m_parts.Values)
2056 { 2196 {
2057 if (part.LinkNum == linknum) 2197 if (part.LinkNum == linknum)
2058 { 2198 {
2199 lockPartsForRead(false);
2059 return part; 2200 return part;
2060 } 2201 }
2061 } 2202 }
2062 } 2203 }
2204 lockPartsForRead(false);
2063 2205
2064 return null; 2206 return null;
2065 } 2207 }
@@ -2087,17 +2229,19 @@ namespace OpenSim.Region.Framework.Scenes
2087 public SceneObjectPart GetChildPart(uint localID) 2229 public SceneObjectPart GetChildPart(uint localID)
2088 { 2230 {
2089 //m_log.DebugFormat("Entered looking for {0}", localID); 2231 //m_log.DebugFormat("Entered looking for {0}", localID);
2090 lock (m_parts) 2232 lockPartsForRead(true);
2091 { 2233 {
2092 foreach (SceneObjectPart part in m_parts.Values) 2234 foreach (SceneObjectPart part in m_parts.Values)
2093 { 2235 {
2094 //m_log.DebugFormat("Found {0}", part.LocalId); 2236 //m_log.DebugFormat("Found {0}", part.LocalId);
2095 if (part.LocalId == localID) 2237 if (part.LocalId == localID)
2096 { 2238 {
2239 lockPartsForRead(false);
2097 return part; 2240 return part;
2098 } 2241 }
2099 } 2242 }
2100 } 2243 }
2244 lockPartsForRead(false);
2101 2245
2102 return null; 2246 return null;
2103 } 2247 }
@@ -2127,17 +2271,19 @@ namespace OpenSim.Region.Framework.Scenes
2127 public bool HasChildPrim(uint localID) 2271 public bool HasChildPrim(uint localID)
2128 { 2272 {
2129 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2273 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2130 lock (m_parts) 2274 lockPartsForRead(true);
2131 { 2275 {
2132 foreach (SceneObjectPart part in m_parts.Values) 2276 foreach (SceneObjectPart part in m_parts.Values)
2133 { 2277 {
2134 //m_log.DebugFormat("Found {0}", part.LocalId); 2278 //m_log.DebugFormat("Found {0}", part.LocalId);
2135 if (part.LocalId == localID) 2279 if (part.LocalId == localID)
2136 { 2280 {
2281 lockPartsForRead(false);
2137 return true; 2282 return true;
2138 } 2283 }
2139 } 2284 }
2140 } 2285 }
2286 lockPartsForRead(false);
2141 2287
2142 return false; 2288 return false;
2143 } 2289 }
@@ -2187,53 +2333,57 @@ namespace OpenSim.Region.Framework.Scenes
2187 if (m_rootPart.LinkNum == 0) 2333 if (m_rootPart.LinkNum == 0)
2188 m_rootPart.LinkNum = 1; 2334 m_rootPart.LinkNum = 1;
2189 2335
2190 lock (m_parts) 2336 lockPartsForWrite(true);
2191 { 2337
2192 m_parts.Add(linkPart.UUID, linkPart); 2338 m_parts.Add(linkPart.UUID, linkPart);
2193 2339
2194 // Insert in terms of link numbers, the new links 2340 lockPartsForWrite(false);
2195 // before the current ones (with the exception of 2341
2196 // the root prim. Shuffle the old ones up 2342 // Insert in terms of link numbers, the new links
2197 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2343 // before the current ones (with the exception of
2344 // the root prim. Shuffle the old ones up
2345 lockPartsForRead(true);
2346 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2347 {
2348 if (kvp.Value.LinkNum != 1)
2198 { 2349 {
2199 if (kvp.Value.LinkNum != 1) 2350 // Don't update root prim link number
2200 { 2351 kvp.Value.LinkNum += objectGroup.PrimCount;
2201 // Don't update root prim link number
2202 kvp.Value.LinkNum += objectGroup.PrimCount;
2203 }
2204 } 2352 }
2353 }
2354 lockPartsForRead(false);
2205 2355
2206 linkPart.LinkNum = 2; 2356 linkPart.LinkNum = 2;
2207 2357
2208 linkPart.SetParent(this); 2358 linkPart.SetParent(this);
2209 linkPart.AddFlag(PrimFlags.CreateSelected); 2359 linkPart.AddFlag(PrimFlags.CreateSelected);
2210 2360
2211 //if (linkPart.PhysActor != null) 2361 //if (linkPart.PhysActor != null)
2212 //{ 2362 //{
2213 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2363 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2214 2364
2215 //linkPart.PhysActor = null; 2365 //linkPart.PhysActor = null;
2216 //} 2366 //}
2217 2367
2218 //TODO: rest of parts 2368 //TODO: rest of parts
2219 int linkNum = 3; 2369 int linkNum = 3;
2220 foreach (SceneObjectPart part in objectGroup.Children.Values) 2370 foreach (SceneObjectPart part in objectGroup.Children.Values)
2371 {
2372 if (part.UUID != objectGroup.m_rootPart.UUID)
2221 { 2373 {
2222 if (part.UUID != objectGroup.m_rootPart.UUID) 2374 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2223 {
2224 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2225 }
2226 part.ClearUndoState();
2227 } 2375 }
2376 part.ClearUndoState();
2228 } 2377 }
2229 2378
2230 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2379 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2231 objectGroup.m_isDeleted = true; 2380 objectGroup.m_isDeleted = true;
2381
2382 objectGroup.lockPartsForWrite(true);
2232 2383
2233 lock (objectGroup.m_parts) 2384 objectGroup.m_parts.Clear();
2234 { 2385
2235 objectGroup.m_parts.Clear(); 2386 objectGroup.lockPartsForWrite(false);
2236 }
2237 2387
2238 // Can't do this yet since backup still makes use of the root part without any synchronization 2388 // Can't do this yet since backup still makes use of the root part without any synchronization
2239// objectGroup.m_rootPart = null; 2389// objectGroup.m_rootPart = null;
@@ -2292,11 +2442,12 @@ namespace OpenSim.Region.Framework.Scenes
2292 Quaternion worldRot = linkPart.GetWorldRotation(); 2442 Quaternion worldRot = linkPart.GetWorldRotation();
2293 2443
2294 // Remove the part from this object 2444 // Remove the part from this object
2295 lock (m_parts) 2445 lockPartsForWrite(true);
2296 { 2446 {
2297 m_parts.Remove(linkPart.UUID); 2447 m_parts.Remove(linkPart.UUID);
2298 } 2448 }
2299 2449 lockPartsForWrite(false);
2450 lockPartsForRead(true);
2300 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2451 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2301 RootPart.LinkNum = 0; 2452 RootPart.LinkNum = 0;
2302 else 2453 else
@@ -2307,6 +2458,7 @@ namespace OpenSim.Region.Framework.Scenes
2307 p.LinkNum--; 2458 p.LinkNum--;
2308 } 2459 }
2309 } 2460 }
2461 lockPartsForRead(false);
2310 2462
2311 linkPart.ParentID = 0; 2463 linkPart.ParentID = 0;
2312 linkPart.LinkNum = 0; 2464 linkPart.LinkNum = 0;
@@ -2624,9 +2776,12 @@ namespace OpenSim.Region.Framework.Scenes
2624 2776
2625 if (selectionPart != null) 2777 if (selectionPart != null)
2626 { 2778 {
2627 lock (m_parts) 2779 lockPartsForRead(true);
2780 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2781 lockPartsForRead(false);
2782 foreach (SceneObjectPart part in parts)
2628 { 2783 {
2629 foreach (SceneObjectPart part in m_parts.Values) 2784 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2630 { 2785 {
2631 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2786 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2632 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2787 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2636,12 +2791,13 @@ namespace OpenSim.Region.Framework.Scenes
2636 break; 2791 break;
2637 } 2792 }
2638 } 2793 }
2794 }
2639 2795
2640 foreach (SceneObjectPart part in m_parts.Values) 2796 foreach (SceneObjectPart part in parts)
2641 { 2797 {
2642 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2798 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2643 }
2644 } 2799 }
2800
2645 } 2801 }
2646 } 2802 }
2647 2803
@@ -2727,11 +2883,9 @@ namespace OpenSim.Region.Framework.Scenes
2727 scale.Y = m_scene.m_maxNonphys; 2883 scale.Y = m_scene.m_maxNonphys;
2728 if (scale.Z > m_scene.m_maxNonphys) 2884 if (scale.Z > m_scene.m_maxNonphys)
2729 scale.Z = m_scene.m_maxNonphys; 2885 scale.Z = m_scene.m_maxNonphys;
2730
2731 SceneObjectPart part = GetChildPart(localID); 2886 SceneObjectPart part = GetChildPart(localID);
2732 if (part != null) 2887 if (part != null)
2733 { 2888 {
2734 part.Resize(scale);
2735 if (part.PhysActor != null) 2889 if (part.PhysActor != null)
2736 { 2890 {
2737 if (part.PhysActor.IsPhysical) 2891 if (part.PhysActor.IsPhysical)
@@ -2746,7 +2900,7 @@ namespace OpenSim.Region.Framework.Scenes
2746 part.PhysActor.Size = scale; 2900 part.PhysActor.Size = scale;
2747 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2901 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2748 } 2902 }
2749 //if (part.UUID != m_rootPart.UUID) 2903 part.Resize(scale);
2750 2904
2751 HasGroupChanged = true; 2905 HasGroupChanged = true;
2752 ScheduleGroupForFullUpdate(); 2906 ScheduleGroupForFullUpdate();
@@ -2787,77 +2941,76 @@ namespace OpenSim.Region.Framework.Scenes
2787 float y = (scale.Y / part.Scale.Y); 2941 float y = (scale.Y / part.Scale.Y);
2788 float z = (scale.Z / part.Scale.Z); 2942 float z = (scale.Z / part.Scale.Z);
2789 2943
2790 lock (m_parts) 2944 lockPartsForRead(true);
2945 if (x > 1.0f || y > 1.0f || z > 1.0f)
2791 { 2946 {
2792 if (x > 1.0f || y > 1.0f || z > 1.0f) 2947 foreach (SceneObjectPart obPart in m_parts.Values)
2793 { 2948 {
2794 foreach (SceneObjectPart obPart in m_parts.Values) 2949 if (obPart.UUID != m_rootPart.UUID)
2795 { 2950 {
2796 if (obPart.UUID != m_rootPart.UUID) 2951 Vector3 oldSize = new Vector3(obPart.Scale);
2797 {
2798 Vector3 oldSize = new Vector3(obPart.Scale);
2799 2952
2800 float f = 1.0f; 2953 float f = 1.0f;
2801 float a = 1.0f; 2954 float a = 1.0f;
2802 2955
2803 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2956 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2957 {
2958 if (oldSize.X*x > m_scene.m_maxPhys)
2804 { 2959 {
2805 if (oldSize.X*x > m_scene.m_maxPhys) 2960 f = m_scene.m_maxPhys / oldSize.X;
2806 { 2961 a = f / x;
2807 f = m_scene.m_maxPhys / oldSize.X; 2962 x *= a;
2808 a = f / x; 2963 y *= a;
2809 x *= a; 2964 z *= a;
2810 y *= a;
2811 z *= a;
2812 }
2813 if (oldSize.Y*y > m_scene.m_maxPhys)
2814 {
2815 f = m_scene.m_maxPhys / oldSize.Y;
2816 a = f / y;
2817 x *= a;
2818 y *= a;
2819 z *= a;
2820 }
2821 if (oldSize.Z*z > m_scene.m_maxPhys)
2822 {
2823 f = m_scene.m_maxPhys / oldSize.Z;
2824 a = f / z;
2825 x *= a;
2826 y *= a;
2827 z *= a;
2828 }
2829 } 2965 }
2830 else 2966 if (oldSize.Y*y > m_scene.m_maxPhys)
2967 {
2968 f = m_scene.m_maxPhys / oldSize.Y;
2969 a = f / y;
2970 x *= a;
2971 y *= a;
2972 z *= a;
2973 }
2974 if (oldSize.Z*z > m_scene.m_maxPhys)
2975 {
2976 f = m_scene.m_maxPhys / oldSize.Z;
2977 a = f / z;
2978 x *= a;
2979 y *= a;
2980 z *= a;
2981 }
2982 }
2983 else
2984 {
2985 if (oldSize.X*x > m_scene.m_maxNonphys)
2986 {
2987 f = m_scene.m_maxNonphys / oldSize.X;
2988 a = f / x;
2989 x *= a;
2990 y *= a;
2991 z *= a;
2992 }
2993 if (oldSize.Y*y > m_scene.m_maxNonphys)
2831 { 2994 {
2832 if (oldSize.X*x > m_scene.m_maxNonphys) 2995 f = m_scene.m_maxNonphys / oldSize.Y;
2833 { 2996 a = f / y;
2834 f = m_scene.m_maxNonphys / oldSize.X; 2997 x *= a;
2835 a = f / x; 2998 y *= a;
2836 x *= a; 2999 z *= a;
2837 y *= a; 3000 }
2838 z *= a; 3001 if (oldSize.Z*z > m_scene.m_maxNonphys)
2839 } 3002 {
2840 if (oldSize.Y*y > m_scene.m_maxNonphys) 3003 f = m_scene.m_maxNonphys / oldSize.Z;
2841 { 3004 a = f / z;
2842 f = m_scene.m_maxNonphys / oldSize.Y; 3005 x *= a;
2843 a = f / y; 3006 y *= a;
2844 x *= a; 3007 z *= a;
2845 y *= a;
2846 z *= a;
2847 }
2848 if (oldSize.Z*z > m_scene.m_maxNonphys)
2849 {
2850 f = m_scene.m_maxNonphys / oldSize.Z;
2851 a = f / z;
2852 x *= a;
2853 y *= a;
2854 z *= a;
2855 }
2856 } 3008 }
2857 } 3009 }
2858 } 3010 }
2859 } 3011 }
2860 } 3012 }
3013 lockPartsForRead(false);
2861 3014
2862 Vector3 prevScale = part.Scale; 3015 Vector3 prevScale = part.Scale;
2863 prevScale.X *= x; 3016 prevScale.X *= x;
@@ -2865,7 +3018,7 @@ namespace OpenSim.Region.Framework.Scenes
2865 prevScale.Z *= z; 3018 prevScale.Z *= z;
2866 part.Resize(prevScale); 3019 part.Resize(prevScale);
2867 3020
2868 lock (m_parts) 3021 lockPartsForRead(true);
2869 { 3022 {
2870 foreach (SceneObjectPart obPart in m_parts.Values) 3023 foreach (SceneObjectPart obPart in m_parts.Values)
2871 { 3024 {
@@ -2884,6 +3037,7 @@ namespace OpenSim.Region.Framework.Scenes
2884 } 3037 }
2885 } 3038 }
2886 } 3039 }
3040 lockPartsForRead(false);
2887 3041
2888 if (part.PhysActor != null) 3042 if (part.PhysActor != null)
2889 { 3043 {
@@ -2964,7 +3118,7 @@ namespace OpenSim.Region.Framework.Scenes
2964 axDiff *= Quaternion.Inverse(partRotation); 3118 axDiff *= Quaternion.Inverse(partRotation);
2965 diff = axDiff; 3119 diff = axDiff;
2966 3120
2967 lock (m_parts) 3121 lockPartsForRead(true);
2968 { 3122 {
2969 foreach (SceneObjectPart obPart in m_parts.Values) 3123 foreach (SceneObjectPart obPart in m_parts.Values)
2970 { 3124 {
@@ -2974,6 +3128,7 @@ namespace OpenSim.Region.Framework.Scenes
2974 } 3128 }
2975 } 3129 }
2976 } 3130 }
3131 lockPartsForRead(false);
2977 3132
2978 AbsolutePosition = newPos; 3133 AbsolutePosition = newPos;
2979 3134
@@ -3091,7 +3246,7 @@ namespace OpenSim.Region.Framework.Scenes
3091 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3246 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3092 } 3247 }
3093 3248
3094 lock (m_parts) 3249 lockPartsForRead(true);
3095 { 3250 {
3096 foreach (SceneObjectPart prim in m_parts.Values) 3251 foreach (SceneObjectPart prim in m_parts.Values)
3097 { 3252 {
@@ -3109,6 +3264,7 @@ namespace OpenSim.Region.Framework.Scenes
3109 } 3264 }
3110 } 3265 }
3111 } 3266 }
3267 lockPartsForRead(false);
3112 3268
3113 m_rootPart.ScheduleTerseUpdate(); 3269 m_rootPart.ScheduleTerseUpdate();
3114 } 3270 }
@@ -3207,7 +3363,7 @@ namespace OpenSim.Region.Framework.Scenes
3207 if (atTargets.Count > 0) 3363 if (atTargets.Count > 0)
3208 { 3364 {
3209 uint[] localids = new uint[0]; 3365 uint[] localids = new uint[0];
3210 lock (m_parts) 3366 lockPartsForRead(true);
3211 { 3367 {
3212 localids = new uint[m_parts.Count]; 3368 localids = new uint[m_parts.Count];
3213 int cntr = 0; 3369 int cntr = 0;
@@ -3217,6 +3373,7 @@ namespace OpenSim.Region.Framework.Scenes
3217 cntr++; 3373 cntr++;
3218 } 3374 }
3219 } 3375 }
3376 lockPartsForRead(false);
3220 3377
3221 for (int ctr = 0; ctr < localids.Length; ctr++) 3378 for (int ctr = 0; ctr < localids.Length; ctr++)
3222 { 3379 {
@@ -3235,7 +3392,7 @@ namespace OpenSim.Region.Framework.Scenes
3235 { 3392 {
3236 //trigger not_at_target 3393 //trigger not_at_target
3237 uint[] localids = new uint[0]; 3394 uint[] localids = new uint[0];
3238 lock (m_parts) 3395 lockPartsForRead(true);
3239 { 3396 {
3240 localids = new uint[m_parts.Count]; 3397 localids = new uint[m_parts.Count];
3241 int cntr = 0; 3398 int cntr = 0;
@@ -3245,7 +3402,8 @@ namespace OpenSim.Region.Framework.Scenes
3245 cntr++; 3402 cntr++;
3246 } 3403 }
3247 } 3404 }
3248 3405 lockPartsForRead(false);
3406
3249 for (int ctr = 0; ctr < localids.Length; ctr++) 3407 for (int ctr = 0; ctr < localids.Length; ctr++)
3250 { 3408 {
3251 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3409 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3258,19 +3416,20 @@ namespace OpenSim.Region.Framework.Scenes
3258 public float GetMass() 3416 public float GetMass()
3259 { 3417 {
3260 float retmass = 0f; 3418 float retmass = 0f;
3261 lock (m_parts) 3419 lockPartsForRead(true);
3262 { 3420 {
3263 foreach (SceneObjectPart part in m_parts.Values) 3421 foreach (SceneObjectPart part in m_parts.Values)
3264 { 3422 {
3265 retmass += part.GetMass(); 3423 retmass += part.GetMass();
3266 } 3424 }
3267 } 3425 }
3426 lockPartsForRead(false);
3268 return retmass; 3427 return retmass;
3269 } 3428 }
3270 3429
3271 public void CheckSculptAndLoad() 3430 public void CheckSculptAndLoad()
3272 { 3431 {
3273 lock (m_parts) 3432 lockPartsForRead(true);
3274 { 3433 {
3275 if (!IsDeleted) 3434 if (!IsDeleted)
3276 { 3435 {
@@ -3295,6 +3454,7 @@ namespace OpenSim.Region.Framework.Scenes
3295 } 3454 }
3296 } 3455 }
3297 } 3456 }
3457 lockPartsForRead(false);
3298 } 3458 }
3299 3459
3300 protected void AssetReceived(string id, Object sender, AssetBase asset) 3460 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3315,7 +3475,7 @@ namespace OpenSim.Region.Framework.Scenes
3315 /// <param name="client"></param> 3475 /// <param name="client"></param>
3316 public void SetGroup(UUID GroupID, IClientAPI client) 3476 public void SetGroup(UUID GroupID, IClientAPI client)
3317 { 3477 {
3318 lock (m_parts) 3478 lockPartsForRead(true);
3319 { 3479 {
3320 foreach (SceneObjectPart part in m_parts.Values) 3480 foreach (SceneObjectPart part in m_parts.Values)
3321 { 3481 {
@@ -3325,7 +3485,7 @@ namespace OpenSim.Region.Framework.Scenes
3325 3485
3326 HasGroupChanged = true; 3486 HasGroupChanged = true;
3327 } 3487 }
3328 3488 lockPartsForRead(false);
3329 ScheduleGroupForFullUpdate(); 3489 ScheduleGroupForFullUpdate();
3330 } 3490 }
3331 3491
@@ -3344,11 +3504,12 @@ namespace OpenSim.Region.Framework.Scenes
3344 3504
3345 public void SetAttachmentPoint(byte point) 3505 public void SetAttachmentPoint(byte point)
3346 { 3506 {
3347 lock (m_parts) 3507 lockPartsForRead(true);
3348 { 3508 {
3349 foreach (SceneObjectPart part in m_parts.Values) 3509 foreach (SceneObjectPart part in m_parts.Values)
3350 part.SetAttachmentPoint(point); 3510 part.SetAttachmentPoint(point);
3351 } 3511 }
3512 lockPartsForRead(false);
3352 } 3513 }
3353 3514
3354 #region ISceneObject 3515 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c0243a5..6b562e5 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -212,6 +212,7 @@ namespace OpenSim.Region.Framework.Scenes
212 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 212 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
213 private Vector3 m_sitTargetPosition; 213 private Vector3 m_sitTargetPosition;
214 private string m_sitAnimation = "SIT"; 214 private string m_sitAnimation = "SIT";
215 private bool m_occupied; // KF if any av is sitting on this prim
215 private string m_text = String.Empty; 216 private string m_text = String.Empty;
216 private string m_touchName = String.Empty; 217 private string m_touchName = String.Empty;
217 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 218 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -389,12 +390,16 @@ namespace OpenSim.Region.Framework.Scenes
389 } 390 }
390 391
391 /// <value> 392 /// <value>
392 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 393 /// Get the inventory list
393 /// </value> 394 /// </value>
394 public TaskInventoryDictionary TaskInventory 395 public TaskInventoryDictionary TaskInventory
395 { 396 {
396 get { return m_inventory.Items; } 397 get {
397 set { m_inventory.Items = value; } 398 return m_inventory.Items;
399 }
400 set {
401 m_inventory.Items = value;
402 }
398 } 403 }
399 404
400 public uint ObjectFlags 405 public uint ObjectFlags
@@ -527,7 +532,6 @@ namespace OpenSim.Region.Framework.Scenes
527 StoreUndoState(); 532 StoreUndoState();
528 533
529 m_groupPosition = value; 534 m_groupPosition = value;
530
531 PhysicsActor actor = PhysActor; 535 PhysicsActor actor = PhysActor;
532 if (actor != null) 536 if (actor != null)
533 { 537 {
@@ -837,7 +841,8 @@ namespace OpenSim.Region.Framework.Scenes
837 if (IsAttachment) 841 if (IsAttachment)
838 return GroupPosition; 842 return GroupPosition;
839 843
840 return m_offsetPosition + m_groupPosition; } 844// return m_offsetPosition + m_groupPosition; }
845 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
841 } 846 }
842 847
843 public SceneObjectGroup ParentGroup 848 public SceneObjectGroup ParentGroup
@@ -989,6 +994,13 @@ namespace OpenSim.Region.Framework.Scenes
989 get { return _flags; } 994 get { return _flags; }
990 set { _flags = value; } 995 set { _flags = value; }
991 } 996 }
997
998 [XmlIgnore]
999 public bool IsOccupied // KF If an av is sittingon this prim
1000 {
1001 get { return m_occupied; }
1002 set { m_occupied = value; }
1003 }
992 1004
993 [XmlIgnore] 1005 [XmlIgnore]
994 public UUID SitTargetAvatar 1006 public UUID SitTargetAvatar
@@ -1064,14 +1076,6 @@ namespace OpenSim.Region.Framework.Scenes
1064 } 1076 }
1065 } 1077 }
1066 1078
1067 /// <summary>
1068 /// Clear all pending updates of parts to clients
1069 /// </summary>
1070 private void ClearUpdateSchedule()
1071 {
1072 m_updateFlag = 0;
1073 }
1074
1075 private void SendObjectPropertiesToClient(UUID AgentID) 1079 private void SendObjectPropertiesToClient(UUID AgentID)
1076 { 1080 {
1077 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1081 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1737,12 +1741,17 @@ namespace OpenSim.Region.Framework.Scenes
1737 public Vector3 GetWorldPosition() 1741 public Vector3 GetWorldPosition()
1738 { 1742 {
1739 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1743 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1740
1741 Vector3 axPos = OffsetPosition; 1744 Vector3 axPos = OffsetPosition;
1742
1743 axPos *= parentRot; 1745 axPos *= parentRot;
1744 Vector3 translationOffsetPosition = axPos; 1746 Vector3 translationOffsetPosition = axPos;
1745 return GroupPosition + translationOffsetPosition; 1747 if(_parentID == 0)
1748 {
1749 return GroupPosition;
1750 }
1751 else
1752 {
1753 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
1754 }
1746 } 1755 }
1747 1756
1748 /// <summary> 1757 /// <summary>
@@ -1753,7 +1762,7 @@ namespace OpenSim.Region.Framework.Scenes
1753 { 1762 {
1754 Quaternion newRot; 1763 Quaternion newRot;
1755 1764
1756 if (this.LinkNum == 0) 1765 if (this.LinkNum < 2) //KF Single or root prim
1757 { 1766 {
1758 newRot = RotationOffset; 1767 newRot = RotationOffset;
1759 } 1768 }
@@ -2109,17 +2118,18 @@ namespace OpenSim.Region.Framework.Scenes
2109 //Trys to fetch sound id from prim's inventory. 2118 //Trys to fetch sound id from prim's inventory.
2110 //Prim's inventory doesn't support non script items yet 2119 //Prim's inventory doesn't support non script items yet
2111 2120
2112 lock (TaskInventory) 2121 TaskInventory.LockItemsForRead(true);
2122
2123 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2113 { 2124 {
2114 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2125 if (item.Value.Name == sound)
2115 { 2126 {
2116 if (item.Value.Name == sound) 2127 soundID = item.Value.ItemID;
2117 { 2128 break;
2118 soundID = item.Value.ItemID;
2119 break;
2120 }
2121 } 2129 }
2122 } 2130 }
2131
2132 TaskInventory.LockItemsForRead(false);
2123 } 2133 }
2124 2134
2125 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2135 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2394,8 +2404,8 @@ namespace OpenSim.Region.Framework.Scenes
2394 { 2404 {
2395 const float ROTATION_TOLERANCE = 0.01f; 2405 const float ROTATION_TOLERANCE = 0.01f;
2396 const float VELOCITY_TOLERANCE = 0.001f; 2406 const float VELOCITY_TOLERANCE = 0.001f;
2397 const float POSITION_TOLERANCE = 0.05f; 2407 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2398 const int TIME_MS_TOLERANCE = 3000; 2408 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2399 2409
2400 if (m_updateFlag == 1) 2410 if (m_updateFlag == 1)
2401 { 2411 {
@@ -2409,7 +2419,7 @@ namespace OpenSim.Region.Framework.Scenes
2409 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2419 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2410 { 2420 {
2411 AddTerseUpdateToAllAvatars(); 2421 AddTerseUpdateToAllAvatars();
2412 ClearUpdateSchedule(); 2422
2413 2423
2414 // This causes the Scene to 'poll' physical objects every couple of frames 2424 // This causes the Scene to 'poll' physical objects every couple of frames
2415 // bad, so it's been replaced by an event driven method. 2425 // bad, so it's been replaced by an event driven method.
@@ -2427,16 +2437,18 @@ namespace OpenSim.Region.Framework.Scenes
2427 m_lastAngularVelocity = AngularVelocity; 2437 m_lastAngularVelocity = AngularVelocity;
2428 m_lastTerseSent = Environment.TickCount; 2438 m_lastTerseSent = Environment.TickCount;
2429 } 2439 }
2440 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2441 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2430 } 2442 }
2431 else 2443 else
2432 { 2444 {
2433 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2445 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2434 { 2446 {
2435 AddFullUpdateToAllAvatars(); 2447 AddFullUpdateToAllAvatars();
2436 ClearUpdateSchedule(); 2448 m_updateFlag = 0; //Same here
2437 } 2449 }
2438 } 2450 }
2439 ClearUpdateSchedule(); 2451 m_updateFlag = 0;
2440 } 2452 }
2441 2453
2442 /// <summary> 2454 /// <summary>
@@ -2463,17 +2475,16 @@ namespace OpenSim.Region.Framework.Scenes
2463 if (!UUID.TryParse(sound, out soundID)) 2475 if (!UUID.TryParse(sound, out soundID))
2464 { 2476 {
2465 // search sound file from inventory 2477 // search sound file from inventory
2466 lock (TaskInventory) 2478 TaskInventory.LockItemsForRead(true);
2479 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2467 { 2480 {
2468 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2481 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2469 { 2482 {
2470 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2483 soundID = item.Value.ItemID;
2471 { 2484 break;
2472 soundID = item.Value.ItemID;
2473 break;
2474 }
2475 } 2485 }
2476 } 2486 }
2487 TaskInventory.LockItemsForRead(false);
2477 } 2488 }
2478 2489
2479 if (soundID == UUID.Zero) 2490 if (soundID == UUID.Zero)
@@ -2674,13 +2685,6 @@ namespace OpenSim.Region.Framework.Scenes
2674 ScheduleFullUpdate(); 2685 ScheduleFullUpdate();
2675 } 2686 }
2676 2687
2677 public void StopLookAt()
2678 {
2679 m_parentGroup.stopLookAt();
2680
2681 m_parentGroup.ScheduleGroupForTerseUpdate();
2682 }
2683
2684 /// <summary> 2688 /// <summary>
2685 /// Set the text displayed for this part. 2689 /// Set the text displayed for this part.
2686 /// </summary> 2690 /// </summary>
@@ -2696,6 +2700,13 @@ namespace OpenSim.Region.Framework.Scenes
2696 SetText(text); 2700 SetText(text);
2697 } 2701 }
2698 2702
2703 public void StopLookAt()
2704 {
2705 m_parentGroup.stopLookAt();
2706
2707 m_parentGroup.ScheduleGroupForTerseUpdate();
2708 }
2709
2699 public void StopMoveToTarget() 2710 public void StopMoveToTarget()
2700 { 2711 {
2701 m_parentGroup.stopMoveToTarget(); 2712 m_parentGroup.stopMoveToTarget();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index eb7f5ff..c3c6342 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 }
@@ -232,17 +237,20 @@ namespace OpenSim.Region.Framework.Scenes
232 /// </summary> 237 /// </summary>
233 public void RemoveScriptInstances() 238 public void RemoveScriptInstances()
234 { 239 {
235 lock (Items) 240 Items.LockItemsForRead(true);
241 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
242 Items.LockItemsForRead(false);
243
244 foreach (TaskInventoryItem item in items)
236 { 245 {
237 foreach (TaskInventoryItem item in Items.Values) 246 if ((int)InventoryType.LSL == item.InvType)
238 { 247 {
239 if ((int)InventoryType.LSL == item.InvType) 248 RemoveScriptInstance(item.ItemID);
240 { 249 m_part.RemoveScriptEvents(item.ItemID);
241 RemoveScriptInstance(item.ItemID);
242 m_part.RemoveScriptEvents(item.ItemID);
243 }
244 } 250 }
245 } 251 }
252
253
246 } 254 }
247 255
248 /// <summary> 256 /// <summary>
@@ -267,8 +275,10 @@ namespace OpenSim.Region.Framework.Scenes
267 if (stateSource == 1 && // Prim crossing 275 if (stateSource == 1 && // Prim crossing
268 m_part.ParentGroup.Scene.m_trustBinaries) 276 m_part.ParentGroup.Scene.m_trustBinaries)
269 { 277 {
278 m_items.LockItemsForWrite(true);
270 m_items[item.ItemID].PermsMask = 0; 279 m_items[item.ItemID].PermsMask = 0;
271 m_items[item.ItemID].PermsGranter = UUID.Zero; 280 m_items[item.ItemID].PermsGranter = UUID.Zero;
281 m_items.LockItemsForWrite(false);
272 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 282 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
273 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 283 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
274 m_part.ParentGroup.AddActiveScriptCount(1); 284 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -290,8 +300,10 @@ namespace OpenSim.Region.Framework.Scenes
290 { 300 {
291 if (m_part.ParentGroup.m_savedScriptState != null) 301 if (m_part.ParentGroup.m_savedScriptState != null)
292 RestoreSavedScriptState(item.OldItemID, item.ItemID); 302 RestoreSavedScriptState(item.OldItemID, item.ItemID);
303 m_items.LockItemsForWrite(true);
293 m_items[item.ItemID].PermsMask = 0; 304 m_items[item.ItemID].PermsMask = 0;
294 m_items[item.ItemID].PermsGranter = UUID.Zero; 305 m_items[item.ItemID].PermsGranter = UUID.Zero;
306 m_items.LockItemsForWrite(false);
295 string script = Utils.BytesToString(asset.Data); 307 string script = Utils.BytesToString(asset.Data);
296 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 308 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
297 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 309 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
@@ -367,14 +379,17 @@ namespace OpenSim.Region.Framework.Scenes
367 /// </param> 379 /// </param>
368 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 380 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
369 { 381 {
370 lock (m_items) 382 m_items.LockItemsForRead(true);
383 if (m_items.ContainsKey(itemId))
371 { 384 {
372 if (m_items.ContainsKey(itemId)) 385 if (m_items.ContainsKey(itemId))
373 { 386 {
387 m_items.LockItemsForRead(false);
374 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 388 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
375 } 389 }
376 else 390 else
377 { 391 {
392 m_items.LockItemsForRead(false);
378 m_log.ErrorFormat( 393 m_log.ErrorFormat(
379 "[PRIM INVENTORY]: " + 394 "[PRIM INVENTORY]: " +
380 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 395 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
@@ -382,6 +397,15 @@ namespace OpenSim.Region.Framework.Scenes
382 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 397 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
383 } 398 }
384 } 399 }
400 else
401 {
402 m_items.LockItemsForRead(false);
403 m_log.ErrorFormat(
404 "[PRIM INVENTORY]: " +
405 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
406 itemId, m_part.Name, m_part.UUID);
407 }
408
385 } 409 }
386 410
387 /// <summary> 411 /// <summary>
@@ -413,11 +437,16 @@ namespace OpenSim.Region.Framework.Scenes
413 /// <returns></returns> 437 /// <returns></returns>
414 private bool InventoryContainsName(string name) 438 private bool InventoryContainsName(string name)
415 { 439 {
416 foreach (TaskInventoryItem item in Items.Values) 440 m_items.LockItemsForRead(true);
441 foreach (TaskInventoryItem item in m_items.Values)
417 { 442 {
418 if (item.Name == name) 443 if (item.Name == name)
444 {
445 m_items.LockItemsForRead(false);
419 return true; 446 return true;
447 }
420 } 448 }
449 m_items.LockItemsForRead(false);
421 return false; 450 return false;
422 } 451 }
423 452
@@ -459,7 +488,9 @@ namespace OpenSim.Region.Framework.Scenes
459 /// <param name="item"></param> 488 /// <param name="item"></param>
460 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 489 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
461 { 490 {
491 m_items.LockItemsForRead(true);
462 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); 492 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
493 m_items.LockItemsForRead(false);
463 foreach (TaskInventoryItem i in il) 494 foreach (TaskInventoryItem i in il)
464 { 495 {
465 if (i.Name == item.Name) 496 if (i.Name == item.Name)
@@ -496,15 +527,14 @@ namespace OpenSim.Region.Framework.Scenes
496 item.ParentPartID = m_part.UUID; 527 item.ParentPartID = m_part.UUID;
497 item.Name = name; 528 item.Name = name;
498 529
499 lock (m_items) 530 m_items.LockItemsForWrite(true);
500 { 531 m_items.Add(item.ItemID, item);
501 m_items.Add(item.ItemID, item); 532 m_items.LockItemsForWrite(false);
502
503 if (allowedDrop) 533 if (allowedDrop)
504 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 534 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
505 else 535 else
506 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 536 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
507 } 537
508 538
509 m_inventorySerial++; 539 m_inventorySerial++;
510 //m_inventorySerial += 2; 540 //m_inventorySerial += 2;
@@ -521,14 +551,13 @@ namespace OpenSim.Region.Framework.Scenes
521 /// <param name="items"></param> 551 /// <param name="items"></param>
522 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 552 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
523 { 553 {
524 lock (m_items) 554 m_items.LockItemsForWrite(true);
555 foreach (TaskInventoryItem item in items)
525 { 556 {
526 foreach (TaskInventoryItem item in items) 557 m_items.Add(item.ItemID, item);
527 { 558 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
528 m_items.Add(item.ItemID, item);
529 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
530 }
531 } 559 }
560 m_items.LockItemsForWrite(false);
532 561
533 m_inventorySerial++; 562 m_inventorySerial++;
534 } 563 }
@@ -541,8 +570,9 @@ namespace OpenSim.Region.Framework.Scenes
541 public TaskInventoryItem GetInventoryItem(UUID itemId) 570 public TaskInventoryItem GetInventoryItem(UUID itemId)
542 { 571 {
543 TaskInventoryItem item; 572 TaskInventoryItem item;
573 m_items.LockItemsForRead(true);
544 m_items.TryGetValue(itemId, out item); 574 m_items.TryGetValue(itemId, out item);
545 575 m_items.LockItemsForRead(false);
546 return item; 576 return item;
547 } 577 }
548 578
@@ -554,46 +584,46 @@ namespace OpenSim.Region.Framework.Scenes
554 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 584 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
555 public bool UpdateInventoryItem(TaskInventoryItem item) 585 public bool UpdateInventoryItem(TaskInventoryItem item)
556 { 586 {
557 lock (m_items) 587 m_items.LockItemsForWrite(true);
588
589 if (m_items.ContainsKey(item.ItemID))
558 { 590 {
559 if (m_items.ContainsKey(item.ItemID)) 591 item.ParentID = m_part.UUID;
592 item.ParentPartID = m_part.UUID;
593 item.Flags = m_items[item.ItemID].Flags;
594 if (item.AssetID == UUID.Zero)
560 { 595 {
561 item.ParentID = m_part.UUID; 596 item.AssetID = m_items[item.ItemID].AssetID;
562 item.ParentPartID = m_part.UUID; 597 }
563 item.Flags = m_items[item.ItemID].Flags; 598 else if ((InventoryType)item.Type == InventoryType.Notecard)
564 if (item.AssetID == UUID.Zero) 599 {
565 { 600 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
566 item.AssetID = m_items[item.ItemID].AssetID;
567 }
568 else if ((InventoryType)item.Type == InventoryType.Notecard)
569 {
570 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
571 601
572 if (presence != null) 602 if (presence != null)
573 { 603 {
574 presence.ControllingClient.SendAgentAlertMessage( 604 presence.ControllingClient.SendAgentAlertMessage(
575 "Notecard saved", false); 605 "Notecard saved", false);
576 }
577 } 606 }
607 }
578 608
579 m_items[item.ItemID] = item; 609 m_items[item.ItemID] = item;
580 m_inventorySerial++; 610 m_inventorySerial++;
581 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 611 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
582
583 HasInventoryChanged = true;
584 m_part.ParentGroup.HasGroupChanged = true;
585 612
586 return true; 613 HasInventoryChanged = true;
587 } 614 m_part.ParentGroup.HasGroupChanged = true;
588 else 615 m_items.LockItemsForWrite(false);
589 { 616 return true;
590 m_log.ErrorFormat( 617 }
591 "[PRIM INVENTORY]: " + 618 else
592 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 619 {
593 item.ItemID, m_part.Name, m_part.UUID, 620 m_log.ErrorFormat(
594 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 621 "[PRIM INVENTORY]: " +
595 } 622 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
623 item.ItemID, m_part.Name, m_part.UUID,
624 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
596 } 625 }
626 m_items.LockItemsForWrite(false);
597 627
598 return false; 628 return false;
599 } 629 }
@@ -606,52 +636,54 @@ namespace OpenSim.Region.Framework.Scenes
606 /// in this prim's inventory.</returns> 636 /// in this prim's inventory.</returns>
607 public int RemoveInventoryItem(UUID itemID) 637 public int RemoveInventoryItem(UUID itemID)
608 { 638 {
609 lock (m_items) 639 m_items.LockItemsForRead(true);
640
641 if (m_items.ContainsKey(itemID))
610 { 642 {
611 if (m_items.ContainsKey(itemID)) 643 int type = m_items[itemID].InvType;
644 m_items.LockItemsForRead(false);
645 if (type == 10) // Script
612 { 646 {
613 int type = m_items[itemID].InvType; 647 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
614 if (type == 10) // Script 648 }
615 { 649 m_items.LockItemsForWrite(true);
616 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 650 m_items.Remove(itemID);
617 } 651 m_items.LockItemsForWrite(false);
618 m_items.Remove(itemID); 652 m_inventorySerial++;
619 m_inventorySerial++; 653 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
620 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
621
622 HasInventoryChanged = true;
623 m_part.ParentGroup.HasGroupChanged = true;
624 654
625 int scriptcount = 0; 655 HasInventoryChanged = true;
626 lock (m_items) 656 m_part.ParentGroup.HasGroupChanged = true;
627 {
628 foreach (TaskInventoryItem item in m_items.Values)
629 {
630 if (item.Type == 10)
631 {
632 scriptcount++;
633 }
634 }
635 }
636 657
637 if (scriptcount <= 0) 658 int scriptcount = 0;
659 m_items.LockItemsForRead(true);
660 foreach (TaskInventoryItem item in m_items.Values)
661 {
662 if (item.Type == 10)
638 { 663 {
639 m_part.RemFlag(PrimFlags.Scripted); 664 scriptcount++;
640 } 665 }
641
642 m_part.ScheduleFullUpdate();
643
644 return type;
645 } 666 }
646 else 667 m_items.LockItemsForRead(false);
668
669
670 if (scriptcount <= 0)
647 { 671 {
648 m_log.ErrorFormat( 672 m_part.RemFlag(PrimFlags.Scripted);
649 "[PRIM INVENTORY]: " +
650 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
651 itemID, m_part.Name, m_part.UUID,
652 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
653 } 673 }
674
675 m_part.ScheduleFullUpdate();
676
677 return type;
678 }
679 else
680 {
681 m_log.ErrorFormat(
682 "[PRIM INVENTORY]: " +
683 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
684 itemID, m_part.Name, m_part.UUID);
654 } 685 }
686 m_items.LockItemsForWrite(false);
655 687
656 return -1; 688 return -1;
657 } 689 }
@@ -704,52 +736,53 @@ namespace OpenSim.Region.Framework.Scenes
704 // isn't available (such as drag from prim inventory to agent inventory) 736 // isn't available (such as drag from prim inventory to agent inventory)
705 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 737 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
706 738
707 lock (m_items) 739 m_items.LockItemsForRead(true);
740
741 foreach (TaskInventoryItem item in m_items.Values)
708 { 742 {
709 foreach (TaskInventoryItem item in m_items.Values) 743 UUID ownerID = item.OwnerID;
710 { 744 uint everyoneMask = 0;
711 UUID ownerID = item.OwnerID; 745 uint baseMask = item.BasePermissions;
712 uint everyoneMask = 0; 746 uint ownerMask = item.CurrentPermissions;
713 uint baseMask = item.BasePermissions;
714 uint ownerMask = item.CurrentPermissions;
715 747
716 invString.AddItemStart(); 748 invString.AddItemStart();
717 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 749 invString.AddNameValueLine("item_id", item.ItemID.ToString());
718 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 750 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
719 751
720 invString.AddPermissionsStart(); 752 invString.AddPermissionsStart();
721 753
722 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 754 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
723 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 755 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
724 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 756 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
725 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 757 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
726 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 758 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
727 759
728 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 760 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
729 invString.AddNameValueLine("owner_id", ownerID.ToString()); 761 invString.AddNameValueLine("owner_id", ownerID.ToString());
730 762
731 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 763 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
732 764
733 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 765 invString.AddNameValueLine("group_id", item.GroupID.ToString());
734 invString.AddSectionEnd(); 766 invString.AddSectionEnd();
735 767
736 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 768 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
737 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 769 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
738 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 770 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
739 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 771 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
740 772
741 invString.AddSaleStart(); 773 invString.AddSaleStart();
742 invString.AddNameValueLine("sale_type", "not"); 774 invString.AddNameValueLine("sale_type", "not");
743 invString.AddNameValueLine("sale_price", "0"); 775 invString.AddNameValueLine("sale_price", "0");
744 invString.AddSectionEnd(); 776 invString.AddSectionEnd();
745 777
746 invString.AddNameValueLine("name", item.Name + "|"); 778 invString.AddNameValueLine("name", item.Name + "|");
747 invString.AddNameValueLine("desc", item.Description + "|"); 779 invString.AddNameValueLine("desc", item.Description + "|");
748 780
749 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 781 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
750 invString.AddSectionEnd(); 782 invString.AddSectionEnd();
751 }
752 } 783 }
784 int count = m_items.Count;
785 m_items.LockItemsForRead(false);
753 786
754 fileData = Utils.StringToBytes(invString.BuildString); 787 fileData = Utils.StringToBytes(invString.BuildString);
755 788
@@ -770,10 +803,9 @@ namespace OpenSim.Region.Framework.Scenes
770 { 803 {
771 if (HasInventoryChanged) 804 if (HasInventoryChanged)
772 { 805 {
773 lock (Items) 806 Items.LockItemsForRead(true);
774 { 807 datastore.StorePrimInventory(m_part.UUID, Items.Values);
775 datastore.StorePrimInventory(m_part.UUID, Items.Values); 808 Items.LockItemsForRead(false);
776 }
777 809
778 HasInventoryChanged = false; 810 HasInventoryChanged = false;
779 } 811 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4c2de27..f05fe59 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,8 +115,11 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
117 private Vector3 m_lastPosition; 119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
121 private Vector3 m_lastPosition;
122 private Vector3 m_lastWorldPosition;
118 private Quaternion m_lastRotation; 123 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 124 private Vector3 m_lastVelocity;
120 //private int m_lastTerseSent; 125 //private int m_lastTerseSent;
@@ -145,7 +150,6 @@ namespace OpenSim.Region.Framework.Scenes
145 private int m_perfMonMS; 150 private int m_perfMonMS;
146 151
147 private bool m_setAlwaysRun; 152 private bool m_setAlwaysRun;
148
149 private bool m_forceFly; 153 private bool m_forceFly;
150 private bool m_flyDisabled; 154 private bool m_flyDisabled;
151 155
@@ -169,7 +173,12 @@ namespace OpenSim.Region.Framework.Scenes
169 protected RegionInfo m_regionInfo; 173 protected RegionInfo m_regionInfo;
170 protected ulong crossingFromRegion; 174 protected ulong crossingFromRegion;
171 175
176<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs
177 private readonly Vector3[] Dir_Vectors = new Vector3[11];
178 private bool m_isNudging = false;
179=======
172 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 180 private readonly Vector3[] Dir_Vectors = new Vector3[9];
181>>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs
173 182
174 // Position of agent's camera in world (region cordinates) 183 // Position of agent's camera in world (region cordinates)
175 protected Vector3 m_CameraCenter; 184 protected Vector3 m_CameraCenter;
@@ -194,6 +203,7 @@ namespace OpenSim.Region.Framework.Scenes
194 private bool m_autopilotMoving; 203 private bool m_autopilotMoving;
195 private Vector3 m_autoPilotTarget; 204 private Vector3 m_autoPilotTarget;
196 private bool m_sitAtAutoTarget; 205 private bool m_sitAtAutoTarget;
206 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
197 207
198 private string m_nextSitAnimation = String.Empty; 208 private string m_nextSitAnimation = String.Empty;
199 209
@@ -204,6 +214,9 @@ namespace OpenSim.Region.Framework.Scenes
204 private bool m_followCamAuto; 214 private bool m_followCamAuto;
205 215
206 private int m_movementUpdateCount; 216 private int m_movementUpdateCount;
217 private int m_lastColCount = -1; //KF: Look for Collision chnages
218 private int m_updateCount = 0; //KF: Update Anims for a while
219 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
207 220
208 private const int NumMovementsBetweenRayCast = 5; 221 private const int NumMovementsBetweenRayCast = 5;
209 222
@@ -234,7 +247,13 @@ namespace OpenSim.Region.Framework.Scenes
234 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 247 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
235 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 248 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
236 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 249 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
250<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs
251 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
252 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
253 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
254=======
237 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 255 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
256>>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs
238 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 257 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
239 } 258 }
240 259
@@ -660,10 +679,7 @@ namespace OpenSim.Region.Framework.Scenes
660 679
661 680
662 AdjustKnownSeeds(); 681 AdjustKnownSeeds();
663
664 // TODO: I think, this won't send anything, as we are still a child here...
665 Animator.TrySetMovementAnimation("STAND"); 682 Animator.TrySetMovementAnimation("STAND");
666
667 // we created a new ScenePresence (a new child agent) in a fresh region. 683 // we created a new ScenePresence (a new child agent) in a fresh region.
668 // Request info about all the (root) agents in this region 684 // Request info about all the (root) agents in this region
669 // Note: This won't send data *to* other clients in that region (children don't send) 685 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -719,25 +735,63 @@ namespace OpenSim.Region.Framework.Scenes
719 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 735 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
720 Dir_Vectors[4] = Vector3.UnitZ; //UP 736 Dir_Vectors[4] = Vector3.UnitZ; //UP
721 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 737 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
738<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs
739 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
740 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
741 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
742 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
743 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
744=======
722 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 745 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
723 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 746 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD
724 Dir_Vectors[7] = -Vector3.UnitX; //BACK 747 Dir_Vectors[7] = -Vector3.UnitX; //BACK
748>>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs
725 } 749 }
726 750
727 private Vector3[] GetWalkDirectionVectors() 751 private Vector3[] GetWalkDirectionVectors()
728 { 752 {
753<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs
754 Vector3[] vector = new Vector3[11];
755=======
729 Vector3[] vector = new Vector3[9]; 756 Vector3[] vector = new Vector3[9];
757>>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs
730 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 758 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
731 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 759 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
732 vector[2] = Vector3.UnitY; //LEFT 760 vector[2] = Vector3.UnitY; //LEFT
733 vector[3] = -Vector3.UnitY; //RIGHT 761 vector[3] = -Vector3.UnitY; //RIGHT
734 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 762 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
735 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 763 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
764<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs
765 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
766 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
770=======
736 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 771 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge
737 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 772 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge
738 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 773 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge
774>>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs
739 return vector; 775 return vector;
740 } 776 }
777
778 private bool[] GetDirectionIsNudge()
779 {
780 bool[] isNudge = new bool[11];
781 isNudge[0] = false; //FORWARD
782 isNudge[1] = false; //BACK
783 isNudge[2] = false; //LEFT
784 isNudge[3] = false; //RIGHT
785 isNudge[4] = false; //UP
786 isNudge[5] = false; //DOWN
787 isNudge[6] = true; //FORWARD_NUDGE
788 isNudge[7] = true; //BACK_NUDGE
789 isNudge[8] = true; //LEFT_NUDGE
790 isNudge[9] = true; //RIGHT_NUDGE
791 isNudge[10] = true; //DOWN_Nudge
792 return isNudge;
793 }
794
741 795
742 #endregion 796 #endregion
743 797
@@ -806,9 +860,24 @@ namespace OpenSim.Region.Framework.Scenes
806 { 860 {
807 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 861 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
808 pos.Y = crossedBorder.BorderLine.Z - 1; 862 pos.Y = crossedBorder.BorderLine.Z - 1;
863 }
864
865 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
866 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
867 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
868 if (KnownChildRegionHandles.Count == 0)
869 {
870 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
871 if (land != null)
872 {
873 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
874 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)
875 {
876 pos = land.LandData.UserLocation;
877 }
878 }
809 } 879 }
810 880
811
812 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 881 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
813 { 882 {
814 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 883 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -943,9 +1012,10 @@ namespace OpenSim.Region.Framework.Scenes
943 public void Teleport(Vector3 pos) 1012 public void Teleport(Vector3 pos)
944 { 1013 {
945 bool isFlying = false; 1014 bool isFlying = false;
946 if (m_physicsActor != null)
947 isFlying = m_physicsActor.Flying;
948 1015
1016 if (m_physicsActor != null)
1017 isFlying = m_physicsActor.Flying;
1018
949 RemoveFromPhysicalScene(); 1019 RemoveFromPhysicalScene();
950 Velocity = Vector3.Zero; 1020 Velocity = Vector3.Zero;
951 AbsolutePosition = pos; 1021 AbsolutePosition = pos;
@@ -956,7 +1026,8 @@ namespace OpenSim.Region.Framework.Scenes
956 SetHeight(m_appearance.AvatarHeight); 1026 SetHeight(m_appearance.AvatarHeight);
957 } 1027 }
958 1028
959 SendTerseUpdateToAllClients(); 1029 SendTerseUpdateToAllClients();
1030
960 } 1031 }
961 1032
962 public void TeleportWithMomentum(Vector3 pos) 1033 public void TeleportWithMomentum(Vector3 pos)
@@ -1001,7 +1072,9 @@ namespace OpenSim.Region.Framework.Scenes
1001 { 1072 {
1002 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1073 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1003 } 1074 }
1004 1075
1076 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1077
1005 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1078 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1006 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1079 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1007 } 1080 }
@@ -1236,7 +1309,6 @@ namespace OpenSim.Region.Framework.Scenes
1236 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1309 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1237 } 1310 }
1238 } 1311 }
1239
1240 lock (scriptedcontrols) 1312 lock (scriptedcontrols)
1241 { 1313 {
1242 if (scriptedcontrols.Count > 0) 1314 if (scriptedcontrols.Count > 0)
@@ -1251,9 +1323,7 @@ namespace OpenSim.Region.Framework.Scenes
1251 1323
1252 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1324 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1253 { 1325 {
1254 // TODO: This doesn't prevent the user from walking yet. 1326 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1255 // Setting parent ID would fix this, if we knew what value
1256 // to use. Or we could add a m_isSitting variable.
1257 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1327 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1258 } 1328 }
1259 1329
@@ -1298,6 +1368,11 @@ namespace OpenSim.Region.Framework.Scenes
1298 update_rotation = true; 1368 update_rotation = true;
1299 } 1369 }
1300 1370
1371 //guilty until proven innocent..
1372 bool Nudging = true;
1373 //Basically, if there is at least one non-nudge control then we don't need
1374 //to worry about stopping the avatar
1375
1301 if (m_parentID == 0) 1376 if (m_parentID == 0)
1302 { 1377 {
1303 bool bAllowUpdateMoveToPosition = false; 1378 bool bAllowUpdateMoveToPosition = false;
@@ -1312,9 +1387,18 @@ namespace OpenSim.Region.Framework.Scenes
1312 else 1387 else
1313 dirVectors = Dir_Vectors; 1388 dirVectors = Dir_Vectors;
1314 1389
1390<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs
1391 bool[] isNudge = GetDirectionIsNudge();
1392
1393
1394
1395
1396
1397=======
1315 // The fact that m_movementflag is a byte needs to be fixed 1398 // The fact that m_movementflag is a byte needs to be fixed
1316 // it really should be a uint 1399 // it really should be a uint
1317 uint nudgehack = 250; 1400 uint nudgehack = 250;
1401>>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs
1318 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1402 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1319 { 1403 {
1320 if (((uint)flags & (uint)DCF) != 0) 1404 if (((uint)flags & (uint)DCF) != 0)
@@ -1324,7 +1408,14 @@ namespace OpenSim.Region.Framework.Scenes
1324 try 1408 try
1325 { 1409 {
1326 agent_control_v3 += dirVectors[i]; 1410 agent_control_v3 += dirVectors[i];
1411<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs
1412 if (isNudge[i] == false)
1413 {
1414 Nudging = false;
1415 }
1416=======
1327 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1417 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
1418>>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs
1328 } 1419 }
1329 catch (IndexOutOfRangeException) 1420 catch (IndexOutOfRangeException)
1330 { 1421 {
@@ -1401,6 +1492,9 @@ namespace OpenSim.Region.Framework.Scenes
1401 // Ignore z component of vector 1492 // Ignore z component of vector
1402 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1493 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1403 LocalVectorToTarget2D.Normalize(); 1494 LocalVectorToTarget2D.Normalize();
1495
1496 //We're not nudging
1497 Nudging = false;
1404 agent_control_v3 += LocalVectorToTarget2D; 1498 agent_control_v3 += LocalVectorToTarget2D;
1405 1499
1406 // update avatar movement flags. the avatar coordinate system is as follows: 1500 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1489,7 +1583,7 @@ namespace OpenSim.Region.Framework.Scenes
1489 // m_log.DebugFormat( 1583 // m_log.DebugFormat(
1490 // "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);
1491 1585
1492 AddNewMovement(agent_control_v3, q); 1586 AddNewMovement(agent_control_v3, q, Nudging);
1493 1587
1494 1588
1495 } 1589 }
@@ -1510,7 +1604,6 @@ namespace OpenSim.Region.Framework.Scenes
1510 m_sitAtAutoTarget = false; 1604 m_sitAtAutoTarget = false;
1511 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1605 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1512 //proxy.PCode = (byte)PCode.ParticleSystem; 1606 //proxy.PCode = (byte)PCode.ParticleSystem;
1513
1514 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1607 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1515 proxyObjectGroup.AttachToScene(m_scene); 1608 proxyObjectGroup.AttachToScene(m_scene);
1516 1609
@@ -1552,7 +1645,7 @@ namespace OpenSim.Region.Framework.Scenes
1552 } 1645 }
1553 m_moveToPositionInProgress = true; 1646 m_moveToPositionInProgress = true;
1554 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1647 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1555 } 1648 }
1556 catch (Exception ex) 1649 catch (Exception ex)
1557 { 1650 {
1558 //Why did I get this error? 1651 //Why did I get this error?
@@ -1574,7 +1667,7 @@ namespace OpenSim.Region.Framework.Scenes
1574 Velocity = Vector3.Zero; 1667 Velocity = Vector3.Zero;
1575 SendFullUpdateToAllClients(); 1668 SendFullUpdateToAllClients();
1576 1669
1577 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1670 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1578 } 1671 }
1579 //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);
1580 m_requestedSitTargetUUID = UUID.Zero; 1673 m_requestedSitTargetUUID = UUID.Zero;
@@ -1612,46 +1705,79 @@ namespace OpenSim.Region.Framework.Scenes
1612 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1705 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1613 if (part != null) 1706 if (part != null)
1614 { 1707 {
1708 part.TaskInventory.LockItemsForRead(true);
1615 TaskInventoryDictionary taskIDict = part.TaskInventory; 1709 TaskInventoryDictionary taskIDict = part.TaskInventory;
1616 if (taskIDict != null) 1710 if (taskIDict != null)
1617 { 1711 {
1618 lock (taskIDict) 1712 foreach (UUID taskID in taskIDict.Keys)
1619 { 1713 {
1620 foreach (UUID taskID in taskIDict.Keys) 1714 UnRegisterControlEventsToScript(LocalId, taskID);
1621 { 1715 taskIDict[taskID].PermsMask &= ~(
1622 UnRegisterControlEventsToScript(LocalId, taskID); 1716 2048 | //PERMISSION_CONTROL_CAMERA
1623 taskIDict[taskID].PermsMask &= ~( 1717 4); // PERMISSION_TAKE_CONTROLS
1624 2048 | //PERMISSION_CONTROL_CAMERA
1625 4); // PERMISSION_TAKE_CONTROLS
1626 }
1627 } 1718 }
1628
1629 } 1719 }
1720 part.TaskInventory.LockItemsForRead(false);
1630 // Reset sit target. 1721 // Reset sit target.
1631 if (part.GetAvatarOnSitTarget() == UUID) 1722 if (part.GetAvatarOnSitTarget() == UUID)
1632 part.SetAvatarOnSitTarget(UUID.Zero); 1723 part.SetAvatarOnSitTarget(UUID.Zero);
1633
1634 m_parentPosition = part.GetWorldPosition(); 1724 m_parentPosition = part.GetWorldPosition();
1635 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1725 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1636 } 1726 }
1637 1727 // part.GetWorldRotation() is the rotation of the object being sat on
1638 if (m_physicsActor == null) 1728 // Rotation is the sittiing Av's rotation
1639 { 1729
1640 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();
1641 } 1746 }
1642 1747
1643 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1748 Quaternion partIRot = Quaternion.Inverse(partRot);
1644 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
1645 1752
1646 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;
1647 SendFullUpdateToAllClients(); 1773 SendFullUpdateToAllClients();
1648 m_requestedSitTargetID = 0; 1774 m_requestedSitTargetID = 0;
1775
1649 if ((m_physicsActor != null) && (m_avHeight > 0)) 1776 if ((m_physicsActor != null) && (m_avHeight > 0))
1650 { 1777 {
1651 SetHeight(m_avHeight); 1778 SetHeight(m_avHeight);
1652 } 1779 }
1653 } 1780 }
1654
1655 Animator.TrySetMovementAnimation("STAND"); 1781 Animator.TrySetMovementAnimation("STAND");
1656 } 1782 }
1657 1783
@@ -1682,13 +1808,9 @@ namespace OpenSim.Region.Framework.Scenes
1682 Vector3 avSitOffSet = part.SitTargetPosition; 1808 Vector3 avSitOffSet = part.SitTargetPosition;
1683 Quaternion avSitOrientation = part.SitTargetOrientation; 1809 Quaternion avSitOrientation = part.SitTargetOrientation;
1684 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1810 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1685 1811 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1686 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1812 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1687 bool SitTargetisSet = 1813 if (SitTargetisSet && !SitTargetOccupied)
1688 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1689 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1690
1691 if (SitTargetisSet && SitTargetUnOccupied)
1692 { 1814 {
1693 //switch the target to this prim 1815 //switch the target to this prim
1694 return part; 1816 return part;
@@ -1702,84 +1824,152 @@ namespace OpenSim.Region.Framework.Scenes
1702 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1824 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1703 { 1825 {
1704 bool autopilot = true; 1826 bool autopilot = true;
1827 Vector3 autopilotTarget = new Vector3();
1828 Quaternion sitOrientation = Quaternion.Identity;
1705 Vector3 pos = new Vector3(); 1829 Vector3 pos = new Vector3();
1706 Quaternion sitOrientation = pSitOrientation;
1707 Vector3 cameraEyeOffset = Vector3.Zero; 1830 Vector3 cameraEyeOffset = Vector3.Zero;
1708 Vector3 cameraAtOffset = Vector3.Zero; 1831 Vector3 cameraAtOffset = Vector3.Zero;
1709 bool forceMouselook = false; 1832 bool forceMouselook = false;
1710 1833
1711 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1834 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1712 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1835 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1713 if (part != null) 1836 if (part == null) return;
1714 { 1837
1715 // 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
1716 // 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
1717 1840
1718 // Is a sit target available? 1841 // part is the prim to sit on
1719 Vector3 avSitOffSet = part.SitTargetPosition; 1842 // offset is the world-ref vector distance from that prim center to the click-spot
1720 Quaternion avSitOrientation = part.SitTargetOrientation; 1843 // UUID is the UUID of the Avatar doing the clicking
1721 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1844
1722 1845 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1723 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1846
1724 bool SitTargetisSet = 1847 // Is a sit target available?
1725 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1848 Vector3 avSitOffSet = part.SitTargetPosition;
1726 ( 1849 Quaternion avSitOrientation = part.SitTargetOrientation;
1727 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1850
1728 || 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.
1729 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1852 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1730 ) 1853 Quaternion partRot;
1731 )); 1854// if (part.LinkNum == 1)
1732 1855// { // Root prim of linkset
1733 if (SitTargetisSet && SitTargetUnOccupied) 1856// partRot = part.ParentGroup.RootPart.RotationOffset;
1734 { 1857// }
1735 part.SetAvatarOnSitTarget(UUID); 1858// else
1736 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1859// { // single or child prim
1737 sitOrientation = avSitOrientation; 1860 partRot = part.GetWorldRotation();
1738 autopilot = false; 1861// }
1739 } 1862 Quaternion partIRot = Quaternion.Inverse(partRot);
1740 1863//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1741 pos = part.AbsolutePosition + offset; 1864 // Sit analysis rewritten by KF 091125
1742 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1865 if (SitTargetisSet) // scipted sit
1743 //{ 1866 {
1744 // offset = pos; 1867 if (!part.IsOccupied)
1745 //autopilot = false; 1868 {
1746 //} 1869//Console.WriteLine("Scripted, unoccupied");
1747 if (m_physicsActor != null) 1870 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1748 { 1871 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1749 // 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
1750 // We can remove the physicsActor until they stand up. 1873 autopilot = false; // Jump direct to scripted llSitPos()
1751 m_sitAvatarHeight = m_physicsActor.Size.Z; 1874 }
1752 1875 else
1753 if (autopilot) 1876 {
1754 { 1877//Console.WriteLine("Scripted, occupied");
1755 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1878 return;
1756 { 1879 }
1757 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); //
1758 1911
1759 RemoveFromPhysicalScene(); 1912 if (m_physicsActor != null)
1760 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1913 {
1761 } 1914 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1762 } 1915 // We can remove the physicsActor until they stand up.
1763 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) )
1764 { 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? */
1765 RemoveFromPhysicalScene(); 1926 RemoveFromPhysicalScene();
1766 } 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();
1767 } 1936 }
1768
1769 cameraAtOffset = part.GetCameraAtOffset();
1770 cameraEyeOffset = part.GetCameraEyeOffset();
1771 forceMouselook = part.GetForceMouselook();
1772 } 1937 }
1773 1938 else return; // physactor is null!
1774 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1939
1775 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
1776 // This calls HandleAgentSit twice, once from here, and the client calls 1965 // This calls HandleAgentSit twice, once from here, and the client calls
1777 // HandleAgentSit itself after it gets to the location 1966 // HandleAgentSit itself after it gets to the location
1778 // 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
1779 // which happens in HandleAgentSit :P 1968 // which happens in HandleAgentSit :P
1780 m_autopilotMoving = autopilot; 1969 m_autopilotMoving = autopilot;
1781 m_autoPilotTarget = pos; 1970 m_autoPilotTarget = autopilotTarget;
1782 m_sitAtAutoTarget = autopilot; 1971 m_sitAtAutoTarget = autopilot;
1972 m_initialSitTarget = autopilotTarget;
1783 if (!autopilot) 1973 if (!autopilot)
1784 HandleAgentSit(remoteClient, UUID); 1974 HandleAgentSit(remoteClient, UUID);
1785 } 1975 }
@@ -2074,31 +2264,65 @@ namespace OpenSim.Region.Framework.Scenes
2074 { 2264 {
2075 if (part != null) 2265 if (part != null)
2076 { 2266 {
2267//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2077 if (part.GetAvatarOnSitTarget() == UUID) 2268 if (part.GetAvatarOnSitTarget() == UUID)
2078 { 2269 {
2270//Console.WriteLine("Scripted Sit");
2271 // Scripted sit
2079 Vector3 sitTargetPos = part.SitTargetPosition; 2272 Vector3 sitTargetPos = part.SitTargetPosition;
2080 Quaternion sitTargetOrient = part.SitTargetOrientation; 2273 Quaternion sitTargetOrient = part.SitTargetOrientation;
2081
2082 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2083 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2084
2085 //Quaternion result = (sitTargetOrient * vq) * nq;
2086
2087 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2274 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2088 m_pos += SIT_TARGET_ADJUSTMENT; 2275 m_pos += SIT_TARGET_ADJUSTMENT;
2089 m_bodyRot = sitTargetOrient; 2276 m_bodyRot = sitTargetOrient;
2090 //Rotation = sitTargetOrient;
2091 m_parentPosition = part.AbsolutePosition; 2277 m_parentPosition = part.AbsolutePosition;
2092 2278 part.IsOccupied = true;
2093 //SendTerseUpdateToAllClients();
2094 } 2279 }
2095 else 2280 else
2096 { 2281 {
2097 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
2098 m_parentPosition = part.AbsolutePosition; 2306 m_parentPosition = part.AbsolutePosition;
2099 } 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
2100 } 2324 }
2101 else 2325 else // no Av
2102 { 2326 {
2103 return; 2327 return;
2104 } 2328 }
@@ -2110,11 +2334,36 @@ namespace OpenSim.Region.Framework.Scenes
2110 2334
2111 Animator.TrySetMovementAnimation(sitAnimation); 2335 Animator.TrySetMovementAnimation(sitAnimation);
2112 SendFullUpdateToAllClients(); 2336 SendFullUpdateToAllClients();
2113 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2114 // So we're also sending a terse update (which has avatar rotation)
2115 // [Update] We do now.
2116 //SendTerseUpdateToAllClients();
2117 } 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.
2118 2367
2119 /// <summary> 2368 /// <summary>
2120 /// Event handler for the 'Always run' setting on the client 2369 /// Event handler for the 'Always run' setting on the client
@@ -2144,7 +2393,7 @@ namespace OpenSim.Region.Framework.Scenes
2144 /// </summary> 2393 /// </summary>
2145 /// <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>
2146 /// <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.
2147 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2396 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2148 { 2397 {
2149 if (m_isChildAgent) 2398 if (m_isChildAgent)
2150 { 2399 {
@@ -2218,7 +2467,7 @@ namespace OpenSim.Region.Framework.Scenes
2218 2467
2219 // 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?
2220 m_forceToApply = direc; 2469 m_forceToApply = direc;
2221 2470 m_isNudging = Nudging;
2222 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2471 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2223 } 2472 }
2224 2473
@@ -2233,7 +2482,7 @@ namespace OpenSim.Region.Framework.Scenes
2233 const float POSITION_TOLERANCE = 0.05f; 2482 const float POSITION_TOLERANCE = 0.05f;
2234 //const int TIME_MS_TOLERANCE = 3000; 2483 //const int TIME_MS_TOLERANCE = 3000;
2235 2484
2236 SendPrimUpdates(); 2485
2237 2486
2238 if (m_newCoarseLocations) 2487 if (m_newCoarseLocations)
2239 { 2488 {
@@ -2269,6 +2518,9 @@ namespace OpenSim.Region.Framework.Scenes
2269 CheckForBorderCrossing(); 2518 CheckForBorderCrossing();
2270 CheckForSignificantMovement(); // sends update to the modules. 2519 CheckForSignificantMovement(); // sends update to the modules.
2271 } 2520 }
2521
2522 //Sending prim updates AFTER the avatar terse updates are sent
2523 SendPrimUpdates();
2272 } 2524 }
2273 2525
2274 #endregion 2526 #endregion
@@ -3122,14 +3374,25 @@ namespace OpenSim.Region.Framework.Scenes
3122 { 3374 {
3123 if (m_forceToApply.HasValue) 3375 if (m_forceToApply.HasValue)
3124 { 3376 {
3125 Vector3 force = m_forceToApply.Value;
3126 3377
3378 Vector3 force = m_forceToApply.Value;
3127 m_updateflag = true; 3379 m_updateflag = true;
3128// movementvector = force;
3129 Velocity = force; 3380 Velocity = force;
3130 3381
3131 m_forceToApply = null; 3382 m_forceToApply = null;
3132 } 3383 }
3384 else
3385 {
3386 if (m_isNudging)
3387 {
3388 Vector3 force = Vector3.Zero;
3389
3390 m_updateflag = true;
3391 Velocity = force;
3392 m_isNudging = false;
3393 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3394 }
3395 }
3133 } 3396 }
3134 3397
3135 public override void SetText(string text, Vector3 color, double alpha) 3398 public override void SetText(string text, Vector3 color, double alpha)
@@ -3181,18 +3444,29 @@ namespace OpenSim.Region.Framework.Scenes
3181 { 3444 {
3182 if (e == null) 3445 if (e == null)
3183 return; 3446 return;
3184 3447
3185 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3448 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3186 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3187 // as of this comment the interval is set in AddToPhysicalScene 3449 // as of this comment the interval is set in AddToPhysicalScene
3188 if (Animator!=null) 3450 if (Animator!=null)
3189 Animator.UpdateMovementAnimations(); 3451 {
3452 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3453 { // else its will lock out other animation changes, like ground sit.
3454 Animator.UpdateMovementAnimations();
3455 m_updateCount--;
3456 }
3457 }
3190 3458
3191 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3459 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3192 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3460 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3193 3461
3194 CollisionPlane = Vector4.UnitW; 3462 CollisionPlane = Vector4.UnitW;
3195 3463
3464 if (m_lastColCount != coldata.Count)
3465 {
3466 m_updateCount = UPDATE_COUNT;
3467 m_lastColCount = coldata.Count;
3468 }
3469
3196 if (coldata.Count != 0 && Animator != null) 3470 if (coldata.Count != 0 && Animator != null)
3197 { 3471 {
3198 switch (Animator.CurrentMovementAnimation) 3472 switch (Animator.CurrentMovementAnimation)
@@ -3840,5 +4114,16 @@ namespace OpenSim.Region.Framework.Scenes
3840 m_reprioritization_called = false; 4114 m_reprioritization_called = false;
3841 } 4115 }
3842 } 4116 }
4117
4118 private Vector3 Quat2Euler(Quaternion rot){
4119 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4120 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4121 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4122 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4123 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4124 return(new Vector3(x,y,z));
4125 }
4126
4127
3843 } 4128 }
3844} \ No newline at end of file 4129}
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;